#ifndef _WIN_UTILS
#define _WIN_UTILS

#include "ofMain.h"

static string	windowTitle;
static int		storedWindowX;
static int		storedWindowY;
static int		storedWindowW;
static int		storedWindowH;
static bool		bCustomFullscreen = false;

#ifdef TARGET_WIN32

static WNDPROC currentWndProc;
static HWND handle  = NULL;

static bool CALLBACK EnumWindowsProc(HWND hWnd, LPARAM processID){

	//get the process id for each window
	DWORD tempID = 0;
	GetWindowThreadProcessId(hWnd, &tempID);

	if( tempID == (DWORD)processID){
		//three windows are associated with our id
		//a console window, the glut window and an invisible gl context
		//we get the name of each window to determin which is the one we want
		wchar_t name[256];
		GetClassName(hWnd, name, 255);
		
		//if you want to see the process names
		//wprintf(L"class name is %s \n", name); 
		
		//we check the process name to see if it GLUT
		//if so we store the handle and then stop the search
		if( wcsncmp(name, L"GLUT", 4) == 0 ){
			handle = hWnd;	
			return false;
		}

	}
	return true;
}

static LRESULT CALLBACK winProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam){	
	
	//we catch close and destroy messages
	//and send them to OF
	switch(Msg){
		case WM_CLOSE:
			OF_EXIT_APP(0);
		break;
		case WM_DESTROY:
			OF_EXIT_APP(0);
			break;
		default:
			//all other messages our handled by glut
			return currentWndProc(hwnd, Msg, wParam, lParam);
		break;
    }

    return 0;
}

//--------------------------------------
static void fixCloseWindow(){
	
   //we get our current process id
   DWORD ourProcessID = GetCurrentProcessId();

   //we run through all windows and look for windows matching
   //our process id
   EnumWindows((WNDENUMPROC)EnumWindowsProc, ourProcessID);

   //a fallback incase no window handle is found
   //we use the top most.
   if(handle == NULL){
		handle = WindowFromDC(wglGetCurrentDC()); 
   }
	
   //store the current message event handler for the window
   currentWndProc = (WNDPROC)::GetWindowLong(handle, GWL_WNDPROC);
   
   //tell the window to now use our event handler!
   SetWindowLong(handle, GWL_WNDPROC, (long)winProc);
}

#endif

//--------------------------------------
static void ofBeginCustomFullscreen(int x, int y, int width, int height){

	if (ofGetWindowMode() == OF_GAME_MODE) return;

	#ifdef TARGET_WIN32
	   
	    HWND vWnd  = FindWindow(NULL,  L"laser tag server");
	    
		if(!bCustomFullscreen){
			
			RECT r;
			
			if(GetWindowRect(vWnd, &r)){ 
				//more accurate as it takes windows elements into account
				storedWindowX = r.left;
				storedWindowY = r.top;
				storedWindowW = r.right - r.left;
				storedWindowH = r.bottom - r.top;
			}else{	
				//fallback
				storedWindowX = 0;
				storedWindowY = 0;
				storedWindowW = ofGetWidth();
				storedWindowH = ofGetHeight();
			}

		}
		    
	    long windowStyle = GetWindowLong(vWnd, GWL_STYLE);
	    
	    windowStyle &= ~WS_OVERLAPPEDWINDOW;
	    windowStyle |= WS_POPUP;
	    
	   	SetWindowLong(vWnd, GWL_STYLE, windowStyle);

		SetWindowPos(vWnd, HWND_TOP, x, y, width, height, SWP_FRAMECHANGED);
		bCustomFullscreen = true;
		
	#endif
}

//--------------------------------------
static void  ofEndCustomFullscreen(){
	
	if (ofGetWindowMode() == OF_GAME_MODE) return;
	
	#ifdef TARGET_WIN32
	
		if(bCustomFullscreen){
			HWND vWnd  = FindWindow(NULL, L"laser tag server");
			
		    long windowStyle = GetWindowLong(vWnd, GWL_STYLE);
			windowStyle  |= WS_OVERLAPPEDWINDOW;
		    windowStyle  &= ~WS_POPUP;
		    

			SetWindowLong(vWnd, GWL_STYLE, windowStyle);
			SetWindowPos(vWnd, HWND_TOP,storedWindowX, storedWindowY, storedWindowW, storedWindowH, SWP_FRAMECHANGED);
			bCustomFullscreen = false;
		}
		
	#endif
}



#endif

