/*
 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: xmdsbreakpoint.cc,v 1.7 2004/07/13 05:29:38 paultcochrane Exp $
*/

/*! @file xmdsbreakpoint.cc
  @brief Breakpoint classes and methods

  More detailed explanation...
*/

#include<xmlbasics.h>
#include<dom3.h>
#include<xmdsutils.h>
#include<xmdsclasses.h>
#include<string>
#include<iostream>
#include<fstream>

// ******************************************************************************
// ******************************************************************************
//				xmdsBreakPoint public
// ******************************************************************************
// ******************************************************************************

extern bool debugFlag;

long nxmdsBreakPoints=0;  //!< Number of xmds breakpoitn objects

// ******************************************************************************
xmdsBreakPoint::xmdsBreakPoint(
			       const xmdsSimulation *const yourSimulation,
			       const bool& yourVerboseMode) :
  xmdsField(yourSimulation,yourVerboseMode) {
  if(debugFlag) {
    nxmdsBreakPoints++;
    printf("xmdsBreakPoint::xmdsBreakPoint\n");
    printf("nxmdsBreakPoints=%li\n",nxmdsBreakPoints);
  }
};

// ******************************************************************************
xmdsBreakPoint::~xmdsBreakPoint() {
  if(debugFlag) {
    nxmdsBreakPoints--;
    printf("xmdsBreakPoint::~xmdsBreakPoint\n");
    printf("nxmdsBreakPoints=%li\n",nxmdsBreakPoints);
  }
};

// ******************************************************************************
void xmdsBreakPoint::processElement(
				     const Element *const yourElement) {
  if(debugFlag) {
    printf("xmdsBreakPoint::processElement\n");
  }

  const NodeList* candidateElements;
  list<XMLString> bpFnameList;

  // ************************************
  // find filename element

  candidateElements = yourElement->getElementsByTagName("filename", NOT_DEEP);

  if(candidateElements->length()==0) {
    // no filename element found, so chuck in the defaults
    bpFname = simulation()->parameters()->simulationName.c_str();
    bpFname += "_break.dat";
    bpStatus = "unknown";
    bpFormat = "binary";
  }
  else if(candidateElements->length()>1) {
    throw xmdsException(yourElement,"Multiple <filename> elements defined");
  }
  else {
    // find out what the filename is, and if no string is specified then barf, because
    // the tag has been specified, but no name
    getAssignmentStrings(yourElement, "filename", NOT_REQD, 1, bpFnameList);
    list<XMLString>::const_iterator tmpIter = bpFnameList.begin();
    bpFname = *tmpIter;
    if (bpFname == "") {
      throw xmdsException(yourElement, "If the <filename> tag is used, you must specify a filename");
    }
    
    // find out what the status is, if any specified
    getAttributeStrings(yourElement, "filename", "status", NOT_REQD, bpStatus);
    // the status has three values: unknown, new and old
    // "unknown" : breakpoint input may exist, but not necessarily (default option)
    // "old" : breakpoint input must exist, barf if not found
    // "new" : breakpoint input not used, input file overwritten if exists
    if (debugFlag) {
      printf("After getAttributeStrings(), bpStatus = %s\n",bpStatus.c_str());
    }

    if ( (bpStatus != "") && (bpStatus != "unknown") && (bpStatus != "new") && (bpStatus != "old") ) {
      throw xmdsException(yourElement, "You must specify either unknown, new, or old as the status");
    }
    else if ( (bpStatus != "") && (bpStatus == "unknown") ) {
      if (verbose()) {
	printf("Breakpoint status set to \"unknown\"\n");
      }
    }
    else if ( (bpStatus != "") && (bpStatus == "new") ) {
      if (verbose()) {
	printf("Breakpoint status set to \"new\"\n");
      }
    }
    else if ( (bpStatus != "") && (bpStatus == "old") ) {
      if (verbose()) {
	printf("Breakpoint status set to \"old\"\n");
      }
    }
    else {
      if (verbose()) {
	printf("Setting the default option (i.e. \"unknown\")\n");
      }
      bpStatus = "unknown";  // this is the default option
    }

    // if the status is "old" do a quick check to see if the file is available, 
    // if not, there's not much point in carrying on
    if (bpStatus == "old") {
      ifstream fIn;
      fIn.open(bpFname.c_str());
      if ( fIn.fail() ) {
	fIn.close();
	char message[256];  // this is ugly!!!  
	// Not my fault, I tried more elegant ways to do it, but this finally worked.  When message is set
	// as an XMLString it printf's alright, but when passed to xmdsException the first few characters
	// aren't printed correctly.  Having to assume the message will always be less than 256 chars is 
	// not a good solution, however, this works...  I fear there is a deeper reason as to why this
	// wasn't working properly...
	sprintf(message,"%s %s %s", "The breakpoint file status is \"old\", but", bpFname.c_str(), "doesn't exist.");
	throw xmdsException(yourElement, message);
      }
      else {
	if (verbose()) {
	  printf("Breakpoint status is \"old\" and %s found\n",bpFname.c_str());
	}
	fIn.close();
      }
    }

    // find out what the file format is, if any specified
    getAttributeStrings(yourElement, "filename", "format", NOT_REQD, bpFormat);
    //format="binary|ascii" (binary is default option)
    if ( (bpFormat != "") && (bpFormat != "binary") && (bpFormat != "ascii") ) {
      throw xmdsException(yourElement, "You must specify either binary or ascii as the format");
    }
    else {
      bpFormat = "binary";  // this is the default option
    }
  }

  if (verbose()) {
    printf("The breakpoint options are:\n");
    printf("   filename = %s\n", bpFname.c_str());
    printf("   status   = %s\n", bpStatus.c_str());
    printf("   format   = %s\n", bpFormat.c_str());
  }

};

