// file: $isip/class/mmedia/TranscriptionDatabase/trans_02.cc
// version: $Id: trans_02.cc 9099 2003-04-18 21:45:43Z parihar $
//

// isip include files
//
#include "TranscriptionDatabase.h"
#include <Console.h>

// method: diagnose
//
// arguments:
//  Integral::DEBUG level: (input) debug level for diagnostics
//
// return: a boolean value indicating status
//
boolean TranscriptionDatabase::diagnose(Integral::DEBUG level_a) {

  //----------------------------------------------------------------------
  //
  // 0. preliminaries
  //
  //----------------------------------------------------------------------

  // output the class name
  //
  if (level_a > Integral::NONE) {
    SysString output(L"diagnosing class ");
    output.concat(CLASS_NAME);
    output.concat(L": ");
    Console::put(output);
    Console::increaseIndention();
  }

  // --------------------------------------------------------------------
  //
  // 1. required public methods
  //
  // --------------------------------------------------------------------

  // set indentation
  //  
  if (level_a > Integral::NONE) {
    Console::put(L"testing required public methods...\n");
    Console::increaseIndention(); 
  }

  TranscriptionDatabase trans_00;
  TranscriptionDatabase trans_01;
  TranscriptionDatabase trans_02;    

  // test the get/set database name methods
  //
  String name_00(L"TIDIGITS");
  String name_01(L"TIMIT");  

  trans_00.setDataBaseName(name_00);
  trans_01.setDataBaseName(name_00);  

  if (trans_00.getDataBaseName().eq(name_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!trans_00.getDataBaseName().eq(name_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  // create the annotation graph
  //
  String gtype_00(L"ORTHOGRAPHIC");

  String ident_00(L"id_00");
  String ident_01(L"id_01");
  String ident_02(L"id_02");
  String ident_03(L"id_03");    
  
  String newid_00;
  String newid_01;
  String newid_02;  

  Float offset_00(2.4);
  Float offset_01(4.9);
  Float offset_02(7.9);  
  Float offset_03(4.0);
  Float offset_04(3.7);
  Float offset_05(0.9);
  
  Anchor* ancr_00 = (Anchor*)NULL;
  Anchor* ancr_01 = (Anchor*)NULL;
  
  String unit_00(L"seconds");
  String feat_00(L"level");
  String value_00(L"word");
  String value_01(L"phoneme");  

  // insert the transcription
  //
  AnnotationGraph angr_00(name_00, gtype_00);
  String atype_00(L"one two three nine zero");  
  newid_00 = angr_00.createAnchor(name_00, offset_00, unit_00);
  newid_01 = angr_00.createAnchor(name_00, offset_01, unit_00);

  ancr_00 = angr_00.getAnchorById(newid_00);
  ancr_01 = angr_00.getAnchorById(newid_01);
  
  newid_00 = angr_00.createAnnotation(name_00, ancr_00, ancr_01, atype_00);
  if (!angr_00.setFeature(newid_00, feat_00, value_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // insert the transcription
  //
  AnnotationGraph angr_01(name_00, gtype_00);    
  String atype_01(L"one seven four oh");  
  newid_00 = angr_01.createAnchor(name_00, offset_02, unit_00);
  newid_01 = angr_01.createAnchor(name_00, offset_03, unit_00);

  ancr_00 = angr_01.getAnchorById(newid_00);
  ancr_01 = angr_01.getAnchorById(newid_01);  
  
  newid_01 = angr_01.createAnnotation(name_00, ancr_00, ancr_01, atype_01);
  if (!angr_01.setFeature(newid_01, feat_00, value_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // insert the transcription
  //
  AnnotationGraph angr_02(name_00, gtype_00);    
  String atype_02(L"six seven two three four six");    
  newid_00 = angr_02.createAnchor(name_00, offset_04, unit_00);
  newid_01 = angr_02.createAnchor(name_00, offset_05, unit_00);

  ancr_00 = angr_02.getAnchorById(newid_00);
  ancr_01 = angr_02.getAnchorById(newid_01);    
  
  newid_02 = angr_02.createAnnotation(name_00, ancr_00, ancr_01, atype_02);
  if (!angr_02.setFeature(newid_02, feat_00, value_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  // test the insert method
  //  
  if (!trans_00.insertRecord(ident_00, angr_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!trans_01.insertRecord(ident_00, angr_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  if (!trans_00.insertRecord(ident_01, angr_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!trans_01.insertRecord(ident_01, angr_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  

  if (!trans_00.insertRecord(ident_02, angr_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!trans_01.insertRecord(ident_02, angr_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  Filename tmp_file00;
  Integral::makeTemp(tmp_file00);
  Filename tmp_file01;
  Integral::makeTemp(tmp_file01);  

  Sof tmp_file_00;
  tmp_file_00.open(tmp_file00, File::WRITE_ONLY, File::TEXT);
  Sof tmp_file_01;
  tmp_file_01.open(tmp_file01, File::WRITE_ONLY, File::TEXT);  

  trans_00.store(tmp_file_00, (long)0);
  trans_01.store(tmp_file_01, (long)1);
  
  tmp_file_00.close();
  tmp_file_01.close();

  // open the database
  //
  trans_00.open(tmp_file00);
  //  trans_01.open(tmp_file01);
  
  trans_00.read(tmp_file_00, (long)0);  
  //  trans_01.read(tmp_file_01, (long)1);

  // test the get methods
  //    
  AnnotationGraph angx_00;  
  if (!trans_00.getRecord(ident_00, angx_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  
  if (!angr_00.eq(angx_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  /*
  if (!trans_01.getRecord(ident_00, angx_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!angr_00.eq(angx_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  
  */
  AnnotationGraph angx_01;    
  if (!trans_00.getRecord(ident_01, angx_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!angr_01.eq(angx_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  /*
  if (!trans_01.getRecord(ident_01, angx_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!angr_01.eq(angx_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  */
  AnnotationGraph angx_02;    
  if (!trans_00.getRecord(ident_02, angx_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!angr_02.eq(angx_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }    
  /*
  if (!trans_01.getRecord(ident_02, angx_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!angr_02.eq(angx_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  */
  // test the get methods
  //
  DoubleLinkedList<Annotation> records_00;
  if (!trans_00.getRecord(ident_00, feat_00, value_00, records_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  
  if (!records_00.getFirst()->getType().eq(atype_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  
  DoubleLinkedList<Annotation> records_01;
  if (!trans_00.getRecord(ident_01, feat_00, value_00, records_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!records_01.getFirst()->getType().eq(atype_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  
  DoubleLinkedList<Annotation> records_02;
  if (!trans_00.getRecord(ident_02, feat_00, value_00, records_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  
  if (!records_02.getFirst()->getType().eq(atype_02)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // close the database
  //
  trans_00.close();
  //  trans_01.open();

  // clear allocated memory
  //
  angr_00.clear();
  angr_01.clear();
  angr_02.clear();

  angx_00.clear();
  angx_01.clear();
  angx_02.clear();
  
  trans_00.clear();
  trans_01.clear();  

  // insert the transcription
  //
  Float offset(0.0);  
  Float offset_06(0.0);
  Float offset_07(0.1);
  Float offset_08(0.2);
  Float offset_09(0.3);  

  String atype_03(L"the");
  String atype_03a(L"tx");
  String atype_03b(L"iy");    

  String atype_04(L"boy");
  String atype_04a(L"b");
  String atype_04b(L"oy");    

  String atype_05(L"ran");
  String atype_05a(L"r");
  String atype_05b(L"an");    

  String newid_03;
  String newid_34;  
  String newid_04;
  String newid_45;  
  String newid_05;
  String newid_56;  
  String newid_06;  

  Anchor* ancr_02 = (Anchor*)NULL;
  Anchor* ancr_23 = (Anchor*)NULL;  
  Anchor* ancr_03 = (Anchor*)NULL;
  Anchor* ancr_34 = (Anchor*)NULL;  
  Anchor* ancr_04 = (Anchor*)NULL;
  Anchor* ancr_45 = (Anchor*)NULL;  
  Anchor* ancr_05 = (Anchor*)NULL;  

  AnnotationGraph angr_03(name_00, gtype_00);    

  DoubleLinkedList<String> records1;
  DoubleLinkedList<String> records2;  
  
  newid_03 = angr_03.createAnchor(name_00, offset_06, unit_00);
  newid_34 = angr_03.createAnchor(name_00, offset, unit_00);  
  newid_04 = angr_03.createAnchor(name_00, offset_07, unit_00);
  newid_45 = angr_03.createAnchor(name_00, offset, unit_00);  
  newid_05 = angr_03.createAnchor(name_00, offset_08, unit_00);
  newid_56 = angr_03.createAnchor(name_00, offset, unit_00);  
  newid_06 = angr_03.createAnchor(name_00, offset_09, unit_00);  

  ancr_02 = angr_03.getAnchorById(newid_03);
  ancr_23 = angr_03.getAnchorById(newid_34);  
  ancr_03 = angr_03.getAnchorById(newid_04);
  ancr_34 = angr_03.getAnchorById(newid_45);  
  ancr_04 = angr_03.getAnchorById(newid_05);
  ancr_45 = angr_03.getAnchorById(newid_56);  
  ancr_05 = angr_03.getAnchorById(newid_06);      

  newid_03 = angr_03.createAnnotation(name_00, ancr_02, ancr_03, atype_03);
  records1.insert(&atype_03);
  if (!angr_03.setFeature(newid_03, feat_00, value_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // okay till here

  newid_03 = angr_03.createAnnotation(name_00, ancr_02, ancr_23, atype_03a);
  records2.insert(&atype_03a);
  if (!angr_03.setFeature(newid_03, feat_00, value_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  
  newid_03 = angr_03.createAnnotation(name_00, ancr_23, ancr_03, atype_03b);
  records2.insert(&atype_03b);    
  if (!angr_03.setFeature(newid_03, feat_00, value_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }    
  
  newid_04 = angr_03.createAnnotation(name_00, ancr_03, ancr_04, atype_04);
  records1.insert(&atype_04);  
  if (!angr_03.setFeature(newid_04, feat_00, value_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  newid_04 = angr_03.createAnnotation(name_00, ancr_03, ancr_34, atype_04a);
  records2.insert(&atype_04a);
  if (!angr_03.setFeature(newid_04, feat_00, value_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  newid_04 = angr_03.createAnnotation(name_00, ancr_34, ancr_04, atype_04b);
  records2.insert(&atype_04b);  
  if (!angr_03.setFeature(newid_04, feat_00, value_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }    
  
  newid_05 = angr_03.createAnnotation(name_00, ancr_04, ancr_05, atype_05);
  records1.insert(&atype_05);  
  if (!angr_03.setFeature(newid_05, feat_00, value_00)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  newid_05 = angr_03.createAnnotation(name_00, ancr_04, ancr_45, atype_05a);
  records2.insert(&atype_05a);
  if (!angr_03.setFeature(newid_05, feat_00, value_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  newid_05 = angr_03.createAnnotation(name_00, ancr_45, ancr_05, atype_05b);
  records2.insert(&atype_05b);  
  if (!angr_03.setFeature(newid_05, feat_00, value_01)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }    
    
  // test the insert method
  //
  trans_02.setDataBaseName(name_00);  
  if (!trans_02.insertRecord(ident_03, angr_03)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  
  DoubleLinkedList<String> records_03;
  DoubleLinkedList<String> records_04;

  Filename tmp_file02;
  Integral::makeTemp(tmp_file02);

  Sof tmp_file_02;
  tmp_file_02.open(tmp_file02, File::WRITE_ONLY, File::TEXT);  

  trans_02.store(tmp_file_02, (long)0);
  
  tmp_file_02.close();

  // open the database
  //
  trans_02.open(tmp_file02);
  
  // test the get methods
  //
  if (!trans_02.getRecord(ident_03, feat_00, value_00, records_03)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  if (!records_03.eq(records1)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }
  
  if (!trans_02.getRecord(ident_03, feat_00, value_01, records_04)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }  
  if (!records_04.eq(records2)) {
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // close the database
  //
  trans_02.close();
  
  // clear allocated memory
  //
  angr_03.clear();
  trans_02.clear();
  
  // reset indentation
  //
  if (level_a > Integral::NONE) {
    Console::decreaseIndention();
  }
  
  //---------------------------------------------------------------------
  //
  // 2. test the i/o methods
  //
  //---------------------------------------------------------------------

  // set indentation
  //
  if (level_a > Integral::NONE) {
    Console::put(L"testing i/o methods...\n");
    Console::increaseIndention(); 
  }

  TranscriptionDatabase trans_03;
  TranscriptionDatabase trans_04;  

  // we need binary and text sof files
  //
  String tmp_filename0;
  Integral::makeTemp(tmp_filename0);
  String tmp_filename1;
  Integral::makeTemp(tmp_filename1);
  
  // open files in write mode
  //
  Sof tmp_file0;
  tmp_file0.open(tmp_filename0, File::WRITE_ONLY, File::TEXT);
  Sof tmp_file1;
  tmp_file1.open(tmp_filename1, File::WRITE_ONLY, File::BINARY);

  trans_00.write(tmp_file0, (long)0);
  trans_00.write(tmp_file1, (long)0);

  // close the files
  //
  tmp_file0.close();
  tmp_file1.close();

  // open the files in read mode
  //
  tmp_file0.open(tmp_filename0);
  tmp_file1.open(tmp_filename1);

  // read the object back
  //  
  trans_03.read(tmp_file0, (long)0);
  
  if (!trans_03.eq(trans_00)) {
    trans_03.debug(L"trans_03");
    trans_00.debug(L"trans_00");
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  trans_04.read(tmp_file1, (long)0);

  if (!trans_04.eq(trans_00)) {
    trans_04.debug(L"trans_04");
    trans_00.debug(L"trans_00");
    return Error::handle(name(), L"diagnose", Error::TEST, __FILE__, __LINE__);
  }

  // close and delete the temporary files
  //
  tmp_file0.close();
  tmp_file1.close();

  // clear allocated memory
  //
  trans_03.clear();
  trans_04.clear();  

  // reset indentation
  //
  if (level_a > Integral::NONE) {
    Console::decreaseIndention();
  }

  //---------------------------------------------------------------------
  //
  // 3. print completion message
  //
  //---------------------------------------------------------------------  

  // reset indentation
  //
  if (level_a > Integral::NONE) {
    Console::decreaseIndention();
  }
  
  if (level_a > Integral::NONE) {
    SysString output(L"diagnostics passed for class ");
    output.concat(name());
    output.concat(L"\n");
    Console::put(output);
  }

  // exit gracefully
  //
  return true;
}




