#ifndef __FBBASE_H__
#define __FBBASE_H__
/**************************************************************************
 Copyright (c) 1994 - 2006 Autodesk, Inc. and/or its licensors.
 All Rights Reserved.
 
 The coded instructions, statements, computer programs, and/or related 
 material (collectively the "Data") in these files contain unpublished 
 information proprietary to Autodesk, Inc. and/or its licensors, which is 
 protected by Canada and United States of America federal copyright law 
 and by international treaties.
 
 The Data may not be disclosed or distributed to third parties, in whole 
 or in part, without the prior written consent of Autodesk, Inc. 
 ("Autodesk").
 
 THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY.
 ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED. AUTODESK MAKES NO 
 WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR 
 ARISING BY CUSTOM OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES 
 OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 
 PURPOSE OR USE. WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT 
 WARRANT THAT THE OPERATION OF THE DATA WILL BE UNINTERRUPTED OR ERROR 
 FREE.
 
 IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS 
 OR SUPPLIERS ("AUTODESK GROUP") BE LIABLE FOR ANY LOSSES, DAMAGES OR 
 EXPENSES OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR MULTIPLE 
 DAMAGES OR OTHER SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS 
 OF PROFITS, REVENUE OR DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR 
 DAMAGES OF ANY KIND), HOWEVER CAUSED, AND REGARDLESS OF THE THEORY OF 
 LIABILITY, WHETHER DERIVED FROM CONTRACT, TORT (INCLUDING, BUT NOT 
 LIMITED TO, NEGLIGENCE), OR OTHERWISE, ARISING OUT OF OR RELATING TO THE 
 DATA OR ITS USE OR ANY OTHER PERFORMANCE, WHETHER OR NOT AUTODESK HAS 
 BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.
 
**************************************************************************/

/**	\file fbcomponent.h
*	Basic class definitions.
*	Contains the basic classes that most SDK objects will derive from. 
*	These classes form the base of many functionalities of the SDK. The file
*	also contains the base macros used in the definition/registration 
*	of the SDK classes.
*/

#include <kaydaradef.h>

// This include directive is necessary because of the definition of the
// FBLibrary class.
#include <kaydaralib.h>

#ifndef FBSDK_DLL 
	#define FBSDK_DLL K_DLLIMPORT
#endif

// Global includes
#include <fbsdk/fbplug.h>
#include <fbsdk/fbarray.h>
#include <fbsdk/fbstring.h>
#include <fbsdk/fbproperties.h>

#ifdef _MSC_VER
//   #pragma warning (disable: 4800)// non dll-interface class "X" used as base for dll-interface class for "Y" (performance warning) 
	#pragma warning (disable: 4275)	// 'int' : forcing value to bool 'true' or 'false' (performance warning) 
	#pragma warning (disable: 4661)	// no suitable definition provided for explicit template instantiation request
#endif

K_FORWARD( IRegister );
K_FORWARD( IError );
K_FORWARD( IStore );
K_FORWARD( KEventBase );
K_FORWARD( KGlobalNamedEvent );

