// Copyright (C) 1999-2015
// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
// For conditions of distribution and use, see copyright notice in "copyright"

#include "basepanda.h"
#include "fitsimage.h"

BasePanda::BasePanda(const BasePanda& a)
{
  numAngles_ = a.numAngles_;
  angles_ = new double[numAngles_];
  for (int ii=0; ii<numAngles_; ii++)
    angles_[ii] = a.angles_[ii];
}

BasePanda::BasePanda(double a1, double a2, int an)
{
  angles_ = NULL;
  setAngles(a1,a2,an);
}

BasePanda::BasePanda(int an, double* a)
{
  angles_ = NULL;
  setAngles(an,a);
}

BasePanda::~BasePanda()
{
  if (angles_)
    delete [] angles_;
}

void BasePanda::sortAngles()
{
  // first, all angles 0<=ang<2_PI
  for (int ii=0; ii<numAngles_; ii++)
    angles_[ii] = zeroTWOPI(angles_[ii]);

  // now, all angs incr in size
  for (int ii=1; ii<numAngles_; ii++) {
    if (angles_[ii] < angles_[ii-1])
      angles_[ii] += M_TWOPI;
  }

  // last sanity check
  if (numAngles_>1 && angles_[0]==0 && angles_[numAngles_-1]==0)
    angles_[numAngles_-1] += M_TWOPI;
}

void BasePanda::setAngles(double a1, double a2, int an)
{
  numAngles_ = an+1;
  if (angles_)
    delete [] angles_;
  angles_ = new double[numAngles_];

  // yes this is really needed
  // for a2<a1
  if (tle(a2,a1,FLT_EPSILON)) {
    a1 = zeroTWOPI(a1);
    a2 = zeroTWOPI(a2);
    if (tle(a2,a1,FLT_EPSILON))
      a2 += M_TWOPI;    
  }

  // for a1=a2 
  if (teq(a2,a1,FLT_EPSILON)) {
    a1 = zeroTWOPI(a1);
    a2 = zeroTWOPI(a2);
    if (a2<=a1)
      a2 += M_TWOPI;    
  }

  // for a2>a1 very small
  if (teq(a2,a1,FLT_EPSILON)) {
    a1 = zeroTWOPI(a1);
    a2 = zeroTWOPI(a2);
    if (teq(a2,a1,FLT_EPSILON))
      a2 += M_TWOPI;    
  }

  for (int ii=0; ii<numAngles_; ii++)
    angles_[ii] = ii*(a2-a1)/an+a1;

  sortAngles();
}

void BasePanda::setAngles(int an, const double* a)
{
  numAngles_ = an;
  if (angles_)
    delete [] angles_;
  angles_ = new double[numAngles_];

  for (int ii=0; ii<numAngles_; ii++)
    angles_[ii] = a[ii];

  sortAngles();
}

void BasePanda::addAngle(double aa)
{
  // we need to insert into the next to the last location
  // new size array
  double* old = angles_;
  angles_ = new double[numAngles_+1];

  // copy old values
  for (int ii=0; ii<numAngles_; ii++)
    angles_[ii] = old[ii];

  // save last
  angles_[numAngles_] = old[numAngles_-1];

  // delete old
  if (old)
    delete [] old;

  // new size on next to last
  angles_[numAngles_-1] = aa;

  numAngles_++;
}

void BasePanda::deleteAngle(int hh)
{
  // new angles array
  double* old = angles_;
  angles_ = new double[numAngles_-1];

  // copy up to angles in question
  for (int ii=0; ii<hh; ii++)
    angles_[ii] = old[ii];

  // copy remainder
  for (int ii=hh; ii<numAngles_-1; ii++)
    angles_[ii] = old[ii+1];

  if (old)
    delete [] old;
  numAngles_--;
}

int BasePanda::isIn(Vector& vv, int nn)
{
  double aa = -vv.angle();
  while (aa<angles_[0])
    aa += M_TWOPI;

  return aa>=angles_[nn] && aa<angles_[nn+1];
}
