// file: $isip/class/sp/FrontEnd/FrontEnd.h
// version: $Id: FrontEnd.h 9236 2003-06-23 18:12:22Z gao $
//

// this file defines the FrontEnd class
//

// make sure definitions are only made once
//
#ifndef ISIP_FRONTEND
#define ISIP_FRONTEND

#ifndef ISIP_FRONTEND_BASE
#include <FrontEndBase.h>
#endif

#ifndef ISIP_FRONTEND_UNDEFINED
#include <FrontEndUndefined.h>
#endif

#ifndef NAME_MAP
#include <NameMap.h>
#endif

// FrontEnd: this class, coupled with FrontEndBase, defines a methodology
// for implementing generic front ends - systems that convert a signal
// (e.g., audio, video) to a feature stream.
//
class FrontEnd : public FrontEndBase {

  //---------------------------------------------------------------------------
  //
  // public constants
  //
  //---------------------------------------------------------------------------
public:

  static const String CLASS_NAME;
  
  enum TYPES { AUDIO = 0, VIDEO, DEF_TYPE = AUDIO };

  static const NameMap TYPES_MAP;
  
  //----------------------------------------
  //
  // i/o related constants
  //
  //----------------------------------------

  static const String PARAM_TYPES;
  
  //----------------------------------------
  //
  // default values and arguments
  //
  //----------------------------------------
 
  //----------------------------------------
  //
  // error codes
  //
  //----------------------------------------  
  
  static const long ERR = 80200;
  
  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:

  // pointer to the base class object
  //
  FrontEndBase* virtual_fe_d;

  // define an empty object used for uninitialized things
  //
  static FrontEndUndefined NO_FRONTEND;

  // memory manager
  //
  static MemoryManager mgr_d;
  
  //---------------------------------------------------------------------------
  //
  // required public methods
  //
  //---------------------------------------------------------------------------
public:

  // method: name
  //
  static const String& name() {
    return CLASS_NAME;
  }
  
  static boolean diagnose(Integral::DEBUG debug_level);
  
  // method: debug
  //  setDebug is inherited from base class
  //
  boolean debug(const unichar* msg) const {
    return virtual_fe_d->debug(msg);
  }

  // method: destructor
  //
  ~FrontEnd() {
    if (virtual_fe_d != (FrontEndBase*)&NO_FRONTEND) {
      delete virtual_fe_d;
    }
  }

  // method: default constructor
  //
  FrontEnd() {
    virtual_fe_d = (FrontEndBase*)&NO_FRONTEND;
  }

  // method: copy constructor
  //
  FrontEnd(const FrontEnd& arg) {
    virtual_fe_d = (FrontEndBase*)&NO_FRONTEND;
    assign(arg);
  }
  
  // method: assign
  //
  boolean assign(const FrontEnd& arg) {
    return assign(*(arg.virtual_fe_d));
  }
  
  // i/o methods
  //
  long sofSize() const;
  
  boolean read(Sof& sof, long tag, const String& name = CLASS_NAME);

  boolean write(Sof& sof, long tag, const String& name = CLASS_NAME) const;

  boolean readData(Sof& sof, const String& pname = String::EMPTY,
		   long size = SofParser::FULL_OBJECT,
		   boolean param = true, boolean nested = false);
  
  boolean writeData(Sof& sof, const String& pname = String::EMPTY) const;  

  // method: eq
  //
  boolean eq(const FrontEnd& arg) const {
    return virtual_fe_d->eq(*(arg.virtual_fe_d));
  }

  // method: new
  //
  static void* operator new(size_t size) {
    return mgr_d.get();
  }

  // method: new[]
  //
  static void* operator new[](size_t size) {
    return mgr_d.getBlock(size);
  }

  // method: delete
  //
  static void operator delete(void* ptr) {
    mgr_d.release(ptr);
  }

  // method: delete[]
  //
  static void operator delete[](void* ptr) {
    mgr_d.releaseBlock(ptr);
  }

  // method: setGrowSize
  //
  static boolean setGrowSize(long grow_size) {
    return mgr_d.setGrow(grow_size);
  }

  // method: clear
  //
  boolean clear(Integral::CMODE ctype = Integral::DEF_CMODE) {
    return virtual_fe_d->clear(ctype);
  }
  
  //---------------------------------------------------------------------------
  //
  // class-specific public methods:
  //  set methods
  //
  //---------------------------------------------------------------------------

  // configuration methods
  //
  boolean setType(TYPES type);

  // method: setVerbosity
  //
  boolean setVerbosity(Integral::DEBUG verbosity) {
    return virtual_fe_d->setVerbosity(verbosity);
  }

  // method: setOutputDirectory
  //
  boolean setOutputDirectory(const String& new_dir) {
    return virtual_fe_d->setOutputDirectory(new_dir);
  }

  // method: setOutputBasename
  //
  boolean setOutputBasename(String& basename) {
    return virtual_fe_d->setOutputBasename(basename);
  }

