#ifndef TreeDiff_hpp
#define TreeDiff_hpp

#include "TreeElements.hpp"
#include "NodePath.hpp"
#include "INodeListener.hpp"

#include <string>
#include <vector>
#include <set>



namespace apoc { namespace legacy {
    
    enum ActionType {
	NoAction = 0x0,
	NodeAdded = 0x1,
	NodeRemoved = 0x2,
	NodeChanged = 0x4
    } ;

    class Listeners
    {
    public:
	Listeners(const NodePath& aNodePath);
	const NodePath& getNodePath() { return mNodePath; }
	void addListener(INodeListener *aListener);
	void removeListener(INodeListener *aListener);
	bool Listeners::hasListeners() const { return !mListeners.empty(); }
	const std::vector<INodeListener *>& getListeners() const 
	{ return mListeners; }
    private:
	NodePath mNodePath;
	std::vector<INodeListener *> mListeners;
    };

    class DiffListener {
    public:
	DiffListener(const std::string& aComponent):mComponent(aComponent) {} ;

	void addListener(const NodePath& aPath,
			 INodeListener *aListener) ;

	bool removeListener(const NodePath& aPath,
			    INodeListener *aListener) ;
	
	void callAddedListeners(const NodePath& aPath) const ;
	void callRemovedListeners(const NodePath& aPath) const ;
	void callChangedListeners(const NodePath& aPath) const ;

    private:
	std::string mComponent;
	std::map<std::string, Listeners *> mListeners ;
	
	void callListeners(const NodePath& aPath, ActionType aType ) const ;

    };




    class TreeDiff: public ITreeHandler, public NodeVisitor
    {
    public:
	TreeDiff(const std::string& aComponent, 
		 const DiffListener* aDiffListener, 
		 Tree *aTree = NULL) ;
	virtual ~TreeDiff() ;

        virtual void startTree(void) ;
        virtual void endTree(void) ;
        virtual void modifyNode(const std::string& aName, int aAttributes) ;
        virtual void replaceNode(const std::string& aName, int aAttributes) ;
        virtual void removeNode(const std::string& aName) ;
        virtual void endNode(void) ;
        virtual void modifyProperty(const std::string& aName,
                                    PropertyType aType,
                                    int aAttributes) ;
        virtual void replaceProperty(const std::string& aName,
                                     PropertyType aType,
                                     int aAttributes) ;
        virtual void endProperty(void)  ;
        virtual void setStringValue(const std::string& aValue, 
                                    const std::string& aLocale = kDefaultLocale) ;
        virtual void setListValue(const std::vector<std::string>& aValue,
                                  const std::string& aLocale = kDefaultLocale) ;
        virtual void addListValues(const std::vector<std::string>& aValues,
                                   const std::string& aLocale = kDefaultLocale) ;


	virtual bool preChildrenProcess(Node& aNode) ;
	virtual bool postChildrenProcess(Node& aNode) ;
	
    protected: 
    private:
	bool mFindingBaseNode;
	const std::string mComponent;
	const DiffListener *mDiffListener;
	Tree *mTree;
	bool mInTree;
	std::vector<std::string> mPathComponents;
	std::vector<ActionType> mActions;

    } ;
    


} } ; // apoc.legacy

#endif // TreeDiff_hpp

