// http://akelpad.sourceforge.net/forum/viewtopic.php?p=35176#35176
// Author: Скрипт переделал AZJIO из скрипта TabSwitch.js от Instructor
//
//
// Description(1033): Closes tabs of the specified type, for example, all htm files
// Description(1049): Закрывает вкладки определённого типа, например все htm-файлы
//
// Arguments:
// -CtrlTab=false       -No Ctrl+Tab hotkey is assigned to TabSwitch.js (default is true).
// -MinTabs=2           -Minimum number of tabs before switch window appeared (default is 2).
// -FontName="Arial"    -Font name. Unchanged, if "".
// -FontStyle=3         -Font style (one of the following):
//                         0  ignored (default).
//                         1  normal.
//                         2  bold.
//                         3  italic.
//                         4  bold italic.
// -FontSize=10         -Font size. Unchanged, if 0 (default).
// -LineGap=10          -Space between items (default is 1).
// -SingleClick=false   -Single mouse click chooses item (default is true).
// -ShowModify=2        -Show modification sign (one of the following):
//                         0  hidden.
//                         1  display asterisk * at the end (default).
//                         2  display asterisk * at the beginning.
// -WindowLeft=100      -Left window position. Special values:
//                        -1 centered (default).
//                        -2 cursor position.
// -WindowTop=100       -Top window position. Special values:
//                        -1 centered (default).
//                        -2 cursor position.
// -WindowMaxHeight=500 -Maximum window height. Special values:
//                        -1 unlimited (default).
// -WindowMaxWidth=500  -Maximum window width. Special values:
//                        -1 unlimited (default).
//
// Usage:
// Toolbar button example:
//   -"Close tabs by extension" Call("Scripts::Main", 1, "CloseTabByExt.js", `-CtrlTab=false -MinTabs=1 -WindowLeft=%bl -WindowTop=%bb`)
// ContextMenu item example:
//   -"Close tabs by extension" Call("Scripts::Main", 1, "CloseTabByExt.js", `-CtrlTab=false -MinTabs=1 -WindowLeft=-2 -WindowTop=-2`)

//Arguments
var bCtrlTab = AkelPad.GetArgValue("CtrlTab", true);
var nMinTabs = AkelPad.GetArgValue("MinTabs", 2);
var pFontName = AkelPad.GetArgValue("FontName", "");
var nFontStyle = AkelPad.GetArgValue("FontStyle", 0);
var nFontSize = AkelPad.GetArgValue("FontSize", 0);
var nLineGap = AkelPad.GetArgValue("LineGap", 1);
var bSingleClick = AkelPad.GetArgValue("SingleClick", true);
var nWindowLeft = AkelPad.GetArgValue("WindowLeft", -1);
var nWindowTop = AkelPad.GetArgValue("WindowTop", -1);
var nWindowMaxHeight = AkelPad.GetArgValue("WindowMaxHeight", -1);
var nWindowMaxWidth = AkelPad.GetArgValue("WindowMaxWidth", -1);
var bAsk = AkelPad.GetArgValue("Ask", false);

//Variables
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();
var hInstanceDLL = AkelPad.GetInstanceDll();
var pClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");
var hWndContainer = 0;
var hWndListBox = 0;
var hHookPost;
var hHookSend;
var dwMainThreadID = oSys.Call("user32::GetWindowThreadProcessId", hMainWnd, 0);
var hSubClass;
var hDC;
var hBrushHollow;
var hFontEdit;
var lpFrameList = [];
var lpAllList = [];
var rcMain = [];
var ptPoint = [];
var nItemHeight;
var nScreenWidth;
var nControlWidth;
var nControlHeight;
var nMaxControlHeight;
var nCharWidth;
var nCharHeight;
var nMaxCharWidth = 0;
var nMaxCharHeight = 0;
var nIconSize = 16;
var nIconGap = 2;
var bNoSwitch = false;
var i;



