#include <algorithm>
#include "XML_Parts.h"

//----< construct XML_Parts instance >---------------------------

XML_Parts::XML_Parts(Toker* pTokr) : pToker(pTokr), Verbose(false)
{
}
//----< destructor >-------------------------------------------

XML_Parts::~XML_Parts()
{
}
//----< is this a terminating token? >-------------------------

bool XML_Parts::isTerminator(string tok)
{
  if(tok.length() == 0)
    return false;
  if(tok == ">")
    return true;
  return false;
}
//
//----< collect an XmlElementParts sequence >------------------

bool XML_Parts::get()
{
  toks.clear();
  string tok;
  do
  {
    if(pToker->isFileEnd())
    {
      if(length() > 0)
        return true;
      return false;
    }
    tok = pToker->getTok();
    if(Verbose)
    {
      if(tok != "\n")
        cout << "\n--tok=" << tok << endl;
      else
        cout << "\n--tok=newline\n";
    }
    if(toks.size() > 0 && tok == "<")
    {
      pToker->putback('<');
      break;
    }
    if(tok != "\n")
      toks.push_back(tok);
  } while(!isTerminator(tok));
  return true;
}
//----< index operator >---------------------------------------

string& XML_Parts::operator[](int n)
{
  if(n < 0 || toks.size() <= (size_t)n)
    throw runtime_error("HydroPlusConfig.xml index out of range. Check for error in within or between <> and </> keys. Ending simulation.\n");
  return toks[n];
}
//----< collect semi-expression as space-seperated string >----

string XML_Parts::show()
{
  if(toks.size() == 0)
    return "";
  string temp(" ");
  for(size_t i=0; i<toks.size(); ++i)
    if(toks[i] != "\n")
      temp.append("").append(toks[i]);
  return temp;
}
//
//----< is tok found in XmlElementParts? >---------------------

int XML_Parts::find_token(const string& tok)
{
  for(int i=0; i<length(); ++i)
    if(tok == toks[i])
      return i;
  return length();
}
//----< remove tok if found in semi-expression >---------------

bool XML_Parts::remove(const string& tok)
{
  vector<string>::iterator it;
  it = find(toks.begin(),toks.end(),tok);
  if(it != toks.end())
  {
    toks.erase(it);
    return true;
  }
  return false;
}
//----< remove leading newlines >------------------------------

void XML_Parts::trimFront()
{
  while(toks.size() > 0 && toks[0] == "\n")
    remove("\n");
}
//----< make tokens lowercase >--------------------------------

void XML_Parts::toLower()
{
  for(int i=0; i<length(); ++i)
  {
    for(size_t j=0; j<(*this)[i].length(); ++j)
    {
      (*this)[i][j] = tolower((*this)[i][j]);
    }
  }
}
