///////////////////////////////////////////////////////////////////////////
//                                                                       //
// NOTICE OF COPYRIGHT                                                   //
//                                                                       //
// Copyright (C) 2012    Andrés Mateus Vargas  <amvargash@gmail.com>     //            
//                                                                       //
// 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:                          //
//                                                                       //
//          http://www.gnu.org/copyleft/gpl.html                         //
//                                                                       //
///////////////////////////////////////////////////////////////////////////

//Ejecutar con $root -l Choque.C

#include <TGClient.h>
#include <RQ_OBJECT.h>
#include <TMath.h>
#include <TVector.h>
#include <TGFrame.h>
#include <TGButton.h>
#include <TGLabel.h>
#include <TGNumberEntry.h>
#include <TLine.h>
#include <TArrow.h>
#include <TCanvas.h>
#include <TGaxis.h>

class WChoque : TGMainFrame {
  private:
  TRootEmbeddedCanvas *fECanvas;
  TGNumberEntry *NEX1, *NEV1, *NEX2, *NEV2, *NEM1, *NEM2;
  float m1,m2; //masas
  float v1i,v2i; //rapideces iniciales
  float v1f,v2f;
  float v1,v2;
  float x1,x2; //posiciones
  float t,dt; //tiempo
  bool state;
  TEllipse *Cuerpo1,*Cuerpo2;
  TCanvas *Lienzo;
  TTimer *Animador;
  TGTextButton *TBPlay;
  void ReDraw();
  public:
  WChoque();
  ~WChoque();
  void TBPlayClicked();
};

WChoque::WChoque() {
  
  TGMainFrame *fWChoque;
  TGHorizontalFrame *HFrame;
  TGVerticalFrame *VFrame;
  TGGroupFrame *GFR1, *GFR2;
  TGLabel *LEX1, *LEX2, *LEY1, *LEY2, *LPhiR1, *LPhiR2;

  LayoutA = new TGLayoutHints(kLHintsCenterX,2,2,2,2);
  LayoutB = new TGLayoutHints(kLHintsCenterX|kLHintsCenterY,5,5,5,5);
  fWChoque = new TGMainFrame(gClient->GetRoot());
  fWChoque->SetWindowName("Choque Frontal Totalmente El\341stico");
  fWChoque->SetCleanup(kDeepCleanup);

  HFrame = new TGHorizontalFrame(fWChoque);
  VFrame = new TGVerticalFrame(HFrame);

  fECanvas = new TRootEmbeddedCanvas("ECanvas",HFrame,350,350);
  fECanvas->GetCanvas()->Range(-10,-10,10,10);

  /******EJEMPLO*****/
  Cuerpo1 = new TEllipse();
  Cuerpo2 = new TEllipse();
  Animador = new TTimer(20);
  Animador->Connect("Timeout()","WChoque",this,"ReDraw()");

  fECanvas->GetCanvas()->SetEditable(kFALSE);
  /*****FIN EJEMPLO****/

  GFR1 = new TGGroupFrame(VFrame,"Cuerpo #1");
  LEX1 = new TGLabel(GFR1,"X1 : ");
  NEX1 = new TGNumberEntry(GFR1);
  NEX1->SetNumStyle(TGNumberFormat::kNESRealTwo);
  NEX1->SetNumber(-10.0);
  LEY1 = new TGLabel(GFR1,"V1 : ");
  NEV1 = new TGNumberEntry(GFR1);
  NEV1->SetNumStyle(TGNumberFormat::kNESRealTwo);
  NEV1->SetNumber(2.5);
  LPhiR1 = new TGLabel(GFR1,"M1 : ");
  NEM1 = new TGNumberEntry(GFR1);
  NEM1->SetNumStyle(TGNumberFormat::kNESRealTwo);
  NEM1->SetNumAttr(TGNumberFormat::kNEAPositive);
  NEM1->SetNumber(1.0);
  GFR1->AddFrame(LEX1);
  GFR1->AddFrame(NEX1);
  GFR1->AddFrame(LEY1);
  GFR1->AddFrame(NEV1);
  GFR1->AddFrame(LPhiR1);
  GFR1->AddFrame(NEM1);

  GFR2 = new TGGroupFrame(VFrame,"Cuerpo #2");
  LEX2 = new TGLabel(GFR2,"X2 : ");
  NEX2 = new TGNumberEntry(GFR2);
  NEX2->SetNumStyle(TGNumberFormat::kNESRealTwo);
  NEX2->SetNumber(10);
  LEY2 = new TGLabel(GFR2,"V2 : ");
  NEV2 = new TGNumberEntry(GFR2);
  NEV2->SetNumStyle(TGNumberFormat::kNESRealTwo);
  NEV2->SetNumber(-5.0);
  LPhiR2 = new TGLabel(GFR2,"M2 : ");
  NEM2 = new TGNumberEntry(GFR2);
  NEM2->SetNumStyle(TGNumberFormat::kNESRealTwo);
  NEM2->SetNumAttr(TGNumberFormat::kNEAPositive);
  NEM2->SetNumber(1.5);
  GFR2->AddFrame(LEX2);
  GFR2->AddFrame(NEX2);
  GFR2->AddFrame(LEY2);
  GFR2->AddFrame(NEV2);
  GFR2->AddFrame(LPhiR2);
  GFR2->AddFrame(NEM2);

  TBPlay = new TGTextButton(VFrame,"Simular");
  TBPlay->Connect("Clicked()","WChoque",this,"TBPlayClicked()");

  VFrame->AddFrame(GFR1,LayoutA);
  VFrame->AddFrame(GFR2,LayoutA);
  VFrame->AddFrame(TBPlay,LayoutA);

  HFrame->AddFrame(fECanvas,LayoutA);
  HFrame->AddFrame(VFrame,LayoutB);
  
  fWChoque->AddFrame(HFrame,LayoutB);
  fWChoque->Resize(fWChoque->GetDefaultSize());
  fWChoque->MapSubwindows();
  fWChoque->MapWindow();
  state = 0;

}

