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

#pragma once

#include "CheckButtonCtrl.h"
#include "GroupBoxCtrl.h"
#include "ListBoxCtrl.h"
#include "MarkerPopupCtrl.h"
#include "PictureCtrl.h"
#include "PullDownMenuCtrl.h"
#include "PushButtonCtrl.h"
#include "RadioButtonCtrl.h"
#include "RadioGroupBoxCtrl.h"
#include "StaticTextCtrl.h"
#include "TabPaneCtrl.h"
#include "TabCtrl.h"
#include "SwapPaneCtrl.h"
#include "SwapCtrl.h"
#include "ThumbnailPopupCtrl.h"
#include "CheckButtonCtrl.h"
#include "CheckGroupBoxCtrl.h"
#include "ColorButtonCtrl.h"
#include "EditIntegerCtrl.h"
#include "EditRealCtrl.h"
#include "EditTextCtrl.h"
#include "SliderCtrl.h"
#include "ColorPopupCtrl.h"
#include "ColorPopupCustomCtrl.h"
#include "PatternPopupCtrl.h"
#include "LineAttributePopupCtrl.h"
#include "LineStylePopupCtrl.h"
#include "LineWeightPopupCtrl.h"
#include "MarkerPopupCtrl.h"
#include "ListBrowserCtrl.h"
#include "TreeCtrl.h"

namespace VectorWorks
{
	namespace VWUI
	{
		// ---------------------------------------------------------------------------------------------------------------
		enum EDialogButton
		{
			kDialogButton_None		= 0,
			kDialogButton_Ok		= 1,
			kDialogButton_Cancel	= 2,
			kDialogButton_CustomA	= 3,
			kDialogButton_CustomB	= 4
		};
		
		class VWCustomCtrl;
		
		// ---------------------------------------------------------------------------------------------------------------
		class VWDialog : public VWControlsContainer
		{
			friend class VWControlsContainer;
			friend class VWCustomCtrl;
			
		protected:
									VWDialog();
		public:
			virtual					~VWDialog();

		// dialog managment
		public:
			virtual EDialogButton	RunDialogLayout();
			TControlID				GetDialogID() const;

			virtual TXString		GetDialogTitle() const;
			virtual void			SetDialogTitle(const TXString &inTitle);

		// dialog saved settings managment
		public:
			// enables saved settings for this dialog
			// if no dialog name is specified, the dialog title is used
			void					SetSavedSettingsTag(const TXString& category);
			void					SetSavedSettingsTag(const TXString& category, const TXString& dialogName);

			// allows additional data to be stored in saved settings for this dialog
			void					SetSavedValue(const TXString& name, const TXString& value);
			bool					GetSavedValue(const TXString& name, TXString& outValue) const;

		// child control managment
		public:
			virtual void				EnableDefaultButton(bool bEnable);
			virtual void				EnableCancelButton(bool bEnable);
			virtual void				EnableControl(TControlID id, bool bEnable);
			virtual void				ShowControl(TControlID id, bool bVisible);
			virtual void				SetControlHelpText(TControlID id, const TXString& helpText);

			virtual void				AddFirstGroupControl(VWControl* pControl);
			virtual void				AddBelowControl(VWControl* pExistingControl, VWControl* pNewControl, short indent = 0, short lineSpacing = 0);
			virtual void				AddRightControl(VWControl* pExistingControl, VWControl* pNewControl, short indent = 0, short lineSpacing = 0);

