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

/*! @file xmdsargv.cc
  @brief Command line argument vector parsing classes and methods

  More detailed explanation...
*/

#include<xmlbasics.h>
#include<dom3.h>
#include<xmdsutils.h>
#include<xmdsclasses.h>

extern bool debugFlag;

// ******************************************************************************
// ******************************************************************************
//                              xmdsArgv Public
// ******************************************************************************
// ******************************************************************************

// ******************************************************************************
xmdsArgv::xmdsArgv(
		   const xmdsSimulation *const yourSimulation,
		   const bool& yourVerboseMode) :
  xmdsElement(yourSimulation,yourVerboseMode) {
  if(debugFlag) {
    printf("xmdsArgv::xmdsArgv\n");
  }
};

// ******************************************************************************
xmdsArgv::~xmdsArgv() {
  if(debugFlag) {
    printf("xmdsArgv::~xmdsArgv\n");
  }

  // destroy xmdsArgs, since they are not managed by the xmdsElement class

  for(list<const xmdsArg*>::const_iterator ppxmdsArg = myArgsList.begin(); ppxmdsArg != myArgsList.end(); ppxmdsArg++) {
    delete (*ppxmdsArg);
  }
};

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

  if(verbose()) {
    printf("Processing argv element ...\n");
  }

  list<XMLString> anXMLStringList;

  // ************************************
  // find and process arg elements
  // ************************************

  const NodeList* candidateElements;

  candidateElements = yourElement->getElementsByTagName("arg",0);

  if(candidateElements->length()==0) {
    throw xmdsException(yourElement,"at least one argument expected");
  }

  for(unsigned long i=0; i<candidateElements->length(); i++) {

    const Element* nextElement = dynamic_cast<const Element*>(candidateElements->item(i));

    xmdsElement* newxmdsArgElement = createxmdsArgElement();

    newxmdsArgElement->processElement(nextElement);
  }
};

// ******************************************************************************
void xmdsArgv::processArgs(
			   const list<XMLString>& argNamesList,
			   const unsigned long& space) const {
  if(debugFlag) {
    printf("xmdsArgv::processArgs\n");
  }

  for(list<XMLString>::const_iterator pXMLString = argNamesList.begin(); pXMLString != argNamesList.end(); pXMLString++) {

    const xmdsArg* nextArg;

    if(!getArg(*pXMLString,nextArg)) {
      sprintf(errorMessage(),"Arg '%s' unknown",pXMLString->c_str());
      throw xmdsException(errorMessage());
    }

    for(list<XMLString>::const_iterator pXMLString2 = argNamesList.begin(); pXMLString2 != pXMLString; pXMLString2++) {
      if(*pXMLString == *pXMLString2) {
	sprintf(errorMessage(),"Duplicate arg '%s'",pXMLString->c_str());
	throw xmdsException(errorMessage());
      }
    }

    if(verbose()) {
      printf("adding arg '%s' to accessible args list\n",pXMLString->c_str());
    }
  }
};

// ******************************************************************************
bool xmdsArgv::getArg(
		      const XMLString& argName,
		      const xmdsArg*& theArg) const {
  if(debugFlag) {
    printf("xmdsArgv::getArg\n");
  }

  theArg=0;

  for(list<const xmdsArg*>::const_iterator ppxmdsArg = myArgsList.begin(); ppxmdsArg != myArgsList.end(); ppxmdsArg++) {
    if(*(*ppxmdsArg)->name()==argName) {
      theArg = *ppxmdsArg;
      return 1;
    }
  }
  return 0;
};

// ******************************************************************************
void xmdsArgv::argNames(
			list<XMLString>& argNamesList) const {
  if(debugFlag) {
    printf("xmdsArgv::argNames\n");
  }

  argNamesList.clear();

  for(list<const xmdsArg*>::const_iterator ppxmdsArg = myArgsList.begin(); ppxmdsArg != myArgsList.end(); ppxmdsArg++) {
    argNamesList.push_back(*(*ppxmdsArg)->name());
  }
};

// ******************************************************************************
xmdsArg* xmdsArgv::createxmdsArg() {
  if(debugFlag) {
    printf("xmdsArgv::createxmdsArg\n");
  }

  xmdsArg* newArg = new xmdsArg(this);
  myArgsList.push_back(newArg);
  return newArg;
};

// ******************************************************************************
// ******************************************************************************
//                              xmdsArgv protected
// ******************************************************************************
// ******************************************************************************


// ******************************************************************************
// ******************************************************************************
//                              xmdsArgv private
// ******************************************************************************
// ******************************************************************************

// ******************************************************************************
xmdsArgElement* xmdsArgv::createxmdsArgElement() {
  if(debugFlag) {
    printf("xmdsArgv::createxmdsArgElement\n");
  }

  xmdsArgElement* newArgElement = new xmdsArgElement(simulation(),verbose(),this);
  myArgsList.push_back(newArgElement);
  return newArgElement;
};



syntax highlighted by Code2HTML, v. 0.9.1