void WChoque::ReDraw(){

  fECanvas->GetCanvas()->SetEditable(kTRUE);

  if ((x1+Cuerpo1->GetR1())>(x2-Cuerpo2->GetR1())){
    v1 = v1f;
    v2 = v2f;
  }

  t = t + dt;
  x1 = x1 + v1*t;
  Cuerpo1->SetX1(x1);
  Cuerpo1->Draw();

  x2 = x2 + v2*t;
  Cuerpo2->SetX1(x2);
  Cuerpo2->Draw();
  
  gPad->Update();
  
  fECanvas->GetCanvas()->SetEditable(kFALSE);
}

void WChoque::TBPlayClicked(){

  if (state==0){
    t = 0.0;
    dt = 1e-3;
    
    m1 = NEM1->GetNumber();
    m2 = NEM2->GetNumber();
    
    v1i = NEV1->GetNumber();
    v2i = NEV2->GetNumber();
    
    v1f = (v1i*(m1-m2)+2*m2*v2i)/(m1+m2);
    v2f =(v2i*(m2-m1)+2*m1*v1i)/(m1+m2);
    
    v1 = v1i;
    v2 = v2i;
    
    //x1 siempre tiene que estar antes para que se
    //cumpla el condicional
    x1 = NEX1->GetNumber();
    x2 = NEX2->GetNumber();
    
    Cuerpo1->SetFillColor(2);
    Cuerpo1->SetR1(m1);
    Cuerpo1->SetR2(Cuerpo1->GetR1());
    Cuerpo1->SetX1(x1);
    Cuerpo1->SetY1(0.0);
    Cuerpo1->Draw();

    Cuerpo2->SetFillColor(4);
    Cuerpo2->SetR1(m2);
    Cuerpo2->SetR2(Cuerpo2->GetR1());
    Cuerpo2->SetX1(x2);
    Cuerpo2->SetY1(0.0);
    Cuerpo2->Draw();
    
    state = 1;
    TBPlay->SetText("Parar");
    Animador->TurnOn();
  }
  else if (state==1){
    Animador->TurnOff();
    TBPlay->SetText("Simular");
    state = 0;
  }

 
}

void Choque() {
  App = new WChoque();
}
