//
//	Copyright © 2006 Nemetschek North America 
//	All Rights Reserved.
//
// Created by Vladislav Stanev

#pragma once

#include "Control.h"
#include "CustomCtrlDrawing.h"
#include "GSDrawPad.h"

namespace VectorWorks
{
	namespace VWUI
	{
		// ------------------------------------------------------------------------------------------------------
		enum EKeyType
		{
			kKeyType_Unknown,
			kKeyType_Shift,
			kKeyType_Control,
			kKeyType_Space,
			kKeyType_Enter,
			kKeyType_Escape,
			kKeyType_Insert,
			kKeyType_Delete,
			kKeyType_BackSpace,
			kKeyType_Home,
			kKeyType_End,
			kKeyType_PageUp,
			kKeyType_PageDown,
			kKeyType_Tab,
			kKeyType_Left,
			kKeyType_Right,
			kKeyType_Up,
			kKeyType_Down,
			kKeyType_F1,
			kKeyType_F2,
			kKeyType_F3,
			kKeyType_F4,
			kKeyType_F5,
			kKeyType_F6,
			kKeyType_F7,
			kKeyType_F8,
			kKeyType_F9,
			kKeyType_F10,
			kKeyType_F11,
			kKeyType_F12
		};

		// ------------------------------------------------------------------------------------------------------
		struct SCustomCtrlMouseEvent
		{
			Uint16				x;
			Uint16				y;
			bool				bShiftDown;
			bool				bCtrlDown;
		};

		// ------------------------------------------------------------------------------------------------------
		struct SCustomCtrlKeyEvent
		{
			EKeyType			keyType;
			Uint32				keyCode;
		};

		// ------------------------------------------------------------------------------------------------------
		struct SCustomCtrlGeneralEvent
		{
			Uint32				wnd;
			Uint32				message;
			Uint32				data1;			// (Win:(WPARAM))(Mac:(void* ioParam))
			Uint32				data2;			// (Win:(LPARAM))(Mac:(void* paneVP))
			Uint32				result;			// (Win:(HRESULT))
		};

		// ------------------------------------------------------------------------------------------------------
		struct SCustomCtrlToolTip
		{
							SCustomCtrlToolTip();

			TXString		fText;
			ViewRect		fRect;
			bool			fbTrackMouse;
			ViewPt			fPos;
		};

		// ------------------------------------------------------------------------------------------------------
		class VWDialog;
		class VWCustomCtrl : public VWControl
		{
			friend class VWDialog;
		public:
								VWCustomCtrl(TControlID id, bool bDefaultPaint=false);
			virtual				~VWCustomCtrl();

			virtual bool		CreateControl(VWDialog* pDlg, Uint16 width, Uint16 height);

		// attributes
		public:
			ViewCoord			GetControlWidth() const;
			ViewCoord			GetControlHeight() const;

			void				Refresh();
			void				UpdateScrollArea(Uint16 width, Uint16 height, Uint16 leftStart, Uint16 topStart, Uint16 stepSize, bool bLiveUpdate, bool bAlwaysShowHoriz=false, bool bAlwaysShowVert=false);
			void				GetScrollArea(Uint16& outLeftStart, Uint16& outTopStart);

			Uint32				GetOSParentHandle() const;
			Uint32				GetOSControlHandle() const;

		// eventing
		protected:
			virtual void		OnControlAttached();
			virtual bool		OnEvent(SCustomCtrlGeneralEvent& event);
			virtual void		OnPaint(VWCustomCtrlDC& dc) = 0;
			virtual void		OnAfterPaint();

			virtual void		OnMouseMoved(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseDown(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseUp(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseClick(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseDblClick(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseRDown(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseRUp(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseRClick(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseRDblClick(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseMDown(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseMUp(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseMClick(const SCustomCtrlMouseEvent& event);
			virtual void		OnMouseMDblClick(const SCustomCtrlMouseEvent& event);

			virtual void		OnMouseWheel(const SCustomCtrlMouseEvent& event, Sint16 deltaX, Sint16 deltaY);

			virtual void		OnKeyDown(const SCustomCtrlKeyEvent& event);
			virtual void		OnKeyUp(const SCustomCtrlKeyEvent& event);
			virtual void		OnChar(const SCustomCtrlKeyEvent& event);

			virtual bool		OnToolTip(size_t id, SCustomCtrlToolTip& inoutToolTip);

		protected:
			virtual void		AttachControl();
			ViewRect			GetControlRect() const;

			// tool tip support
		protected:
			void				EnableToolTips(bool bEnable);
			void				ClearActiveTooltip( void );
			void				RemoveAllToolTips();
			void				RemoveToolTip(size_t id);
			size_t				AddToolTip(const SCustomCtrlToolTip& toolTip);

		// OS Event handlers
		private:
#ifdef _WINDOWS
			static LRESULT CALLBACK _CustomWindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam);
			LRESULT					CustomWindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam);

			WNDPROC					fpDefaultWndProc;

			HWND					fhParentWnd;
			HWND					fhCustomWnd;

			void*					fpToolTipItem;
			HWND					fhToolTip;
			bool					fbTrackingMouse;
#else
			static OSStatus			_WindowMouseEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* inUserData);
			static void				_CustomMacHandler(long inMessage, void *ioParam, void *paneVP, int dialogID, int componentID );
			void					CustomMacHandler(long inMessage, void *ioParam, void *paneVP, int dialogID, int componentID );
			
			void*					fpParentWnd;
			ControlRef				fControlRef;
			Rect					fControlRect;
#endif

			bool					fbDefaultPaint;
			ViewRect				fCustomCtrlRect;

			struct SToolTipDef
			{
				SCustomCtrlToolTip	fToolTip;
				size_t				fTipID;
				bool				fbCustomPos;
			};

			typedef std::vector<SToolTipDef>		TToolTipsArray;
			bool					fbToolTipsEnabled;
			TToolTipsArray			farrToolTips;
			SToolTipDef*			fpActiveToolTip;
		};
	}
}