// file: $isip/class/algo/Algorithm/algo_00.cc
// version: $Id: algo_00.cc 10655 2008-01-04 19:40:15Z dom5 $
//

// isip include files
//
#include "Algorithm.h"

#include <AlgorithmContainer.h>
#include <Calculus.h>
#include <Cepstrum.h>
#include <CoefficientLabel.h>
#include <Connection.h>
#include <Constant.h>
#include <Correlation.h>
#include <Covariance.h>
#include <DisplayData.h>
#include <DynamicFilter.h>
#include <Energy.h>
#include <Filter.h>
#include <FilterBank.h>
#include <FourierTransform.h>
#include <Generator.h>
#include <LogAreaRatio.h>
#include <Mask.h>
#include <Math.h>
#include <Output.h>
#include <Prediction.h>
#include <Reflection.h>
#include <Spectrum.h>
#include <Statistics.h>
#include <Window.h>
#include <Rps.h>
#include <Lyapunov.h>
#include <CorrelationIntegral.h>
#include <MutualInformation.h>
#include <CorrelationEntropy.h>
#include <CorrelationDimension.h>

//------------------------------------------------------------------------
//
// required public methods
//
//-----------------------------------------------------------------------

// method: destructor
//
// arguments: none
//
// return: none
//
// this is destructor
//
Algorithm::~Algorithm() {

  // clean up memory and reset
  //
  if (virtual_algo_d != (AlgorithmBase*)&NO_ALGORITHM) {
    delete virtual_algo_d;
  }

  // exit gracefully
  //
}

// method: default constructor
//
// arguments: none
//
// return: none
//
// this is the default constructor
//
Algorithm::Algorithm() {

  // clean up memory and reset
  //
  virtual_algo_d = (AlgorithmBase*)&NO_ALGORITHM;
  
  // exit gracefully
  //
}

// method: copy constructor
//
// arguments:
//  const Algorithm& arg: (input) input object  
//
// return: none
//
// this is copy constructor
//
Algorithm::Algorithm(const Algorithm& arg_a) {

  // initialize pointer
  //
  virtual_algo_d = (AlgorithmBase*)&NO_ALGORITHM;
  
  // assign the argument
  //
  assign(arg_a);

  // exit gracefully
  //
}

// method: assign
//
// arguments:
//  const Algorithm& arg: (input) object to assign
//
// return: a boolean value
//
// this method assigns input argument to current argument
//
boolean Algorithm::assign(const Algorithm& arg_a) {

  // call the master method
  //
  return assign(*(arg_a.virtual_algo_d));
}

//---------------------------------------------------------------------------
//
// class-specific public methods:
//  public methods required by the AlgorithmBase interface contract
//
//---------------------------------------------------------------------------

