#pragma once

#include "thread.h"

#ifdef _DEBUG
	#import "..\\..\\Target\\Debug\\ButtonWPForm.tlb"
#else
	#import "..\\..\\Target\\Release\\ButtonWPForm.tlb"
#endif
using namespace ButtonWPForm;

namespace Ooganizer
{

	enum BUTTON_STATE
	{
		// These are the states that coincide with the states defined
		// in ButtonWPFormCCW
		BUTTON_NONE = 1, 
		BUTTON_DOWN = 2,    // BUTTON_ADD				
		BUTTON_TOGGLED = 3, // BUTTON_DELETE

		// Button Up is the Hover image (Used on Mouse Over),
		// it is NOT DEFINED in BHInteracter
		BUTTON_UP = 1000
	};

	////
	// ButtonThemeSetting, this static holds our current Button Theme Setting
	// ~This structure can be reloaded when a ThemeChange occured (WM_THEMECHANGED)
	////
	struct ButtonThemeSetting
	{
		// Init Flags
		bool bIsInitialized;
		bool bIsChanged;

		// Int Button Dimension/Location
		long Top;
		long Right;
		long Height;
		long Width;

		// String Button Locations
		_bstr_t bstrBUTTON_UP;
		_bstr_t bstrBUTTON_DOWN;
		_bstr_t bstrTOGGLE_UP;
	
		ButtonThemeSetting()
		{
			Top = 0;
			Right = 0;
			Height = 0;
			Width = 0;
			bIsInitialized = false;
			bIsChanged = false;
		}
	};

	class CWHPaccess;	
	class WPFCaller;

	#define BLANK_HookWndItem(n) HookWndItem n = {NULL,NULL,NULL,NULL}
	//////////////////////////////////////////////////////////////////////
	// Strc: HookWndItem
	// Desc: Hook Item is used in the HookedWndList. Each HookWndItem keeps track
	//		 of all the addresses needed for each hook for each Windows, 
	//		 as well as each Window's WPFCaller.		
	//////////////////////////////////////////////////////////////////////
	struct HookWndItem
	{	
		HWND hWnd;	
		WNDPROC HookWndProc;
		WNDPROC DefWndProc;		
		WPFCaller* wpfcaller;
	};	
	//////////////////////////////////////////////////////////////////////
	// Clss: WPFCaller
	// Desc: This class is responsible for overriding wndproc draw routines
	//       and communicate to the WPF COM object 
	//////////////////////////////////////////////////////////////////////
	class WPFCaller : Thread
	{
	public:		
		// All Windows Messages *Except NCDestroy & UnHook* enter here
		virtual LRESULT OnDefault (HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
		WPFCaller(HookWndItem Item, HINSTANCE hInstance);
		~WPFCaller();

		// Each WPFCaller is mapped to a HookWndItem (Hooked Window)
		HWND m_hWnd;
		WNDPROC m_HookWndProc;
		WNDPROC m_DefWndProc;								 
		HINSTANCE m_hInst;		

		// Window W32 State Settings
		// ~we are keeping track of the Hooked W32 sizes
		int m_wndHeight;
		int m_wndWidth;
		RECT m_wndRECT;

		// We need to keep track of the Button State in order 
		// to know what to draw
		BUTTON_STATE m_ButtonState;
		BUTTON_STATE m_ButtonToggledState; // We can overwrite buttonDown state
										   // with another state. this allows us to 
										   // specify which state to use to overwrite.

		BUTTON_STATE m_ButtonStateLastSaved;
		BUTTON_STATE m_ButtonToggledStateLastSaved;
		bool m_bButtonIsArtificiallyHidden_MOVE;
		bool m_bButtonIsMinimized;
		bool m_bButtonIsBeingRestored;
		
		// Transparency / Fade Effect
		BYTE GetAlpha();
		void SetAlpha(BYTE bAlpha);
		void StartRestoreEventFadeTimer();

		// Client Events		
		void StartCloseButNotDestroyTimer();
		int m_StartCloseButNotDestroyTimerCount;

		// Drag N' Dropped Files
		int m_nDragDroppedFilesCount;
		_bstr_t m_bstrDragDroppedFilesSemiColonSep;

		// OpenFile or FileSaveAs Dialog Prms Passing
		wchar_t m_strFileNameLocationBuf[MAX_PATH + 1];
		wchar_t m_strFileTypesBuf[MAX_PATH + 1];

		// WPFProc Will load the Button Settings via COM which
		// we'll use to draw the Icon
		ButtonThemeSetting m_ButtonThemeSetting;
		
		// Window Handles
		HWND m_hwndWPForm;		// passed back to us by ButtonWPForm
		HWND m_hwndW32Window;	// our w32 Button
			
		// ThreadStuff (WPFComThread)
		bool m_bThreadIsReady;
		HANDLE m_thread;
		DWORD m_threadID;

	private:

		// OnDefault() uses this function to possible send messages
		// to the EventDispatcher in C# for further processing
		void EventDispatcherHandler(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);

		// We don't need to right now, but we may need it more in the future.
		// Office passes in startup file prms via DDE (other apps may too)
		void HandleDDEMessages(HWND hWnd, UINT Msg,WPARAM wParam,LPARAM lParam);

		// Win32 Button Window * Created for better speed *
		// Responsible for setting up the WNDCLASSEX struct and register the Window
		BOOL InitApplication(HINSTANCE hInstance);	

		// Responsible for Creating and Showing a new Window Class Instance
		BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);

		// Thread Entry
		int WINAPI threadproc(HINSTANCE hinstance, HINSTANCE hPrevInstance, void* vArg, int nCmdShow);

		// Thread Entry
		virtual DWORD Run(LPVOID vArg)
		{
			return(threadproc(m_hInst,NULL,vArg,TRUE));
		}
	};
}