			VWCheckButtonCtrl*			GetCheckButtonCtrByID(TControlID id);
			VWGroupBoxCtrl*				GetGroupBoxCtrlByID(TControlID id);
			VWListBoxCtrl*				GetListBoxCtrlByID(TControlID id);
			VWMarkerPopupCtrl*			GetMarkerPopupCtrlByID(TControlID id);
			VWPictureCtrl*				GetPictureCtrlByID(TControlID id);
			VWPullDownMenuCtrl*			GetPullDownMenuCtrlByID(TControlID id);
			VWPushButtonCtrl*			GetPushButtonCtrlByID(TControlID id);
			VWRadioButtonCtrl*			GetRadioButtonCtrlByID(TControlID id);
			VWRadioGroupBoxCtrl*		GetRadioGroupBoxCtrlByID(TControlID id);
			VWStaticTextCtrl*			GetStaticTextCtrlByID(TControlID id);
			VWTabPaneCtrl*				GetTabPaneCtrlByID(TControlID id);
			VWTabCtrl*					GetTabCtrlByID(TControlID id);
			VWSwapPaneCtrl*				GetSwapPaneCtrlByID(TControlID id);
			VWSwapCtrl*					GetSwapCtrlByID(TControlID id);
			VWThumbnailPopupCtrl*		GetThumbnailPopupCtrlByID(TControlID id);
			VWCheckButtonCtrl*			GetCheckButtonCtrlByID(TControlID id);
			VWCheckGroupBoxCtrl*		GetCheckGroupBoxCtrlByID(TControlID id);
			VWColorButtonCtrl*			GetColorButtonCtrlByID(TControlID id);
			VWEditIntegerCtrl*			GetEditIntegerCtrlByID(TControlID id);
			VWEditRealCtrl*				GetEditRealCtrlByID(TControlID id);
			VWEditTextCtrl*				GetEditTextCtrlByID(TControlID id);
			VWSliderCtrl*				GetSliderCtrlByID(TControlID id);
			VWColorPopupCtrl*			GetColorPopupCtrlByID(TControlID id);
			VWColorPopupCustomCtrl*		GetColorPopupCustomCtrlByID(TControlID id);
			VWPatternPopupCtrl*			GetPatternPopupCtrlByID(TControlID id);
			VWLineAttributePopupCtrl*	GetLineAttributePopupCtrlByID(TControlID id);
			VWLineStylePopupCtrl*		GetLineStylePopupCtrlByID(TControlID id);
			VWLineWeightPopupCtrl*		GetLineWeightPopupCtrlByID(TControlID id);
			VWListBrowserCtrl*			GetListBrowserCtrlByID(TControlID id);
			VWTreeCtrl*					GetTreeCtrlByID(TControlID id);

			// tab pane managment
			void						AddTabPaneControl(VWTabPaneCtrl* pTabPane);

		// Dynamic Data Exchange
		public:
			virtual void	UpdateData(bool bSafeToUI=false);
			void	AddDDX_StaticText(TControlID controlID, TXString* pValue);
			void	AddDDX_CheckButton(TControlID controlID, bool* pCheckState);
			void	AddDDX_CheckButton(TControlID controlID, Boolean* pCheckState);
			void	AddDDX_CheckGroupBox(TControlID controlID, bool* pCheckState);
			void	AddDDX_ColorButton(TControlID controlID, RGBColor* pSelectedColor);
			void	AddDDX_EditInteger(TControlID controlID, long* pValue);
			void	AddDDX_EditReal(TControlID controlID, double* pValue, VWEditRealCtrl::EEditControlType editType);
			void	AddDDX_EditText(TControlID controlID, TXString* pValue, bool bMultiline=false);
			void	AddDDX_Slider(TControlID controlID, long* pPosition);
			void	AddDDX_RadioButton(TControlID controlID, bool* pCheckState);
			void	AddDDX_RadioButton(TControlID controlID, Boolean* pCheckState);
			void	AddDDX_RadioGroupBox(TControlID controlID, bool* pCheckState);
			void	AddDDX_PulldownMenu(TControlID controlID, short* pSelected);
			void	AddDDX_ListBox(TControlID controlID, short* pSelected);
			void	AddDDX_ColorPopup(TControlID controlID, RGBColor* pSelectedColor, bool bMatchBlackBkgr=true);
			void	AddDDX_ColorPopupCustom(TControlID controlID, ColorRef* pSelectedColor);
			void	AddDDX_PatternPopup(TControlID controlID, short* pPatternIndex, RGBColor* pForeColor, RGBColor* pBackColor);
			void	AddDDX_LineAttribsPopup(TControlID controlID, short* pLineStyle, short* pLineWeight);
			void	AddDDX_LineStylePopup(TControlID controlID, short* pLineStyle);
			void	AddDDX_LineWeightPopup(TControlID controlID, short* pLineWeight);
			void	AddDDX_MarkerPopup(TControlID controlID, SMarkerStyle* pValue);


			template<class TControlClass>
			void		AddDDX_Control(TControlClass* pControl);

		// tools
		public:			
			// Displays an alert dialog that informs the user of a serious problem
			// that requires intervention or correction before work can continue.
			static void				AlertCritical(const TXString& text, const TXString& advice = "");

			// Displays a dialog which informs the user about the result of a command.
			// Offers no user choices; the user acknowledges the message by clicking the OK button.
			static void				AlertInform(const TXString& text, const TXString& advice = "", bool bMinorAlert = false);

			// Displays a dialog that alerts the user to a condition
			// or situation that requires the user's decision and input before preceeding,
			// such as an impending action with potentially destructive or irreversible consequencies. 
			static EDialogButton	AlertQuestion(	const TXString& question,
													const TXString& advice = "",
													EDialogButton defaultButton = kDialogButton_None,
													const TXString& strOkText = "",
													const TXString& strCancelText = "",
													const TXString& strCustomButtonAText = "",
													const TXString& strCustomButtonBText = "" );