  // method: setOutputExtension
  //
  boolean setOutputExtension(String& extension) {
    return virtual_fe_d->setOutputExtension(extension);
  }  

  // method: setOutputPreserve
  //
  boolean setOutputPreserve(long new_preserve_level) {
    return virtual_fe_d->setOutputPreserve(new_preserve_level);
  }
    
  // method: setOutputSuffix
  //
  boolean setOutputSuffix(String& suffix) {
    return virtual_fe_d->setOutputSuffix(suffix);
  }

  // method: setOutputType
  //
  boolean setOutputType(File::TYPE type) {
    return virtual_fe_d->setOutputType(type);
  }
  
  // method: setOutputType
  //
  boolean setOutputType(String& type) {
    if (type.eq(File::TYPE_TEXT, false)) {
      return virtual_fe_d->setOutputType(File::TEXT);
    }
    else {
      return virtual_fe_d->setOutputType(File::BINARY);
    }
  }  
  
  // method: setNumChannels
  //
  boolean setNumChannels(long arg) {
    return virtual_fe_d->setNumChannels(arg);
  }

  // method: setCoefName
  //  set the name of the required features
  //
  boolean setCoefName(const String& name) {
    return virtual_fe_d->setCoefName(name);
  }

  //---------------------------------------------------------------------------
  //
  // class-specific public methods:
  //  get methods
  //
  //---------------------------------------------------------------------------

  // method: getType
  //
  TYPES getType() const {
    return (TYPES)TYPES_MAP(virtual_fe_d->className());
  }
  
  // method: getVerbosity
  //
  Integral::DEBUG getVerbosity() const {
    return virtual_fe_d->getVerbosity();
  }

  // method: getOutputBasename
  //
  const boolean getOutputBasename(String& basename) const {
    return virtual_fe_d->getOutputBasename(basename);
  }

  // method: getOutputExtension
  //
  const boolean getOutputExtension(String& extension) const {
    return virtual_fe_d->getOutputExtension(extension);
  }  

  // method: getOutputSuffix
  //
  const boolean getOutputSuffix(String& suffix) const {
    return virtual_fe_d->getOutputSuffix(suffix);
  }  
  
  // method: getOutputType
  //
  const File::TYPE& getOutputType() const {
    return virtual_fe_d->getOutputType();
  }

  // method: getVector
  //  get the coeff vector for a given frame
  //
  boolean getVector(VectorFloat& coeffs, long channel,
		    long frame_index) {
    return virtual_fe_d->getVector(coeffs, channel, frame_index);
  }
  
  // method: getNumFeatures
  //  get the total number of features after process a certain recipe
  //
  long getNumFeatures() {
    return virtual_fe_d->getNumFeatures();
  }
  
  // method: getNumChannels
  //
  long getNumChannels() const {
    return virtual_fe_d->getNumChannels();
  }
  
  // method: getNumFrames
  //  get the total number of frames of the AudioFile
  //
  long getNumFrames() {
    return virtual_fe_d->getNumFrames();
  }

  // method: getFrameDuration
  //  get the frame duration
  //
  float getFrameDuration() const {
    return virtual_fe_d->getFrameDuration();
  }
  
  // method: getID
  //
  virtual const String& getID() const {
    return virtual_fe_d->getID();
  }
  
  // method: isNameInput
  //  determine if a coefficient is an input or not
  //
  boolean isNameInput(const String& name) const {
    return virtual_fe_d->isNameInput(name);
  }

  // method: getInputFlag
  //  determine if input file exist
  //
  boolean getInputFlag() const {
    return virtual_fe_d->getInputFlag();
  }

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

  // method: eq
  //
  boolean eq(const FrontEndBase& arg) const {
    return virtual_fe_d->eq(arg);
  }

  // assign methods
  //
  boolean assign(const FrontEndBase& arg);

  // method: className
  //
  const String& className() const {
    return virtual_fe_d->className();
  }

  // method: open
  //
  boolean open(const Filename& input) {
    return virtual_fe_d->open(input);
  }

  // method: close
  //
  boolean close() {
    return virtual_fe_d->close();
  }

  // method: init
  //
  boolean init(float start_time, float stop_time, int channel) {
    return virtual_fe_d->init(start_time, stop_time, channel);
  }
  
  // method: run
  //  process an entire file at a time
  //
  boolean run(const Filename& input) {
    return virtual_fe_d->run(input);
  }

  //---------------------------------------------------------------------------
  //
  // class-specific public methods:
  //  additional parameter file processing methods
  //
  //---------------------------------------------------------------------------

  // method: load
  //
  boolean load(const Filename& input);

  //---------------------------------------------------------------------------
  //
  // private methods
  //
  //---------------------------------------------------------------------------
private:

  // reset methods
  //
  boolean reset();
};

// end of include file
//
#endif
