/*
  Copyright (C) 2000-2004

  Code contributed by Greg Collecutt, Joseph Hope and Paul Cochrane

  This file is part of xmds.
 
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

/*
  $Id: xsil2graphics.cc,v 1.17 2004/07/13 05:29:38 paultcochrane Exp $
*/

/*! @file xsil2graphics.cc
  @brief the xsil2graphics utility program classes and methods

  More detailed explanation...
*/

// This program converts xmds field data objects in XSIL
// format to various other input formats

#include<config.h>
#include<xmlbasics.h>
#include<dom3.h>
#include<kissdom.h>
#include<xmlparser.h>
#include<xmdsutils.h>
#include<xsilfield.h>
#include<getopt_xmds.h>

// **********************************************************************

//! Display the usage of xsil2graphics
void display_usage() {
  printf("\n");
  printf("xsil2graphics utility supplied with xmds version ");
  printf(VERSION);
  printf(" release ");
  printf(RELEASE);
  printf("\n"
	 "\n"
	 "Usage: xsil2graphics [options] infile\n"
	 "Options:\n"
	 "  infile:       required, the input xsil file\n"
	 "  -h/--help:    optional, display this information\n"
	 "  -m/--matlab:  optional, produce matlab output (default)\n"
	 "  -s/--scilab:  optional, produce scilab output\n"
	 "  -o/--outfile: optional, alternate output file name\n"
	 "  -v/--verbose: optional, verbose output\n"
	 "\n"
	 "For further help, please see http://www.xmds.org\n");
}

bool debugFlag = 0;
bool xmlDebugFlag = 0;

// **********************************************************************

//! The main routine of xsil2graphics
/*!
  @param argc The number of arguments to the program
  @param argv The "vector" of arguments to the program
*/
int main(
	 int argc,
	 char **argv) {

  bool verbose=0;
  XMLString inFileName;
  XMLString outFileName="";
  XMLString outFileNameBase;
  outputFormatEnum outFormat = FORMAT_NONE;

  // process arguments
  int resp;
  while (1) {
    static struct option long_options[] = 
      {
	{"help", no_argument, 0, 'h'},
	{"verbose", no_argument, 0, 'v'},
	{"matlab", no_argument, 0, 'm'},
	{"scilab", no_argument, 0, 's'},
	{"outfile", required_argument, 0, 'o'},
	{"debug", no_argument, 0, 'd'},
	{"xmldebug", no_argument, 0, 'x'},
	{0,0,0,0}
      };
    int option_index = 0;
    resp = getopt_xmds_long(argc, argv, "hvdxmso:", long_options, &option_index);
    if (resp == -1) {
      break;
    }
    switch (resp) {
    case 'h':
      display_usage();
      return 0;
    case 'v':
      verbose = 1;
      break;
    case 'd':
      debugFlag = 1;
      break;
    case 'x':
      xmlDebugFlag = 1;
    case 'm':
      outFormat = FORMAT_MATLAB;
      break;
    case 's':
      outFormat = FORMAT_SCILAB;
      break;
    case 'o':
      outFileName = optarg;
      break;
    default:
      display_usage();
      return 0;
    }
  }

  // process non-option command line elements
  if (optind_xmds < argc) {
    int fnameCount = 0;
    while (optind_xmds < argc) {
      fnameCount++;
      if (fnameCount > 1) {
	// error, input file name already exists
	printf("Error: multiple input files not allowed\n\n");
	display_usage();
	return 0;
      }
      inFileName = argv[optind_xmds++];
    }
  }

  if(inFileName.length()==0) {
    // error, no input file was specified
    printf("Error: no input file specified.\nExiting.\n");
    return 1;
  }

  // set matlab to be the default output
  if(outFormat==FORMAT_NONE) {
    printf("Output file format defaulting to matlab.\n");
    outFormat=FORMAT_MATLAB;
  }

  // create the XMLParser
  XMLParser myXMLParser;

  // now load xmds script and results into the DOMImplementation

  Document* theDocument=0;

  if(verbose) {
    printf("Parsing file '%s' ...\n",inFileName.c_str());
  }

  try {
    theDocument=myXMLParser.parseFromFile(inFileName.c_str());
  }
  catch(XMLParserException XMLRoutinesErr) {
    printf("Could not load Document\n");
    printf("due to the following XMLParserException:\n");
    printf("%s",XMLRoutinesErr.getError());
    printf("Exiting.\n");
    return 1;
  }

  if(outFileName.length()==0) {
    // Create default output file name
    unsigned long lastdot=0;
    for(unsigned long i=0; i<inFileName.length(); i++) {
      if(inFileName.data(i)=='.') {
	lastdot=i;
      }
    }

    if(lastdot>0) {
      inFileName.subString(outFileName,0,lastdot);
    }
    else {
      outFileName=inFileName;
    }

    // keep the base file name for use in xsilfield
    outFileNameBase = outFileName;

    if(outFormat==FORMAT_MATLAB) {
      printf("Generating output for matlab\n");
      outFileName += ".m";
    }
    else if(outFormat==FORMAT_SCILAB) {
      printf("Generating output for scilab\n");
      outFileName += ".sci";
    }
    else {
      printf("Error: unspecified output format\n");
      printf("I got %s as the format\n", outFileName.c_str());
    }

    printf("Output file name defaulting to '%s'\n",outFileName.c_str());
  }
  else {
    // display what the output filename is
    printf("Output file name set to '%s'\n", outFileName.c_str());
  }


  // ************************************
  // find and process xsil children
  // ************************************

  const NodeList* candidateElements;
  list<const Node*> xsilNodeList;

  if(*theDocument->documentElement()->nodeName() == "simulation") {

    candidateElements = theDocument->documentElement()->getElementsByTagName("XSIL",0);

    if(candidateElements->length()<1) {
      printf("Error: no <xsil> elements from within <simulation> element.\nExiting.\n");
      return 1;
    }

    for(unsigned long i=0; i<candidateElements->length(); i++) {
      xsilNodeList.push_back(candidateElements->item(i));
    }
  }
  else if(*theDocument->documentElement()->nodeName() == "XSIL") {
    xsilNodeList.push_back(theDocument->documentElement());
  }
  else {
    printf("Error: expecting root element to be <XSIL> or <simulation>.\nExiting.\n");
    return 1;
  }

  list<const Node*>::const_iterator ppNode = xsilNodeList.begin();

  FILE* outfile = fopen(outFileName.c_str(),"w");

  if(outfile==0) {
    printf("Error: Could not open file '%s' for writing.\nExiting.\n",outFileName.c_str());
    return 1;
  }

  for(unsigned long i=0; i<xsilNodeList.size(); i++) {

    const Element* nextElement = dynamic_cast<const Element*> (*ppNode);

    printf("Proccessing xsil data container %li ...\n",i+1);

    xsilField myxsilField;

    try {
      myxsilField.processElement(nextElement);
    }
    catch(xmdsException xmdsErr) {
      printf("Could not load data container\n");
      printf("due to the following xsilException:\n");
      printf("%s",xmdsErr.getError());
      printf("Exiting.\n");
      fclose(outfile);
      return 1;
    }

    printf("Writing data container %li to file ...\n",i+1);

    myxsilField.writeAsFormat(outfile,outFormat,i+1,outFileNameBase.c_str());

    ppNode++;
  }

  fclose(outfile);

  return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1