/****************************************************************************************************

		MCCommandBinding.h
		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Author:	Arnaud
		Date:	1/24/2005

****************************************************************************************************/

#ifndef __MCCommandBinding__
#define __MCCommandBinding__

#if CP_PRAGMA_ONCE
#pragma once
#endif



#include "MCBasicTypes.h"
#include "MCPtrArray.h"
#include "MCPtr.h"

//The context for global keyboard shortcuts
const IDType gMainBindingContextID= 'Main';

class TMCPlatformEvent;


//links a command (generally menu entry) with a user defined keyboard shortcut
class TMCCommandBinding : public TMCObject
{
public: 
	TMCCommandBinding();
	TMCCommandBinding(const TMCCommandBinding& other);
	virtual ~TMCCommandBinding();

	int32				GetCommandID	()	const	{ return fCommandID; }
	boolean				IsValid			()	const	{ return fIsValid; }
	boolean				GetShift		()	const	{ return fShift; }
	boolean				GetStickyShift	()	const	{ return fStickyShift; }
	boolean				GetControl		()	const	{ return fControl; }
	boolean				GetAlt			()	const	{ return fAlt; }
	int16				GetChar			()	const	{ return fChar; }
	const TMCString&	GetCommandName	()	const	{ return fCommandName; }

	void				SetCommandID	(	int32	inCommandID)		{ MCAssert(inCommandID != 0); fCommandID= inCommandID; }
	void				SetShift		(	boolean	inShift)			{ fShift		= inShift; }
	void				SetStickyShift	(	boolean	inStickyShift)		{ fStickyShift	= inStickyShift; }
	void				SetControl		(	boolean	inControl)			{ fControl		= inControl; }
	void				SetAlt			(	boolean	inAlt)				{ fAlt			= inAlt; }
	void				SetChar			(	int16	inChar)				{ fChar			= inChar; }
	void				SetCommandName	(	const TMCString& inName)	{ fCommandName	= inName; }

	boolean				Check(TMCPlatformEvent* event);

	virtual void		Validate		(	boolean				inShift,
											boolean				inStickyShift,
											boolean				inControl,
											boolean				inAlt,
											int16				inChar,
											const TMCString&	inCommandName);

protected:
	int32				fCommandID;		//must be unique and constant... (can be the menu's action number or a tool id)
	boolean				fIsValid;		//false until all the fields have been filled
	boolean				fShift;
	boolean				fStickyShift;
	boolean				fControl;
	boolean				fAlt;
	int16				fChar;
	TMCDynamicString	fCommandName;
	int32				fPrivate;
};



class TMCCommandBindingGroup : public TMCObject
{
public:
	TMCCommandBindingGroup()				{ fGroupID= 0; }
	virtual ~TMCCommandBindingGroup()		{ fBindings.DeleteAndRemoveAll(); }

	void							SetGroupID				( IDType inGroupID)			{ fGroupID	 = inGroupID; }
	void							SetGroupName			( const TMCString& inName)	{ fGroupName = inName; }

	IDType							GetGroupID				()	const					{ return fGroupID; }
	const TMCString&				GetGroupName			()							{ return fGroupName; }

	TMCCommandBinding&				AddBinding				();


	TMCCommandBinding*				FindSameShortcut	( const TMCCommandBinding& inShortcut);

	TMCCommandBinding*				FindBinding			( const int32 inCommandID);

	int32							GetBindingsCount	() const					{ return fBindings.GetElemCount(); }
	TMCCommandBinding&				GetBinding			(int32 bindingIndex)		{ return *(fBindings[bindingIndex]); }

	void							Sort				();

protected:
	virtual TMCCommandBinding*		CreateCommandBinding()	{ return new TMCCommandBinding(); }

private:
	TMCCommandBindingGroup&			operator=			(const TMCCommandBindingGroup& other)	{ MCNotify("FORBIDDEN"); return *this; }
	TMCCommandBindingGroup			(const TMCCommandBindingGroup& other)						{ fGroupID= 0; MCNotify("FORBIDDEN"); }

protected:
	IDType								fGroupID;
	TMCDynamicString					fGroupName;	//eg File, Edit...
	TMCPtrArray<TMCCommandBinding>		fBindings;	//we own the pointers
};



struct TMCCommandAndContext
{
	TMCPtr<TMCCommandBinding>		fCommand;
	TMCPtr<TMCCommandBindingGroup>	fGroup;
};


class TMCCommandBindingContext : public TMCObject
{
public:
	TMCCommandBindingContext	()	{ fBindingContextID= 0; }
	~TMCCommandBindingContext	()	{ fBindingGroups.DeleteAndRemoveAll(); }

	void							SetBindingContextID		( IDType inContextID)		{ fBindingContextID	= inContextID; }
	void							SetBindingContextName	( const TMCString& inName)	{ fBindingContextName = inName; }

	IDType							GetBindingContextID		()							{ return fBindingContextID;}
	const TMCString&				GetBindingContextName	()							{ return fBindingContextName; }

	TMCCommandBindingGroup&			AddBindingGroup			();

	void							FindSameShortcut		( const TMCCommandBinding& inShortcut, TMCCommandAndContext& result);
	TMCCommandBinding*				FindBinding				( const int32	inCommandID);
	TMCCommandBindingGroup*			FindBindingGroup		( const IDType	inGroupID);

	int32							GetBindingGroupsCount	() const					{ return fBindingGroups.GetElemCount(); }
	TMCCommandBindingGroup&			GetBindingGroup			(int32 groupIndex)			{ return *(fBindingGroups[groupIndex]); }

	void							Sort					();

protected:
	virtual TMCCommandBindingGroup*	CreateBindingGroup		()	{ return new TMCCommandBindingGroup(); }

private:
	TMCCommandBindingContext& operator= (const TMCCommandBindingContext& other)		{ MCNotify("FORBIDDEN"); return *this;}
	TMCCommandBindingContext			(const TMCCommandBindingContext& other)		{ fBindingContextID= 0; MCNotify("FORBIDDEN"); }

protected:
	IDType									fBindingContextID;
	TMCDynamicString						fBindingContextName;	//eg Main, VertexModeler...
	TMCPtrArray<TMCCommandBindingGroup>		fBindingGroups;
};



class TMCCommandBindingContextList : public TMCPtrArray<TMCCommandBindingContext>
{
public:
	TMCCommandBinding*			FindBinding			( const int32	inCommandID);
	TMCCommandBindingContext*	FindBindingContext	( const IDType	inContextID);
};


















#endif
