#include "../dwlcore.h"

#define ID_MAIN_ICON 0
#define CM_1 1
#define CM_2 2
#define CM_3 3
#define CM_4 4
#define CM_5 5
#define CM_6 6

#define WM_HOOKKEYDOWN (WM_USER+1)
#define WM_HOOKKEYUP (WM_USER+2)

// translucent layered windows
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED           0x00080000
#define LWA_COLORKEY            0x00000001
#define LWA_ALPHA               0x00000002
#endif
typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
lpfnSetLayeredWindowAttributes m_pSetLayeredWindowAttributes;
// --


HBRUSH m_hBackBrush;

//_____________________________________________________________________________
void __stdcall myKeyCallback(int UserData, HWND hWnd, int Down, int Key, int Shift){
  HDC hdc;
  char S[80];
  HWND myWnd = (HWND)UserData;
  hdc=GetDC(myWnd);

  itoa( Key, S, 16);
  TextOut(hdc,200,112,S,strlen(S));
  itoa( Shift, S, 16);
  TextOut(hdc,240,112,S,strlen(S));
  ReleaseDC(myWnd,hdc);
}

//_____________________________________________________________________________
LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){
  static POINT mousepos;
  POINT mpos;
  HDC hdc;
  PAINTSTRUCT ps;
  RECT rect;
  CREATESTRUCT *pCS;
  char S[80];

	switch (uMsg){
   	case WM_PAINT:
      hdc = BeginPaint( hWnd, &ps );
      SetBkColor(hdc, GetSysColor(COLOR_BTNFACE) );
      EndPaint( hWnd, &ps );
      return 1;
    case WM_LBUTTONDOWN:
      GetCursorPos(&mousepos);
      SetCapture(hWnd);
      break;//return 0;
    case WM_LBUTTONUP:
      GetCursorPos(&mousepos);
      ReleaseCapture();
      return 0;
    case WM_MOUSEMOVE:
      if(wParam & MK_LBUTTON){
        GetCursorPos(&mpos);
        GetWindowRect(hWnd,&rect);
        rect.left += mpos.x - mousepos.x;
        rect.top += mpos.y - mousepos.y;
        SetWindowPos(hWnd,0,rect.left,rect.top,0,0,SWP_NOSIZE|SWP_NOZORDER);
        mousepos.x = mpos.x;
        mousepos.y = mpos.y;
      }
      return 0;
    case WM_COMMAND:
     	switch(wParam){
        case CM_1:
          if (SendDlgItemMessage(hWnd, CM_1, BM_GETSTATE,0, 0) & BST_CHECKED) {
            wlDisableKey(0,VK_TAB,MOD_ALT,1);
          }else{
            wlDisableKey(0,VK_TAB,MOD_ALT,0);
          }
          break;
       	case CM_2:
          if (SendDlgItemMessage(hWnd, CM_2, BM_GETSTATE,0, 0) & BST_CHECKED) {
            wlDisableKey(0,VK_ESCAPE,MOD_CONTROL,1);
          }else{
            wlDisableKey(0,VK_ESCAPE,MOD_CONTROL,0);
          }
          break;
        case CM_3:
          if (SendDlgItemMessage(hWnd, CM_3, BM_GETSTATE,0, 0) & BST_CHECKED) {
			      wlDisableKey(0,'V',MOD_CONTROL,1);
          }else{
            wlDisableKey(0,'V',MOD_CONTROL,0);
          }
         	break;
        case CM_4:
          if (SendDlgItemMessage(hWnd, CM_4, BM_GETSTATE,0, 0) & BST_CHECKED) {
            wlSetKeyPostMessage(hWnd,WM_HOOKKEYDOWN,WM_HOOKKEYUP);
          }else{
            wlSetKeyPostMessage(0,0,0);
          }
         	break;
        case CM_5:
          if (SendDlgItemMessage(hWnd, CM_5, BM_GETSTATE,0, 0) & BST_CHECKED) {
			      wlSetKeyCallback(myKeyCallback,(int)hWnd,kDownEvents);
          }else{
            wlSetKeyCallback(NULL,0,0);
          }
         	break;
      }
      break;
    case WM_HOOKKEYDOWN:
      hdc=GetDC(hWnd);
      itoa(lParam >> 16,S,16);
      TextOut(hdc,240,96,S,strlen(S));
	    itoa(lParam & 0xffff,S,16);
      TextOut(hdc,200,96,S,strlen(S));
      ReleaseDC(hWnd,hdc);
      break;
  	case WM_CREATE:
      pCS = (CREATESTRUCT*)lParam;
      CreateWindow("BUTTON","no Alt-Tab",WS_CHILD|BS_AUTOCHECKBOX|WS_VISIBLE,40,48,128,16,hWnd, (HMENU)CM_1 ,pCS->hInstance,NULL);
      CreateWindow("BUTTON","no Ctrl-ESC",WS_CHILD|BS_AUTOCHECKBOX|WS_VISIBLE,40,64,128,16,hWnd, (HMENU)CM_2 ,pCS->hInstance,NULL);
      CreateWindow("BUTTON","no Ctrl-V",WS_CHILD|BS_AUTOCHECKBOX|WS_VISIBLE,40,80,128,16,hWnd, (HMENU)CM_3 ,pCS->hInstance,NULL);
      CreateWindow("BUTTON","Display Events",WS_CHILD|BS_AUTOCHECKBOX|WS_VISIBLE,40,96,128,16,hWnd, (HMENU)CM_4 ,pCS->hInstance,NULL);
      CreateWindow("BUTTON","Key Callback",WS_CHILD|BS_AUTOCHECKBOX|WS_VISIBLE,40,112,128,16,hWnd, (HMENU)CM_5 ,pCS->hInstance,NULL);
     	break;
    case WM_DESTROY:
     	PostQuitMessage(0);
      break;
	}
  return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


HWND InitMainWindow(HINSTANCE hInstance){
  WNDCLASS  wc;
  HWND hwnd;
  HMODULE hUser32;
  int left = GetSystemMetrics(SM_CXSCREEN)/2 -200;
  int width = 400;
  int top = GetSystemMetrics(SM_CYSCREEN)/2 -150;
  int height = 300;

  hUser32 = GetModuleHandle("USER32.DLL");
  if (hUser32){
    m_pSetLayeredWindowAttributes = (lpfnSetLayeredWindowAttributes)GetProcAddress(hUser32, "SetLayeredWindowAttributes");
  }


  m_hBackBrush = GetSysColorBrush(COLOR_3DFACE);// CreateSolidBrush(RGB(0,0,0));

  // Set up and register window class
  wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  wc.lpfnWndProc = WindowProc ;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInstance;
  wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ID_MAIN_ICON));
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = m_hBackBrush;
  wc.lpszMenuName = 0;
  wc.lpszClassName = "dwinlock_cpp_demo";
  RegisterClass(&wc);
  // Create a window
  hwnd = CreateWindowEx(WS_EX_TOPMOST | (m_pSetLayeredWindowAttributes ? WS_EX_LAYERED : 0),
                        "dwinlock_cpp_demo",
                        "dwinlock cpp demo",
                        WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
                        left,
                        top,
                        width,
                        height,
                        NULL,
                        0,
                        hInstance,
                        0);


  if (m_pSetLayeredWindowAttributes) {
    m_pSetLayeredWindowAttributes(hwnd,RGB(0,0,0),220,/*LWA_COLORKEY |*/LWA_ALPHA );
#if 0
      {
        HWND h=FindWindow("Shell_TrayWnd",NULL);
        LONG L=GetWindowLong(h,GWL_EXSTYLE);
        SetWindowLong(h,GWL_EXSTYLE,L | WS_EX_LAYERED);
        m_pSetLayeredWindowAttributes(h,RGB(170,177,163),191,/*LWA_COLORKEY|*/LWA_ALPHA);

        //h=(HWND)0x000404FC;
        //L=GetWindowLong(h,GWL_EXSTYLE);
        //SetWindowLong(h,GWL_EXSTYLE,L |(WS_EX_LAYERED|WS_EX_TOPMOST));
        //m_pSetLayeredWindowAttributes(h,RGB(170,177,163),127,/*LWA_COLORKEY|*/LWA_ALPHA);
      }
#endif
  }
  //SetWindowLong(hwnd,GWL_USERDATA,(long)this);
  return hwnd;
}
//_____________________________________________________________________________
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
  MSG msg;
  HWND hwnd=InitMainWindow(hInstance);
  if (!hwnd) return 0;

  //Load dwinlock's dGina.dll and get all function pointer
  if ( !dwlInit() ) {
    DestroyWindow(hwnd);
  }

  ShowWindow(hwnd,SW_SHOW);
  while (GetMessage(&msg,NULL,0,0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  //release dGina.dll
  dwlExit();

  return msg.wParam;
}