#ifndef TreeMerger_hpp
#define TreeMerger_hpp

#include "TreeElements.hpp"

namespace apoc { namespace legacy {

class TreeMerger : public ITreeHandler 
{
    public :
        TreeMerger(Tree *aTree = NULL) : mTree(aTree) {}
        virtual ~TreeMerger(void) {}

        void merge(const IUpdateLayer& aUpdate) ;
        void finalise(void) ;
        Tree *getTree(void) const { return mTree ; }

        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) ;
    protected :
    private :
        Tree *mTree ;
        typedef std::vector<Node *> ContextStack ;
        ContextStack mStack ;
        bool mFinalised ;

        void getMergeContext(StructuralNode *& aParentNode, 
                             const std::string& aName, 
                             Node *& aInitialNode) const ;
        void modifyGenericNode(const std::string& aName, int aAttributes,
                               PropertyType aType = UnknownProperty) ;
        void replaceGenericNode(const std::string& aName, int aAttributes,
                                PropertyType aType = UnknownProperty) ;
} ;

} } // apoc.legacy

#endif // TreeMerger_hpp