//Get list of documents
nCurSel = GetFrameList(lpFrameList, lpAllList);
// WScript.Echo(lpFrameList.length);
if (lpFrameList.length > 0)
// if (lpFrameList.length >= nMinTabs && lpFrameList.length > 0)
{

	//Get font
	if (pFontName || nFontStyle || nFontSize)
		hFontEdit = CreateFont(pFontName, nFontStyle, nFontSize);
	else
		hFontEdit = AkelPad.SendMessage(hWndEdit, 0x31 /*WM_GETFONT*/ , 0, 0);
	if (!hFontEdit) WScript.Quit();

	//Get maximum character size
	if (lpSize = AkelPad.MemAlloc(8 /*sizeof(SIZE)*/ )) {
		if (hDC = oSys.Call("user32::GetDC", hWndEdit)) {
			oSys.Call("gdi32::SelectObject", hDC, hFontEdit);

			for (i = 0; i < lpFrameList.length; ++i) {
				if (oSys.Call("gdi32::GetTextExtentPoint32" + _TCHAR, hDC, lpFrameList[i][0], lpFrameList[i][0].length, lpSize)) {
					nCharWidth = AkelPad.MemRead(_PtrAdd(lpSize, 0) /*offsetof(SIZE, cx)*/ , 3 /*DT_DWORD*/ );
					nCharHeight = AkelPad.MemRead(_PtrAdd(lpSize, 4) /*offsetof(SIZE, cy)*/ , 3 /*DT_DWORD*/ );
					if (nCharWidth > nMaxCharWidth) nMaxCharWidth = nCharWidth;
					if (nCharHeight > nMaxCharHeight) nMaxCharHeight = nCharHeight;
				}
			}
			oSys.Call("user32::ReleaseDC", hWndEdit, hDC);
		}
		nMaxCharWidth += nIconSize + nIconGap + 16;

		AkelPad.MemFree(lpSize);
	}

	//Create dialog
	if (AkelPad.WindowRegisterClass(pClassName, 0x21 /*WM_MOUSEACTIVATE*/ ,
			0x2B /*WM_DRAWITEM*/ )) {
		if (hWndContainer = oSys.Call("user32::CreateWindowEx" + _TCHAR, 0, pClassName, 0, 0x80000000 /*WS_POPUP*/ , 0, 0, 0, 0, hMainWnd, 0, hInstanceDLL, DialogCallback)) {
			if (hWndListBox = oSys.Call("user32::CreateWindowEx" + _TCHAR, 0, "LISTBOX", 0, 0x50700010 /*WS_VISIBLE|WS_CHILD|WS_HSCROLL|WS_VSCROLL|WS_DLGFRAME|LBS_OWNERDRAWFIXED*/ , 0, 0, 0, 0, hWndContainer, 0, hInstanceDLL, 0)) {
				//Make hWndContainer invisible
				hBrushHollow = oSys.Call("gdi32::GetStockObject", 5 /*HOLLOW_BRUSH*/ );
				oSys.Call("user32::SetClassLong" + _TCHAR, hWndContainer, -10 /*GCL_HBRBACKGROUND*/ , hBrushHollow);

				AkelPad.SendMessage(hWndListBox, 48 /*WM_SETFONT*/ , hFontEdit, 1);
				nItemHeight = nMaxCharHeight + nLineGap;
				i = AkelPad.SendMessage(hWndListBox, 0x1A1 /*LB_GETITEMHEIGHT*/ , 0, 0);
				if (nItemHeight < i)
					nItemHeight = i;
				else
					AkelPad.SendMessage(hWndListBox, 0x1A0 /*LB_SETITEMHEIGHT*/ , 0, nItemHeight);
				nMaxControlHeight = lpFrameList.length * nItemHeight + oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYDLGFRAME*/ ) * 2;
				if (nWindowMaxHeight > 0)
					nControlHeight = Math.min(nWindowMaxHeight, nMaxControlHeight);
				else
					nControlHeight = nMaxControlHeight;
				nControlHeight = Math.min(oSys.Call("user32::GetSystemMetrics", 62 /*SM_CYMAXIMIZED*/ ) - 8, nControlHeight);
				if (nWindowMaxWidth > 0)
					nControlWidth = Math.min(nWindowMaxWidth, nMaxCharWidth);
				else
					nControlWidth = nMaxCharWidth;
				nControlWidth = Math.min(oSys.Call("user32::GetSystemMetrics", 61 /*SM_CXMAXIMIZED*/ ) - 8, nControlWidth);

				if (nMaxCharWidth > nControlWidth) {
					AkelPad.SendMessage(hWndListBox, 0x194 /*LB_SETHORIZONTALEXTENT*/ , nMaxCharWidth, 0);
					if (nMaxControlHeight == nControlHeight)
						nControlHeight += oSys.Call("user32::GetSystemMetrics", 21 /*SM_CXHSCROLL*/ );
				}

				//Fill listbox
				for (i = 0; i < lpFrameList.length; ++i)
					oSys.Call("user32::SendMessage" + _TCHAR, hWndListBox, 0x180 /*LB_ADDSTRING*/ , 0, lpFrameList[i][0]);

				GetWindowSize(hMainWnd, 0, rcMain);
				if (nWindowLeft >= 0)
					rcMain.left = nWindowLeft;
				else if (nWindowLeft == -2) {
					GetCursorPos(ptPoint);
					rcMain.left = ptPoint.x;
				} else
					rcMain.left += rcMain.right / 2 - nControlWidth / 2;
				if (!(nScreenWidth = oSys.Call("user32::GetSystemMetrics", 78 /*SM_CXVIRTUALSCREEN*/ )))
					nScreenWidth = oSys.Call("user32::GetSystemMetrics", 61 /*SM_CXMAXIMIZED*/ );
				rcMain.left = Math.min(rcMain.left, Math.max((nScreenWidth - 8) - nControlWidth, 0));
				if (rcMain.left < 0) rcMain.left = 0;

				if (nWindowTop >= 0)
					rcMain.top = nWindowTop;
				else if (nWindowTop == -2) {
					GetCursorPos(ptPoint);
					rcMain.top = ptPoint.y;
				} else
					rcMain.top += rcMain.bottom / 2 - nControlHeight / 2;
				rcMain.top = Math.min(rcMain.top, Math.max((oSys.Call("user32::GetSystemMetrics", 62 /*SM_CYMAXIMIZED*/ ) - 8) - nControlHeight, 0));
				if (rcMain.top < 0) rcMain.top = 0;

				oSys.Call("user32::SetWindowPos", hWndContainer, 0, rcMain.left, rcMain.top, nControlWidth, nControlHeight, 0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/ );
				oSys.Call("user32::SetWindowPos", hWndListBox, 0, 0, 0, nControlWidth, nControlHeight, 0x16 /*SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE*/ );
				AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , nCurSel, 0);
				oSys.Call("user32::ShowWindow", hWndContainer, 4 /*SW_SHOWNOACTIVATE*/ );
				//oSys.Call("user32::SetFocus", hWndListBox);
				//oSys.Call("user32::ShowWindow", hWndContainer, 5 /*SW_SHOW*/);
				//oSys.Call("user32::UpdateWindow", hMainWnd);

				//Cause listbox is non-active, hook and send to listbox keyboard and mouse actions.
				if (hHookPost = AkelPad.ThreadHook(3 /*WH_GETMESSAGE*/ , HookPostCallback, dwMainThreadID, 0x201 /*WM_LBUTTONDOWN*/ ,
						0x0A1 /*WM_NCLBUTTONDOWN*/ ,
						0x204 /*WM_RBUTTONDOWN*/ ,
						0x0A4 /*WM_NCRBUTTONDOWN*/ ,
						0x207 /*WM_MBUTTONDOWN*/ ,
						0x0A7 /*WM_NCMBUTTONDOWN*/ ,
						0x100 /*WM_KEYDOWN*/ ,
						0x101 /*WM_KEYUP*/ ,
						0x104 /*WM_SYSKEYDOWN*/ ,
						0x105 /*WM_SYSKEYUP*/ ,
						0x20A /*WM_MOUSEWHEEL*/ )) {
					if (hHookSend = AkelPad.ThreadHook(4 /*WH_CALLWNDPROC*/ , HookSendCallback, dwMainThreadID, 0x6 /*WM_SETFOCUS*/ )) {
						if (hSubClass = AkelPad.WindowSubClass(hWndListBox, ListBoxCallback, 0x021 /*WM_MOUSEACTIVATE*/ ,
								0x087 /*WM_GETDLGCODE*/ ,
								0x100 /*WM_KEYDOWN*/ ,
								0x101 /*WM_KEYUP*/ ,
								0x201 /*WM_LBUTTONDOWN*/ ,
								0x202 /*WM_LBUTTONUP*/ ,
								0x203 /*WM_LBUTTONDBLCLK*/ )) {
							//Allow other scripts running
							AkelPad.ScriptNoMutex();

							//Message loop
							AkelPad.WindowGetMessage();

							AkelPad.WindowUnsubClass(hWndListBox);
						}
						AkelPad.ThreadUnhook(hHookSend);
					}
					AkelPad.ThreadUnhook(hHookPost);
				}

				if (!bNoSwitch) {
					i = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0);
					// oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/ , 0, lpFrameList[i][1]);
					// Редактируемый участок 1
					var Pos;
					var Ext;
					Pos = lpFrameList[i][0].indexOf(" - ")
					Ext = lpFrameList[i][0].substr(Pos + 3)
					if (bAsk)
					{
						var mess = "";
						for (i = 0; i < lpAllList.length; ++i) {
							if (Ext === lpAllList[i][0])
							{
								mess += AkelPad.GetFilePath(lpAllList[i][2], 2) + "\n";
							}
						}
						if (AkelPad.MessageBox(hMainWnd, mess, "Close those tabs?", 32, 0, 1 , "&OK", 0x1 , 2 , "&Cancel", 0) == 1)
						{
							for (i = 0; i < lpAllList.length; ++i) {
								if (Ext === lpAllList[i][0])
								{
									oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1287 /*AKD_FRAMEDESTROY*/ , 0, lpAllList[i][1]);
								}
							}
						}
					} else {
						for (i = 0; i < lpAllList.length; ++i) {
							if (Ext === lpAllList[i][0])
							{
								oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1287 /*AKD_FRAMEDESTROY*/ , 0, lpAllList[i][1]);
							}
						}
					}
					// Конец Редактируемый участок 1
				}
				//oSys.Call("user32::DestroyWindow", hWndListBox);
			}
			oSys.Call("user32::DestroyWindow", hWndContainer);
		}
		AkelPad.WindowUnregisterClass(pClassName);
	}

	//Release font
	if (pFontName || nFontStyle || nFontSize) {
		if (hFontEdit)
			oSys.Call("gdi32::DeleteObject", hFontEdit);
	}
} else {
	if (lpFrameList.length >= 2)
		oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/ , 0, lpFrameList[nCurSel][1]);
}

