// file: $isip/util/speech/isip_segment_concat/isip_segment_concat.cc
// version: $Id: isip_segment_concat.cc 10622 2006-08-24 16:04:42Z dom5 $
//
// isip include files
//
#include "isip_segment_concat.h"

// isip_concat_segment: utility that extractes the segmental features.
//
int main(int argc, const char** argv) {
  
  // declare primary objects
  //
  Sdb sdb;
  CommandLine cmdl(sdb);
  
  // declare local variables used to handle command line options
  //    
  Boolean min_max_flag;
  String min_max_file_type;
  Filename min_max_file;
  Long dim(0);
  String input_file_format;
  String input_file_type;
  DebugLevel debug_level;
  DebugLevel verbosity;
  Filename log_file;
  String output_file_type;
  String output_file_format;
  String ratio;
  Filename transdb_file;
  Filename audiodb_file;
  String trans_level;  
  Boolean duration_flag;
  Boolean normalize_flag;
  Filename symbol_list_file;
    
  //---------------------------------------------------------------------------
  //
  // configure and parse the command line:
  //  add only the options that are not included by default.
  // 
  //---------------------------------------------------------------------------

  // set up messages
  //
  cmdl.setUsage(
#include "usage_message.text"
                );
  cmdl.setHelp(
#include "help_message.text"
               );

  cmdl.setIdent("$Revision: 10622 $",
		"$Name: $",
		"$Date: 2006-08-24 11:04:42 -0500 (Thu, 24 Aug 2006) $");

  // set command line options
  //  
  cmdl.addFlagParam(min_max_flag, OPTION_MIN_MAX_FLAG);
  cmdl.addOptionParam(min_max_file, OPTION_MIN_MAX_FILE,
		      CommandLine::DEF_EMPTY); 
  cmdl.addOptionParam(dim, OPTION_DIM, DEF_DIM);
  cmdl.addOptionParam(input_file_format, OPTION_INPUT_FILE_FORMAT,
		      DEF_FILE_FORMAT);
  cmdl.addOptionParam(input_file_type, OPTION_INPUT_FILE_TYPE, DEF_FILE_TYPE);
  cmdl.addOptionParam(debug_level, CommandLine::DEF_PARAM_DEBUG);
  cmdl.addOptionParam(verbosity, CommandLine::DEF_PARAM_VERBOSITY);
  cmdl.addOptionParam(log_file, CommandLine::DEF_PARAM_LFILE,
		      CommandLine::DEF_LFILE_NAME);
  cmdl.addOptionParam(output_file_type, OPTION_OUTPUT_FILE_TYPE,
		      (String)CommandLine::DEF_EMPTY);
  cmdl.addOptionParam(output_file_format, OPTION_OUTPUT_FILE_FORMAT,
		      DEF_FILE_FORMAT);
  cmdl.addOptionParam(ratio, OPTION_RATIO, (String)CommandLine::DEF_EMPTY);
  cmdl.addOptionParam(transdb_file, OPTION_TRANS_DB, CommandLine::DEF_EMPTY);
  cmdl.addOptionParam(audiodb_file, OPTION_AUDIO_DB, CommandLine::DEF_EMPTY);  
  cmdl.addOptionParam(trans_level, OPTION_TRANS_LEVEL,
		      (String)CommandLine::DEF_EMPTY);
  cmdl.addFlagParam(duration_flag, OPTION_DURATION_FLAG);
  cmdl.addFlagParam(normalize_flag, OPTION_NORMALIZE_FLAG);
  cmdl.addOptionParam(symbol_list_file, OPTION_SYMBOL_LIST,
		      CommandLine::DEF_EMPTY);
  
  // parse the command line
  //
  if (!cmdl.parse(argc, argv)) {
    cmdl.printUsage();
  }
  
  // open the log file
  //
  if (log_file.ne(CommandLine::DEF_LFILE_NAME)) {
    Console::open(log_file);
    Console::setLineWrap(File::NO_WRAP);
  }

  // echo the command line
  //
  if (verbosity > Integral::BRIEF) {
    cmdl.printCommandLine();
    cmdl.printVersion();
  }

  //-------------------------------------------------------------------------
  //
  // branch on various cases
  //
  //-------------------------------------------------------------------------
  
  // case 1: if min_max flag is set, compute the min and max in each
  // dimension
  //
  if (min_max_flag) {
    
    //-------------------------------------------------------------------------
    //
    // verification of the input parameters
    //
    //-------------------------------------------------------------------------

    if (min_max_file.eq(CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    }
    if (audiodb_file.eq(CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    }
    if (input_file_format.eq(FILE_FORMAT_RAW) && ((long)dim <= (long)0)) {
      cmdl.printUsage();
    };
    
    //-------------------------------------------------------------------------
    //
    // set the various options
    //
    //-------------------------------------------------------------------------

    // set the file format
    //
    FeatureFile::FILE_FORMAT in_f_format = FeatureFile::SOF;
    if (input_file_format.eq(FILE_FORMAT_RAW)) {
      in_f_format = FeatureFile::RAW;
    }
  
    // set the file type
    //
    FeatureFile::FILE_TYPE in_f_type = FeatureFile::TEXT;
    if (input_file_type.eq(FILE_TYPE_BINARY)) {
      in_f_type = FeatureFile::BINARY;
    }
    FeatureFile::FILE_TYPE o_f_type = FeatureFile::TEXT;
    if (output_file_type.eq(FILE_TYPE_BINARY)) {
      o_f_type = FeatureFile::BINARY;
    }
    
    // local variables
    //
    Sdb symbol_list_sdb;
    SegmentConcat sc;

    // set the parameters of the sc object
    //
    sc.setDebug(debug_level);
    sc.setVerbosity(verbosity);
    sc.setDimension(dim);
    sc.setAlgorithm(SegmentConcat::MIN_MAX);
    sc.setInputType(in_f_type);
    sc.setInputFormat(in_f_format);
    sc.setOutputType(o_f_type);
    sc.setMinMaxFile(min_max_file);
    sc.setAudioDatabaseFile(audiodb_file);

    //-------------------------------------------------------------------------
    //
    // process the data
    //
    //-------------------------------------------------------------------------
    
    sc.compute(sdb, symbol_list_sdb);
  }
  
  // case 2: compute the segmental features on file basis
  //
  else if (symbol_list_file.length() == (long)0) {
    
    //-------------------------------------------------------------------------
    //
    // verification of the input parameters
    //
    //-------------------------------------------------------------------------

    if (input_file_format.eq(FILE_FORMAT_RAW) && ((long)dim <= (long)0)) {
      cmdl.printUsage();
    };
    if (ratio.eq((String)CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    };
    if (audiodb_file.eq(CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    }
    if (transdb_file.eq(CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    };
    if (trans_level.eq((String)CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    };
    if (normalize_flag) {
      
      // verification incase the user specifies the normalize flag,
      // check for min_max_file
      //
      if (min_max_file.eq(CommandLine::DEF_EMPTY)) {
	cmdl.printUsage();
      }
    }

    //-------------------------------------------------------------------------
    //
    // set the various options
    //
    //-------------------------------------------------------------------------

    // set the file format
    //
    FeatureFile::FILE_FORMAT in_f_format = FeatureFile::SOF;
    if (input_file_format.eq(FILE_FORMAT_RAW)) {
      in_f_format = FeatureFile::RAW;
    }
    FeatureFile::FILE_FORMAT o_f_format = FeatureFile::SOF;
    if (output_file_format.eq(FILE_FORMAT_RAW)) {
      o_f_format = FeatureFile::RAW;
    }
  
    // set the file type
    //
    FeatureFile::FILE_TYPE in_f_type = FeatureFile::TEXT;
    if (input_file_type.eq(FILE_TYPE_BINARY)) {
      in_f_type = FeatureFile::BINARY;
    }
    FeatureFile::FILE_TYPE o_f_type = FeatureFile::TEXT;
    if (output_file_type.eq(FILE_TYPE_BINARY)) {
      o_f_type = FeatureFile::BINARY;
    }

    // local variables
    //
    Sdb symbol_list_sdb;
    SegmentConcat sc;

    // set the parameters of the sc object
    //
    sc.setDebug(debug_level);
    sc.setVerbosity(verbosity);
    sc.setDimension(dim);
    sc.setAlgorithm(SegmentConcat::SEG_CONCAT);
    if (normalize_flag) {
      sc.setImplementation(SegmentConcat::NORMALIZE);
    }
    sc.setInputType(in_f_type);
    sc.setInputFormat(in_f_format);
    sc.setOutputType(o_f_type);
    sc.setOutputFormat(o_f_format);
    sc.setDurationFlag(duration_flag);
    sc.setMinMaxFile(min_max_file);    
    sc.setAudioDatabaseFile(audiodb_file);
    sc.setTransDatabaseFile(transdb_file);
    sc.setLevel(trans_level);

    // parse the ratio on the based of enlimiter ":"
    // ratio1:ratio2:ratio3:...
    //
    long pos = (long)0;
    long num_ratio = (long)0;
    VectorLong seg_ratio;
    String temp_ratio;    
    while (ratio.tokenize(temp_ratio, pos, L":")) {
      seg_ratio.setLength(++num_ratio);
      temp_ratio.trim();
      seg_ratio(num_ratio-(long)1).assign(temp_ratio);    
    }
    sc.setRatio(seg_ratio);
    
    //-------------------------------------------------------------------------
    //
    // get the value of the options that are defined as command line
    // class options.
    //
    //-------------------------------------------------------------------------
    
    String cmdl_value;
    
    if (cmdl.getValue(cmdl_value, CommandLine::DEF_PARAM_DIRECTORY)) {
      sc.setOutputDirectory(cmdl_value);
    }    
    if (cmdl.getValue(cmdl_value, CommandLine::DEF_PARAM_EXTENSION)) {
      sc.setOutputExtension(cmdl_value);
    }    
    if (cmdl.getValue(cmdl_value, CommandLine::DEF_PARAM_PRESERVE)) {
      long preserve;
      cmdl_value.get(preserve);
      sc.setOutputPreserve(preserve);
    }  
    if (cmdl.getValue(cmdl_value, CommandLine::DEF_PARAM_SUFFIX)) {
      sc.setOutputSuffix(cmdl_value);
    }
    
    //-------------------------------------------------------------------------
    //
    // process the data
    //
    //-------------------------------------------------------------------------
    
    sc.compute(sdb, symbol_list_sdb);
  }
  
  // case 3: compute the segmental features on symbol basis
  //
  else if (symbol_list_file.length() != (long)0) {    
    
    //-------------------------------------------------------------------------
    //
    // verification of the input parameters
    //
    //-------------------------------------------------------------------------
    
    if (input_file_format.eq(FILE_FORMAT_RAW) && ((long)dim <= (long)0)) {
      cmdl.printUsage();
    };
    if (ratio.eq((String)CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    };
    if (audiodb_file.eq(CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    }
    if (transdb_file.eq(CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    };
    if (trans_level.eq((String)CommandLine::DEF_EMPTY)) {
      cmdl.printUsage();
    };
    if (normalize_flag) {
      
      // verification incase the user specifies the normalize flag,
      // check for min_max_file
      //
      if (min_max_file.eq(CommandLine::DEF_EMPTY)) {
	cmdl.printUsage();
      }
    }
    
    //-------------------------------------------------------------------------
    //
    // set the various options
    //
    //-------------------------------------------------------------------------

    // set the file format
    //
    FeatureFile::FILE_FORMAT in_f_format = FeatureFile::SOF;
    if (input_file_format.eq(FILE_FORMAT_RAW)) {
      in_f_format = FeatureFile::RAW;
    }
    FeatureFile::FILE_FORMAT o_f_format = FeatureFile::SOF;
    if (output_file_format.eq(FILE_FORMAT_RAW)) {
      o_f_format = FeatureFile::RAW;
    }
  
    // set the file type
    //
    FeatureFile::FILE_TYPE in_f_type = FeatureFile::TEXT;
    if (input_file_type.eq(FILE_TYPE_BINARY)) {
      in_f_type = FeatureFile::BINARY;
    }
    FeatureFile::FILE_TYPE o_f_type = FeatureFile::TEXT;
    if (output_file_type.eq(FILE_TYPE_BINARY)) {
      o_f_type = FeatureFile::BINARY;
    }
    
    // local variables
    //
    Sdb symbol_list_sdb;
    Sof symbol_list_sof;    
    SegmentConcat sc;

    // set the parameters of the sc object
    //
    sc.setDebug(debug_level);
    sc.setVerbosity(verbosity);
    sc.setDimension(dim);
    sc.setAlgorithm(SegmentConcat::SEG_CONCAT_SYMBOL);
    if (normalize_flag) {
      sc.setImplementation(SegmentConcat::NORMALIZE);
    }
    sc.setInputType(in_f_type);
    sc.setInputFormat(in_f_format);
    sc.setOutputType(o_f_type);
    sc.setOutputFormat(o_f_format);
    sc.setDurationFlag(duration_flag);
    sc.setMinMaxFile(min_max_file);
    sc.setAudioDatabaseFile(audiodb_file);
    sc.setTransDatabaseFile(transdb_file);
    sc.setLevel(trans_level);
    
    // parse the ratio on the based of enlimiter ":"
    // ratio1:ratio2:ratio3:...
    //
    long pos = (long)0;
    long num_ratio = (long)0;
    VectorLong seg_ratio;
    String temp_ratio;    
    while (ratio.tokenize(temp_ratio, pos, L":")) {
      seg_ratio.setLength(++num_ratio);
      temp_ratio.trim();
      seg_ratio(num_ratio-(long)1).assign(temp_ratio);    
    }
    sc.setRatio(seg_ratio);
    
    // read the symbol list as sdb
    //    
    symbol_list_sof.open(symbol_list_file, File::READ_ONLY);
    symbol_list_sdb.read(symbol_list_sof, (long)0);
    symbol_list_sof.close();
    
    //-------------------------------------------------------------------------
    //
    // get the value of the options that are defined as command line
    // class options.
    //
    //-------------------------------------------------------------------------
    
    String cmdl_value;
    
    if (cmdl.getValue(cmdl_value, CommandLine::DEF_PARAM_DIRECTORY)) {
      sc.setOutputDirectory(cmdl_value);
    }    
    if (cmdl.getValue(cmdl_value, CommandLine::DEF_PARAM_EXTENSION)) {
      sc.setOutputExtension(cmdl_value);
    }    
    if (cmdl.getValue(cmdl_value, CommandLine::DEF_PARAM_PRESERVE)) {
      long preserve;
      cmdl_value.get(preserve);
      sc.setOutputPreserve(preserve);
    }  
    if (cmdl.getValue(cmdl_value, CommandLine::DEF_PARAM_SUFFIX)) {
      sc.setOutputSuffix(cmdl_value);
    }
    
    //-------------------------------------------------------------------------
    //
    // process the data
    //
    //-------------------------------------------------------------------------
    
    sc.compute(sdb, symbol_list_sdb);    
  }  
  
  // close the log file
  //
  if (log_file.ne(CommandLine::DEF_LFILE_NAME)) {
    Console::close();
  }
  
  // exit gracefully
  //
  return Integral::exit();
}
