/// Filter lines using regular expressions (custom dialog)

// Modified by Infocatcher
// version: 2011-03-23

try
{
  var hMainWnd=AkelPad.GetMainWnd();
}
catch (oError)
{
  WScript.Quit();
}

if (!(AkelPad.Include("sr_function.js")) || !(AkelPad.Include("selCompleteLine.js")))
{
  WScript.Quit();
}

//Options
var bMustStart=false;
var bMustEnd=false;
var bRegExp=true;      //Regular expressions search
var bSensitive=false;  //Case sensitive search
var bNewDoc=false;
var bAllDocuments=false;
var nAction=1;         //1 - extract lines that contains pFindIt (include)
                       //2 - delete lines that contains pFindIt (exclude)
var nFilterStrings=10;
var bPrefillSelected=true;

//Control IDs
var IDC_INPUT          =1001;
var IDC_MUST_START     =1002;
var IDC_MUST_END       =1003;
var IDC_REGEXP         =1004;
var IDC_MATCHCASE      =1005;
var IDC_NEWDOC         =1006;
var IDC_ALLFILES       =1007;
var IDC_INCLUDE        =1008;
var IDC_EXCLUDE        =1009;
var IDC_OK             =1010;
var IDC_APPLY          =1011;
var IDC_CANCEL         =1012;
var IDC_STATIC         =-1;

//Variables
var WshShell=new ActiveXObject("WScript.shell");
var oSys=AkelPad.SystemFunction();
var oSet=AkelPad.ScriptSettings();
var pScriptName=WScript.ScriptName;
var hInstanceDLL=AkelPad.GetInstanceDll();
var dialogClass = "AkelPad::Scripts::" + pScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");
var bAkelEdit=AkelPad.IsAkelEdit();
var lpFilterStrings=[];
var hWndDialog;
var hWndStatic;
var hWndString;
var hWndMustStart;
var hWndMustEnd;
var hWndRegExp;
var hWndCase;
var hWndNewDoc;
var hWndAll;
var hWndGroup;
var hWndInclude;
var hWndExclude;

var hWndOK;
var hWndApply;
var hWndCancel;
var ptScale=[];
var hGuiFont;
var lpBuffer;
var pFindIt="";
var pStrPrefill="";
var nStrExpLength;

if (ScriptEngineMajorVersion() <= 5 && ScriptEngineMinorVersion() < 5)
{
  AkelPad.MessageBox(hMainWnd, GetLangString(0), pScriptName, 48 /*MB_ICONEXCLAMATION*/);
  WScript.Quit();
}

var IDC_RECALL=1099;
hWndDialog=oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, dialogClass, 0);
if (hWndDialog)
{
  oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 273 /*WM_COMMAND*/, IDC_RECALL, 0);
  WScript.Quit();
}

if (AkelPad.WindowRegisterClass(dialogClass))
{
  if (lpBuffer=AkelPad.MemAlloc(256 * _TSIZE))
  {
    var sizeNonClient=[];
    sizeNonClient.cx=oSys.Call("user32::GetSystemMetrics", 7 /*SM_CXFIXEDFRAME*/) * 2;
    sizeNonClient.cy=oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYFIXEDFRAME*/) * 2 + oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/);

    //Get scale factor for ScaleX and ScaleY
    ScaleInit(0, hMainWnd);

    //Create dialog
    hWndDialog=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                         0,                              //dwExStyle
                         dialogClass,                    //lpClassName
                         0,                              //lpWindowName
                         0x90CA0000,                     //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                         ScaleX(0),                      //x
                         ScaleY(0),                      //y
                         ScaleX(348) + sizeNonClient.cx, //nWidth
                         ScaleY(210) + sizeNonClient.cy, //nHeight
                         hMainWnd,                       //hWndParent
                         0,                              //ID
                         hInstanceDLL,                   //hInstance
                         DialogCallback);                //Script function callback. To use it class must be registered by WindowRegisterClass.
    if (hWndDialog)
    {
      //Disable main window, to make dialog modal
      //oSys.Call("user32::EnableWindow", hMainWnd, false);

      AkelPad.ScriptNoMutex(); // Allow other scripts running
      AkelPad.WindowGetMessage(); //Message loop
    }
    AkelPad.MemFree(lpBuffer);
  }
  AkelPad.WindowUnregisterClass(dialogClass);
}


