#include <stdio.h>
#include "pintup3d.h"

 
/* --Methode-- */
PINTuple3D::PINTuple3D(NTuple* nt, bool ad)
: PIDrawer3D()
{
  mNT = nt;
  mAdDO = ad; 
  SelectXYZ(NULL, NULL, NULL);
  SelectErrBar();
}

PINTuple3D::~PINTuple3D()
{
  if (mAdDO && mNT)  delete mNT;
}

/* --Methode-- */
void  PINTuple3D::SelectXYZ(const char* px, const char* py, const char* pz)
{
if (mNT == NULL)  xK = yK = zK = -1;
if (px == NULL) xK = -1;
else xK = mNT->IndexNom(px);
if (py == NULL) yK = -1;
else yK = mNT->IndexNom(py);
if (pz == NULL) zK = -1;
else zK = mNT->IndexNom(pz);
}

/* --Methode-- */
void  PINTuple3D::SelectErrBar(const char* erbx, const char* erby, const char* erbz)
{
if (mNT == NULL)  xebK = yebK = zebK = -1;
if (erbx == NULL) xebK = -1;
else xebK = mNT->IndexNom(erbx);
if (erby == NULL) yebK = -1;
else yebK = mNT->IndexNom(erby);
if (erbz == NULL) zebK = -1;
else zebK = mNT->IndexNom(erbz);
}


/* --Methode-- */
void PINTuple3D::UpdateLimits()
{
  if (!mNT) return;
  if (mNT->NEntry() <= 0)  return;
  if ( (xK < 0) || (yK < 0)  || (zK < 0) )   return;

  // Commencer par trouver nos limites
  float xmin, xmax, ymin, ymax, zmin, zmax;
  xmin = ymin = 9.e19;
  xmax = ymax = -9.e19;
  zmax = zmax = -9.e19;
  mNT->GetMinMax(xK, xmin, xmax);
  mNT->GetMinMax(yK, ymin, ymax);
  mNT->GetMinMax(zK, zmin, zmax);

// Centre du champ en C = (xmin+xmax)/2., (ymin+ymax)/2  (zmin+zmax)*0.5
// Distance D = Max(xmax-xmin,ymin-ymax)*2
// Observateur en O = X+D, Yc+2*D 
  double D = xmax-xmin;
  if (D < (ymax-ymin))  D = ymax-ymin;
  D *= 1.4;
  
  Set3DView((xmin+xmax)/2., (ymin+ymax)/2, (zmin+zmax)/2., 
            (xmin+xmax)/2.+D , (ymin+ymax)/2.-2.5*D , zmin+(zmax-zmin)*0.85, 0.25, 0.25);  

  x3Min = xmin;  // - 0.05*(xmax-xmin);
  x3Max = xmax;  // + 0.05*(xmax-xmin);
  y3Min = ymin;  // - 0.05*(ymax-ymin);
  y3Max = ymax;  // + 0.05*(ymax-ymin);
  z3Min = zmin;  // - 0.05*(zmax-zmin);
  z3Max = zmax;  // + 0.05*(zmax-zmin);

//  printf("PINTuple3D::UpdateLimits() : %g-%g  %g-%g  %g-%g (%g) \n", xmin,xmax,ymin,ymax,zmin,zmax,D);
//  printf("PINTuple3D::UpdateLimits() :  %g %g %g << %g %g %g \n", 
//         (xmin+xmax)/2., (ymin+ymax)/2, (zmin+zmax)*0.5, 
//         (xmin+xmax)/2.+D , (ymin+ymax)/2.+2.*D , zmin+(zmax-zmin)*0.1);
}


/* --Methode-- */
void PINTuple3D::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
{
double xp,yp,zp,xer,yer,zer;
int nok;

// On trace les axes - En attendant de faire mieux - Reza 8/12/98
if (axesFlags != kAxesNone)  DrawAxes(g);

if (!mNT) return;
if ( (xK < 0) || (yK < 0) || (zK < 0) )  return;

#if defined(__DECCXX) || defined(__KCC__)
PIGraphic3D* g3 = dynamic_cast<PIGraphic3D*>(g);
#else
PIGraphic3D* g3 = (PIGraphic3D*)(g);
#endif

if (mLAtt == PI_NotDefLineAtt)  g3->SelLine(PI_ThinLine);

nok = 0;  
for (int i=0; i<mNT->NEntry(); i++) {
  xp = mNT->GetVal(i, xK);
  yp = mNT->GetVal(i, yK);
  zp = mNT->GetVal(i, zK);
  nok++;
  g3->DrawMarker3D(xp, yp, zp); 
  if ( xebK >= 0 ) {
    xer = mNT->GetVal(i, xebK);
    g3->DrawLine3D(xp-xer, yp, zp, xp+xer, yp, zp);
  }
  if ( yebK >= 0 ) {
    yer = mNT->GetVal(i, yebK);
    g3->DrawLine3D(xp, yp-yer, zp, xp, yp+yer, zp);
  }
  if ( zebK >= 0 ) {
    zer = mNT->GetVal(i, zebK);
    g3->DrawLine3D(xp, yp, zp-zer, xp, yp, zp+zer);
  }
}

return;
}