function DialogCallback(hWnd, uMsg, wParam, lParam) {
	if (uMsg == 0x021 /*WM_MOUSEACTIVATE*/ ) {
		return 3 /*MA_NOACTIVATE*/ ;
	} else if (uMsg == 0x2B /*WM_DRAWITEM*/ ) {
		var hDC;
		var hIcon;
		var nItemID;
		var nItemState;
		var lpItem;
		var rcItem = [];
		var crText;
		var crBk;
		var hBrushBk;
		var nModeBkOld;

		hDC = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 32 : 24) /*offsetof(DRAWITEMSTRUCT, hDC)*/ , 2 /*DT_QWORD*/ );
		nItemID = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 8 : 8) /*offsetof(DRAWITEMSTRUCT, itemID)*/ , 3 /*DT_DWORD*/ );
		nItemState = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 16) /*offsetof(DRAWITEMSTRUCT, itemState)*/ , 3 /*DT_DWORD*/ );
		lpItem = _PtrAdd(lParam, _X64 ? 40 : 28) /*offsetof(DRAWITEMSTRUCT, rcItem)*/ ;
		RectToArray(lpItem, rcItem);

		//Set background
		if (nItemState & 0x1 /*ODS_SELECTED*/ ) {
			crText = oSys.Call("user32::GetSysColor", 14 /*COLOR_HIGHLIGHTTEXT*/ );
			crBk = oSys.Call("user32::GetSysColor", 13 /*COLOR_HIGHLIGHT*/ );
			hBrushBk = oSys.Call("user32::GetSysColorBrush", 13 /*COLOR_HIGHLIGHT*/ );
		} else {
			crText = oSys.Call("user32::GetSysColor", 8 /*COLOR_WINDOWTEXT*/ );
			crBk = oSys.Call("user32::GetSysColor", 5 /*COLOR_WINDOW*/ );
			hBrushBk = oSys.Call("user32::GetSysColorBrush", 5 /*COLOR_WINDOW*/ );
		}
		oSys.Call("user32::FillRect", hDC, lpItem, hBrushBk);
		nModeBkOld = oSys.Call("gdi32::SetBkMode", hDC, 1 /*TRANSPARENT*/ );

		//Draw icon
		hIcon = AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 38 /*FI_ICONHANDLE*/ , lpFrameList[nItemID][1]);
		oSys.Call("user32::DrawIconEx", hDC, rcItem.left, rcItem.top + (rcItem.bottom - rcItem.top) / 2 - nIconSize / 2, hIcon, nIconSize, nIconSize, 0, 0, 0x3 /*DI_NORMAL*/ );

		//Draw text
		oSys.Call("gdi32::SetTextColor", hDC, crText);
		oSys.Call("gdi32::SetBkColor", hDC, crBk);
		oSys.Call("gdi32::TextOut" + _TCHAR, hDC, rcItem.left + nIconSize + nIconGap, rcItem.top + (rcItem.bottom - rcItem.top) / 2 - nMaxCharHeight / 2, lpFrameList[nItemID][0], lpFrameList[nItemID][0].length);

		oSys.Call("gdi32::SetBkMode", hDC, nModeBkOld);
	}
	return 0;
}

