// http://akelpad.sourceforge.net/forum/viewtopic.php?p=29052#29052
// Version: 1.1
// Author: Shengalts Aleksander aka Instructor
//
//
// Description(1033): Fast macro execution and/or test how fast macro executed.
// Description(1049): Быстрое выполнение скрипта и/или тест скорости выполнения скрипта.
//
// Arguments:
// -Macro="MyMacro"     -Saved macro name. If "", then execute last recorded macro. Default is "".
// -Repeat=10           -Repeat count (default is 1).
// -NoRedraw=2          -Lock redraw for fast execution (one of the following):
//                         0  don't lock redraw.
//                         1  edit window (default).
//                         2  main window.
// -Test=true           -Show message with execution time and last error value (default is false).
//
// Usage:
// Call("Scripts::Main", 1, "MacroSpeed.js", `-Macro="MyMacro" -Repeat=0`)

//Arguments
var pMacro=AkelPad.GetArgValue("Macro", "");
var nRepeat=AkelPad.GetArgValue("Repeat", 1);
var nNoRedraw=AkelPad.GetArgValue("NoRedraw", 1);
var bTest=AkelPad.GetArgValue("Test", false);

//Variables
var hMainWnd=AkelPad.GetMainWnd();
var hWndEdit=AkelPad.GetEditWnd();
var oSys=AkelPad.SystemFunction();
var hWndLock=0;
var nTimeStart;
var nTimeEnd;
var lpdwLastError;
var dwLastError=0;

if (nNoRedraw == 1)
  hWndLock=hWndEdit;
else if (nNoRedraw == 2)
  hWndLock=hMainWnd;

if (lpdwLastError=AkelPad.MemAlloc(4 /*sizeof(DWORD)*/))
{
  if (bTest) nStartTime=oSys.Call("kernel32::GetTickCount");
  if (hWndLock) SetRedraw(hWndLock, false);

  //Execute macro
  AkelPad.Call("Macros::Main", 1, pMacro, nRepeat, 1 /*EMF_SCRIPTSNOSYNC*/);

  //Wait macro
  for (;;)
  {
    WScript.Sleep(100);
    AkelPad.Call("Macros::Main", 4, lpdwLastError);
    dwLastError=AkelPad.MemRead(lpdwLastError, 3 /*DT_DWORD*/);
    if (!(dwLastError & 0x0001 /*MS_PLAYING*/) && !(dwLastError & 0x1000 /*MS_INITIALIZING*/)) break;
  }

  if (hWndLock) SetRedraw(hWndLock, true);
  if (bTest)
  {
    nTimeEnd=oSys.Call("kernel32::GetTickCount");
    WScript.Echo("Time (ms)=" + (nTimeEnd - nStartTime) + "; Last error=" + dwLastError);
  }
  AkelPad.MemFree(lpdwLastError);
}

function SetRedraw(hWnd, nNoRedraw)
{
  AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, nNoRedraw, 0);
  if (nNoRedraw) oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
