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

#include "BriqueBumper.h"
#include "ExplosionBrique.h"

#include <MOGL_GestionnaireObjet.h>
#include <MOGL_Temps.h>
#include <iostream>
#include "BibliothequeSon.h"
#include "Constante.h"

#ifndef M_PI
#define M_PI 3.14159265359
#endif

#define SIGN(a) (((a)<0)?-1:1)

MOGL_Objet * BriqueBumper::_ObjetSource=NULL;

BriqueBumper::BriqueBumper(TableauBase * p_TableauBase): ElementTableau(p_TableauBase), _Z(0), 
                                                         _VitesseZ(9), _Right(false), _Rotation(0)
{
  _Z=2*M_PI*(rand()/(RAND_MAX+0.0))-1;
  if (_ObjetSource==NULL)
  {
    PreCharger();
  }
   _ElementArbre=new MOGL_Objet(*_ObjetSource);
  _Decors=true;
}

BriqueBumper::BriqueBumper(const BriqueBumper & p_BriqueBumper): ElementTableau(p_BriqueBumper), _VitesseZ(9),
                                                                 _Right(p_BriqueBumper._Right)
{
  _Z=2*M_PI*(rand()/(RAND_MAX+0.0))-1;
  _ElementArbre=new MOGL_Objet(*_ObjetSource);
}

BriqueBumper::~BriqueBumper()
{
  delete _ElementArbre;
}

void BriqueBumper::PreCharger()
{
  _ObjetSource=new MOGL_Objet;
  MOGL_GestionnaireObjet::ChargerObjetASCTriangle((Constante::GetGlobalDir()+Constante::GetDataDir()+"/flip.tri").c_str(),
                                                  *Texture::GetGestionnaireTexture(), *_ObjetSource);
}

Generateur * BriqueBumper::CreerGenerateurParticules()
{
  return NULL;
}


void BriqueBumper::Maj()
{
  _Z+=MOGL_Temps::GetVariationDistance(_VitesseZ);
  if (_Z>=2*M_PI)
  {
    _Z-=static_cast<float>(2*M_PI);
  }

  MOGL_MatriceTransformation mat;
  _ElementArbre->ReinitialiserPosition();
  if (_Right)
  {
    mat(0,0) = -1;
    mat(2,2) = -1;
    _ElementArbre->AjouteTransformation(mat);
  }

  mat = MOGL_MatriceTransformation::FabriqueRotation(0,0,_Rotation);
  _ElementArbre->AjouteTransformation(mat);
  _ElementArbre->AjouterTranslation(_X,_Y,sin(_Z)/4);
}

void BriqueBumper::InitialiserPosition()
{
  _ElementArbre->ReinitialiserPosition();
  MOGL_MatriceTransformation mat;
  if (_Right)
  {
    mat(0,0) = -1;
    mat(2,2) = -1;
    _ElementArbre->AjouteTransformation(mat);
  }

  mat = MOGL_MatriceTransformation::FabriqueRotation(0,0,_Rotation);
  _ElementArbre->AjouteTransformation(mat);
  _ElementArbre->AjouterTranslation(_X,_Y,0);
}


void BriqueBumper::SetPosition(double p_X, double p_Y)
{
  _X=p_X;
  _Y=p_Y;
  if (_ElementArbre!=NULL)
  {
    _ElementArbre->ReinitialiserPosition();
    _ElementArbre->AjouterTranslation(_X,_Y,sin(_Z)/4);
  }
}

Struct_Collision BriqueBumper::TesterCollision(Balle * p_Balle)
{
  Struct_Collision collision;
  collision.TempsCollision = p_Balle->GetTempsMax();
  collision.VitesseX=p_Balle->GetVitesseTotaleX();
  collision.VitesseY=p_Balle->GetVitesseTotaleY();
  float invRight = 1;
  if (_Right)
  {
    invRight = -1;
  }

  _Bumper = true;
  Struct_Collision col, colNew;
  float roti = -_Rotation*3.14159/180;

  col = _SegmentCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(),
                          p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(),
                          _X, _Y, roti,
                          invRight * 6.83, 1.56, invRight * 1.83, 8.56,
                          0, 0, 0, 0, p_Balle->GetTempsMax());
  col.AddFacteurCollision = 1.5;

  colNew = _SegmentCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(),
                             p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(),
                             _X, _Y, roti,
                             0, 8, 0, 3,
                             0, 0, 0, 0, p_Balle->GetTempsMax());
  if (colNew.TempsCollision < col.TempsCollision)
  {
    _Bumper = false;
    col = colNew;
  }

  colNew = _SegmentCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(),
                             p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(),
                             _X, _Y, roti,
                             invRight * 0.62, 2.08, invRight * 6, 0,
                             0, 0, 0, 0, p_Balle->GetTempsMax());
  if (colNew.TempsCollision < col.TempsCollision)
  {
    _Bumper = false;
    col = colNew;
  }

  colNew = _CircleCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(),
                            p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(),
                            _X, _Y, roti,
                            invRight * 1, 3, 1, 0, 0, 0, p_Balle->GetTempsMax());
  if (colNew.TempsCollision < col.TempsCollision)
  {
    _Bumper = false;
    col = colNew;
  }

  colNew = _CircleCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(),
                            p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(),
                            _X, _Y, roti,
                            invRight * 6, 1, 1, 0, 0, 0, p_Balle->GetTempsMax());
  if (colNew.TempsCollision < col.TempsCollision)
  {
    _Bumper = false;
    col = colNew;
  }

  colNew = _CircleCollision(p_Balle->GetPositionX(), p_Balle->GetPositionY(),p_Balle->GetRayon(),
                            p_Balle->GetVitesseTotaleX(), p_Balle->GetVitesseTotaleY(),
                            _X, _Y, roti,
                            invRight * 1, 8, 1, 0, 0, 0, p_Balle->GetTempsMax());
  if (colNew.TempsCollision < col.TempsCollision)
  {
    _Bumper = false;
    col = colNew;
  }

  return col;
}


bool BriqueBumper::Toucher(Balle * p_Balle, double p_Temps)
{
  if (_Bumper)
  {
    BibliothequeSon::SonBumper->Jouer(false);
  }
  else
  {
    BibliothequeSon::SonRebond->Jouer(false);
  }
  return false;
}

void BriqueBumper::_AnalyserLigne()
{
  ElementCollision::_AnalyserLigne();
  It_Map_Params it;
  it = _Params.find("position");
  if (it != _Params.end())
  {
    if (it->second == "right")
    {
      _Right = true;
    }
  }

  it = _Params.find("ri");
  if (it != _Params.end())
  {
    stringstream st(it->second);
    st>>_Rotation;
  }
  else
  {
    _Rotation = 0;
  }

}
