/*****************************************************************************
 *
 *  Copyright (C) 2003 Cédric Brégardis <cedric.bregardis@free.fr>
 *
 *  This file is part of BRIQUOLO
 *
 *  BRIQUOLO 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.
 *
 *  BRIQUOLO 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 BRIQUOLO; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *****************************************************************************/
#include "TableauEditeur.h"
#include "Gestionnaire.h"
#include <sstream>
#include "I18n.h"

TableauEditeur::TableauEditeur(MOGL_Fenetre * p_Fenetre)
  : TableauBase(p_Fenetre), _PasX(5), _PasY(5), _ElementCourant(NULL), _Ajout(true), _SaisieLigne(false),
    _NbBriqueSup(0)
{
  _Curseur=new Curseur(this);
  _Univers->AjouterElement(_Curseur);

  _Camera=new MOGL_Camera();
  _Camera->SetFov(45);
  _Camera->SetHaut(0,0,1);
  _Camera->SetPosition(20,-13, 40);
  _Camera->SetDirection(0,1,-0.8f);
  _Camera->SetClipping(0.2f,2000);

  _Univers->SetCamera(_Camera);

  _PanneauLigneOptionEditeur = new PanneauLigneOptionEditeur(_Fenetre);
  _PanneauLigneOptionEditeur->SetActivation(true);

  _PanneauOutilsEditeur=new PanneauOutilsEditeur(_Fenetre);
  _PanneauOutilsEditeur->SetActivation(true);
  _PanneauOutilsEditeur->_ChoixAction->ChangementElement.Connecter(this, &TableauEditeur::_ChangementAction);
}

TableauEditeur::~TableauEditeur()
{
  delete _Curseur;
  delete _Camera;
  delete _PanneauOutilsEditeur;
}

void TableauEditeur::Activer(bool p_Activation)
{
  if (p_Activation!=_Activation)
  {
    if (p_Activation)
    {
      _Fenetre->AjouterInterface(_PanneauOutilsEditeur);
      _Fenetre->AjouterInterface(_PanneauLigneOptionEditeur);
    }
    else
    {
      _Fenetre->RetirerInterface(_PanneauOutilsEditeur);
      _Fenetre->RetirerInterface(_PanneauLigneOptionEditeur);
    }
  }
  TableauBase::Activer(p_Activation);
}

