// ----------------------------------------------------------------------------
//
// 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.
//
// ----------------------------------------------------------------------------
//
// mkbinarysrchtbl.C
//
// Author:               Sameer Nene
// Date:                 06/14/94
// Version:              1.0.0
// Modification History:
//   06/14/94 - Added feature to directly sample an interpolation and contruct
//              the search table rather than first sampling it with sample.
//              Actually, the feature already exists in the class
//              BinarySearch; I am just using it. Use of this feature can
//              result in hughly faster performance on OSF/1 V1.3 due to the
//              way it deals with memory.
//   06/26/94: Change necessary because of modification of FullSearch interface
//
//
// Classes:
//
// Notes:
//   This command is used to construct a binary search method (table) for the
//   supplied data and parameters. See the man page for more details.
//   
// ----------------------------------------------------------------------------

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

int main(int argc, char **argv)
{
  int i, j, k, l, m, n, o, ns, s1, s2, t, v;
  char buf[1024], *p;
  ErrorScope::Error error;
  Vector d, f, rangemin, rangemax;
  CommandParser cp(argc, argv, "s:v:V");
  DataSet ds;
  Handle h;
  Interpolation *ip;

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

  if((n = cp.getNumValueParams()) == 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 << endl << "Constructing search table..." << endl;
  }
  
  for(i = 0, j = sa.getSize(); i < j; ++i) {
    if((ns = cp.getNumSampleValueParams()) != 0) {
      if((error = IOUtil::get(&h, sa[i])) != ErrorScope::OK) {
	cout << error << endl;
	exit(1);
      }
    
      if((ip = PersistentInterpolation::safeCast(h())) == 0) {
	cout << ErrorScope::INCORRECT_FORMAT << endl;
	exit(1);
      }
      if(ip -> dimension() != (l = cp.getNumSampleValues(o = i < ns ? i : ns - 1))) {
	cout << ErrorScope::PARAMETER_ERROR << endl;
	exit (1);
      }
      for(k = 0, t = 1, f.length(l); k < l; ++k) {
	if((m = int(cp.getSampleValue(o, k))) > 0) {
	  t *= m;
	  f.element(k, m);
	}
	else {
	  cout << ErrorScope::PARAMETER_ERROR << endl;
	  exit (1);
	}
      }
      s1 = t;
      s2 = ip -> dimension();
    }
    else {
      if((error = IOUtil::get(&ds, sa[i])) != ErrorScope::OK) {
	cerr << error << ": " << sa[i] << endl << "Exiting" << endl;
	exit(1);
      }
      s1 = ds().getSize();
      s2 = ds.getSize();
    }
    
    v = cp.getNumValues(0);
    if(n == 1)
      if(v == 2 || (v == 3 && cp.getValue(0, 0) == s1)) {
	cp.getNumSampleValueParams() ? d.length(1) : ds.setDimension(1);
	rangemin.length(1);
	rangemax.length(1);
	cp.getNumSampleValueParams() ? d.element(0, s1) : ds.setSize(0, s1);
	rangemin.element(0, cp.getValue(0, 0));
	rangemax.element(0, cp.getValue(0, 1));
      }
      else {
	cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
	exit (1);
      }
    else if(v == 2 && n == s2) {
      if(cp.getNumSampleValueParams() != 0)
	d.length(n);
      rangemin.length(n);
      rangemax.length(n);
      for(k = 0; k < n; ++k) {
	if(cp.getNumValues(k) != 2) {
	  cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
	  exit (1);
	}
	if(cp.getNumSampleValueParams() != 0)
	  d.element(k, cp.getNumSampleValueParams() ?  f.element(k) : ds.getSize(k));
	rangemin.element(k, cp.getValue(k, 0));
	rangemax.element(k, cp.getValue(k, 1));
      }
    }
    else if(v == 3) {
      cp.getNumSampleValueParams() ? d.length(n) : ds.setDimension(n);
      rangemin.length(n);
      rangemax.length(n);
      for(k = 0, t = 1; k < n; ++k) {
	if(cp.getNumValues(k) != 3) {
	  cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
	  exit (1);
	}
	t *= int(v = int(cp.getValue(k, 0)));
	cp.getNumSampleValueParams() ? d.element(k, int(v)) : ds.setSize(k, int(v));
	rangemin.element(k, cp.getValue(k, 1));
	rangemax.element(k, cp.getValue(k, 2));
      }
      if(t != s1) {
	cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
	exit (1);
      }
    }
    else {
      cerr << ErrorScope::PARAMETER_ERROR << endl << "Exiting" << endl;
      exit (1);
    }

    if((p = strrchr(strcpy(buf, sa[i]), '.')) != 0)
      *p = 0;
    
    if(cp.getNumSampleValueParams() != 0) {
      BinarySearch s(*ip, f, d, rangemin, rangemax);

      if((error = IOUtil::put(s, strcat(buf, ".tbl"))) != ErrorScope::OK) {
	cerr << error << ": " << buf << endl << "Exiting" << endl;
	exit(1);
      }
    }
    else {
      BinarySearch s(ds, rangemin, rangemax);
      
      if((error = IOUtil::put(s, strcat(buf, ".tbl"))) != ErrorScope::OK) {
	cerr << error << ": " << buf << endl << "Exiting" << endl;
	exit(1);
      }
    }
  }

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

  return 0;
}
