// file: $isip/class/pr/LanguageModel/lm_07.cc
//

// system include files
//
#include <typeinfo>

// isip include files
//
#include "LanguageModel.h"
#include <LanguageModelIHD.h>
#include <LanguageModelJSGF.h>
#include <LanguageModelXML.h>
#include <LanguageModelBNF.h>
#include <LanguageModelABNF.h>

// method: setFormat
//
// arguments: format_a: (input) the format of the language model
//
// return: boolean indicating statis
//
// This method accepts an enumerated ALGORITHM value and sets the
// format of the language model based on this value.  An object
// for this specific language model type is then allocated.
//
boolean LanguageModel::setFormat(ALGORITHM format_a) {

  // if the language model has already been assigned a type,
  // clear it
  //
  if (virtual_lm_d != (LanguageModelBase*)&NO_LANGUAGE_MODEL) {
    clear();
  }
  
  // digraph format
  //
 
  if (format_a == IHD) {
    virtual_lm_d = new LanguageModelIHD;
    format_d = format_a;
    return true;
  }
  else if (format_a == JSGF) {
    virtual_lm_d = new LanguageModelJSGF;
    format_d = format_a;
    return true;
  }
  else if (format_a == XML) {
    virtual_lm_d = new LanguageModelXML;
    format_d = format_a;
    return true;
  }
  else if (format_a == BNF) {
    virtual_lm_d = new LanguageModelBNF;
    format_d = format_a;
    return true;
  }
  else if (format_a == ABNF) {
    virtual_lm_d = new LanguageModelABNF;
    format_d = format_a;
    return true;
  }
  
  return Error::handle(name(), L"setFormat",
		       Error::TEST, __FILE__, __LINE__);
  
}

// method: convert
//
// arguments: format_a: (input) the format of the language model
//
// return: boolean indicating statis
//
// This method accepts an enumerated ALGORITHM value and converts the
// format of the language model based on this value.  An new object
// for this specific language model type is then allocated and the
// current one is deleted.
//
boolean LanguageModel::convert(ALGORITHM format_a) {
  
  // if the current language model format is undefined, return an error
  //
  if (format_d == UNKNOWN) {
    return Error::handle(name(), L"convert: the current format is undefined",
			 Error::TEST, __FILE__, __LINE__);    
  }
  
  // if the format of the current language model matches format_a, then
  // do nothing.
  else if (format_d == format_a) {
    
    // exit gracefully
    //
    return true;
  }
  
  LanguageModelBase* temp_lm = virtual_lm_d;  
  
  if (format_a == IHD) {
    virtual_lm_d = new LanguageModelIHD;
  }
  else if (format_a == JSGF) {
    virtual_lm_d = new LanguageModelJSGF;
  }
  else if (format_a == XML) {
    virtual_lm_d = new LanguageModelXML;
  }
  else if (format_a == BNF) {
    virtual_lm_d = new LanguageModelBNF;
  }
  else if (format_a == ABNF) {
    virtual_lm_d = new LanguageModelABNF;
  }
  else {
    return Error::handle(name(), L"convert: unknown format",
			 Error::TEST, __FILE__, __LINE__);      
  }
  
  virtual_lm_d->setRuleModel(temp_lm->getRuleModel());  
  delete(temp_lm);
  
  format_d = format_a;
  
  // exit gracefully
  //
  return true;
  
}

// method: minimizeGraph
//
// arguments: none
//
// return: boolean indicating statis
//
// This method minimizes the language model graphs using LanguageModelBNF's
// minimization routine.  This method does not change the format of the graph,
// just the graph structure.
//
boolean LanguageModel::minimizeGraph() {

  LanguageModelBNF lm_bnf;

  // set the populate the LanguageModelBNF object and minimize
  // the graph
  //
  lm_bnf.setRuleModel(getRuleModel());
  lm_bnf.minimizeGraph();

  return setRuleModel(lm_bnf.getRuleModel());  
}