function HookPostCallback(nCode, wParam, lParam) {
	var uMsg = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 8 : 4) /*offsetof(MSG, message)*/ , 3 /*DT_DWORD*/ );
	var nParamW;
	var nParamL;

	if (uMsg == 0x201 /*WM_LBUTTONDOWN*/ ||
		uMsg == 0x0A1 /*WM_NCLBUTTONDOWN*/ ||
		uMsg == 0x204 /*WM_RBUTTONDOWN*/ ||
		uMsg == 0x0A4 /*WM_NCRBUTTONDOWN*/ ||
		uMsg == 0x207 /*WM_MBUTTONDOWN*/ ||
		uMsg == 0x0A7 /*WM_NCMBUTTONDOWN*/ ) {
		var hWnd = AkelPad.MemRead(_PtrAdd(lParam, 0) /*offsetof(MSG, hwnd)*/ , 2 /*DT_QWORD*/ );

		if (hWnd != hWndListBox) {
			//Not in rect
			bNoSwitch = true;

			//Exit message loop
			oSys.Call("user32::PostQuitMessage", 0);
		}
	} else if (uMsg == 0x100 /*WM_KEYDOWN*/ ||
		uMsg == 0x101 /*WM_KEYUP*/ ||
		uMsg == 0x104 /*WM_SYSKEYDOWN*/ ||
		uMsg == 0x105 /*WM_SYSKEYUP*/ ||
		uMsg == 0x20A /*WM_MOUSEWHEEL*/ ) {
		nParamW = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8) /*offsetof(MSG, nParamW)*/ , 2 /*DT_QWORD*/ );
		nParamL = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12) /*offsetof(MSG, lParam)*/ , 2 /*DT_QWORD*/ );
		AkelPad.SendMessage(hWndListBox, uMsg, nParamW, nParamL);
		AkelPad.MemCopy(_PtrAdd(lParam, _X64 ? 8 : 4) /*offsetof(MSG, message)*/ , 0 /*WM_NULL*/ , 3 /*DT_DWORD*/ );
	}
}

