var g_hAkelPad = AkelPad.GetMainWnd();
var oSys=AkelPad.SystemFunction();
//! Поймать отладчиком сообщения(почему то не работает)
function TRACE(msg)
{
	var msgn = "AKELPAD: "+msg+"\n"
	var mem = AkelPad.MemAlloc((msgn.length+1)*_TSIZE);
	AkelPad.MemCopy(mem, msgn, _TSTR);
	oSys.Call("kernel32::OutpuDebugString"+_TCHAR,mem);
	AkelPad.MemFree(mem);
}
//! Константы. Честно слово помнить сотни констант не совсем удобно и читаемо
//! Файлы лежат в коллекции скриптов на форуме
//! В user32.js есть декларация MB_OK = 0x00000000 на которую интерпретатор матерится
//! если построена DEBUG версия(в студии) RELEASE не пробовал.
//! Но пострка с инсталляции пропускает

AkelPad.Include("win32\\user32.js");
AkelPad.Include("win32\\gdi32.js");

var g_pDock = 0;
var g_hDockWnd = 0;
var DOCKCLASSNAME = "DOCKWINDOW.JS";
var IDC_MSG = 1000;
var IDC_EXIT = 1001;

//! AkelDLL.h
var DKS_LEFT    =1
var DKS_RIGHT   =2
var DKS_TOP     =3
var DKS_BOTTOM  =4

//Dock flags
var DKF_OWNTHREAD     =0x00000001
var DKF_FIXEDSIZE     =0x00000002
var DKF_DRAGDROP      =0x00000004
var DKF_HIDDEN        =0x00000008
var DKF_NODROPLEFT    =0x00000010
var DKF_NODROPRIGHT   =0x00000020
var DKF_NODROPTOP     =0x00000040
var DKF_NODROPBOTTOM  =0x00000080

//Dock action
var DK_ADD         =0x00000001
var DK_DELETE      =0x00000002
var DK_SUBCLASS    =0x00000004
var DK_UNSUBCLASS  =0x00000008
var DK_SETLEFT     =0x00000010
var DK_SETRIGHT    =0x00000020
var DK_SETTOP      =0x00000040
var DK_SETBOTTOM   =0x00000080
var DK_HIDE        =0x00000100
var DK_SHOW        =0x00000200
var DK_FINDDOCK    =0x00000400
var DK_FINDCHILD   =0x00000800

