
//**************************************************************************/
// Copyright (c) 2008 Autodesk, Inc.
// All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk license
// agreement provided at the time of installation or download, or which
// otherwise accompanies this software in either electronic or hard copy form.
//
//**************************************************************************/
// DESCRIPTION:
// CREATED: October 2008
//**************************************************************************/

namespace mudbox {

/// This class is the base of all node types that can be structured in a hierarchy.
class MBDLL_DECL TreeNode : virtual public Node
{
public:
	DECLARE_CLASS;

	TreeNode( void );
	~TreeNode( void );
	virtual void Serialize( Stream &s );

	/// Adds a node/subtree to the list of children. The added node will be removed from the current parent if it has one.
	virtual void AddChild( TreeNode *pChild, bool bFirst = false ) const;
	/// Removes a node/subtree from the list of children.
	virtual void RemoveChild( TreeNode *pChild ) const;
	/// Returns the first node from the child list
	virtual TreeNode *FirstChild( void ) const;
	/// Returns the parent node
	virtual TreeNode *Parent( void ) const;
	/// Returns the next linked node with the same parent
	virtual TreeNode *NextSibling( void ) const;
	/// Returns the previous linked node with the same parent
	virtual TreeNode *PrevSibling( void ) const;

	/// Returns the first child with the specified type. When the bAutoCreate parameter is true and such a child does not exists, it creates it with the preferred descedant type.
	virtual TreeNode *ChildByClass( const ClassDesc *pClass, bool bAutoCreate = true ) const;
	/// Same as above, a most confortable version.
	template < typename type >
	inline type *ChildByClass( bool bAutoCreate = true ) const { return dynamic_cast<type *>( ChildByClass( type::StaticClass(), bAutoCreate ) ); };
	/// Returns the first child with the specified type, or returns zero if no child found.
	virtual TreeNode *ChildByClass( const ClassDesc *pClass, unsigned int iIndex = 0 ) const;
	/// Same as above, a most confortable version.
	template < typename type >
	inline type *ChildByClass( unsigned int iIndex = 0 ) const { return dynamic_cast<type *>( ChildByClass( type::StaticClass(), iIndex ) ); };
	/// Deletes all child which is derived from a specific class.
	virtual void DeleteChildByClass( const ClassDesc *pClass );

	/// Returns descriptive information about the node
	virtual QString Info( void ) const;
	/// Returns if the node is visible. Should be overridden in derived classes.
	virtual bool Visible( void ) const;
	/// Sets the node visibility Should be overridden in derived classes.
	virtual void SetVisible( bool b );
	/// Returns if the node is locked. Should be overridden in derived classes.
	virtual bool Locked( void ) const;
	/// Sets the locking of the node. Should be overridden in derived classes.
	virtual void SetLocked( bool b );

	/// This function is called then the node is linked to a new parent.
	virtual void OnLinked( const TreeNode *pOldParent );

private:
	mutable aptr<TreeNode> m_pNext;
	mutable aptr<TreeNode> m_pPrev;
	mutable aptr<TreeNode> m_pParent;
	mutable aptr<TreeNode> m_pChildren;
	abool m_bVisible, m_bLocked;
};

}; // end of namespace mudbox
