/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/

#pragma once

#include "glmAbstractGraphicalNode.h"

#include "glmStickyNotes.h"

namespace glm
{
    /**
	* \brief AbstractGraphicalContainerNode comments
	*/
    class GLM_CORE_API AbstractGraphicalContainerNode
    {
    public:
		GLM_ABSTRACTCLASS_STAT_ID(glm::MemoryStatIds::Editors)
        typedef SmartPointer<AbstractGraphicalContainerNode> SP;

        /**
		* \brief destructor
		*/
        virtual ~AbstractGraphicalContainerNode();

        /**
		* \brief Add a child behavior
		* \param childNode The child behavior to add
		* \return True if child behavior was correctly added
		*/
        virtual void addChildNode(AbstractGraphicalNode* childNode);

        /**
		* \brief Remove a child behavior
		* \param childNode The child behavior to remove
		* \return True if child behavior was correctly removed
		*/
        virtual bool removeChildNode(AbstractGraphicalNode* childNode);

        /**
		* \brief Check if a given child behavior has been added to current behavior container
		* \param childNode The child behavior to check
		* \return True if the given child behavior belongs to current behavior container
		*/
        bool hasChildNode(const AbstractGraphicalNode* childNode) const;

        /**
		* \brief Get the child behavior id in the current behavior container
		* \param childNode The child behavior to check
		* \return The id of the given child behavior, -1 if not in this behavior container
		*/
        int getChildNodeId(const AbstractGraphicalNode* childNode) const;

        /**
		* \brief Get all the children behaviors belonging to current behavior container
		* \return The children behaviors belonging to current behavior container
		*/
        const glm::Array<AbstractGraphicalNode::SP>& getChildrenNodes() const;
		glm::Array< AbstractGraphicalNode::SP >& touchChildrenNodes();

        /**
		* \brief Update the idle status of every children
		*/
        virtual void updateAvoidedChildren();

        virtual bool checkChildrenConnections();

        bool isChildNodeInFlow(const AbstractGraphicalNode* childNode) const;

        bool isBrowsable() const;
        virtual bool isChildCollapsed() const;

        void addAStickyNotes(StickyNotes* stickyNotes);
        bool removeAStickyNotes(StickyNotes* stickyNotes);
        bool hasAStickyNotes(StickyNotes* stickyNotes);
        const glm::Array<StickyNotes::SP>& getStickyNotesPool() const;

        /**
		* \brief Compute the map of predecessors of all the nodes in the container
		*/
        void computePredecessorsMap(glm::GlmMap<AbstractGraphicalNode*, AbstractGraphicalNode*>& predecessorsMap) const;
        void computePredecessorsListMap(glm::GlmMap<AbstractGraphicalNode*, glm::PODArray<AbstractGraphicalNode*>>& predecessorsMap) const;

    protected:
        /**
		* \brief default constructor
		*/
        AbstractGraphicalContainerNode();

    private:
        GLM_DISALLOW_COPY_AND_ASSIGN(AbstractGraphicalContainerNode);

    protected:
        /// Children node contained within current node
        glm::Array<AbstractGraphicalNode::SP> _childrenNodes;

        bool _browsable;

        glm::Array<StickyNotes::SP> _stickyNotesPool;

    public:
        bool _isExpanded;
    };

    //-------------------------------------------------------------------------
    // getChildrenNodes
    //-------------------------------------------------------------------------
    inline const glm::Array<AbstractGraphicalNode::SP>&
    AbstractGraphicalContainerNode::getChildrenNodes() const
    {
        return _childrenNodes;
    }

	//-------------------------------------------------------------------------
	// touchChildrenNodes
	//-------------------------------------------------------------------------
	inline glm::Array< AbstractGraphicalNode::SP >&
		AbstractGraphicalContainerNode::touchChildrenNodes()
	{
		return _childrenNodes;
	}

    //-------------------------------------------------------------------------
    // getChildrenNodes
    //-------------------------------------------------------------------------
    inline const glm::Array<StickyNotes::SP>&
    AbstractGraphicalContainerNode::getStickyNotesPool() const
    {
        return _stickyNotesPool;
    }

    //-------------------------------------------------------------------------
    // isBrowsable
    //-------------------------------------------------------------------------
    inline bool
    AbstractGraphicalContainerNode::isBrowsable() const
    {
        return _browsable;
    }
} // namespace glm
