// ----------------------------------------------------------------------------
//
// Copyright (C) Columbia University, 1994. All Rights Reserved.
// Sameer A. Nene, Shree K. Nayar, Hiroshi Murase
//
// See file LICENSE for details of software license agreement.
//
// ----------------------------------------------------------------------------
//
// ninterpolation.C
//
// Author:               Sameer Nene
// Date:                 08/28/94
// Version:              1.0
// Modification History:
//
// Bugs:
//
// Classes:
//   NamedInterpolation
//
// Notes:
//   Private class. Not for public use.
//   
// ----------------------------------------------------------------------------

#include <X11/PEX5/PEXlib.h>
#include <string.h>
#include <values.h>
#include "interpolation.h"
#include "ninterpolation.h"
#include "vector.h"
#include "xmanifold.h"

NamedInterpolation::NamedInterpolation() : d_name_p(0), d_ip(0), d_sid(0),
d_visible(VISIBLE), d_dmap1(0), d_dmap2(0), d_sfreq1(0), d_sfreq2(0),
d_param_p(0)
{
}

NamedInterpolation::NamedInterpolation(const char *name, Interpolation *ip) : d_name_p(new char[strlen(name) + 1]), d_ip(ip), d_sid(0), d_visible(VISIBLE),
d_dmap1(0), d_dmap2(0), d_sfreq1(0), d_sfreq2(0), d_param_p(0)
{
  strcpy(d_name_p, name);
}

NamedInterpolation::~NamedInterpolation()
{
  delete[] d_name_p;
  delete d_ip;
  if(d_sid != 0) {
    PEXDestroyStructures(Global::d_display, 1, &d_sid);
    d_sid = 0;
  }
}

void NamedInterpolation::rename(const char *name)
{
  delete[] d_name_p;
  strcpy(d_name_p = new char[strlen(name) + 1], name);
}

void NamedInterpolation::constructPEXStruct()
{
  int i, j, k, l, m;
  double inc, inc2;
  PEXCoord *pt;
  PEXColor color;
  PEXArrayOfVertex verts;
  PEXArrayOfFacetData dummy;

  if(d_sid != 0)
    PEXDestroyStructures(Global::d_display, 1, &d_sid);
  d_sid = PEXCreateStructure(Global::d_display);
  PEXSetViewIndex(Global::d_display, d_sid, PEXOCStore, 1);
  d_min.x = d_min.y = d_min.z = MAXFLOAT;
  d_max.x = d_max.y = d_max.z = MINFLOAT;
  if((i = d_ip -> dimension()) == 1) {
    Vector v(*d_param_p);
    pt = new PEXCoord[d_sfreq1 + 1];
    for(i = 0, inc = 1. / (j = d_sfreq1), v.element(d_dmap1, 0.);
	i < j; ++i, v.element(d_dmap1, v.element(d_dmap1) + inc)) {
      translate(d_ip -> sample(v), &pt[i]);
      adjustRange(pt[i], &d_min, &d_max);
    }
    v.element(d_dmap1, 1.);
    translate(d_ip -> sample(v), &pt[i]);
    adjustRange(pt[i], &d_min, &d_max);

    color.rgb = allocColor();
    PEXSetLineColor(Global::d_display, d_sid, PEXOCStore, PEXColorTypeRGB,
		    &color);
    PEXPolyline(Global::d_display, d_sid, PEXOCStore, j + 1, pt);
    delete[] pt;
  }
  else if(i >= 2) {
    Vector v(*d_param_p);
    pt = new PEXCoord[(d_sfreq1 + 1) * (d_sfreq2 + 1)];
    for(i = 0, m = 0, v.element(d_dmap1, 0.), inc = 1. / (j = d_sfreq1),
	inc2 = 1. / (l = d_sfreq2); i < j;
	++i, v.element(d_dmap1, v.element(d_dmap1) + inc)) {
      for(k = 0, v.element(d_dmap2, 0.); k < l;
	  ++k, ++m, v.element(d_dmap2, v.element(d_dmap2) + inc2)) {
	translate(d_ip -> sample(v), &pt[m]);
	adjustRange(pt[m], &d_min, &d_max);
      }
      v.element(d_dmap2, 1.);
      translate(d_ip -> sample(v), &pt[m]);
      adjustRange(pt[m++], &d_min, &d_max);
    }
    v.element(d_dmap1, 1.);
    for(k = 0, v.element(d_dmap2, 0.); k < l;
	++k, ++m, v.element(d_dmap2, v.element(d_dmap2) + inc2)) {
      translate(d_ip -> sample(v), &pt[m]);
      adjustRange(pt[m], &d_min, &d_max);
    }
    v.element(d_dmap2, 1.);
    translate(d_ip -> sample(v), &pt[m]);
    adjustRange(pt[m], &d_min, &d_max);
    
    color.rgb = allocColor();
    PEXSetSurfaceColor(Global::d_display, d_sid, PEXOCStore,
		       PEXColorTypeRGB, &color);
    verts.no_data = pt;
    PEXQuadrilateralMesh(Global::d_display, d_sid, PEXOCStore,
			 PEXShapeConvex, PEXGANone, PEXGANone, PEXColorTypeRGB,
			 dummy, l + 1, j + 1, verts);
    delete[] pt;
  }
}

void NamedInterpolation::interpolation(Interpolation *ip)
{
  delete d_ip;
  d_ip = ip;
}

void NamedInterpolation::makeVisible()
{
  d_visible = VISIBLE;
}

void NamedInterpolation::makeInvisible()
{
  d_visible = INVISIBLE;
}

void NamedInterpolation::setDimensionMap(int dmap1, int dmap2)
{
  d_dmap1 = dmap1;
  d_dmap2 = dmap2;
}

void NamedInterpolation::setSamplingFreq(int sfreq1, int sfreq2)
{
  d_sfreq1 = sfreq1;
  d_sfreq2 = sfreq2;
}

void NamedInterpolation::setSamplingParams(const Vector &param)
{
  delete d_param_p;
  d_param_p = new Vector(param);
}

const char* NamedInterpolation::dataName() const
{
  return d_name_p;
}

Interpolation* NamedInterpolation::interpolation() const
{
  return d_ip;
}

PEXStructure NamedInterpolation::getPEXStruct() const
{
  return d_sid;
}

int NamedInterpolation::getVisibility() const
{
  return d_visible;
}

void NamedInterpolation::getExtents(PEXCoord *min, PEXCoord *max) const
{
  *min = d_min;
  *max = d_max;
}

void NamedInterpolation::getDimensionMap(int *dmap1, int *dmap2) const
{
  *dmap1 = d_dmap1;
  *dmap2 = d_dmap2;
}

void NamedInterpolation::getSamplingFreq(int *sfreq1, int *sfreq2) const
{
  *sfreq1 = d_sfreq1;
  *sfreq2 = d_sfreq2;
}

Vector NamedInterpolation::getSamplingParams() const
{
  return *d_param_p;
}

