//-----------------------------------------------------------------
// main.C.sample 
// This file is an example for a main.C Demeter main file.
// It provides sample code fragments showing how to use some of the 
// Demeter runtime libraries. To have a quick test of your environment 
// rename this file to main.C and compile the environment. 
//-----------------------------------------------------------------

#include "cdabs.h"


void out_of_store()
{
  cerr << "cdabs: operator new failed, out of store\n";
  exit( 1 );
}

#ifndef __GNUC__
extern PF set_new_handler( PF );
#else
extern "C"  PF set_new_handler( PF );
#endif

/*
 * GEN_DIR is a global variable containing the path of the generation
 * environment. This path is used to find the cd-print and cd-parse
 * class dictionaries.
 * Do NOT delete the following statement.
 */

char* GEN_DIR = getenv( "GEN_DIR" );

int main( int argc, char* argv[], char* envp[] )
{
  // set new handler to catch out of memory exception
  set_new_handler( &out_of_store );

  //----------------------------------------
  // Parsing an object 
  //----------------------------------------
  // specify file to parse in 
  const int MAXPATH = 256;
  char Dem_input[MAXPATH];

  // Input file is first argument
  if( argc >= 2 )
     strcpy( Dem_input, argv[1] );
  else {
     strcpy( Dem_input, "demeter-input" );  // default input 
  }

  // parse it in 
  cout << "Parsing in object in: " << Dem_input << ". \n";
  Demeter_in* iDemeter_in = new Demeter_in();
  if ( ( Demeter_in* ) iDemeter_in -> g_parse( Dem_input ) == NULL )
  {
     cerr << "Parser error." << endl;
     exit(1);
  }
  cout << endl;

  //----------------------------------------
  // Drawing an object 
  //----------------------------------------
  cout << "Drawing the parsed object:\n";
  iDemeter_in -> g_draw();
  cout << "\nEnd of drawing.\n" << endl;

  //----------------------------------------
  // Copying an object 
  //----------------------------------------
  cout << "Copying the object.\n";
  Demeter_in* nDemeter_in = ( Demeter_in* ) iDemeter_in -> g_copy();
  cout << endl;

  //----------------------------------------
  // Displaying the copied object as a tree
  //----------------------------------------
  cout << "Displaying the copied object as a tree:\n";
  nDemeter_in -> g_displayAsTree();
  cout << "\nEnd of display.\n" << endl;

  //----------------------------------------
  // Comparing two objects 
  //----------------------------------------
  cout << "Comparing the two objects:\n";
  if ( iDemeter_in -> g_equal( nDemeter_in ) == 1 )
     cout << "copied and original object are equal\n" << endl;
  else
     cout << "copied and original object are NOT equal\n" << endl;

  //----------------------------------------
  // Printing an object 
  //----------------------------------------
  cout << "Pretty printing the parsed object:\n";
  char* tmp_filename = "notmod/tmp/demeter-output";
  ofstream outFile( tmp_filename );
  if ( !outFile ) {
    cerr << "cdabs error: unable to open " << tmp_filename
         << " for output" << endl;
    exit( 1 );
  }
  cout << iDemeter_in << endl;
  iDemeter_in -> g_print( outFile );
  outFile.close();
  cout << "\nEnd of printing.\n" << endl;

  //----------------------------------------
  // Selftest of generic parser/printer 
  //----------------------------------------
  cout << "Selftest of generic parser/printer:\n";
  Demeter_in* iDemeter_in_printed = new Demeter_in();
  iDemeter_in_printed = (Demeter_in*)iDemeter_in_printed->g_parse( tmp_filename );
  if( iDemeter_in->g_equal( iDemeter_in_printed ) == 1 ) {
    cout << "g_parse and g_parse( g_print( g_parse ) ) are equal.\n"
         << "Selftest passed.\n";
  } else {
    cout << "g_parse and g_parse( g_print( g_parse ) ) are NOT equal.\n"
         << "Selftest failed.\n";
  }
  cout << endl;

  //----------------------------------------
  // Your own code follows after this 
  //----------------------------------------

  cout << "\n*** FINISHED ***" << endl;

  return ( 0 );
}
