// ----------------------------------------------------------------------------
//
// 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.
//
// ----------------------------------------------------------------------------
//
// sample.C
//
// Author:               Sameer Nene
// Date:                 06/13/94
// Version:              1.0.0
// Modification History:
//   06/13/94 - Changed parameter input from -v to -s for greater consistency.
//
// Classes:
//
// Notes:
//   This command is used to (re)sample an interpolation according to the
//   supplied parameters. See man pages for more details
//   
// ----------------------------------------------------------------------------

#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include "errorscope.h"
#include "parser.h"
#include "dataset.h"
#include "ioutil.h"
#include "handle.h"
#include "interpolation.h"
#include "persinterp.h"
#include "stringary.h"

static void sample(const Interpolation *ip, Vector &v, DataSetIter &it,
		   const CommandParser &cp, int o, int level)
{
  int i, s = int(cp.getSampleValue(o, level)) - 1;
  double t, inc;

  if(level == cp.getNumSampleValues(o) - 1) {
    for(i = 0, t = 0., inc = 1. / s; i < s; ++i, t += inc, ++it) {
      v.element(level, t);
      it() = ip -> sample(v);
    }
    v.element(level, 1.);
    it() = ip -> sample(v);
    ++it;
  }
  else {
    for(i = 0, t = 0., inc = 1. / s; i < s; ++i, t += inc) {
      v.element(level, t);
      sample(ip, v, it, cp, o, level + 1);
    }
    v.element(level, 1.);
    sample(ip, v, it, cp, o, level + 1);
  }
}

int main(int argc, char **argv)
{
  char buf[1024], *p;
  int i, j, k, l, m, n, o, s, t;
  Handle h;
  Interpolation *ip;
  CommandParser cp(argc, argv, "c:s:CV");
  ErrorScope::Error error;

  if((error = cp.error()) != ErrorScope::OK) {
    cerr << error << endl << "Exiting" << endl;
    exit(1);
  }

  StringAry &sa = cp.getObjectList();

  if((n = cp.getNumSampleValueParams()) == 0) {
    cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
    exit (1);
  }

  if(cp.getVerboseFlag() != 0)
    cerr << "Copyright \xA9 Columbia University, 1994. All Rights Reserved." << endl << "Sameer Nene, Shree Nayar, Hiroshi Murase" << endl << endl << "Sampling..." << endl;

  if(cp.getCombineFlag()) {
    for(i = 0, j = sa.getSize(), s = 0; i < j; ++i) {
      for(k = 0, l = cp.getNumSampleValues(o = i < n ? i : n - 1), t = 1; k < l; ++k)
	if((m = int(cp.getSampleValue(o, k))) > 0)
	  t *= m;
	else {
	  cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
	  exit (1);
	}
      s += t;
    }

    DataSet ds(1, s);
    DataSetIter it(ds);
    ds.setSize(0, s);

    for(i = 0; i < j; ++i) {
      o = i < n ? i : n - 1;

      if((error = IOUtil::get(&h, sa[i])) != ErrorScope::OK) {
	cerr << error << ": " << sa[i] << endl << "Exiting" << endl;
	exit(1);
      }

      if((ip = PersistentInterpolation::safeCast(h())) == 0) {
	cerr << ErrorScope::INCORRECT_FORMAT << ": " << sa[i] << endl << "Exiting" << endl;
	exit(1);
      }
      if((l = ip -> dimension()) != cp.getNumSampleValues(o)) {
	cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
	exit (1);
      }
      
      Vector v(l);
      sample(ip, v, it, cp, o, 0);
    }
    
    strcat(strcpy(buf, cp.getCombineName()), ".smp");

    if((error = IOUtil::put(ds, buf)) != ErrorScope::OK) {
      cerr << error << ": " << buf << endl << "Exiting" << endl;
      exit(1);
    }
  }
  else {
    for(i = 0, j = sa.getSize(); i < j; ++i) {
      if((error = IOUtil::get(&h, sa[i])) != ErrorScope::OK) {
	cerr << error << ": " << sa[i] << endl << "Exiting" << endl;
	exit(1);
      }

      if((ip = PersistentInterpolation::safeCast(h())) == 0) {
	cerr << ErrorScope::INCORRECT_FORMAT << ": " << sa[i] << endl << "Exiting" << endl;
	exit(1);
      }
      if(ip -> dimension() != (l = cp.getNumSampleValues(o = i < n ? i : n - 1))) {
	cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
	exit (1);
      }
      for(k = 0, t = 1; k < l; ++k) {
	if((m = int(cp.getSampleValue(o, k))) > 0)
	  t *= m;
	else {
	  cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
	  exit (1);
	}
      }

      DataSet ds(l, t);
      DataSetIter it(ds);
      for(k = 0; k < l; ++k)
	ds.setSize(k, int(cp.getSampleValue(o, k)));

      Vector v(l);
      sample(ip, v, it, cp, o, 0);

      if((p = strrchr(strcpy(buf, sa[i]), '.')) != 0)
	*p = 0;
      
      if((error = IOUtil::put(ds, strcat(buf, ".smp"))) != ErrorScope::OK) {
	cerr << error << ": " << buf << endl << "Exiting" << endl;
	exit(1);
      }
    }
  }

  if(cp.getVerboseFlag() != 0)
    cerr << "Done..." << endl;

  return 0;
}