function HookSendCallback(nCode, wParam, lParam) {
	var uMsg = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8) /*offsetof(CWPSTRUCT, message)*/ , 3 /*DT_DWORD*/ );
	var nParamW;
	var nParamL;

	if (uMsg == 0x6 /*WM_SETFOCUS*/ ) {
		bNoSwitch = true;

		//Exit message loop
		oSys.Call("user32::PostQuitMessage", 0);
	}
}

function ListBoxCallback(hWnd, uMsg, wParam, lParam) {
	if (uMsg == 0x021 /*WM_MOUSEACTIVATE*/ ) {
		return 3 /*MA_NOACTIVATE*/ ;
	} else if (uMsg == 0x087 /*WM_GETDLGCODE*/ ) {
		AkelPad.WindowNoNextProc(hSubClass);
		return 0x4 /*DLGC_WANTALLKEYS*/ ;
	} else if (uMsg == 0x100 /*WM_KEYDOWN*/ ) {
		if (wParam == 0x43 /*c*/ ) {
			if (bCtrlTab || (oSys.Call("user32::GetKeyState", 0x11 /*VK_CONTROL*/ ) & 0x8000)) {
				i = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0);
				AkelPad.SetClipboardText(lpFrameList[i][0]);
			}
		} else if (wParam == 0x9 /*VK_TAB*/ ) {
			var nCount;

			nCount = AkelPad.SendMessage(hWndListBox, 0x18B /*LB_GETCOUNT*/ , 0, 0);
			i = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0);

			if (!(oSys.Call("user32::GetKeyState", 0x10 /*VK_SHIFT*/ ) & 0x8000)) {
				if (++i >= nCount)
					i = 0;
			} else {
				if (--i < 0)
					i = nCount - 1;
			}
			AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , i, 0);
		} else if (wParam == 0xD /*VK_RETURN*/ ) {
			//Exit message loop
			oSys.Call("user32::PostQuitMessage", 0);
		} else if (wParam == 0x1B /*VK_ESCAPE*/ ) {
			bNoSwitch = true;

			//Exit message loop
			oSys.Call("user32::PostQuitMessage", 0);
		}
	} else if (uMsg == 0x101 /*WM_KEYUP*/ ) {
		if (wParam == 0x11 /*VK_CONTROL*/ ) {
			if (bCtrlTab) {
				//Exit message loop
				oSys.Call("user32::PostQuitMessage", 0);
			}
		}
	} else if (uMsg == 0x201 /*WM_LBUTTONDOWN*/ ) {
		var lResult = AkelPad.SendMessage(hWndListBox, 0x01A9 /*LB_ITEMFROMPOINT*/ , 0, lParam);

		if (HIWORD(lResult) == 0)
			AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , LOWORD(lResult), 0);
		AkelPad.WindowNoNextProc(hSubClass);
	} else if (uMsg == 0x202 /*WM_LBUTTONUP*/ ||
		uMsg == 0x203 /*WM_LBUTTONDBLCLK*/ ) {
		if (uMsg == 0x203 /*WM_LBUTTONDBLCLK*/ || bSingleClick) {
			//Exit message loop
			oSys.Call("user32::PostQuitMessage", 0);
		}
	}
}

