#ifndef __DISPLAYTREENODE_H
#define __DISPLAYTREENODE_H

/*@@@**************************************************************************
 ** \file  displayTreeNode
 * \date   Mon Apr 13 14:16:43 GMT 2009
 * \author Hernan Badino
 * \notes  
*******************************************************************************
******************************************************************************/

/* INCLUDES */
#include "operator.h"
#include "drawingList.h"

#include <vector>

/* CONSTANTS */


namespace VIC
{
    class CDisplayTreeNodeAbstract
    {
    /// Data types
    public:
        
        typedef enum
        {
            NT_OPERATOR,
            NT_DISPLAY
        } ENodeType_t;
        

    /// Consructor/Destructor.
    public:

        /// Constructor.
        CDisplayTreeNodeAbstract ( CDisplayTreeNodeAbstract * f_parent_p = NULL ) 
                : m_parent_p ( f_parent_p  ) {};
        
        /// Destructor. 
       virtual ~CDisplayTreeNodeAbstract() {}

        /// Get node type
        virtual ENodeType_t                 getNodeType () const = 0;
        
        /// Get children count.
        virtual unsigned int                getChildCount () const 
        { 
            return 0; 
        }

        /// Get name.
        virtual std::string                 getName() const = 0;

        /// Get parent.
        virtual CDisplayTreeNodeAbstract *  getParent()
        {
            return m_parent_p;
            
        }

        /// Get child.
        virtual CDisplayTreeNodeAbstract *  getChild ( 
                unsigned int /* f_number_ui */ ) const
        { 
            return NULL;
        }

        int getIndexInParent ( ) const
        {
            if (m_parent_p)
            {
                for (unsigned int i = 0; 
                     i < m_parent_p -> getChildCount(); 
                     ++i)
                {
                    if ( getName() == 
                         m_parent_p -> getChild ( i ) -> getName( ) )
                        return i;
                }
            }
            
            return -1;    
        }

    protected:

        /// Parent node.
        CDisplayTreeNodeAbstract *  m_parent_p;       
    };
    
    class CDisplayNode: public CDisplayTreeNodeAbstract
    {
        friend class CDisplayOpNode;
        
    public:
        /// Constructor.
        CDisplayNode ( CDrawingList *              f_drawingList_p,
                       CDisplayTreeNodeAbstract *  f_parent_p = NULL )
                : CDisplayTreeNodeAbstract (      f_parent_p  ),
                  m_drawingList_p (           f_drawingList_p ) {};
        
        /// Destructor. 
        virtual ~CDisplayNode() 
        {
            if (m_drawingList_p) 
                delete m_drawingList_p;
        }
        
        /// Get node type
        virtual ENodeType_t getNodeType () const
        { 
            return CDisplayTreeNodeAbstract::NT_DISPLAY; 
        };

        std::string getName() const 
        {
            if ( m_drawingList_p )
                return m_drawingList_p -> getName();
            return "";
        }
        
        S2D<int> getPosition() const 
        {
            if ( m_drawingList_p )
                return m_drawingList_p -> getPosition();

            return S2D<int>();
        }

        bool isVisible() const 
        {
            if ( m_drawingList_p )
                return m_drawingList_p -> isVisible();

            return false;
        }

        int getElementsCount( ) const 
        {
            if ( m_drawingList_p )
                return m_drawingList_p -> getElementsCount();
            return -1;
        }

        void setVisibility( bool f_val_b ) const 
        {
            if ( m_drawingList_p )
                return m_drawingList_p -> setVisibility(f_val_b);
        }

        CDrawingList * getDrawingList() const 
        {
            return m_drawingList_p;
        }

    protected:        
        CDrawingList * m_drawingList_p;        
    };
    
    class CDisplayOpNode: public CDisplayTreeNodeAbstract
    {        
    /// Constructor/Destructor
    public:
        
        CDisplayOpNode ( COperator *                 f_op_p,
                         CDisplayTreeNodeAbstract *  f_parent_p = NULL );

        virtual ~CDisplayOpNode ( );

    /// Some methods.
    public:
        void              appendChild( CDisplayOpNode *   f_child_p );
        void              appendChild( CDisplayNode   *   f_child_p );

        /// Get node type
        virtual ENodeType_t getNodeType() const
        { 
            return CDisplayTreeNodeAbstract::NT_OPERATOR; 
        };

        unsigned int      getChildCount () const 
        { 
            return ( m_opChildren.size() + 
                     m_displayChildren.size() );    
        }

        /// Generic getChild.
        virtual CDisplayTreeNodeAbstract *  
                          getChild ( unsigned int f_number_ui ) const; 

        /// Specific getChild.
        CDisplayOpNode *  getOpChild      ( const COperator * const f_op_p) const;

        /// Specific getChild.
        CDisplayOpNode *  getOpChild      (  const unsigned int f_number_ui ) const;

        /// Specific number of displays.
        unsigned int      getOpCount ( ) const
        {
            return m_opChildren.size();
        }

        /// Specific getChild.
        CDisplayNode   *  getDisplayChild ( const std::string & f_name_str ) const;

        /// Specific getChild.
        CDisplayNode   *  getDisplayChild ( const unsigned int f_number_ui ) const;

        /// Specific number of displays.
        unsigned int      getDisplayCount ( ) const
        {
            return m_displayChildren.size();
        }

        /// Get index of this node in the parent.
        int               getIndexInParent ( ) const;

        std::string       getName() const { return ( m_operator_p -> getName() ); }
        
        COperator *       getOperator() const { return  m_operator_p; }
        
    protected:
        /// Children.
        std::vector<CDisplayOpNode *>     m_opChildren;

        /// Children.
        std::vector<CDisplayNode *>       m_displayChildren;
        
        /// Data.
        COperator *                       m_operator_p;
    };
}


#endif // __DISPLAYTREENODE_H

/* ////////////  Version History ///////////////
 *  $Log: displayTreeNode.h,v $
 *  Revision 1.2  2009/11/18 15:51:01  badino
 *  badino: documentation added. Some other global changes.
 *
 *//////////////////////////////////////////////