function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 1)  //WM_CREATE
  {
    //Read settings
    if (oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/))
    {
      //lpFilterStrings=new Array(nFilterStrings);
      for (i=0; i < nFilterStrings; ++i)
      {
        var tmp=oSet.Read("Find" + i, 3 /*PO_STRING*/);
        if (tmp == undefined)
          break;
        lpFilterStrings[i]=tmp;
      }
      pFindIt=lpFilterStrings[0] || "";

      bMustStart=oSet.Read("MustStart", 1 /*PO_DWORD*/);
      bMustEnd=oSet.Read("MustEnd", 1 /*PO_DWORD*/);
      bRegExp=oSet.Read("RegExp", 1 /*PO_DWORD*/);
      bNewDoc=oSet.Read("NewDoc", 1 /*PO_DWORD*/);
      bSensitive=oSet.Read("Sensitive", 1 /*PO_DWORD*/);
      bAllDocuments=oSet.Read("AllFiles", 1 /*PO_DWORD*/);
      nAction=oSet.Read("Action", 1 /*PO_DWORD*/);

      oSet.End();
    }

    if (bPrefillSelected)
    {
      var selText = AkelPad.GetSelText();
      if (!/\n|\r/.test(selText))
        pStrPrefill = selText.substr(0, 255);
    }

    hGuiFont=oSys.Call("gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);

    //Dialog caption
    oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, pScriptName);


    ////Static window

    //Create window
    hWndStatic=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                         0,            //dwExStyle
                         "STATIC",     //lpClassName
                         0,            //lpWindowName
                         0x50000000,   //WS_VISIBLE|WS_CHILD
                         ScaleX(14),   //x
                         ScaleY(13),   //y
                         ScaleX(305),  //nWidth
                         ScaleY(13),   //nHeight
                         hWnd,         //hWndParent
                         IDC_STATIC,   //ID
                         hInstanceDLL, //hInstance
                         0);           //lpParam
    //Set font and text
    SetWindowFontAndText(hWndStatic, hGuiFont, GetLangString(3));


    ////Edit window

    //Create window
    hWndString=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                       0,            //dwExStyle
                       "COMBOBOX",   //lpClassName
                       0,            //lpWindowName
                       0x50210042,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|WS_VSCROLL|CBS_DROPDOWN|CBS_AUTOHSCROLL
                       ScaleX(11),   //x
                       ScaleY(31),   //y
                       ScaleX(323),  //nWidth
                       ScaleY(160),  //nHeight
                       hWnd,         //hWndParent
                       IDC_INPUT,    //ID
                       hInstanceDLL, //hInstance
                       0);           //lpParam
    //Fill combobox
    for (i=0; i < nFilterStrings && lpFilterStrings[i] != undefined; ++i)
    {
      AkelPad.MemCopy(lpBuffer, lpFilterStrings[i], _TSTR);
      AkelPad.SendMessage(hWndString, 0x143 /*CB_ADDSTRING*/, 0, lpBuffer);
    }

    //Set font and text
    SetWindowFontAndText(hWndString, hGuiFont, pStrPrefill);
    !pStrPrefill && AkelPad.SendMessage(hWndString, 0x14E /*CB_SETCURSEL*/, 0, 0);


    //Select text
    AkelPad.SendMessage(hWndString, 177 /*EM_SETSEL*/, 0, -1);


    ////Checkbox Must start

    //Create window
    hWndMustStart=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                         0,              //dwExStyle
                         "BUTTON",       //lpClassName
                         0,              //lpWindowName
                         0x50010003,     //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
                         ScaleX(14),     //x
                         ScaleY(60),     //y
                         ScaleX(155),    //nWidth
                         ScaleY(16),     //nHeight
                         hWnd,           //hWndParent
                         IDC_MUST_START, //ID
                         hInstanceDLL,   //hInstance
                         0);             //lpParam
    //Set font and text
    SetWindowFontAndText(hWndMustStart, hGuiFont, GetLangString(9));


    ////Checkbox Must end

    //Create window
    hWndMustEnd=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                         0,              //dwExStyle
                         "BUTTON",       //lpClassName
                         0,              //lpWindowName
                         0x50010003,     //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
                         ScaleX(177),    //x
                         ScaleY(60),     //y
                         ScaleX(155),    //nWidth
                         ScaleY(16),     //nHeight
                         hWnd,           //hWndParent
                         IDC_MUST_END,   //ID
                         hInstanceDLL,   //hInstance
                         0);             //lpParam
    //Set font and text
    SetWindowFontAndText(hWndMustEnd, hGuiFont, GetLangString(10));


    ////Checkbox RegExp

    //Create window
    hWndRegExp=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                         0,            //dwExStyle
                         "BUTTON",     //lpClassName
                         0,            //lpWindowName
                         0x50010003,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
                         ScaleX(14),   //x
                         ScaleY(89),   //y
                         ScaleX(155),  //nWidth
                         ScaleY(16),   //nHeight
                         hWnd,         //hWndParent
                         IDC_REGEXP,   //ID
                         hInstanceDLL, //hInstance
                         0);           //lpParam
    //Set font and text
    SetWindowFontAndText(hWndRegExp, hGuiFont, GetLangString(4));


    ////Checkbox Sensitive

    //Create window
    hWndCase=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                       0,             //dwExStyle
                       "BUTTON",      //lpClassName
                       0,             //lpWindowName
                       0x50010003,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
                       ScaleX(14),    //x
                       ScaleY(110),   //y
                       ScaleX(155),   //nWidth
                       ScaleY(16),    //nHeight
                       hWnd,          //hWndParent
                       IDC_MATCHCASE, //ID
                       hInstanceDLL,  //hInstance
                       0);            //lpParam
    //Set font and text
    SetWindowFontAndText(hWndCase, hGuiFont, GetLangString(5));


    ////Checkbox New document

    //Create window
    hWndNewDoc=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                       0,             //dwExStyle
                       "BUTTON",      //lpClassName
                       0,             //lpWindowName
                       0x50010003,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
                       ScaleX(14),    //x
                       ScaleY(131),   //y
                       ScaleX(155),   //nWidth
                       ScaleY(16),    //nHeight
                       hWnd,          //hWndParent
                       IDC_NEWDOC,    //ID
                       hInstanceDLL,  //hInstance
                       0);            //lpParam
    //Set font and text
    SetWindowFontAndText(hWndNewDoc, hGuiFont, GetLangString(12));

    ////GroupBox 1

    //Create window
    hWndGroup=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                        0,            //dwExStyle
                        "BUTTON",     //lpClassName
                        0,            //lpWindowName
                        0x50000007,   //WS_VISIBLE|WS_CHILD|BS_GROUPBOX
                        ScaleX(180),  //x
                        ScaleY(96),   //y
                        ScaleX(155),  //nWidth
                        ScaleY(58),   //nHeight
                        hWnd,         //hWndParent
                        IDC_STATIC,   //ID
                        hInstanceDLL, //hInstance
                        0);           //lpParam
    //Set font and text
    SetWindowFontAndText(hWndGroup, hGuiFont, "");


    ////Checkbox Include

    //Create window
    hWndInclude=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                          0,            //dwExStyle
                          "BUTTON",     //lpClassName
                          0,            //lpWindowName
                          0x50000009,   //WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
                          ScaleX(186),  //x
                          ScaleY(110),  //y
                          ScaleX(143),  //nWidth
                          ScaleY(16),   //nHeight
                          hWnd,         //hWndParent
                          IDC_INCLUDE,  //ID
                          hInstanceDLL, //hInstance
                          0);           //lpParam
    //Set font and text
    SetWindowFontAndText(hWndInclude, hGuiFont, GetLangString(6));


    ////Checkbox Exclude

    //Create window
    hWndExclude=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                          0,            //dwExStyle
                          "BUTTON",     //lpClassName
                          0,            //lpWindowName
                          0x50000009,   //WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
                          ScaleX(186),  //x
                          ScaleY(131),  //y
                          ScaleX(143),  //nWidth
                          ScaleY(16),   //nHeight
                          hWnd,         //hWndParent
                          IDC_EXCLUDE,  //ID
                          hInstanceDLL, //hInstance
                          0);           //lpParam
    //Set font and text
    SetWindowFontAndText(hWndExclude, hGuiFont, GetLangString(7));


    if (AkelPad.IsMDI())
    {
      ////Checkbox All files

      //Create window
      hWndAll=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                         0,             //dwExStyle
                         "BUTTON",      //lpClassName
                         0,             //lpWindowName
                         0x50010003,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
                         ScaleX(14),    //x
                         ScaleY(152),   //y
                         ScaleX(155),   //nWidth
                         ScaleY(16),    //nHeight
                         hWnd,          //hWndParent
                         IDC_ALLFILES,  //ID
                         hInstanceDLL,  //hInstance
                         0);            //lpParam
      //Set font and text
      SetWindowFontAndText(hWndAll, hGuiFont, GetLangString(8));
    }


    ////OK button window

    //Create window
    hWndOK=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                      0,            //dwExStyle
                      "BUTTON",     //lpClassName
                      0,            //lpWindowName
                      0x50010000,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP
                      ScaleX(93),   //x
                      ScaleY(175),  //y
                      ScaleX(75),   //nWidth
                      ScaleY(23),   //nHeight
                      hWnd,         //hWndParent
                      IDC_OK,       //ID
                      hInstanceDLL, //hInstance
                      0);           //lpParam
    //Set font and text
    SetWindowFontAndText(hWndOK, hGuiFont, GetLangString(1));


    ////Apply button window

    //Create window
    hWndApply=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                     0,            //dwExStyle
                     "BUTTON",     //lpClassName
                     0,            //lpWindowName
                     0x50010000,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP
                     ScaleX(177),  //x
                     ScaleY(175),  //y
                     ScaleX(75),   //nWidth
                     ScaleY(23),   //nHeight
                     hWnd,         //hWndParent
                     IDC_APPLY,    //ID
                     hInstanceDLL, //hInstance
                     0);           //lpParam
    //Set font and text
    SetWindowFontAndText(hWndApply, hGuiFont, GetLangString(11));


    ////Cancel button window

    //Create window
    hWndCancel=oSys.Call("user32::CreateWindowEx" + _TCHAR,
                         0,            //dwExStyle
                         "BUTTON",     //lpClassName
                         0,            //lpWindowName
                         0x50010000,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP
                         ScaleX(261),  //x
                         ScaleY(175),  //y
                         ScaleX(75),   //nWidth
                         ScaleY(23),   //nHeight
                         hWnd,         //hWndParent
                         IDC_CANCEL,   //ID
                         hInstanceDLL, //hInstance
                         0);           //lpParam
    //Set font and text
    SetWindowFontAndText(hWndCancel, hGuiFont, GetLangString(2));


    //Checks
    if (bMustStart)    AkelPad.SendMessage(hWndMustStart, 241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);
    if (bMustEnd)      AkelPad.SendMessage(hWndMustEnd,   241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);
    if (bRegExp)       AkelPad.SendMessage(hWndRegExp,    241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);
    if (bSensitive)    AkelPad.SendMessage(hWndCase,      241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);
    if (bNewDoc)       AkelPad.SendMessage(hWndNewDoc,    241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);
    if (bAllDocuments) AkelPad.SendMessage(hWndAll,       241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);
    if (nAction == 2)
      AkelPad.SendMessage(hWndExclude, 241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);
    else
      AkelPad.SendMessage(hWndInclude, 241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);

    oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_REGEXP, 0);

    //Center dialog
    CenterWindow(hMainWnd, hWnd);
  }
  else if (uMsg == 7)  //WM_SETFOCUS
  {
    oSys.Call("user32::SetFocus", hWndString);
  }
  else if (uMsg == 256)  //WM_KEYDOWN
  {
    if (wParam == 27)  //VK_ESCAPE
    {
      //Escape key pushes Cancel button
      oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 273 /*WM_COMMAND*/, IDC_CANCEL, 0);
    }
    else if (wParam == 13)  //VK_RETURN
    {
      if (oSys.Call("user32::GetAsyncKeyState", 160 /*VK_LSHIFT*/) ||
          oSys.Call("user32::GetAsyncKeyState", 161 /*VK_RSHIFT*/) ||
          oSys.Call("user32::GetAsyncKeyState", 162 /*VK_LCONTROL*/) ||
          oSys.Call("user32::GetAsyncKeyState", 163 /*VK_RCONTROL*/))
        oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_APPLY, 0);
      else //Return key pushes OK button
        oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 273 /*WM_COMMAND*/, IDC_OK, 0);
    }
  }
  else if (uMsg == 273)  //WM_COMMAND
  {
    if ((wParam & 0xffff) == IDC_INPUT)
    {
      nStrExpLength=oSys.Call("user32::GetWindowTextLength" + _TCHAR, hWndString);

      oSys.Call("user32::EnableWindow", hWndOK,    !!nStrExpLength);
      oSys.Call("user32::EnableWindow", hWndApply, !!nStrExpLength);
    }
    else if ((wParam & 0xffff) == IDC_MUST_START ||
             (wParam & 0xffff) == IDC_MUST_END ||
             (wParam & 0xffff) == IDC_REGEXP ||
             (wParam & 0xffff) == IDC_MATCHCASE ||
             (wParam & 0xffff) == IDC_NEWDOC ||
             (wParam & 0xffff) == IDC_ALLFILES ||
             (wParam & 0xffff) == IDC_INCLUDE ||
             (wParam & 0xffff) == IDC_EXCLUDE)
    {
      if ((wParam & 0xffff) == IDC_MUST_START)
        bMustStart=AkelPad.SendMessage(hWndMustStart, 240 /*BM_GETCHECK*/, 0, 0);
      else if ((wParam & 0xffff) == IDC_MUST_END)
        bMustEnd=AkelPad.SendMessage(hWndMustEnd, 240 /*BM_GETCHECK*/, 0, 0);
      else if ((wParam & 0xffff) == IDC_REGEXP)
      {
        bRegExp=AkelPad.SendMessage(hWndRegExp, 240 /*BM_GETCHECK*/, 0, 0);
        oSys.Call("user32::EnableWindow", hWndMustStart, !bRegExp);
        oSys.Call("user32::EnableWindow", hWndMustEnd,   !bRegExp);
      }
      else if ((wParam & 0xffff) == IDC_MATCHCASE)
        bSensitive=AkelPad.SendMessage(hWndCase, 240 /*BM_GETCHECK*/, 0, 0);
      else if ((wParam & 0xffff) == IDC_NEWDOC)
        bNewDoc=AkelPad.SendMessage(hWndNewDoc, 240 /*BM_GETCHECK*/, 0, 0);
      else if ((wParam & 0xffff) == IDC_ALLFILES)
        bAllDocuments=AkelPad.SendMessage(hWndAll, 240 /*BM_GETCHECK*/, 0, 0);
      else if ((wParam & 0xffff) == IDC_INCLUDE)
        nAction=1;
      else if ((wParam & 0xffff) == IDC_EXCLUDE)
        nAction=2;
    }
    else if ((wParam & 0xffff) == IDC_RECALL)
    {
      if (bPrefillSelected)
      {
        var selText = AkelPad.GetSelText();
        if (selText && !/\n|\r/.test(selText))
        {
          pStrPrefill = selText.substr(0, 255);
          SetWindowFontAndText(hWndString, hGuiFont, pStrPrefill);
          //AkelPad.SendMessage(hWndString, 177 /*EM_SETSEL*/, 0, -1);
          AkelPad.SendMessage(hWndDialog, 7 /*WM_SETFOCUS*/, 0, 0);
        }
      }
      if (oSys.Call("user32::IsIconic", hWndDialog))
        oSys.Call("user32::ShowWindow", hWndDialog, 9 /*SW_RESTORE*/);
      AkelPad.SendMessage(hWndDialog, 7 /*WM_SETFOCUS*/, 0, 0);
    }
    else if ((wParam & 0xffff) == IDC_OK ||
             (wParam & 0xffff) == IDC_APPLY)
    {
      oSys.Call("user32::GetWindowText" + _TCHAR, hWndString, lpBuffer, 256);
      pFindIt=AkelPad.MemRead(lpBuffer, _TSTR);

      if (nFilterStrings)
      {
        for (i=0; i < nFilterStrings; ++i)
        {
          if (lpFilterStrings[i] == pFindIt)
          {
            AkelPad.SendMessage(hWndString, 0x144 /*CB_DELETESTRING*/, i, 0);
            DeleteFromArray(lpFilterStrings, i, 1);
          }
        }
        InsertInArray(lpFilterStrings, pFindIt, 0);
        if (lpFilterStrings.length > nFilterStrings)
          DeleteFromArray(lpFilterStrings, -1, 1);

        AkelPad.MemCopy(lpBuffer, pFindIt, _TSTR);
        AkelPad.SendMessage(hWndString, 0x14A /*CB_INSERTSTRING*/, 0, lpBuffer);
        AkelPad.SendMessage(hWndString, 0x14E /*CB_SETCURSEL*/, 0, 0);
      }

      oSys.Call("user32::EnableWindow", hWndOK,    false);
      oSys.Call("user32::EnableWindow", hWndApply, false);
      oSys.Call("user32::EnableWindow", hMainWnd,  false); // Block main window
      //if (hWndAll) oSys.Call("user32::EnableWindow", hWndAll, false);

      //if ((wParam & 0xffff) == IDC_OK)
      //  LinesFilter(false);
      //else
      //  LinesFilter(true);
      try
      {
        LinesFilter();
      }
      catch (e)
      {
        var err = e;
      }

      //oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 273 /*WM_COMMAND*/, IDC_INPUT, 0);
      oSys.Call("user32::EnableWindow", hWndOK,    true);
      oSys.Call("user32::EnableWindow", hWndApply, true);
      oSys.Call("user32::EnableWindow", hMainWnd,  true);

      if (err) throw err;

      if ((wParam & 0xffff) == IDC_OK) oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 16 /*WM_CLOSE*/, 0, 0);
    }
    else if ((wParam & 0xffff) == IDC_CANCEL)
    {
      oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 16 /*WM_CLOSE*/, 0, 0);
    }
  }
  else if (uMsg == 16)  //WM_CLOSE
  {
    //Enable main window
    //oSys.Call("user32::EnableWindow", hMainWnd, true);

    //Save settings
    if (oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/))
    {
      for (i=0; i < nFilterStrings; ++i)
        oSet.Write("Find" + i, 3 /*PO_STRING*/, lpFilterStrings[i]);

      oSet.Write("MustStart", 1 /*PO_DWORD*/, bMustStart);
      oSet.Write("MustEnd", 1 /*PO_DWORD*/, bMustEnd);
      oSet.Write("RegExp", 1 /*PO_DWORD*/, bRegExp);
      oSet.Write("Sensitive", 1 /*PO_DWORD*/, bSensitive);
      oSet.Write("NewDoc", 1 /*PO_DWORD*/, bNewDoc);
      oSet.Write("AllFiles", 1 /*PO_DWORD*/, bAllDocuments);
      oSet.Write("Action", 1 /*PO_DWORD*/, nAction);

      oSet.End();
    }

    //Destroy dialog
    oSys.Call("user32::DestroyWindow", hWnd);
  }
  else if (uMsg == 2)  //WM_DESTROY
  {
    //Exit message loop
    oSys.Call("user32::PostQuitMessage", 0);
  }
  return 0;
}