void TableauEditeur::ClavierUp(SDL_keysym * key)
{
  if (!_Pause)
  {

    if (!_SaisieLigne)
    {
      if (key->sym == SDLK_F11)
      {
        _PanneauLigneOptionEditeur->SetEditMode(true);
        _PanneauOutilsEditeur->SetPause(true);
        _SaisieLigne = true;
      }

      if (_Ajout)
      {
        switch (key->sym)
        {
          case SDLK_i :
          {
            float x=_Curseur->GetPositionX();
            float y=_Curseur->GetPositionY() + _PanneauOutilsEditeur->GetVariationY();
            if (y>_YMax)
            {
              y=_Curseur->GetPositionY();
            }
            _Curseur->SetPosition(x, y);
            break;
          }
          case SDLK_k :
          {
            float x=_Curseur->GetPositionX();
            float y=_Curseur->GetPositionY() - _PanneauOutilsEditeur->GetVariationY();
            if (y<_YMin)
            {
              y=_Curseur->GetPositionY();
            }
            _Curseur->SetPosition(x, y);
            break;
          }
          case SDLK_j :
          {
            float x=_Curseur->GetPositionX() - _PanneauOutilsEditeur->GetVariationX();
            float y=_Curseur->GetPositionY();
            if (x<_XMin)
            {
              x=_Curseur->GetPositionX();
            }
            _Curseur->SetPosition(x, y);
            break;
          }
          case SDLK_l :
          {
            float x=_Curseur->GetPositionX() + _PanneauOutilsEditeur->GetVariationX();
            float y=_Curseur->GetPositionY();
            if (x>_XMax)
            {
              x=_Curseur->GetPositionX();
            }
            _Curseur->SetPosition(x, y);
            break;
          }
          case SDLK_SPACE :
          {
            ElementTableau * elem=Gestionnaire::GetElementTableau(_PanneauOutilsEditeur->GetIdentifiantElement(), this);
            elem->SetPosition(_Curseur->GetPositionX(), _Curseur->GetPositionY());
            elem->SetLigneOption(_PanneauLigneOptionEditeur->_LabelLigne->GetLabel());
            elem->InitialiserPosition();
            AjouterElementTableau(elem);
            break;
          }
          default:
            break;
        }
        _PanneauOutilsEditeur->_LabelSup->SetCacher(true);
      }
      else
      {
        // Edition
        ElementTableau * elemTemp=NULL;
        switch (key->sym)
        {
          case SDLK_i :
          {            
            float y=_YMax+1;
            float x=_Curseur->GetPositionX();
            float dist=sqrt((_YMax-_YMin)*(_YMax-_YMin) + (_XMax-_XMin)*(_XMax-_XMin)) +1 ;
            for(Set_ElementTableau::iterator it=_SetElementTableau.begin(); it!=_SetElementTableau.end(); it++)
            {
              float dist2=sqrt((_Curseur->GetPositionY()-(*it)->GetPositionY()) * (_Curseur->GetPositionY()-(*it)->GetPositionY()) +
                               (_Curseur->GetPositionX()-(*it)->GetPositionX()) * (_Curseur->GetPositionX()-(*it)->GetPositionX()));
              if ((*it)->GetPositionY()>_Curseur->GetPositionY() && dist2<=dist)
              {
                _NbBriqueSup = 1;
                _CurrentSup = 0;
                _ListSup.clear();
                _ListSup.push_back(*it);
                y=(*it)->GetPositionY();
                x=(*it)->GetPositionX();
                elemTemp=*it;
                dist=dist2;
              }
              else
              {
                if ((*it)->GetPositionX()==x && (*it)->GetPositionY()==y)
                {
                  _NbBriqueSup++;
                  _ListSup.push_back(*it);
                }
              }
            }
            break;
          }
          case SDLK_k :
          {            
            float y=_YMin-1;
            float x=_Curseur->GetPositionX();
            float dist=sqrt((_YMax-_YMin)*(_YMax-_YMin) + (_XMax-_XMin)*(_XMax-_XMin)) +1 ;

            for(Set_ElementTableau::iterator it=_SetElementTableau.begin(); it!=_SetElementTableau.end(); it++)
            {
              float dist2=sqrt((_Curseur->GetPositionY()-(*it)->GetPositionY()) * (_Curseur->GetPositionY()-(*it)->GetPositionY()) +
                               (_Curseur->GetPositionX()-(*it)->GetPositionX()) * (_Curseur->GetPositionX()-(*it)->GetPositionX()));
              if ((*it)->GetPositionY()<_Curseur->GetPositionY() && dist2<dist)
              {
                _NbBriqueSup = 1;
                _CurrentSup = 0;
                _ListSup.clear();
                _ListSup.push_back(*it);
                y=(*it)->GetPositionY();
                x=(*it)->GetPositionX();
                elemTemp=*it;
                dist=dist2;
              }
              else
              {
                if ((*it)->GetPositionX()==x && (*it)->GetPositionY()==y)
                {
                  _NbBriqueSup++;
                  _ListSup.push_back(*it);
                }
              }
            }
            break;
          }
          case SDLK_j :
          {            
            float x=_XMin-1;
            float y=_Curseur->GetPositionY();
            float dist=sqrt((_YMax-_YMin)*(_YMax-_YMin) + (_XMax-_XMin)*(_XMax-_XMin)) +1 ;
            for(Set_ElementTableau::iterator it=_SetElementTableau.begin(); it!=_SetElementTableau.end(); it++)
            {
              float dist2=sqrt((_Curseur->GetPositionY()-(*it)->GetPositionY()) * (_Curseur->GetPositionY()-(*it)->GetPositionY()) +
                               (_Curseur->GetPositionX()-(*it)->GetPositionX()) * (_Curseur->GetPositionX()-(*it)->GetPositionX()));
              if ((*it)->GetPositionX()<_Curseur->GetPositionX() && dist2<dist)
              {
                _NbBriqueSup = 1;
                _CurrentSup = 0;
                _ListSup.clear();
                _ListSup.push_back(*it);
                y=(*it)->GetPositionY();
                x=(*it)->GetPositionX();
                elemTemp=*it;
                dist=dist2;
              }
              else
              {
                if ((*it)->GetPositionX()==x && (*it)->GetPositionY()==y)
                {
                  _NbBriqueSup++;
                  _ListSup.push_back(*it);
                }
              }
            }
            break;
          }
          case SDLK_l :
          {            
            float x=_XMax+1;
            float y=_Curseur->GetPositionY();
            float dist=sqrt((_YMax-_YMin)*(_YMax-_YMin) + (_XMax-_XMin)*(_XMax-_XMin)) +1 ;
            for(Set_ElementTableau::iterator it=_SetElementTableau.begin(); it!=_SetElementTableau.end(); it++)
            {
              float dist2=sqrt((_Curseur->GetPositionY()-(*it)->GetPositionY()) * (_Curseur->GetPositionY()-(*it)->GetPositionY()) +
                               (_Curseur->GetPositionX()-(*it)->GetPositionX()) * (_Curseur->GetPositionX()-(*it)->GetPositionX()));
              if ((*it)->GetPositionX()>_Curseur->GetPositionX() && dist2<dist)
              {
                _NbBriqueSup = 1;
                _CurrentSup = 0;
                _ListSup.clear();
                _ListSup.push_back(*it);
                y=(*it)->GetPositionY();
                x=(*it)->GetPositionX();
                elemTemp=*it;
                dist=dist2;
              }
              else
              {
                if ((*it)->GetPositionX()==x && (*it)->GetPositionY()==y)
                {
                  _NbBriqueSup++;
                  _ListSup.push_back(*it);
                }
              }
            }
            break;
          }
          case SDLK_KP_PLUS:
          {
            if (_NbBriqueSup > 1)
            {
              if (_CurrentSup<_NbBriqueSup-1)
              {
                _CurrentSup++;
              }
              else
              {
                _CurrentSup = 0;
              }
              elemTemp = _ListSup[_CurrentSup];
            }
            break;
          }
          case SDLK_KP_MINUS:
          {
            if (_NbBriqueSup > 1)
            {
              if (_CurrentSup>0)
              {
                _CurrentSup--;
              }
              else
              {
                _CurrentSup = _NbBriqueSup-1;
              }
              elemTemp = _ListSup[_CurrentSup];
            }
            break;
          }
          case SDLK_SPACE :
          {
            if (_ElementCourant!=NULL)
            {
              RetirerElementTableau(_ElementCourant);
              if (_NbBriqueSup > 1)
              {
                for(T_Vector_ElemTableau::iterator it = _ListSup.begin(); it != _ListSup.end(); it++)
                {
                  if (*it == _ElementCourant)
                  {
                    _ListSup.erase(it);
                    _NbBriqueSup--;
                    break;
                  }
                }
                delete _ElementCourant;
                _CurrentSup = 0;
                _ElementCourant = _ListSup[0];
              }
              else
              {
                delete _ElementCourant;
                _ElementCourant=NULL;
              }
              _PanneauLigneOptionEditeur->SetLigneOption("");
            }
            break;
          }
          default:
            break;
        }

        // On a un nouvel élément ?
        if (elemTemp!=NULL)
        {
          if (_ElementCourant!=NULL)
          {
            _ElementCourant->SetSelectionner(false);
          }
          elemTemp->SetSelectionner(true);
          _ElementCourant=elemTemp;
          _PanneauLigneOptionEditeur->SetLigneOption(_ElementCourant->GetLigneOption());
          _Curseur->SetPosition(_ElementCourant->GetPositionX(), _ElementCourant->GetPositionY());
        }
        if (_NbBriqueSup > 1)
        {
          _PanneauOutilsEditeur->_LabelSup->SetCacher(false);
          stringstream st;
          st<<STACKED_BRICK<<_CurrentSup<<"/"<<_NbBriqueSup;
          _PanneauOutilsEditeur->_LabelSup->SetLabel(st.str());
        }
        else
        {
          _PanneauOutilsEditeur->_LabelSup->SetCacher(true);
        }
      }
    }
    else
    {
      if (key->sym == SDLK_F11)
      {
        _PanneauLigneOptionEditeur->ValiderLigne();
        if (_ElementCourant != NULL)
        {
          _ElementCourant->SetLigneOption(_PanneauLigneOptionEditeur->_LabelLigne->GetLabel());
          _ElementCourant->InitialiserPosition();
        }
        _PanneauLigneOptionEditeur->SetEditMode(false);
        _PanneauOutilsEditeur->SetPause(false);
        _SaisieLigne = false;
      }
    }
  }
}