// method: assign
//
// arguments:
//  const AlgorithmBase& arg: (input) object to assign
//
// return: a boolean value indicating status
//
// this method assigns input argument to current argument
//
boolean Algorithm::assign(const AlgorithmBase& arg_a) {

  // clear the data
  //
  clear();

  // if this is already an algorithm, branch on it's
  // real type
  //
  if (typeid(arg_a) == typeid(Algorithm)) {
    return assign(*((Algorithm&)arg_a).virtual_algo_d);
  }

  // branch on algorithm choices
  //
  else if (typeid(arg_a) == typeid(AlgorithmContainer)) {
    setType(ALGORITHM_CONTAINER);
  }
  else if (typeid(arg_a) == typeid(Calculus)) {
    setType(CALCULUS);
  }
  else if (typeid(arg_a) == typeid(Cepstrum)) {
    setType(CEPSTRUM);
  }
  else if (typeid(arg_a) == typeid(CoefficientLabel)) {
    setType(COEFFICIENT_LABEL);
  }
  else if (typeid(arg_a) == typeid(Connection)) {
    setType(CONNECTION);
  }
  else if (typeid(arg_a) == typeid(Constant)) {
    setType(CONSTANT);
  }
  else if (typeid(arg_a) == typeid(Correlation)) {
    setType(CORRELATION);
  }
  else if (typeid(arg_a) == typeid(Covariance)) {
    setType(COVARIANCE);
  }
  else if (typeid(arg_a) == typeid(DisplayData)) {
    setType(DISPLAY_DATA);
  }
  else if (typeid(arg_a) == typeid(DynamicFilter)) {
    setType(DYNAMIC_FILTER);
  }
  else if (typeid(arg_a) == typeid(Energy)) {
    setType(ENERGY);
  }
  else if (typeid(arg_a) == typeid(Filter)) {
    setType(FILTER);
  }
  else if (typeid(arg_a) == typeid(FilterBank)) {
    setType(FILTER_BANK);
  }
  else if (typeid(arg_a) == typeid(FourierTransform)) {
    setType(FOURIER_TRANSFORM);
  }
  else if (typeid(arg_a) == typeid(Generator)) {
    setType(GENERATOR);
  }
  else if (typeid(arg_a) == typeid(LogAreaRatio)) {
    setType(LOG_AREA_RATIO);
  }
  else if (typeid(arg_a) == typeid(Mask)) {
    setType(MASK);
  }
  else if (typeid(arg_a) == typeid(Math)) {
    setType(MATH);
  }
  else if (typeid(arg_a) == typeid(Output)) {
    setType(OUTPUT);
  }    
  else if (typeid(arg_a) == typeid(Prediction)) {
    setType(PREDICTION);
  }
  else if (typeid(arg_a) == typeid(Reflection)) {
    setType(REFLECTION);
  }
  else if (typeid(arg_a) == typeid(Spectrum)) {
    setType(SPECTRUM);
  }
  else if (typeid(arg_a) == typeid(Statistics)) {
    setType(STATISTICS);
  }
  else if (typeid(arg_a) == typeid(Window)) {
    setType(WINDOW);
  }
  else if (typeid(arg_a) == typeid(Rps)) {
    setType(RPS);
  }
  else if (typeid(arg_a) == typeid(Lyapunov)) {
    setType(LYAPUNOV);
  }
  else if (typeid(arg_a) == typeid(CorrelationIntegral)) {
    setType(CORRELATION_INTEGRAL);
  }
  else if (typeid(arg_a) == typeid(MutualInformation)) {
    setType(MUTUAL_INFORMATION);
  }
  else if (typeid(arg_a) == typeid(CorrelationEntropy)) {
    setType(CORRELATION_ENTROPY);
  }
  else if (typeid(arg_a) == typeid(CorrelationDimension)) {
    setType(CORRELATION_DIMENSION);
  }

  // error
  //
  else {
    return Error::handle(name(), L"assign", Error::ENUM, __FILE__, __LINE__);
  }
  
  // call the base assign method
  //
  return virtual_algo_d->assign(arg_a);
}

//---------------------------------------------------------------------------
//
// we define non-integral constants in the default constructor
//      
//---------------------------------------------------------------------------

// constants: class name
//
const String Algorithm::CLASS_NAME(L"Algorithm");

// constants: i/o related constants
//
const String Algorithm::DEF_PARAM(L"");
const String Algorithm::PARAM_TYPES(L"name");

// constants: name map for enum
//
const NameMap Algorithm::TYPES_MAP(L"AlgorithmContainer, Calculus, Cepstrum, CoefficientLabel, Connection, Constant, Correlation, Covariance, DisplayData, DynamicFilter, Energy, Filter, FilterBank, FourierTransform, Generator, LogAreaRatio, Mask, Math, Output, Prediction, Reflection, Spectrum, Statistics, Window, Rps, Lyapunov, CorrelationIntegral, MutualInformation, CorrelationEntropy, CorrelationDimension");

// constants: instantiation of the NO_ALGORITHM object
//
AlgorithmUndefined Algorithm::NO_ALGORITHM;

// static instantiations: memory manager
//
MemoryManager Algorithm::mgr_d(sizeof(Algorithm), Algorithm::name());
