/***************************************************************************
 *   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 _TMAINWINDOW_H_
#define _TMAINWINDOW_H_

#include <map>

#include "lib/commons.h"
#include "components/stdgui/tframe.h"
#include "components/stdgui/tframe.h"
#include "components/stdgui/tsplitter.h"

#include "components/framework/tapplication.h"
#include "components/framework/tapplwindow.h"
#include "components/framework/threadhandler.h"

#define CENTER_PANEL_ID -1
#define TOP_PANEL_ID -2
#define LEFT_PANEL_ID -3
#define RIGHT_PANEL_ID -4
#define BOTTOM_PANEL_ID -5


class TApplicationPanel;
class TApplication;

class TMainWindow : public TFrame , public TApplicationWindow
{
    protected:
        struct TApplicationPanelMeta
        {
            TApplicationPanelMeta(TApplicationPanel * _panel = NULL) : bVisible(false), panel(_panel) {}
            ~TApplicationPanelMeta();
            bool bVisible;
            TApplicationPanel * panel;

            /** détruit le panneau contenu */
            void destroyContent(TApplicationWindow * owner);
        };
        typedef std::map<int,TApplicationPanelMeta *> TApplicationPanelMap;


    public:
        TMainWindow(wxWindow* parent, int iWindowId, const wxString & sTitle, long style = wxDEFAULT_FRAME_STYLE, const wxString & sName = wxT(""));
        virtual ~TMainWindow();

        /** demande la fermeture de la fenetre */
        virtual bool tryToClose() = 0;

        /** reconstruit les splitters avec les panneaux */
        virtual void updatePanels();

        // PANNEAUX
        /** defini le panneau du haut */
        virtual void setTopPanel(TApplicationPanel * panel, bool bDeleteOld = true);
        /** renvoie un pointeur sur le panneau du haut (NULL si pas de panneau) */
        virtual TApplicationPanel * getTopPanel() const { return this->topPanel.panel; }
        /** defini le panneau de droite */

        virtual void setRightPanel(TApplicationPanel * panel, bool bDeleteOld = true);
        /** renvoie un pointeur sur le panneau du haut (NULL si pas de panneau) */
        virtual TApplicationPanel * getRightPanel() { return this->rightPanel.panel; }

        /** defini le panneau du bas */
        virtual void setBottomPanel(TApplicationPanel * panel, bool bDeleteOld = true);
        /** renvoie un pointeur sur le panneau du haut (NULL si pas de panneau) */
        virtual TApplicationPanel * getBottomPanel() { return this->bottomPanel.panel; }

        /** defini le panneau gauche */
        virtual void setLeftPanel(TApplicationPanel * panel, bool bDeleteOld = true);
        /** renvoie un pointeur sur le panneau du haut (NULL si pas de panneau) */
        virtual TApplicationPanel * getLeftPanel() { return this->leftPanel.panel; }

        /** defini le panneau central */
        virtual void setCenterPanel(TApplicationPanel * panel, bool bDeleteOld = true);
        /** renvoie un pointeur sur le panneau du haut (NULL si pas de panneau) */
        virtual TApplicationPanel * getCenterPanel() { return this->centerPanel.panel; }


        void onCloseWindow(wxCloseEvent & evt);

        /** ajoute un handler sur un thread qui doit etre gere lors de l'arret de l'appli */
        void addManageableThread(ThreadHandler * t);
        /** supprime un handler sur un thread qui ne doit plus etre gere lors de l'arret de l'appli */
        void removeManageableThread(ThreadHandler * t);

        /** charge les panneaux d'une fenetre a partir des informations stockes sous forme XML */
        virtual bool loadPanels(TiXmlElement * panelsNode);

        /** charge les parametres du composant a partir des informations contenues dans le noeud passe en parametre */
        virtual bool loadParameters(TiXmlElement * parametersNode);
        /** renvoie les parametres du composant sous la forme d'un noeud xml */
        virtual TiXmlElement * getParameters();

        /** supprime tout le contenu de la fenetre. Devrait être appelé avant le destructeur, tant que toute la structure de l'application est encore accessible */
        virtual void destroyWindowContent();

    protected:
        /** finalise l'initialisation de la fenetre */
        void endInit() { this->bInitialized = true; this->updatePanels(); }
        friend TMainWindow * TApplication::getMainWindow();

    private:
        void build();

        TApplicationPanelMeta   centerPanel;
        TApplicationPanelMeta   topPanel;
        TApplicationPanelMeta   leftPanel;
        TApplicationPanelMeta   rightPanel;
        TApplicationPanelMeta   bottomPanel;
        TApplicationPanelMap    floatingPanels;

        TSplitter *             topSplitter;
        TSplitter *             leftSplitter;
        TSplitter *             rightSplitter;
        TSplitter *             bottomSplitter;

        bool                    bInitialized;

        TThreadHandlersList     threadHandlers;

        std::map<TSplitter *,int> splittersPosMap;
};

#endif