void TableauEditeur::_ChangementAction(unsigned int p_Action)
{
  switch(p_Action)
  {
    case 0:
    {
      if (_ElementCourant!=NULL)
      {
        _ElementCourant->SetSelectionner(false);
      }
      _ElementCourant=NULL;
      _PanneauLigneOptionEditeur->SetLigneOption("");
      _Ajout=true;
      _PanneauOutilsEditeur->_LabelSup->SetCacher(true);
      break;
    }
    case 1:
    {
      if (_SetElementTableau.size()>0)
      {
        Set_ElementTableau::iterator it=_SetElementTableau.begin();
        _NbBriqueSup = 1;
        _CurrentSup = 0;
        _ListSup.clear();
        _ListSup.push_back(*it);
        float x = (*it)->GetPositionX();
        float y = (*it)->GetPositionY();
        for(it++; it!=_SetElementTableau.end(); it++)
        {
          if ((*it)->GetPositionX()==x && (*it)->GetPositionY()==y)
          {
            _NbBriqueSup++;
            _ListSup.push_back(*it);
          }
        }
        if (_NbBriqueSup > 1)
        {
          _PanneauOutilsEditeur->_LabelSup->SetCacher(false);
          stringstream st;
          st<<STACKED_BRICK<<_CurrentSup<<"/"<<_NbBriqueSup;
          _PanneauOutilsEditeur->_LabelSup->SetLabel(st.str());
        }

        _ElementCourant=*(_SetElementTableau.begin());
        _PanneauLigneOptionEditeur->SetLigneOption(_ElementCourant->GetLigneOption());
        _Curseur->SetPosition(_ElementCourant->GetPositionX(), _ElementCourant->GetPositionY());
        _ElementCourant->SetSelectionner(true);
      }
      else
      {
        _ElementCourant=NULL;
        _PanneauLigneOptionEditeur->SetLigneOption("");
      }
      _Ajout=false;
      break;
    }
  }
}

void TableauEditeur::SetPause(bool p_Pause)
{
  TableauBase::SetPause(p_Pause);
  _PanneauLigneOptionEditeur->SetPause(p_Pause);
  if (p_Pause)
  {
    _PanneauOutilsEditeur->SetPause(true);
  }
  else
  {
    if (_SaisieLigne)
    {
      _PanneauOutilsEditeur->SetPause(true);
    }
    else
    {
      _PanneauOutilsEditeur->SetPause(false);
    }

  }
}

bool TableauEditeur::Charger(const char * p_NomFichier)
{
  bool ret = TableauBase::Charger(p_NomFichier);
  _ElementCourant = NULL;
  return ret;
}