function LinesFilter()
{
  var hWndFrameInit=AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
  var hWndEditCur;
  var oPattern;
  var pSelText;
  var pArray;
  var pResult;
  var pResults=[];
  var nSelStart;
  var nSelEnd;
  var i;

  if (bRegExp && AkelPad.Include("cnRegExp.js")) pFindIt=cnRegExp(pFindIt);

  oPattern=new RegExp(
    bRegExp
      ? pFindIt
      : "^" + (bMustStart ? "" : ".*") + EscRegExp(pFindIt) + (bMustEnd ? "" : ".*") + "$",
    (bSensitive ? "" : "i")
  );

  while (1)
  {
    hWndEditCur=AkelPad.GetEditWnd();
    nSelStart=AkelPad.GetSelStart();
    nSelEnd=AkelPad.GetSelEnd();
    if (nSelStart == nSelEnd || !/\n|\r/.test(AkelPad.GetSelText()))
    {
      //AkelPad.SetSel(0, -1);
      var selectAll = true;
      pSelText = AkelPad.GetTextRange(0, -1, 2 /*\n*/);
    }
    else
    {
      //SelCompliteLine(hWndEditCur, nSelStart, nSelEnd);
      var sel = selCompleteLine(hWndEditCur, nSelStart, nSelEnd);
      pSelText = AkelPad.GetTextRange(sel[0], sel[1], 2 /*\n*/);
    }
    //nSelStart=AkelPad.GetSelStart();
    //nSelEnd=AkelPad.GetSelEnd();
    //pSelText=AkelPad.GetSelText(2 /*\n*/);
    if (!bAkelEdit)
      pSelText=pSelText.replace(/\r/g, "\n");
    pResult="";

    //if (nAction == 1)
    //{
    //  if (pArray=pSelText.match(oPattern))
    //    pResult=pArray.join("");
    //}
    //else
    //{
    //  pResult=pSelText.replace(oPattern, "");
    //}

    var lines = pSelText.split("\n");
    var res = [];
    var include = nAction == 1;
    var exclude = nAction == 2;
    for (i = 0, l = lines.length; i < l; i++)
    {
      var line = lines[i];
      if (oPattern.test(line))
      {
        if (include) res.push(line);
      }
      else
      {
        if (exclude) res.push(line);
      }
    }
    pResult = res.join("\n");

    if (bNewDoc)
    {
      if (!bAllDocuments)
        createNewDoc(pResult);
      else if (pResult)
        pResults[pResults.length] = pResult;
    }
    else
    {
      if (selectAll)
        AkelPad.SetSel(0, -1);
      else
        AkelPad.SetSel(sel[0], sel[1]);

      //nFirstLine=SaveLineScroll(hWndEditCur);
      AkelPad.ReplaceSel(pResult, -2);
      //RestoreLineScroll(hWndEditCur, nFirstLine);
      //AkelPad.SetSel(nSelStart, nSelStart);
      //AkelPad.SetSel(nSelStart, nSelStart + pResult.length);
    }

    if (bAllDocuments)
    {
      //Next MDI frame
      AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4316 /*IDM_WINDOW_FRAMENEXT*/, 0);
      if (hWndFrameInit == AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0))
      {
        if (bNewDoc)
        {
          createNewDoc(pResults.join("\n"));
          pResults=[];
        }
        break;
      }
    }
    else break;
  }
}