var AKD_RESIZE	= WM_USER + 253;
var AKD_DOCK	= WM_USER + 254;
var AKDN_MAIN_ONFINISH = WM_USER + 6;
//! Создаёт окно
function CreateWindow(_class,title,style,x,y,cx,cy,parent,menu,lparam)
{
	var mem_class = AkelPad.MemAlloc((_class.length+1)*_TSIZE);
	AkelPad.MemCopy(mem_class, _class, _TSTR);
	var mem_title = AkelPad.MemAlloc((title.length+1)*_TSIZE);
	AkelPad.MemCopy(mem_title, title, _TSTR);
	var hwnd = oSys.Call("user32::CreateWindowEx" + _TCHAR,
							0,                      //dwExStyle
							mem_class,                 //lpClassName
							mem_title,                      //lpWindowName
							style,
							x,y,cx,cy,
							parent, menu,
							AkelPad.GetInstanceDll(),
							lparam);
	AkelPad.MemFree(mem_class);
	AkelPad.MemFree(mem_title);
	return hwnd;
}
function ShowWindow(hwnd,how)
{
	return oSys.Call("user32::ShowWindow",hwnd,how);
}
function UpdateWindow(hwnd)
{
	return oSys.Call("user32::UpdateWindow",hwnd);
}
//! Создаёт панельку
function CreateDock()
{
	/***
	typedef struct _DOCK {
	0  struct _DOCK *next;
	4  struct _DOCK *prev;
	8  DWORD dwFlags;       //Dock flags: see DKF_* defines.
	12 HWND hWnd;           //Dock window handle.
	16 int nSide;           //Dock side: DKS_LEFT, DKS_TOP, DKS_RIGHT or DKS_BOTTOM.
	20 RECT rcSize;         //Dock window client RECT.
	20 .left
	24 .top
	28 .right
	32 .bottom
	36 RECT rcDragDrop;     //Drag-and-drop client RECT.
	36 .left
	40 .top
	44 .right
	48 .bottom
	} DOCK;
	***/
	var pDock = AkelPad.MemAlloc(52/*sizeof(DOCK)*/);
	AkelPad.MemCopy(pDock + 8/*dwFlags*/, DKF_NODROPLEFT|DKF_NODROPRIGHT|DKF_FIXEDSIZE|DKF_DRAGDROP, 3 /*DT_DWORD*/);
	AkelPad.MemCopy(pDock + 16, DKS_BOTTOM, 3 /*DT_DWORD*/);
	g_pDock = AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_ADD, pDock);
	AkelPad.MemFree(pDock);
	if(g_pDock != 0)
	{
		g_hDockWnd =  CreateWindow(DOCKCLASSNAME,"qwerty",WS_VISIBLE|WS_CHILD,0,0,400,30,g_hAkelPad,0,DockWindowProc);
		if(g_hDockWnd!=0)
		{
			ShowWindow(g_hDockWnd,SW_SHOW);
			oSys.Call("user32::GetWindowRect",g_hDockWnd,g_pDock+20);
			var szL = AkelPad.MemRead(g_pDock+20, 3 /*DT_DWORD*/);
			var szT = AkelPad.MemRead(g_pDock+24, 3 /*DT_DWORD*/);
			var szR = AkelPad.MemRead(g_pDock+28, 3 /*DT_DWORD*/);
			var szB = AkelPad.MemRead(g_pDock+32, 3 /*DT_DWORD*/);
			/*rcSize={0,0,right-left,bottom-top}*/
			AkelPad.MemCopy(g_pDock+20, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+24, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+28, szR-szL, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+32, szB-szT, 3 /*DT_DWORD*/);
			/*rcDragDrop=rcSize*/
			AkelPad.MemCopy(g_pDock+36, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+40, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+44, szR-szL, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+48, szB-szT, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+12, g_hDockWnd, 3 /*DT_DWORD*/);
			AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SUBCLASS, g_pDock);
			AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SHOW, g_pDock);
			AkelPad.SendMessage(g_hAkelPad, AKD_RESIZE, 0, 0);
			return 1;
		}
		else
		{
			AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_DELETE,g_pDock);
			g_pDock = 0;
			return 0;
		}
	}
	else return 0;
}
/////! Нук главного окна. Не совсем понятно что он может делать
/////! Что возвращать? и пр
function AkelPadCallBack(hwnd,umsg,wparam,lparam)
{
	if(umsg == AKDN_MAIN_ONFINISH)
	{
		TRACE("AKDN_MAIN_ONFINISH");
		AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
	}
	return 0;
}

