/***************************************************************************
 *   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.             *
 ***************************************************************************/

#include "tapplwindow.h"

#include <wx/window.h>

#include "tapplicationpanel.h"

TApplicationWindow::~TApplicationWindow()
{
    this->destroyWindowContent();
}

/** supprime tout le contenu de la fenetre */
void TApplicationWindow::destroyWindowContent()
{
    TPanelsMap::iterator it = this->panelsMap.begin();
    while(it != this->panelsMap.end())
    {
        delete (*it).second;
        it++;
    }

    this->panelsMap.erase(this->panelsMap.begin(), this->panelsMap.end());
}


/** retrouve un panel a partir de son ID */
TApplicationPanel * TApplicationWindow::getPanel(int iPanelId) const
{
    TPanelsMap::const_iterator it = this->panelsMap.find(iPanelId);
    if(it == this->panelsMap.end())
        return NULL;

    return (*it).second;
}

/**
 * enregistre un panneau dans la fenetre
 * @returns false si un panneau avec le meme ID existe déjà
 */
bool TApplicationWindow::registerPanel(TApplicationPanel * panel)
{
    if(this->getPanel(panel->getID()))
        return false;
    this->panelsMap[panel->getID()] = panel;
    return true;
}

/** supprime une référence à un panneau */
bool TApplicationWindow::unregisterPanel(int iPanelId)
{
    TPanelsMap::iterator it = this->panelsMap.find(iPanelId);
    if(it == this->panelsMap.end())
        return false;

    this->panelsMap.erase(it);
    return true;
}

/** charge les panneaux d'une fenetre a partir des informations stockés sous forme XML */
bool TApplicationWindow::loadPanels(TiXmlElement * panelsNode)
{
    TiXmlElement * elt = panelsNode->FirstChildElement(XMLCC_NODE_PANEL);
    while(elt)
    {
        int iId = 0;
        if(elt->QueryIntAttribute( XMLCC_ATTR_PANEL_ID , & iId ) != TIXML_SUCCESS )
            return false;

        TApplicationPanel * panel = this->getPanel(iId);
        if(panel)
        {
            TiXmlElement * params = elt->FirstChildElement(XMLCC_NODE_PANEL_PARAMS);
            if(params)
            {
                if(!panel->loadParameters(params))
                    return false;
            }

            TiXmlElement * elements = elt->FirstChildElement(XMLCC_NODE_PANEL_ELTS);
            if(elements)
            {
                if(!panel->loadElements( elements ))
                    return false;
            }
        }

        elt = elt->NextSiblingElement(XMLCC_NODE_PANEL);
    }
    return true;
}

/** sauvegarde les panneaux d'une fenetre en XML */
TiXmlElement * TApplicationWindow::getPanelsNode()
{
    if(!this->panelsMap.size())
        return NULL;

    TiXmlElement * root = new TiXmlElement(XMLCC_NODE_WINDOW_PANELS);
    TiXmlElement * elt = NULL;

    TPanelsMap::iterator itB = this->panelsMap.begin();
    TPanelsMap::iterator itE = this->panelsMap.end();
    while(itB != itE)
    {
        if((*itB).second->mightBeSaved())
        {
            elt = new TiXmlElement(XMLCC_NODE_PANEL);

            elt->SetAttribute( XMLCC_ATTR_PANEL_ID , (*itB).second->getID() );

            TiXmlElement * params = (*itB).second->getParameters();
            if(params)
                elt->LinkEndChild( params );

            TiXmlElement * elements = (*itB).second->getElementsNode();
            if(elements)
                elt->LinkEndChild( elements );

            root->LinkEndChild( elt );
            elt = NULL;
        }

        itB++;
    }

    return root;
}

#define XML_PARAM_NODE_POSITION "Position"
#define XML_PARAM_ATTR_POS_Y "y"
#define XML_PARAM_ATTR_POS_X "x"
#define XML_PARAM_NODE_SIZE "Size"
#define XML_PARAM_ATTR_SIZE_H "height"
#define XML_PARAM_ATTR_SIZE_W "width"

/** charge les parametres du composant a partir des informations contenues dans le noeud passé en paramètre */
bool TApplicationWindow::loadParameters(TiXmlElement * parametersNode)
{
    TiXmlElement * elt = parametersNode->FirstChildElement(XML_PARAM_NODE_POSITION);
    if(elt)
    {
        wxPoint pos = dynamic_cast<wxWindow *>(this)->GetPosition();
        elt->QueryIntAttribute( XML_PARAM_ATTR_POS_Y , & pos.y );
        elt->QueryIntAttribute( XML_PARAM_ATTR_POS_X , & pos.x );
        dynamic_cast<wxWindow *>(this)->Move(pos);
    }

    elt = parametersNode->FirstChildElement(XML_PARAM_NODE_SIZE);
    if(elt)
    {
        wxSize size = dynamic_cast<wxWindow *>(this)->GetSize();
        int i;
        if(elt->QueryIntAttribute( XML_PARAM_ATTR_SIZE_H , &i ) == TIXML_SUCCESS )
            size.SetHeight(i);
        if(elt->QueryIntAttribute( XML_PARAM_ATTR_SIZE_W , &i ) == TIXML_SUCCESS )
            size.SetWidth(i);
        dynamic_cast<wxWindow *>(this)->SetSize(size);
    }

    dynamic_cast<wxWindow *>(this)->Refresh();

    return true;
}

/** renvoie les parametres du composant sous la forme d'un noeud xml */
TiXmlElement * TApplicationWindow::getParameters()
{
    TiXmlElement * root = new TiXmlElement(XMLCC_NODE_WINDOW_PARAMS);

    TiXmlElement * elt = new TiXmlElement(XML_PARAM_NODE_POSITION);
    wxPoint pos = dynamic_cast<wxWindow *>(this)->GetPosition();
    elt->SetAttribute( XML_PARAM_ATTR_POS_Y , pos.y );
    elt->SetAttribute( XML_PARAM_ATTR_POS_X , pos.x );
    root->LinkEndChild( elt );

    elt = new TiXmlElement(XML_PARAM_NODE_SIZE);
    wxSize size = dynamic_cast<wxWindow *>(this)->GetSize();
    elt->SetAttribute( XML_PARAM_ATTR_SIZE_H , size.GetHeight() );
    elt->SetAttribute( XML_PARAM_ATTR_SIZE_W , size.GetWidth() );
    root->LinkEndChild( elt );

    bool bIsVisible = dynamic_cast<wxWindow *>(this)->IsShown();
    dynamic_cast<wxWindow *>(this)->Show(true);
    dynamic_cast<wxWindow *>(this)->Refresh();
    dynamic_cast<wxWindow *>(this)->Show(bIsVisible);

    return root;

}

/** reconstruit les splitters avec les panneaux */
void TApplicationWindow::updatePanels()
{
}

