/***************************************************************************
 *   Copyright (C) 2005 by Thierry CHARLES   *
 *   thierry@les-charles.net   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef _NAVIGATOR_PANEL_ELEMENT_H_
#define _NAVIGATOR_PANEL_ELEMENT_H_

#include <set>
#include <wx/event.h>
#include <wx/treectrl.h>
#include "lib/commons.h"
#include "components/stdgui/tgenbutton.h"
#include "components/stdgui/tgenbuttonlistener.h"
#include "components/framework/tpanelelement.h"
#include "components/framework/tapplicationpanel.h"
#include "components/framework/elementinfo.h"
#include "xpe_components/parser/parserres.h"

#define PELT_TYPE_NAVIGATOR "PELT_TYPE_NAVIGATOR"

class PovFileParserRes;
class PovPanelElement;
class PovFileInfo;
class NavigatorSelectionListener;
class NavigatorItemData;

/**
 * @short Un element de panneau d'application affichant le contenu du document en cours d'edition
 * @author Thierry CHARLES <thierry@les-charles.net>
 * @version 0.1
 */
class NavigatorPanelElement : public TPanelElement, protected TApplicationPanelListener, protected TGenButtonListener, protected FileParserResListener, public wxEvtHandler
{
    TRANSLATABLE;
    public:
        NavigatorPanelElement(TApplicationPanel * _owner, int iID = -1);
        virtual ~NavigatorPanelElement();

        /** renvoie l'instance du navigateur si celle-ci existe */
        static NavigatorPanelElement * getInstance() { return instance; }

        /** renvoie une constante identifiant le type de cet element de maniere a pouvoir le reconstruire lors du chargement des preferences */
        virtual const char * getElementType() const { return PELT_TYPE_NAVIGATOR; }

        /** indique si le composant doit etre sauvegarde */
        virtual bool mightBeSaved() const { return true; }

        static TPanelElementInfo getElementInfo() { return TPanelElementInfo(PELT_TYPE_NAVIGATOR,wxSTr("Navigator"), getDefaultIcon(), 0, 1); }

        /** renvoie l'icone associee au composant */
        static const TBitmap * getDefaultIcon();

        /** ajout un listener de selection */
        void addSelectionListener(NavigatorSelectionListener * l);
        /** supprime un listener de selection */
        void removeSelectionListener(NavigatorSelectionListener * l);
        /** propage un changement de selection */
        void fireSelectionChanged(NavigatorItemData * data);

    protected:
        /** construit le panneau conteneur et son contenu (appellee automatiquement par getContentPanel et detruit automatiquement par le destructeur) */
        virtual TPanel * buildContentPanel();

        /** indique qu'un element va etre supprime d'un paneau */
        virtual void removingElement(TApplicationPanel * panel, TPanelElement * elt);
        /** indique qu'un element est ajoute a un panneau */
        virtual void addingElement(TApplicationPanel * panel, TPanelElement * elt);
        /** indique que les donnees d'un element ont change */
        virtual void elementDataChanged(TApplicationPanel * panel, const TPanelElement * elt);
        /** indique qu'un element devient visible / cache */
        virtual void elementVisibilityChanged(TApplicationPanel * panel, TPanelElement * elt, bool bVisible);

        virtual void buttonToggled(TGenButton * btn);

        /** signale des modifications sur un fichier */
        virtual void fileInfoUpdated(FileParserRes * parser, FileInfo * file);

        /** efface et reactualise completement l'affichage */
        void reinitDisplay();

        /**
         * actualise completement l'affichage (apres qu'il ait ete efface)
         * @see reinitDisplay()
         */
        void initDisplayFor(const PovPanelElement * elt);
        /**
         * rempli un noeud de l'arbre avec le contenu d'un objet d'informations
         */
        void fillTreeNodeWith(wxTreeItemId node, PovFileInfo * info, bool bIsInclude = false);

        /** retourne l'instance de parserRes adaptee au fichier en cours d'edition */
        FileParserRes * getParserRes(const TPanelElement * elt = NULL);

        /** efface le contenu de l'arbre et toutes les donnees associees */
        void clear();


        void onTreeLeftClick(wxTreeEvent & event);
        void onTreeDblClick(wxTreeEvent & event);
        void onTreeRightClick(wxTreeEvent & event);

    private:
        wxTreeCtrl * contents;
        TGenButton * btnLocal;
        TGenButton * btnDeclare;
        TGenButton * btnMacro;
        TGenButton * btnBookmarks;
        TGenButton * btnIncludes;

        bool bUpdateRunning;

        PovFileParserRes * resPov;

        const TPanelElement * currentElt;

        typedef std::set<NavigatorSelectionListener *> TListenerList;
        TListenerList listeners;

        static NavigatorPanelElement * instance;
};

/**
 * classe representant les donnees contenues dans l'arbre du navigateur
 * @short donnees d'un noeud
 */
class NavigatorItemData : public wxTreeItemData
{
    public:
        NavigatorItemData(const wxString & _sName, const wxString & _sSearchString, const wxString & _sHelp) : sName(_sName), sSearchString(_sSearchString), sHelp(_sHelp) {}

        /** renvoie le nom de l'element */
        const wxString & getName() const { return this->sName; }
        /** renvoie la chaine de recherche associee au noeud */
        const wxString & getSearchString() const { return this->sSearchString; }
        /** renvoie l'aide associee au noeud */
        const wxString & getHelp() const { return this->sHelp; }
    private:
        wxString sName;
        wxString sSearchString;
        wxString sHelp;
};

/** template d'ecouteur de modifications de selection */
class NavigatorSelectionListener
{
    public:
        virtual ~NavigatorSelectionListener() {}
        virtual void selectionChanged(NavigatorPanelElement * navigator, NavigatorItemData * selectedItem) = 0;
};

#endif // _NAVIGATOR_PANEL_ELEMENT_H_