function GetFrameList(lpFrameList, lpAllList) {
	// var lpCurFrame=AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
	var lpInitFrame;
	var lpFrame;
	var pNumFind;
	var pStrFind = ":";
	var i;
	var j;
	var n;

	// Редактируемый участок 2
	lpInitFrame = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/ , 8 /*FWF_BYTABINDEX*/ , 0);
	lpFrame = lpInitFrame;

	j = -1
	for (i = 0; lpFrame; ++i) {

		lpAllList[i] = [0, 0];
		lpAllList[i][0] = AkelPad.GetFilePath(AkelPad.MemRead(AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 32 /*FI_FILEW*/ , lpFrame), 1 /*DT_UNICODE*/ ), 4 /*расширение*/ );
		lpAllList[i][1] = lpFrame;
		lpAllList[i][2] = AkelPad.MemRead(AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 32 /*FI_FILEW*/ , lpFrame), 1 /*DT_UNICODE*/ );

// Если не найден то добавляем, иначе добавляем +1 к количеству, делая подсчёт однотипных
		if (pStrFind.indexOf(":" + lpAllList[i][0] + ":") === -1) {
			pStrFind += lpAllList[i][0] + ":"
			j += 1
			lpFrameList[j] = [0, 0];
			lpFrameList[j][0] = lpAllList[i][0];
			lpFrameList[j][1] = lpFrame;
// 			if (typeof(lpFrameList[j][2]) == "undefined") {
// 				lpFrameList[j][2] = 0
// 			}
			lpFrameList[j][2] = 1;
		} else {
			for (n = 0; n < lpFrameList.length; ++n) {
				if (lpAllList[i][0] === lpFrameList[n][0])
					lpFrameList[n][2] += 1;
			}
		}
		lpFrame = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/ , 8 /*FWF_BYTABINDEX*/ , i + 1);
		if (lpFrame == lpInitFrame) break;
	}
	lpFrameList.sort(SortNum) // но сортируется по первой колонке, не то что требуется
	
	if (lpAllList.length < nMinTabs)
	{
		WScript.Quit();
	}

