// file: gc_read_0.cc
// 

// isip include files
//
#include "grammar_compiler.h"
#include "grammar_compiler_constants.h"

// system include files
//
#include <string.h>


// method: read_grammar_cc
//  
// arguments:
//  char_1** symbols: (output) the array of symbols
//  int_4& size: (output) number of symbols in array
//  char_1* file: (input) the file name
//  char_1*& buffer: (input/output) the buffer that the symbols point to
//  int_4& buffer_size: (input/output) the size of the buffer
//
// return: a logical_1 indicating status
//
// this method reads the grammar from file and parses it into an array
// of symbols
//
logical_1 read_grammar_cc(char_1** symbols_a, int_4& size_a,
			  char_1* file_a, char_1*& buffer_a,
			  int_4& buffer_size_a) {
  
  // open the input file
  //
  Param_file gram_file;
  gram_file.init_cc(file_a);

  
  // get the main grammar string
  //
  if (gram_file.get_cc((char_1*)buffer_a, (char_1*)ISIP_UTTERANCE) ==
      ISIP_FALSE) {
    
    // if the main string is not found
    //
    fprintf(stdout, "\nSorry! The root node for network not found:\n Please define the variable '$isip_utterance' in the grammar network file\n");
    exit(ISIP_PROTO_ERROR);
  }

  int_4 size = 0;
  int_4 len = (int_4)0;

  // substitute the variables inside the grammar
  //
  while ((gram_file.token_count_cc(size, VARIABLE_CHAR, buffer_a)
	  == ISIP_TRUE) && (size > 0)) {

    
    // allocate a temporary buffer
    //
    char_1* tmpbuf = new char_1[buffer_size_a];
  
    // copy this buffer
    //
    len = strlen((char*)buffer_a) + 1;
    strcpy((char*)tmpbuf, (char*)buffer_a);
    memset(buffer_a, 0, buffer_size_a);
   
    // adjust the space between symbols inside the tmpbuf
    //
    gram_file.symbol_pad_cc(tmpbuf, len, (char_1*)SYMBOLS);
    
    // parse the tmpbuf into an array of symbols
    //
    gram_file.tokenize_cc(symbols_a, size, tmpbuf, (char_1)' ');

    int_4 needed_size = 0;
    for (int_4 i = 0; i < size; i++) {
      
      // make sure we don't need to increase the buffer size
      //
      if ((needed_size + GC_GRAM_MAX_SYMBOL_SIZE *
	   GC_COMMON_SYMBOL_LEN + 1) > buffer_size_a) {

	// create some scratch space and copy the old string over, preserving
	// it
	//
	char_1* tmp_copy = new char_1[strlen((char*)buffer_a) + 1];
	strcpy((char*)tmp_copy, (char*)buffer_a);

	// delete the old buffer and resize it
	//
	delete [] buffer_a;
	buffer_a = new char_1[needed_size + GC_GRAM_MAX_SYMBOL_SIZE *
			     GC_COMMON_SYMBOL_LEN + 1];
	buffer_size_a = needed_size + GC_GRAM_MAX_SYMBOL_SIZE *
	  GC_COMMON_SYMBOL_LEN + 1;

	// copy the contents back
	//
	strcpy((char*)buffer_a, (char*)tmp_copy);

	// delete the temporary copy
	//
	delete [] tmp_copy;
      }
	
      if (symbols_a[i][0] == VARIABLE_CHAR) {

	// group the variable value
	//
	strcat((char*)buffer_a, "(");
	
	// append to the end of the buffer
	//
	if (gram_file.get_cc(&buffer_a[strlen((char*)buffer_a)],
			     symbols_a[i]) == ISIP_FALSE) {
	  fprintf(stdout, "variable %s not found\n", symbols_a[i]);
	  return ISIP_FALSE;
	}
	strcat((char*)buffer_a, ") ");
	needed_size = strlen((char*)buffer_a) + 1;
      }
      else {
	strcat((char*)buffer_a, (char*)symbols_a[i]);
	strcat((char*)buffer_a, " ");
	needed_size += strlen((char*)buffer_a) + 1;
      } //end of else
    } //end of for i<size
    
    // free memory
    //
    delete [] tmpbuf;
  
    // eat the last space
    //
    buffer_a[strlen((char*)buffer_a) - 1] = (char_1)NULL;
  } //end of while loop   .... && (size > 0)
  
  // adjust the space between symbols inside the buffer
  //
  gram_file.symbol_pad_cc(buffer_a, ISIP_MAX_STRING_LENGTH,
			  (char_1*)SYMBOLS);
  gram_file.token_count_cc(size_a, ' ', buffer_a);
  
  // parse the buffer into an array of symbols
  //
  gram_file.tokenize_cc(symbols_a, size_a, buffer_a, (char_1)' ');
  
  // remove some redundant braces
  //
  gram_file.compact_tokens_cc(symbols_a, size_a, (char_1*)SYMBOLS);
  
  for (int_4 i = size_a; i < GC_GRAM_MAX_SYMBOL_SIZE; i++) {
    symbols_a[i] = (char_1*)NULL;
  }
  
  // preprocessing the grammar, distribute the probability value
  // from sub-expression to terminals
  
  preprocessing_grammar_cc(symbols_a, size_a);

  
  // exit gracefully
  //
  return ISIP_TRUE;
}