function createNewDoc(text) {
	if(!text)
		return;
        AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*wParam=MAKEWPARAM(0,IDM_FILE_NEW)*/, 1 /*lParam=TRUE*/);
        AkelPad.ReplaceSel(text);
        AkelPad.SendMessage(AkelPad.GetEditWnd(), 3087 /*AEM_SETMODIFY*/, false, 0);
        AkelPad.SendMessage(AkelPad.GetEditWnd(), 3079 /*AEM_EMPTYUNDOBUFFER*/, 0, 0);
        AkelPad.SetSel(0, 0);
}


//Functions
function GetLangString(nStringID)
{
  var nLangID=AkelPad.GetLangId(1 /*LANGID_PRIMARY*/);

  if (nLangID == 0x4) //LANG_CHINESE
  {
    if (nStringID == 0)
      return "JScript 版本低于 5.5。";
    if (nStringID == 1)
      return "确定";
    if (nStringID == 2)
      return "取消";
    if (nStringID == 3)
      return "字符串包含:";
    if (nStringID == 4)
      return "正则表达式";
    if (nStringID == 5)
      return "区分大小写";
    if (nStringID == 6)
      return "包括行";
    if (nStringID == 7)
      return "排除行";
    if (nStringID == 8)
      return "所有文件";
    if (nStringID == 9)
      return "在开始";
    if (nStringID == 10)
      return "在结束";
    if (nStringID == 11)
      return "应用";
    if (nStringID == 12)
      return "到新文档";
  }
  else
  {
    if (nStringID == 0)
      return "JScript version is less than 5.5.";
    if (nStringID == 1)
      return "OK";
    if (nStringID == 2)
      return "Cancel";
    if (nStringID == 3)
      return "String contain:";
    if (nStringID == 4)
      return "Regular expressions";
    if (nStringID == 5)
      return "Case sensitive";
    if (nStringID == 6)
      return "Include lines";
    if (nStringID == 7)
      return "Exclude lines";
    if (nStringID == 8)
      return "All files";
    if (nStringID == 9)
      return "Must start";
    if (nStringID == 10)
      return "Must end";
    if (nStringID == 11)
      return "Apply";
    if (nStringID == 12)
      return "To new document";
  }
  return "";
}