// ******************************************************************************
// ******************************************************************************
//				xmdsBreakPoint private
// ******************************************************************************
// ******************************************************************************

// ******************************************************************************
void xmdsBreakPoint::writeDefines(
				  FILE *const outfile) const {
  if(debugFlag) {
    printf("xmdsBreakPoint::writeDefines\n");
  }

  if(verbose()) {
    printf("Writing break point defines ...\n");
  }
  /*
  fprintf(outfile,"// ********************************************************\n");
  fprintf(outfile,"// break point defines\n");
  fprintf(outfile,"\n");
  */
  // see xmdsMomentGroup::writeDefines for the way Greg did it.

};

// ******************************************************************************
void xmdsBreakPoint::writeGlobals(
				  FILE *const outfile) const {
  if(debugFlag) {
    printf("xmdsBreakPoint::writeGlobals\n");
  }

  if(verbose()) {
    printf("Writing break point globals ...\n");
  }

  /*
  fprintf(outfile,"// ********************************************************\n");
  fprintf(outfile,"// break point globals\n");
  fprintf(outfile,"\n");
  */

};

// ******************************************************************************
void xmdsBreakPoint::writePrototypes(
				     FILE *const outfile) const {
  if(debugFlag) {
    printf("xmdsBreakPoint::writePrototypes\n");
  }

  if(verbose()) {
    printf("Writing break point prototypes ...\n");
  }

  /*
  fprintf(outfile,"// ********************************************************\n");
  fprintf(outfile,"// break point prototypes\n",myGroupNumber);
  fprintf(outfile,"\n");
  */

};

// ******************************************************************************
void xmdsBreakPoint::writeRoutines(
				   FILE *const outfile) const {
  if(debugFlag) {
    printf("xmdsBreakPoint::writeRoutines\n");
  }

  if(verbose()) {
    printf("Writing break point routines ...\n");
  }

};



syntax highlighted by Code2HTML, v. 0.9.1