#ifdef FBSDKUseNamespace
	namespace FBSDKNamespace {
#endif

#ifndef FBINCLUDE
// Section that must be exported
#else
#endif

#define FB_DEFAULT_SDK_ICON	"openreality_noicon.tif"

/** Macro for classes with no properties
*/
#define FBImplementNoProperties( Class ) \
	void Class::Class##InitProperties() {}

#define FBPropertiesDeclare( Class, Parent ) \
   private:	void Class##InitProperties();\
   public:	virtual void InitProperties() { Parent::InitProperties(); Class##InitProperties(); }

// For internal use only.
#define __FBClassInit	mLocalPtr = NULL
#define __FBClassImplementation( ThisComponent )	int ThisComponent::TypeInfo=FBPlug::mGlobalTypeInfo++
#define __FBClassDeclare( Name,Parent ) \
  public: \
	virtual char *ClassName()		{ return #Name; } \
	FBPropertiesDeclare( Name, Parent );\
	virtual bool Is( int pTypeId )	{ return (pTypeId==TypeInfo) ? true : Parent::Is( pTypeId ); } \
	HData##Name mLocalPtr; \
	virtual ~ Name(); \
	static int TypeInfo; \
  private: \

/** Storable Class implementation.
*	This should be placed in the source code file for a class.
*/
#define FBStorableClassImplementation(ClassName, Type)\
	char* ClassName::FbxGetObjectSubType(){ return #ClassName; }\
	HIObject RegisterStorable##ClassName##Create(HIObject /*pOwner*/, char* pName, void* /*pData*/){\
		ClassName* Class = new ClassName(pName);\
		Class->mAllocatedComponent = true;\
		if( Class->FBCreate() ){\
			return Class->GetHIObject();\
		} else {\
			delete Class;\
			return NULL;}}\
	FBLibraryModule(ClassName##Storable){\
		FBString lGroup = "FbxStorable/";\
		lGroup += #Type;\
		FBRegisterObject(ClassName##R2, lGroup, #ClassName, "", RegisterStorable##ClassName##Create, true, NULL);}

/** Element Class implementation.
*	This should be placed in the source code file for a class.
*/
#define FBElementClassImplementation(ClassName,IconFileName)\
	HIObject RegisterElement##ClassName##Create(HIObject /*pOwner*/, char* pName, void* /*pData*/){\
		ClassName* Class = new ClassName(pName);\
		Class->mAllocatedComponent = true;\
		if( Class->FBCreate() ){\
			return Class->GetHIObject();\
		} else {\
			delete Class;\
			return NULL;}}\
	FBLibraryModule(ClassName##Element){\
		FBRegisterObject(ClassName##R2, "Browsing/Templates/Elements", #ClassName, "", RegisterElement##ClassName##Create, true, IconFileName);}

/**	Storable Class declaration.
*	Overloads the necessary functions when a class inherits from
*	FBComponent (or its derivatives) and that you want it to be persistent.
*	\param Name		Name of class to declare.
*	\param Parent	Parent class to associate with \e Name.
*/
#define FBStorableClassDeclare(Name, Parent)\
	FBClassDeclare(Name, Parent);\
public:\
	virtual char* FbxGetObjectSubType();


/**	Initialize a property: component.
*	\param	Param		Owner name.
*	\param	Type		Type of variable.
*	\param	PropName	Component name.
*	\param	Get			Get function pointer.
*	\param	Set			Set function pointer.
*/
#define FBPropertyInitComponent( Param,Type,PropName,Get,Set ) \
	{ \
		PropertyAdd(PropName.Init( (void *)Param,#PropName,(H##Type (*)(void *))Get,(void (*)(void *,H##Type))Set )); \
		PropName.TypeInfo = &Type::TypeInfo; \
	}

/** Macro to verify the type of a component.
*	Used to compare a component to another, by verifying their
*	Class::TypeInfo values.
*	\param Component		Component to verify.
*	\param ComponentType	Type to verify \e Component with.
*	\return \b true if object is of type \e ComponentType.
*/
#define FBIS( Component,ComponentType ) \
	(Component)->Is( ComponentType::TypeInfo )

////////////////////////////////////////////////////////////////////////////////////
// Utility function
////////////////////////////////////////////////////////////////////////////////////
// For internal use only.
__FB_FORWARD( FBComponent );

/* \internal Get a handle to the FBComponent belonging to an HIObject.
*	This will not create the internal SDK object, and will return NULL if
*	the SDK object has not been initialized.
*	\param Object	Internal object for which the FBComponent is required.
*	\return Handle to FBComponent belonging to \e Object.
*/
HFBComponent FBSDK_DLL GetHFBComponent( HIObject Object ) ;

/**	Get the FBComponent from an Internal Object.
*	\param	pObject		Object to get SDK object for.
*	\param	pAutoCreate	Create object if it doesn't exist? (default is \b true)
*	\return	FBComponent for \e pObject.
*/
FBSDK_DLL HFBComponent  FBGetFBComponent( HIObject pObject, bool pAutoCreate=true );

/**	Get the FBPlug from an Internal Object.
*	\param	pObject		Object to get SDK object for.
*	\param	pAutoCreate	Create object if it doesn't exist? (default is \b true)
*	\return	FBComponent for \e pObject.
*/
FBSDK_DLL HFBPlug       FBGetFBPlug( HIObject pObject, bool pAutoCreate=true );

/** Get the Root FBComponent
*/
FBSDK_DLL FBArrayTemplate<HFBComponent>& FBGetComponentArray();

////////////////////////////////////////////////////////////////////////////////////
// Registration macros
////////////////////////////////////////////////////////////////////////////////////
// Event registration/unregistration.
// For internal use only.
#define FBRegisterEvent		( Object, EventId, EventProc )	IQ(	Object,IRegister)->Register		( EventId,(HICallback)this,(kICallbackHandler)EventProc );
#define FBRegisterLEvent	( Object, EventId, EventProc )	IQL(Object,IRegister)->Register		( EventId,(HICallback)this,(kICallbackHandler)EventProc );
#define FBUnregisterEvent	( Object, EventId, EventProc )	IQ(	Object,IRegister)->Unregister	( EventId,(HICallback)this,(kICallbackHandler)EventProc );
FBSDK_DLL bool FBObject_Register  ( char * pGroupName,char * pName,char * pDescription, kObjectCreatorFnc pCreatorFnc, bool pIsMultipleAllowed,char * pIconFilename);
FBSDK_DLL bool FBObject_Unregister( char * pGroupName,char * pName, unsigned int nth=0 );
inline  bool FBUnregisterObject( char * pGroupName,char * pName, unsigned int nth=0 ) { return FBObject_Unregister( pGroupName,pName,nth ); }
#define FBRegisterObject( LocalId,Path,Name,Description,Constructor,IsMultipleAllowed,IconFilename ) \
	static int __R##LocalId = FBObject_Register( Path,Name,Description,Constructor,IsMultipleAllowed,IconFilename )
typedef HIRegister	HISender;
typedef HKEventBase HKEvent;
typedef void (ICallback::*FBCallback)(HISender pSender,HKEvent pEvent);
FBSDK_DLL void FBRegisterNonManagedPersistentClass(char* pClassName);

FBSDK_DLL int FBRegister_ClassId(char* pClassName);
#define FBDeclareUserObject(ClassName)\
public:\
	static int		ClassId;\
	virtual int		GetUserClassId();\
	virtual char*	FbxGetObjectSubType()

////////////////////////////////////////////////////////////////////////////////////
// FBComponent
////////////////////////////////////////////////////////////////////////////////////
#ifdef new
	#define RENEW new
	#undef new
#endif

////////////////////////////////////////////////////////////////////////////////////
// FBSceneList
////////////////////////////////////////////////////////////////////////////////////
FB_FORWARD( FBPropertyListComponent );
__FB_FORWARD( FBComponent );
FB_DEFINE_LIST( FBSDK_DLL, Component );

FB_FORWARD( FBFolder );
FB_DEFINE_COMPONENT( FBSDK_DLL, Folder );

//! Possible actions when a notify plug event occurs
enum FBConnectionAction
{
	//PlugNotify actions
	kFBActionUnknown,	//!< Unknown action.
	kFBRequestConnect,	//!< Request connection of source to destination.
	kFBConnect,			//!< Connect source to destination.
	kFBConnected,		//!< Connected source to destination.
	kFBDisconnect,		//!< Disconnect source from destination.
	kFBDisconnected,	//!< Disconnected source from destination.
	kFBBeginChange,		//!< Begin change on destination.
	kFBEndChange,		//!< End change on destination.
	kFBConnectedOwner,	//!< Connected owner to destination.
	kFBDisconnectOwner,	//!< Disconnect owner from destination.

	//PlugDataNotify actions
	kFBCandidate,		//!< Data candidate event, before the data is set.
	kFBCandidated,		//!< Data candidate event, after the data is set.

	//PlugStateNotify actions
	kFBDestroy,			//!< Component destroy.
	kFBSelect,			//!< Component selection.
	kFBUnselect,		//!< Component de-selection.
	kFBReselect,		//!< Component re-selection.
	kFBRename,			//!< Component is going to be renamed.
	kFBRenamed,			//!< Component has been renamed.
	kFBPrefixRename,	//!< Component prefix is going to be renamed.
	kFBPrefixRenamed,	//!< Component prefix has been renamed.
	kFBDescription		//!< Component description event.
};

//! Available flags for any component (Warning! PRELIMINARY Implemention)
enum FBObjectFlag
{
	kFBFlagSelectable = (1 << 0),			//!< Can be selected
	kFBFlagDeletable = (1 << 1),			//!< Can be deleted
	kFBFlagSavable = (1 << 2),				//!< Can be saved
	kFBFlagVisible = (1 << 3),				//!< Can be visible
	kFBFlagClonable = (1 << 4),				//!< Can be cloned
	kFBFlagSystem = (1 << 5),				//!< Created from System (not from user)
	kFBFlagNewable = (1 << 6),				//!< Deleted on File->New
	kFBFlagRenamable = (1 << 7),			//!< Can be renamed
	kFBFlagMergeable = (1 << 8),			//!< Can be merged
	kFBFlagBrowsable = (1 << 9),			//!< Visible in the Scene Navigator/Schematic View/Property View/Model View.
	kFBFlagDetachable = (1 << 10),			//!< Object can be "detached". Used by the apply manager contextual menu.
	kFBFlagUndoable = (1 << 11),			//!< Object can undo its actions and states.
	kFBFlagKeyable = (1 << 12),				//!< Object can Key his property. (System Camera can't) 

	// Temporary/VersionTransition Flags
	kFBFlagStory = (1 << 13),				//!< Object created/used by the Story tool. Useful flag for filtering Story objects.
	kFBFlagStorable6 = (1 << 14),			//!< System/Obsolete.
    kFBFlagStorableData6 = (1 << 15),		//!< System/Obsolete.
    kFBFlagUniqueName = (1 << 16),			//!< Object unique name can be added to the unique name list (at first, only RootNode have this flag)
};

enum FBNamespaceAction
{
    kFBConcatNamespace,                     //!< Use to add a namespace name to object.
    kFBReplaceNamespace,                    //!< Use to replace a define namespace
    kFBRemoveAllNamespace                   //!< Remove all the namespace name
};

FB_DEFINE_ENUM(FBSDK_DLL, ConnectionType);
FB_DEFINE_ENUM(FBSDK_DLL, ConnectionAction);
FB_DEFINE_ENUM(FBSDK_DLL, ObjectFlag);

/** \b PropertyList: Component.
*/
class FBSDK_DLL FBPropertyListComponent : public FBPropertyBaseList< HFBComponent >
{
  private:
	bool mParents;
  public:
	//! Constructor.
	FBPropertyListComponent();
	/**	Add a component to the list.
	*	\param	pItem	Component to add to list.
	*	\return Number of components in list after operation.
	*/
	virtual int Add( HFBComponent pItem );
	/**	Remove the component at \e pIndex from list.
	*	\param	pIndex	Index of Component to remove.
	*/
    virtual void RemoveAt( int pIndex );
	/**	Get the Component at \e pIndex.
	*	\param	pIndex	Index of Component to get a handle on.
	*	\return Component at \e pIndex.
	*/
	virtual HFBComponent operator[](int pIndex);
	/**	Get the Component count.
	*	\return Number of Components.
	*/
	virtual int GetCount();

	friend class FBComponent;
};


////////////////////////////////////////////////////////////////////////////////////
// FBPropertyListObject
////////////////////////////////////////////////////////////////////////////////////

FB_FORWARD( FBPropertyListObject );

/** \b List of scene objects.
*   This list is a more generic container often used as object properties.
*   The types of actual object that it can contain can be specialised.
*/
class FBSDK_DLL FBPropertyListObject : public FBPropertyBaseList< HFBComponent >
{
  public:
    //! Constructor.
    FBPropertyListObject();

    /** Get the object count.
    *   \return Number of Objects.
    */
    virtual int GetCount();

    //@{
    /** Get the object at \e pIndex.
    *   \param  pIndex  Index of the object to query.
    *   \return The object at \e pIndex.
    */
    virtual HFBComponent operator[]( int pIndex );
    virtual HFBComponent GetAt( int pIndex );
    //@}

    /** Add an object at the end of the list.
    *   \param  pObject Object to add to list.
    *   \return Index of the newly added object. A return value of '-1' indicated the the object has not been added.
    */
    virtual int Add( HFBComponent pObject );

    /** Replace an existing entry at a specific index.
    *   \param  pIndex    Index of the object that should be replaced.
    *   \param  pObject   Object to insert in the list.
    *   \return Index of the replaced object. A return value of '-1' indicated the the object has not been replaced.
    */
    virtual int SetAt(int pIndex, HFBComponent pObject);

    /** Remove an object at a specific index.
    *   \param  pIndex    Index of the object that should be removed.
    */
    virtual void RemoveAt( int pIndex );

    /** Insert an object at a specific index.
    *   \param  pIndex    Index where the object should be inserted.
    *   \param  pObject   Object to insert in the list.
    *   \return Index of the inserted object. A return value of '-1' indicated the the object has not been inserted.
    */
    virtual int InsertAt(int pIndex, HFBComponent pObject);

    /** Clears the content of the list.
    */
    virtual void Clear();

private:
    //@{
    /** Restricted methods.
    *   Voluntarily making the copy constructor and assignment
    *   operator unavailable.
    */
    FBPropertyListObject( const FBPropertyListObject& );
    const FBPropertyListObject& operator =( const FBPropertyListObject& );
    //@}
};

/**	Basic Open Reality SDK Element.
*   There are 2 reasons for the existence of this base class:
*   1- To encapsulate internal application object so that they can be exposed
*      to the Open Reality SDK.
*   2- To be used as the base class of an object that has one or more
*      FBProperty-type data members.
*	The FBComponent class is used to encapsulate objects which have FBProperty
*   data members.
*/
class FBSDK_DLL FBComponent : public FBPlug
{
public:
	HDataFBComponent mLocalPtr;					

protected:
	FBString		mName;

public:
	static int		TypeInfo;
	bool			mAllocatedComponent;

	/** Constructor
	*	\param pObject  Object to copy component from (default is NULL).
	*/
	FBComponent( HIObject pObject=NULL );		

	//! Destructor.
	virtual ~FBComponent();								

	/** Open Reality Creation function.
	*	\return Outcome of creation (true/false).
	*/
	virtual bool FBCreate();

	//! Open Reality Destruction function.
	virtual void FBDestroy();

	// \internal Open Reality Deletion function.
	virtual void FBDelete();

	// \internal Assign component to an internal pointer.
	virtual bool SetHIObject(HIObject pObject, bool pSDKComponent);

	/** Add a Property to the component's Property manager.
	*	\param Property The property to add to the property manager.
	*	\return Index in the property array where \e Property was inserted.
	*/
	int	PropertyAdd( FBProperty *Property );

	/** Remove a Property from the component's Property manager.
	*	\param Property The property to remove from the property manager.
	*/
	void PropertyRemove( FBProperty* Property );

	/** Create user or dynamic property.
	*	\param pName The name of the property.
	*	\param pType Type of the property see enum FBPropertyType.
	*	\param pDataType DataType of the property is a text define in ANIMATIONNODE_TYPE_??? in fbdata.h.
	*	\param pAnimatable To specify if the property can be animated.
	*	\param pIsUser To specify if the property is available as a custom property or dynamic and attached to the object.
	*	\param pReferenceSource Use that param to specify the property that a reference refer to.
	*/
	FBProperty* PropertyCreate( char* pName, FBPropertyType pType, char * pDataType, bool pAnimatable, bool pIsUser = false, FBProperty* pReferenceSource = NULL  );


	// \internal Overloaded function to initialize all properties for an object.
	virtual void InitProperties();

	// \internal Intializes FBComponent properties.
	void FBComponentInitProperties();

	/** GetObjectFlags
	*	\return	Get all object flags in one call. Flags can be concatened.
	*/
	FBObjectFlag GetObjectFlags();

	/** SetObjectFlags
	*	\param	pFlags	Set flags values. Important note: this function overwrite all flags with those passed in parameter.
	*/
	void SetObjectFlags(FBObjectFlag pFlags);

	/** HasObjectFlags
	*	\param	pFlags	Flags to check if they are present.
	*	\return			True if all flags in pFlags are enabled.
	*/
	bool HasObjectFlags(FBObjectFlag pFlags);

	/** EnableObjectFlags
	*	\param	pFlags	Flags to enable.
	*/
	void EnableObjectFlags(FBObjectFlag pFlags);

	/** DisableObjectFlags
	*	\param	pFlags	Flags to disable.
	*/
	void DisableObjectFlags(FBObjectFlag pFlags);

    /** ProcessNamespaceHierarchy.
    *   This function is a recursive function that will go through the whole hierarchy(childs) to add/replace the prefix
    *   If you need to work on a single object, use the ProcessObjectPrefix function
    *   \param  pNamespaceAction        Indicate which operation to do on the hierarchy(childs).
    *   \param  pNamespaceName          Indicate the Namespace name on Add/Delete or the prefix to replace in case of replace
    *   \param  pReplaceTo              Indicate the new Namespace Name or NULL in case of Add or delete
    *   \param  pAddRight               indicate if we add the namespace on right most or left most side or other namespace
    */
    void ProcessNamespaceHierarchy( FBNamespaceAction pNamespaceAction, const char* pNamespaceName, const char* pReplaceTo=NULL, bool pAddRight=true );

    /** ProcessObjectNamespace.
    *   This function is the same as ProcessNamespaceHierarchy except that it will apply only on the current object and won't
    *   be apply to the object childs
    */
    void ProcessObjectNamespace ( FBNamespaceAction pNamespaceAction, const char* pNamespaceName, const char* pReplaceTo=NULL, bool pAddRight=true );

	/** Get the class name.
	*	\return The class name (i.e. "FBComponent").
	*/
	virtual char* ClassName();

	//@{
	// \internal Overloaded allocation/destruction operator.
	void *operator new( size_t stAllocateBlock );
	void operator delete( void *pvMem );

	void *operator new( size_t stAllocateBlock,	int blockType, const char *filename, int linenumber  );
#if	_MSC_VER >= 1200
	void operator delete( void *pvMem, int blockType, const char *filename, int linenumber  );
#endif
	//@}

	FBPropertyManager		PropertyList;	//!< <b>Read Only Property:</b> Manages all of the properties for the component.
	FBPropertyListComponent	Components;		//!< <b>List:</b> List of components.
	FBPropertyListComponent	Parents;		//!< <b>List:</b> Parents.
	FBPropertyBool			Selected;		//!< <b>Read Write Property:</b> Selected property.
	FBPropertyString		Name;			//!< <b>Read Write Property:</b> Unique name of object.

#if !defined(K_NO_FOLDER)
	FBPropertyFolder		Folder;			//!< <b>Read Write Property:</b> The folder that contain this component.
#endif

public:
    IObject_Declare(Implementation);		// \internal Interface to IObject
    ICallback_Declare(Implementation);		// \internal Interface to ICallback


	/** Returns true if object is of type TypeId.
	*	\param pTypeId TypeId to compare object to.
	*	\return Result of the comparison.
	*/
	virtual bool Is( int pTypeId );			

	friend FBSDK_DLL void FBComponentSetName( HFBComponent pObject, char *pName );
	friend FBSDK_DLL char* FBComponentGetName( HFBComponent pObject );
};

#ifdef RENEW
	#define new new( _NORMAL_BLOCK, __FILE__, __LINE__)
	#undef RENEW
#endif

////////////////////////////////////////////////////////////////////////////////////
// FBEvent
////////////////////////////////////////////////////////////////////////////////////
__FB_FORWARD( FBEvent );

/** Base Event class.
*	All events in the Open Reality SDK inherit from this class.
*/
class FBSDK_DLL FBEvent : public FBComponent {
	__FBClassDeclare( FBEvent,FBComponent );
public:
	/** Constructor.
	*	Receives an object of type HKEvent that the 
	*	corresponding callback will receive as a parameter. 
	*	\param pEvent  Internal event to obtain information from.
	*/
	FBEvent( HKEvent pEvent );

	FBPropertyInt	Type;				//!< <b>Read Only Property:</b> Type of event.
};

////////////////////////////////////////////////////////////////////////////////////
// FBEventConnectionNotify
////////////////////////////////////////////////////////////////////////////////////
__FB_FORWARD( FBEventConnectionNotify );

//! Connection notify event class.
class FBSDK_DLL FBEventConnectionNotify : public FBEvent
{
	__FBClassDeclare(FBEventConnectionNotify, FBEvent);

public:
	/**	Constructor.
	*	\param pEvent	 Base event (internal) to obtain information from.
	*/
	FBEventConnectionNotify(HKEventBase pEvent);

	FBPropertyConnectionAction	Action;			//!< <b>Read Only Property:</b> Connection's action performed.
	FBPropertyInt				SrcIndex;		//!< <b>Read Only Property:</b> Index of the source in the destination component.
	FBPropertyConnectionType	ConnectionType;	//!< <b>Read Only Property:</b> Connection's type.
	FBPropertyPlug				SrcPlug;		//!< <b>Read Only Property:</b> The source plug involved in the action.
	FBPropertyPlug				DstPlug;		//!< <b>Read Only Property:</b> The destination plug involved in the action.
	FBPropertyPlug				NewPlug;		//!< <b>Read Only Property:</b> New plug created by the action. (Mostly used by merge/replace)
};

////////////////////////////////////////////////////////////////////////////////////
// FBEventConnectionDataNotify
////////////////////////////////////////////////////////////////////////////////////
__FB_FORWARD( FBEventConnectionDataNotify );

//! Connection notify event class.
class FBSDK_DLL FBEventConnectionDataNotify : public FBEvent
{
	__FBClassDeclare(FBEventConnectionDataNotify, FBEvent);

public:
	/**	Constructor.
	*	\param pEvent	 Base event (internal) to obtain information from.
	*/
	FBEventConnectionDataNotify(HKEventBase pEvent);

	FBPropertyConnectionAction	Action;			//!< <b>Read Only Property:</b> Connection's action performed.
	FBPropertyPlug				Plug;			//!< <b>Read Only Property:</b> The plug involved in the action.
	void*						GetData();		//!< Available data pointer
	void*						GetOldData();	//!< Last available data pointer
};

////////////////////////////////////////////////////////////////////////////////////
// FBEventConnectionStateNotify
////////////////////////////////////////////////////////////////////////////////////
__FB_FORWARD( FBEventConnectionStateNotify );

//! Connection notify event class.
class FBSDK_DLL FBEventConnectionStateNotify : public FBEvent
{
	__FBClassDeclare(FBEventConnectionStateNotify, FBEvent);

public:
	/**	Constructor.
	*	\param pEvent	 Base event (internal) to obtain information from.
	*/
	FBEventConnectionStateNotify(HKEventBase pEvent);

	FBPropertyConnectionAction	Action;			//!< <b>Read Only Property:</b> Connection's action performed.
	FBPropertyPlug				Plug;			//!< <b>Read Only Property:</b> The plug involved in the action.
	void*						GetData();		//!< Available data pointer
	void*						GetOldData();	//!< Last available data pointer
};

////////////////////////////////////////////////////////////////////////////////////
// FBLibrary
////////////////////////////////////////////////////////////////////////////////////
/** Library class for DLL registration.
*	Manages the DLL control via a global FBLibrary object. For each DLL to be created, an implementation
*	of the FBLibrary functions will be necessary, see the sample code to see an example implementation.
*/
class FBSDK_DLL FBLibraryBase : public ICallback
{
public:
	FBLibraryBase();
	virtual ~FBLibraryBase();
    IObject_Declare(Implementation);		// \internal Interface to IObject
    ICallback_Declare(Implementation);		// \internal Interface to ICallback

	/** Initialize library.
	*	Initial load of DLL into memory.
	*	\return \b true if successful.
	*/
	virtual bool LibInit();

	/**	Open library.
	*	Library is opened to peruse the exported symbols.
	*	\return \b true if successful.
	*/
	virtual bool LibOpen();

	/**	Is library ready?
	*	Ready the library to begin accessing the functions. Any on library
	*	activation code should be placed in this function.
	*	\return \b true if successful.
	*/
	virtual bool LibReady();

	/**	Close library.
	*	\return \b true if successful.
	*/
	virtual bool LibClose();

	/**	Release library.
	*	\return \b true if successful.
	*/
	virtual bool LibRelease();

	KGlobalNamedEvent  *mLibrary_Open,*mLibrary_Ready,*mLibrary_Close,*mLibrary_Release;

	void Library_OpenHandler(HIRegister pCaller,HKEventBase pEvent);
	void Library_ReadyHandler(HIRegister pCaller,HKEventBase pEvent);
	void Library_CloseHandler(HIRegister pCaller,HKEventBase pEvent);
	void Library_ReleaseHandler(HIRegister pCaller,HKEventBase pEvent);
};

////////////////////////////////////////////////////////////////////////////////////
// FBLibrary
////////////////////////////////////////////////////////////////////////////////////
/** Library class for DLL registration.
*	Manages the DLL control via a global FBLibrary object. For each DLL to be created, an implementation
*	of the FBLibrary functions will be necessary, see the sample code to see an example implementation.
*/
class FBLibrary : public FBLibraryBase
{
public:
	/** Initialize library.
	*	Initial load of DLL into memory.
	*	\return \b true if successful.
	*/
	virtual bool LibInit();

	/**	Open library.
	*	Library is opened to peruse the exported symbols.
	*	\return \b true if successful.
	*/
	virtual bool LibOpen();

	/**	Is library ready?
	*	Ready the library to begin accessing the functions. Any on library
	*	activation code should be placed in this function.
	*	\return \b true if successful.
	*/
	virtual bool LibReady();

	/**	Close library.
	*	\return \b true if successful.
	*/
	virtual bool LibClose();

	/**	Release library.
	*	\return \b true if successful.
	*/
	virtual bool LibRelease();
};

/** Declare the library for the application.
*	Creates the FBLibrary object and generic interface functions for DLL access.
*/
#define FBLibraryDeclare( LibName ) \
static FBLibrary LibName##GlobalFBLibrary; \
extern "C" {	\
	K_DLLEXPORT bool LIBRARY_INIT(HIError /*Error*/) \
	{ \
		FB_EXT_INIT( LibName ); if (LibName##GlobalFBLibrary.LibInit()) return true; return false; \
	} \
} \
FB_DLL_INIT( LibName, Operation )				\
{												\
	switch( Operation )							\
	{											\
		case kFBDllLoad:						\
		{				

/*	\internal Define a module registration call.
*	\param Name		Module to register.
*/
#define FBLibraryModule(Name)					\
	void FBModule##Name()

/**	\internal Declare the module's registration functions.
*	\param ClassName	Class to declare registration functions for.
*/
#define FBLibraryRegister( ClassName )			\
	extern void FBModule##ClassName( );			\
	FBModule##ClassName( );

/**	\internal Declare the module's registration functions for storable classes.
*	\param ClassName	Class to declare registration functions for.
*/
#define FBLibraryRegisterStorable( ClassName )			\
	extern void FBModule##ClassName##Storable( );			\
	FBModule##ClassName##Storable( );

/**	\internal Declare the module's registration functions for element classes.
*	\param ClassName	Class to declare registration functions for.
*/
#define FBLibraryRegisterElement( ClassName )			\
	extern void FBModule##ClassName##Element( );			\
	FBModule##ClassName##Element( );

//! Finish library declaration.
#define FBLibraryDeclareEnd						\
		}										\
		break;									\
        default:                                \
        break;                                  \
	}											\
}

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

#define FBCustomManagerImplementation( ThisComponent )  \
    FBClassImplementation( ThisComponent )              \


#define FBRegisterCustomManager( ClassName )            \
    FBLibraryModule( ClassName )                        \
    {                                                   \
        static ClassName g##ClassName;                  \
        g##ClassName.FBCreate();                        \
        g##ClassName.RegisterManager();                 \
    }                                                   \


#define FBCustomManagerDeclare( ClassName )             \
FBClassDeclare( ClassName, FBCustomManager );           \
    public:                                             \
    ClassName() : FBCustomManager() { FBClassInit; }    \
    private:                                            \


////////////////////////////////////////////////////////////////////////////////////
// FBCustomManager
////////////////////////////////////////////////////////////////////////////////////

__FB_FORWARD( FBCustomManager );

/** Custom manager class for user controled observer objects.
*	This class is used to create a singleton object that has a lifetime similar to
*   the one of the application. Meaning that it is created early in the
*   initialization of the application and survives across File->Open and File->New,
*   being destroyed upon shutdown of the application.
*
*   The manager object is notified by the application at certain points in time,
*   such as when the scene is cleared or the application is shutting down.
*
*   Manager objects are not saved or mentionned in the FBX files created. Its
*   behavior can be controlled via custom configuration files.
*/
class FBSDK_DLL FBCustomManager : public FBComponent {
    __FBClassDeclare( FBCustomManager, FBComponent );
public:
    /** Constructor.
    */
    FBCustomManager();

    /** Instantiating the manager is not enough. It also need to be registered in
    *   the list of all managers. This call is done automatically via the use
    *   of the macro 'FBRegisterCustomManager'.
    */
    void RegisterManager();

    /** Open Reality Creation function.
    *   \return Outcome of creation (true/false).
    */
    virtual bool FBCreate();

    //! Open Reality Destruction function.
    virtual void FBDestroy();


    IObject_Declare(Implementation);            // Interface to IObject

    /** This method is called upon the loading of the plugin, right after
    *   FBCreate is called. Since it happens very early in the lifespan of
    *   the application, not all the initialization is done. So access to
    *   system objects is very limited.
    *
    */
    virtual bool     Init()   ;

    /** Now all the basic initialization is done, but we have yet to load any
    *   FBX files or even create the GUI.
    *   /warning if Init does not return true, the 'Close()' method will
    *   not be called.
    */
    virtual bool     Open()   ;

    /** This callback is used when the scene is cleared. This may be from a new
    *   file being loaded (not appended to the current one), a File->New or the
    *   application being shutdown.
    */
    virtual bool     Clear()  ;

    /** The application is shutting down. Time to cleanup anything that references
    *   system resources.
    */
    virtual bool     Close()  ;

};


#ifdef FBSDKUseNamespace
	}
#endif

#endif