		// creational
		protected:
			bool					CreateDilaog(const TXString& dlgTitle, const TXString& defaultBtn, const TXString& cancelBtn, bool hasHelp=true, bool bResizableWidth=false, bool bResizableHeight=false);
			bool					CreateDilaog(short strListID, short dlgTitleIndex, short defaultBtnIndex, short cancelBtnIndex, bool hasHelp=true, bool bResizableWidth=false, bool bResizableHeight=false);
			bool					CreateDialogLayoutFromRsrc(short TEXTResourceID);

			void					SetDefaultButtonHelpString(const TXString& helpText);
			void					SetDefaultButtonHelpString(short strListID, short strHelpIndex);
			void					SetCancelButtonHelpString(const TXString& helpText);
			void					SetCancelButtonHelpString(short strListID, short strHelpIndex);

			virtual ViewRect		GetDialogDimension() const;
			virtual ViewPt			GetDialogPosition() const;
			virtual void			SetDialogPosition(ViewCoord left, ViewCoord top);
			virtual void			GetDialogSize(ViewCoord& outWidth, ViewCoord& outHeight) const;
			virtual void			SetDialogSize(ViewCoord width, ViewCoord height) const;


		// virtuals
		protected:
			virtual bool			CreateDialogLayout() = 0;
			virtual TXString		GetContextualHelpID() const;
			virtual void			OnInizializeContent();
			virtual	void			OnDDXInitialize() = 0;
			virtual void			OnUpdateUI();

		// events
		protected:
			virtual void			OnSetUpEvent();
			virtual void			OnSetDownEvent();
			virtual void			OnDefaultButtonEvent();
			virtual void			OnCancelButtonEvent();
			virtual void			OnControlEvent(VWControl* pParentControl);
			virtual void			OnBeforeDispatchEvent(TControlID controlID, VWDialogEventArgs& eventArg);

		// private dialong event handler
		private:
			static void			DialogEventHandler(long dlogID, long& itemHit, void* data, void* env);
			void				LocalDialogEventHandler(long& itemHit, void* pData);

		// events dispatcher map
		protected:
			virtual void DispatchEvent(TControlID controlID, VWDialogEventArgs& eventArg);

		protected:
			void				AddControl(VWControl* pControl, bool fake=false);
			VWControl*			GetControl(TControlID id);
			void				SetDialogClose(bool bCloseWithOK);
			void				UpdateSavedSettings(bool bRead);
			bool				GetDDXControlValue(TControlID controlID, TXString& outValue);

		// extended custom control event support
		protected:
			void				InitExtendedEventSupport();
			void				DeinitExtendedEventSupport();
			void				InstallExtendedEventSupport(VWControl* pControl);
#ifndef _WINDOWS
			static OSStatus		_WindowMouseEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* inUserData);
			VWCustomCtrl*		GetCustomCtrlAtPoint(const ViewPt& pt);
#endif

		protected:
			// true when the dialog is setup
			// this prevets the calling dispatcher when the dialog is not setup
			bool				fbIsSetup;

			// the item hit when default button or cancel button events occure
			// used to prevend the dialog from closing if you dont call VWDialog::OnDefaultButtonEvent or VWDialog::OnCancelButtonEvent
			long*				fpItemHit;

			void*				fpArrControls;

			// tab panes for which this dialog will pass data
			void*				fpArrTabPanes;

			// DDX data
			void*				fpArrDDXData;

			// saved settings support
			TXString			fstrDialogCategory;
			TXString			fstrDialogName;
			void*				farrSavedSettingsItems;
			ViewRect			fSavedDialogPosition;

			// extended custom control event support
#ifndef _WINDOWS
			EventHandlerUPP		fEventHandlerUPP;
			EventHandlerRef		fEventHandlerRef;
#endif
		};


		// ---------------------------------------------------------------------------------------------------------------
		template<class TControlClass>
		void VWDialog::AddDDX_Control(TControlClass* pControl)
		{
			if ( pControl == NULL )
				return;

			VWControl*	pThisControl	= pControl;
			VWControl*	pOldControl		= this->GetControl( pThisControl->GetControlID() );
			// this control should not be added twice
			ASSERTN( kVStanev, pOldControl == NULL || pThisControl == pOldControl );
			if ( pOldControl == NULL || pThisControl == pOldControl ) {
				pThisControl->fpParentDlg	= this;
				pThisControl->AttachControl();
				this->InstallExtendedEventSupport( pThisControl );
				if ( pOldControl == NULL ) {
					this->AddControl( pThisControl, false );
				}
			}
		}
	}
}