var but1=0;
var but2=0;
//! Оконная процедура панельки
//! В плагинах я делал диалогом, но тут пришлось обычным окном
function DockWindowProc(hwnd, umsg, wparam,lparam)
{
	if(umsg == WM_CREATE)
	{
		but1 = CreateWindow("BUTTON","MSG",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,10,2,80,25,hwnd,IDC_MSG,0);
		but2 = CreateWindow("BUTTON","EXIT",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,95,2,80,25,hwnd,IDC_EXIT,0);
		ShowWindow(but1,SW_SHOW);UpdateWindow(but1);
		ShowWindow(but2,SW_SHOW);UpdateWindow(but2);
		TRACE("WM_CREATE: "+but1+"+"+but2);
		return 0;
	}
	else if(umsg == WM_COMMAND)
	{
		var CODE = (wparam >> 16) & 0x0FFFF;
		var IDC  = wparam & 0x0FFFF;
		if(CODE == BN_CLICKED)
		{
			if(IDC == IDC_MSG)
			{
				//! сказать привет
				AkelPad.MessageBox(g_hAkelPad, "Нажали кнопку MSG", "MSG", 0 /*MB_OK*/);
			}
			else if(IDC == IDC_EXIT)
			{
				//! Выйти. Из плагина так работает
				AkelPad.MessageBox(g_hAkelPad, "Нажали кнопку EXIT", "EXIT", 0 /*MB_OK*/);
				AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_UNSUBCLASS,g_pDock);
				AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_DELETE,g_pDock);
				g_pDock = 0;
				oSys.Call("user32::DestroyWindow",hwnd);
				//g_hDockWnd = 0;
				AkelPad.SendMessage(g_hAkelPad, AKD_RESIZE, 0, 0);
			}
		}
		return 0;
	}
	else if(umsg == WM_PAINT)
	{
		//! Типа покрасим черным цветом, он оно почемуто не красит. Ну в принципе это не важно
		ps = AkelPad.MemAlloc(64/*sizeof PAINTSTRUCT*/);
		oSys.Call("user32::BeginPaint",hwnd,ps);
		var hdc = AkelPad.MemRead(ps, 3 /*DT_DWORD*/);TRACE("HDC: "+hdc);
		var hbr = oSys.Call("gdi32::GetStockObject",BLACK_BRUSH);TRACE("HDC: "+hbr);
		oSys.Call("gdi32::SelectObject",hdc,hbr);
		var ptL=AkelPad.MemRead(ps+8, 3 /*DT_DWORD*/),
			ptT=AkelPad.MemRead(ps+12, 3 /*DT_DWORD*/),
			ptR=AkelPad.MemRead(ps+16, 3 /*DT_DWORD*/),
			ptB=AkelPad.MemRead(ps+20, 3 /*DT_DWORD*/);
		TRACE("("+ptL+";"+ptT+")-("+ptR+";"+ptB+")");
		oSys.Call("gdi32::Rectangle",hdc,ptL,ptT,ptR,ptB);
		oSys.Call("user32::EndPaint",hwnd,ps);
		AkelPad.MemFree(ps);
	}
	else if(umsg == WM_SIZE)
	{
		//! Меняем Drag&Drob область за размером панельки
		if(g_pDock)
		{
			oSys.Call("user32::GetWindowRect",g_hDockWnd,g_pDock+36);
			var szL = AkelPad.MemRead(g_pDock+36, 3 /*DT_DWORD*/);
			var szT = AkelPad.MemRead(g_pDock+40, 3 /*DT_DWORD*/);
			var szR = AkelPad.MemRead(g_pDock+44, 3 /*DT_DWORD*/);
			var szB = AkelPad.MemRead(g_pDock+48, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+36, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+40, 0, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+44, szR-szL, 3 /*DT_DWORD*/);
			AkelPad.MemCopy(g_pDock+48, szB-szT, 3 /*DT_DWORD*/);
		}
	}
	else if(umsg == WM_CLOSE)
	{
		//! Закрывают.
		AkelPad.SendMessage(hwnd, WM_COMMAND, (BN_CLICKED <<16)+IDC_EXIT, 0);
		return 1;
	}
	else if(umsg == WM_DESTROY)
	{
		//! Закрыли нас. 
		g_hDockWnd = 0;
		//! Выйти из цикла
		oSys.Call("user32::PostQuitMessage",0);
		return 0;
	}
	//! Всё остальное нас пока не интересует
	return oSys.Call("user32::DefWindowProc"+_TCHAR,hwnd,umsg,wparam,lparam);
}

//! Пегистрируем класс окна
var res = AkelPad.WindowRegisterClass(DOCKCLASSNAME);
//! Создаем панельку
if(CreateDock())
{
	//! Сабкласим главное окно
	if(AkelPad.WindowSubClass(g_hAkelPad, AkelPadCallBack))
	{
		//! Поток в цикл сообщений
		AkelPad.WindowGetMessage();
		//! Вышли(только по закрытии панельки)
		AkelPad.WindowUnsubClass(g_hAkelPad);
		//! Сняли хук
	}
	if(g_hDockWnd != 0)
	{
		//! По идее сюда не попадем
		AkelPad.MessageBox(g_hAkelPad, "ATEXIT", "ATEXIT", 0 /*MB_OK*/);
		TRACE("g_hDock != NULL at finish");
		AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
		g_hDockWnd = 0;
	}
}
//! Класс долой
AkelPad.WindowUnregisterClass(DOCKCLASSNAME);
//! Говорим "Пока"
AkelPad.MessageBox(g_hAkelPad, "Конец выполнения скрипта", "FINISH", 0 /*MB_OK*/);
//! Вернуть фокус
oSys.Call("user32::SetFocus",g_hAkelPad);

//! 
TRACE("FINISH");