// This may look like C code, but it is really -*- C++ -*-
// classe pour tracer des flow chart (champs de vecteurs) 2d
// NB herite de PIDrawer 
// O. Perdereau 01/2002
// 
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#include "sopnamsp.h"
#include "machdefs.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <math.h>

#include "histos.h"
#include "ntuple.h"

#include "nbtri.h" 

#include "pi2dvec.h"

#include <sys/time.h>
#include <sys/resource.h>

//++
// Class	PI2dVecDrawer
// Lib		PIGcont
// include	pigncont.h2dvec.h
// 
// 
// Classe de trace d'un champ de vecteurs (flow chart) en 2 dimensions
//
//
//--
//++ 
// Links        Parents
// PIDrawer
//--
//
//++
// Titre	Constructeurs et Méthodes 
//--

//++
// PI2dVecDrawer::PI2dVecDrawer(NTupleInterface* nti,bool autodel)
//  Constructeur 
// 
//--
PI2dVecDrawer::PI2dVecDrawer(NTupleInterface* nti,bool autodel)
{
  _nti = nti;
  
  _autodel = autodel;
  SelectXY(NULL, NULL);
  SelectVW(NULL, NULL);

  // This drawer has *NO* specific control tools 
  mFgSpecContWind = false;

}


/* --Methode-- */
PI2dVecDrawer::~PI2dVecDrawer()
{
  
  if(_autodel){ //cout << " destructeur de PI2dVecDrawer / autodel "<<endl;
    if(_nti!=NULL){delete _nti ; _nti=NULL;}
  }

}

/* --Methode-- */
void PI2dVecDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax){

  if(_nti==NULL){cout << " PI2dVecDrawer::Draw : null ntuple "<<endl; return;}
  if ( (xK < 0) || (yK < 0) ){cout << " PI2dVecDrawer::Draw : no X/Y "<<endl;  return;}
  if ( (vK < 0) || (wK < 0) ){cout << " PI2dVecDrawer::Draw : no VX/VY "<<endl;  return;}

  int npt = _nti->NbLines();
  int i=0;
  double x,y,vx,vy;
  double xa[2];
  double ya[2];
  g->SaveGraphicAtt();

  // choix de la couleur   
  g->SelForeground(GetGraphicAtt().GetFgColor());

  // choix de la ligne 
  PILineAtt mlatt = GetGraphicAtt().GetLineAtt() ;
  if(mlatt==PI_NotDefLineAtt) GetGraphicAtt().SetLineAtt(PI_NormalLine);

  g->SelLine(GetGraphicAtt().GetLineAtt() );

  // choix du marker 
  if(GetGraphicAtt().GetMarker()==PI_NotDefMarker)
    GetGraphicAtt().SetMarkerAtt(5,PI_FCircleMarker);
  g->SelMarker(GetGraphicAtt().GetMarkerSize(),GetGraphicAtt().GetMarker());

  // choix de la fleche 
  
  if(GetGraphicAtt().GetArrowMarker()==PI_NotDefArrowMarker)
    GetGraphicAtt().SetArrowMarkerAtt(5,PI_BasicArrowMarker);

  

   g->SelArrowMarker(GetGraphicAtt().GetArrowMarkerSize(),GetGraphicAtt().GetArrowMarker());
 


  for(i=0 ; i<npt ; i++){
    x = _nti->GetCell(i,xK) ;
    y = _nti->GetCell(i,yK) ;
    vx = _nti->GetCell(i,vK) + x;
    vy = _nti->GetCell(i,wK) + y;
    g->DrawMarker(x,y);
    
    //g->DrawLine(x,y,vx,vy);
    
    g->DrawArrowMarker(x,y,vx,vy);

  }

  g->RestoreGraphicAtt();

}
/* --Methode-- */
void PI2dVecDrawer::UpdateLimits()
{
  // Doit calculer les limites

  double xmn,xmx,ymn,ymx;
  double vmn,vmx;

  _nti->GetMinMax(0,xmn,xmx);
  _nti->GetMinMax(1,ymn,ymx);
  
  SetLimits(xmn, xmx, ymn, ymx);
}

/* --Methode-- */
int   PI2dVecDrawer::SelectXY(const char* px, const char* py)
{
  string name;
  if (_nti == NULL)  xK = yK = -1;
  if (px == NULL) xK = -1;
  else { name = px; xK = _nti->ColumnIndex(name); }
  if (py == NULL) yK = -1;
  else { name = py; yK = _nti->ColumnIndex(name); }
  
  int ret = xK;
  if( ret > yK) ret = yK;
  return(ret);
}

/* --Methode-- */
int  PI2dVecDrawer::SelectVW(const char* px, const char* py)
{
  string name;
  if (_nti == NULL)  vK = vK = -1;
  if (px == NULL) vK = -1;
  else { name = px; vK = _nti->ColumnIndex(name); }
  if (py == NULL) wK = -1;
  else { name = py; wK = _nti->ColumnIndex(name); }
  
  int ret = vK;
  if( ret > wK) ret = wK;
  return(ret);
}



/* --Methode-- */
double PI2dVecDrawer::GetDistanceToPoint(double x, double y)
{
 if(_nti==NULL) return 1.e+9;
 if( xK<0 || yK<0 ) return 1.e+9;
 if( vK<0 || wK<0 ) return 1.e+9;

 double dist = -1.e+18;
 for(int i=0; i<_nti->NbLines(); i++) {
   double xp=_nti->GetCell(i,xK);
   double yp=_nti->GetCell(i,yK);
   xp = (xp-x)/(XMax()-XMin())/0.5;
   yp = (yp-y)/(YMax()-YMin())/0.5;
   xp = xp*xp+yp*yp;
   if(dist<0. || xp<dist) dist = xp;
 }
 dist=sqrt(fabs(dist));
 cout<<dist<<"PI2dVecDrawer: xlim="<<XMin()<<","<<XMax()<<" ylim="<<YMin()<<","<<YMax()
     <<" NbLines="<<_nti->NbLines()<<endl;
 cout<<"....d="<<dist<<" x="<<x<<" y="<<y<<endl;
 cout<<"****** NON teste (CMV) ******"<<endl;

 return dist;
}