// делаем ширину пунктов одинаковой, для пунктов от 1 до 9 добавляем пробел слева
	for (i = 0; i < lpFrameList.length; ++i) {
		if (10 > lpFrameList[i][2])
		{
			lpFrameList[i][0] = "  " + lpFrameList[i][2] +" - " + lpFrameList[i][0];
		} else {
			lpFrameList[i][0] = lpFrameList[i][2] +" - " + lpFrameList[i][0];
		}
	}
	// Конец Редактируемый участок 2
	return 0;
}

function SortNum(a, b){
	return b[2] - a[2];
//     if(a < b)
//         return -1
//     if(a > b)
//         return 1
//     return 0
}

function CreateFont(pFaceName, nFontStyle, nPointSize) {
	//Release it with: oSys.Call("gdi32::DeleteObject", hFont);
	var lpLogFontSrc;
	var lpLogFontDst;
	var hDC;
	var hFont = 0;
	var nHeight;
	var nWeight;
	var nItalic;

	if (lpLogFontDst = AkelPad.MemAlloc(92 /*sizeof(LOGFONTW)*/ )) {
		lpLogFontSrc = AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 48 /*FI_EDITFONTW*/ , 0);
		oSys.Call("kernel32::RtlMoveMemory", lpLogFontDst, lpLogFontSrc, 92 /*sizeof(LOGFONTW)*/ );

		if (nPointSize) {
			if (hDC = oSys.Call("user32::GetDC", hMainWnd)) {
				nHeight = -oSys.Call("kernel32::MulDiv", nPointSize, oSys.Call("gdi32::GetDeviceCaps", hDC, 90 /*LOGPIXELSY*/ ), 72);
				AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 0) /*offsetof(LOGFONTW, lfHeight)*/ , nHeight, 3 /*DT_DWORD*/ );
				oSys.Call("user32::ReleaseDC", hMainWnd, hDC);
			}
		}
		if (nFontStyle != 0 /*FS_NONE*/ ) {
			nWeight = (nFontStyle == 2 /*FS_FONTBOLD*/ || nFontStyle == 4 /*FS_FONTBOLDITALIC*/ ) ? 700 /*FW_BOLD*/ : 400 /*FW_NORMAL*/ ;
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 16) /*offsetof(LOGFONTW, lfWeight)*/ , nWeight, 3 /*DT_DWORD*/ );
			nItalic = (nFontStyle == 3 /*FS_FONTITALIC*/ || nFontStyle == 4 /*FS_FONTBOLDITALIC*/ ) ? 1 : 0;
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 20) /*offsetof(LOGFONTW, lfItalic)*/ , nItalic, 5 /*DT_BYTE*/ );
		}
		if (_TSTR == 0 /*DT_ANSI*/ && !pFaceName)
			pFaceName = AkelPad.MemRead(_PtrAdd(lpLogFontDst, 28) /*offsetof(LOGFONTW, lfFaceName)*/ , 1 /*DT_UNICODE*/ );
		if (pFaceName)
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 28) /*offsetof(LOGFONTW, lfFaceName)*/ , pFaceName.substr(0, 32 /*LF_FACESIZE*/ ), _TSTR);

		hFont = oSys.Call("gdi32::CreateFontIndirect" + _TCHAR, lpLogFontDst);
		AkelPad.MemFree(lpLogFontDst);
	}
	return hFont;
}

function GetCursorPos(ptPoint) {
	var lpPoint;

	ptPoint.x = 0;
	ptPoint.y = 0;

	if (lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/ )) {
		if (oSys.Call("user32::GetCursorPos", lpPoint)) {
			ptPoint.x = AkelPad.MemRead(_PtrAdd(lpPoint, 0) /*offsetof(POINT, x)*/ , 3 /*DT_DWORD*/ );
			ptPoint.y = AkelPad.MemRead(_PtrAdd(lpPoint, 4) /*offsetof(POINT, y)*/ , 3 /*DT_DWORD*/ );
		}
		AkelPad.MemFree(lpPoint);
	}
}

function RectToArray(lpRect, rcRect) {
	rcRect.left = AkelPad.MemRead(_PtrAdd(lpRect, 0) /*offsetof(RECT, left)*/ , 3 /*DT_DWORD*/ );
	rcRect.top = AkelPad.MemRead(_PtrAdd(lpRect, 4) /*offsetof(RECT, top)*/ , 3 /*DT_DWORD*/ );
	rcRect.right = AkelPad.MemRead(_PtrAdd(lpRect, 8) /*offsetof(RECT, right)*/ , 3 /*DT_DWORD*/ );
	rcRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12) /*offsetof(RECT, bottom)*/ , 3 /*DT_DWORD*/ );
	return rcRect;
}

function GetWindowSize(hWnd, hWndOwner, rcRect) {
	var lpRect;
	var bResult = false;

	if (lpRect = AkelPad.MemAlloc(16 /*sizeof(RECT)*/ )) {
		if (oSys.Call("user32::GetWindowRect", hWnd, lpRect)) {
			RectToArray(lpRect, rcRect);
			rcRect.right -= rcRect.left;
			rcRect.bottom -= rcRect.top;

			if (hWndOwner)
				bResult = oSys.Call("user32::ScreenToClient", hWndOwner, lpRect);
			else
				bResult = true;
			rcRect.left = AkelPad.MemRead(_PtrAdd(lpRect, 0) /*offsetof(RECT, left)*/ , 3 /*DT_DWORD*/ );
			rcRect.top = AkelPad.MemRead(_PtrAdd(lpRect, 4) /*offsetof(RECT, top)*/ , 3 /*DT_DWORD*/ );
		}
		AkelPad.MemFree(lpRect);
	}
	return bResult;
}

function LOWORD(dwNumber) {
	return (dwNumber & 0xffff);
}

function HIWORD(dwNumber) {
	return (dwNumber >> 16);
}

function MAKELONG(a, b) {
	return (a & 0xffff) | ((b & 0xffff) << 16);
}