#include "Rules.h"

//contains all of the functions that require loading.

//Attempt to load an attack path.
bool Rules::addAttackPath(const string & patternName)
{
  //see if the hash already has this pattern. Return true if it does, but do nothing else.
  map <string, AttackPath> :: iterator occurenceOfPattern;

  occurenceOfPattern=playerAttackPaths.find(patternName);
  if (occurenceOfPattern!=playerAttackPaths.end())
    return true;

  //otherwise populate a temporary data value
  AttackPath tempAP;

  //load attack path data.
  int x = 0, y = 0;

  session->getInt("Battle Clickzone X", x);
  session->getInt("Battle Clickzone Y", y);

  tempAP.setBounds(320,250);
  tempAP.setAxis(x,y);

  xmlDocPtr doc;
  xmlXPathContextPtr xpathCtx;

  if (!prepareXMLFile (doc, xpathCtx, "resources/game/AttackPatternManifest.xml", ""))
    return false;

  string searchString="/AttackPatternManifest/AttackPattern[@ID='"+ patternName + "']";
  xmlChar *keyword;
  int intToLoad;
  ostringstream stringStream(searchString);

  intToLoad=0;
  keyword = getFirstElementUsingXPath (doc, xpathCtx, searchString, "/InitialRadius", "");
  if (keyword!=NULL)
    {
      intToLoad=int(xmlXPathCastStringToNumber(keyword));
      xmlFree(keyword);
    }
  if (intToLoad <= 0)
    intToLoad=15;
  tempAP.setInitialRadius(intToLoad);

  intToLoad=0;
  keyword = getFirstElementUsingXPath (doc, xpathCtx, searchString, "/TimePerSegment", "");
  if (keyword!=NULL)
    {
      intToLoad=int(xmlXPathCastStringToNumber(keyword));
      xmlFree(keyword);
    }
  if (intToLoad <= 0)
    intToLoad=5000;
  tempAP.setTimePerSegment(intToLoad);

  bool done=false;
  int pointCounter=0;
  int xCoord, yCoord;

  while (!done)
    {
      pointCounter++;
      stringStream.str("");
      stringStream<<"/Point["<<pointCounter<<"]";
      if (!xPathExists(doc, xpathCtx, searchString, stringStream.str(), ""))
        {
          done=true;
          continue;
        }
      xCoord=0;
      keyword = getFirstElementUsingXPath (doc, xpathCtx, searchString, stringStream.str(),"/X");
      if (keyword!=NULL)
        {
          xCoord=int(xmlXPathCastStringToNumber(keyword));
          xmlFree(keyword);
        }
      yCoord=0;
      keyword = getFirstElementUsingXPath (doc, xpathCtx, searchString, stringStream.str(),"/Y");
      if (keyword!=NULL)
        {
          yCoord=int(xmlXPathCastStringToNumber(keyword));
              xmlFree(keyword);
        }
      tempAP.addPoint(xCoord, yCoord);
    }
  //one you've loaded everything,
  tempAP.validateAndInitialize();

  //closing xml stuff.
  xmlXPathFreeContext(xpathCtx);
  xmlFreeDoc (doc);

  //Now you push it.
  playerAttackPaths[patternName]=tempAP;
  return true;
}

//make a DefensePoint and add it to playerDefenseArray.
//Slightly randomize its parameters
//x formula gets a scroll after 60 seconds formula.
void Rules::prepareAndAddDefensePoint(const string & name)
{
  xmlDocPtr doc;
  xmlXPathContextPtr xpathCtx;

  if (!prepareXMLFile (doc, xpathCtx, "resources/game/DefensePatternManifest.xml", ""))
    return;

  xmlChar *keyword;
  if (!xPathExists(doc, xpathCtx, "/DefensePatternManifest/DefensePattern[@ID='", name, "']"))
    writeToErrorLog("Unable to find entry for DefensePattern "+name+", using defaults.",0);

  string searchString="/DefensePatternManifest/DefensePattern[@ID='"+ name + "']";

  DefensePoint dp;
  PositionFormula pf;
  Param positionFormulaSettings, hash;
  string dimensionName;
  int intToLoad;
  bool done, done2=false;
  ostringstream stringStream(searchString);
  int pointCounter=0, formulaCounter=0;
  int loopCounter=0;

  intToLoad=0;
  keyword = getFirstElementUsingXPath (doc, xpathCtx, searchString, "/InitialRadius", "");
  if (keyword!=NULL)
    {
      intToLoad=int(xmlXPathCastStringToNumber(keyword));
      xmlFree(keyword);
    }
  if (intToLoad <= 0)
    intToLoad=10;
  playerDefenseArray.setInitialRadius(intToLoad);

  while (!done2)
    {
      pointCounter++;
      dp.clear();

      //prepare search string 2
      stringStream.str("");
      stringStream<<"/Point["<<pointCounter<<"]";
      //if there is no Point by that index, abort.
      if (!xPathExists(doc, xpathCtx, searchString, stringStream.str(), ""))
        {
          done2=true;
          continue;
        }

      //load HP
      intToLoad=0;
      keyword = getFirstElementUsingXPath (doc, xpathCtx, searchString, stringStream.str(),"/HP");
      if (keyword!=NULL)
        {
          intToLoad=int(xmlXPathCastStringToNumber(keyword));
          xmlFree(keyword);
        }
      if (intToLoad < 1)
        intToLoad=1;
      dp.setHitPoints(intToLoad);

      //load all formulae
      //It's the same code so we'll use a counter.
      done=false; formulaCounter=0; loopCounter=0;
      while (loopCounter < 2)
        {
          positionFormulaSettings.clearParamState();
          formulaCounter++;

          stringStream.str("");
          if (loopCounter==0)
            stringStream<<"/Point["<<pointCounter<<"]"<<"/XFormula["<<formulaCounter<<"]";
          else
            stringStream<<"/Point["<<pointCounter<<"]"<<"/YFormula["<<formulaCounter<<"]";
          //if there is no Formula by that index, abort.
          if (!xPathExists(doc, xpathCtx, searchString, stringStream.str(), ""))
            {
              formulaCounter=0;
              loopCounter++;
              continue;
            }
          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/StartTime"); hash.setString("Key Name", "Start Time");
          hash.setInt("Default Value", 0);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/Duration"); hash.setString("Key Name", "Duration");
          hash.setInt("Default Value", -1);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/TimeShift"); hash.setString("Key Name", "Time Shift");
          hash.setInt("Default Value", 0);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/Offset"); hash.setString("Key Name", "Offset");
          hash.setInt("Default Value", 0);hash.setInt("Randomize Style", RANDOMIZE_STYLE_LINEAR_ADD); hash.setInt("Randomize Magnitude", 10);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/Linear"); hash.setString("Key Name", "Linear");
          hash.setInt("Default Value", 0); hash.setInt("Randomize Style", RANDOMIZE_STYLE_PERCENTAGE); hash.setInt("Randomize Magnitude", 10);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/Quadratic"); hash.setString("Key Name", "Quadratic");
          hash.setInt("Default Value", 0); hash.setInt("Randomize Style", RANDOMIZE_STYLE_PERCENTAGE); hash.setInt("Randomize Magnitude", 10);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/Sine/Amplitude"); hash.setString("Key Name", "Sine Amplitude");
          hash.setInt("Default Value", 0); hash.setInt("Randomize Style", RANDOMIZE_STYLE_PERCENTAGE); hash.setInt("Randomize Magnitude", 10);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/Sine/Period"); hash.setString("Key Name", "Sine Period");
          hash.setInt("Default Value", 1000); hash.setInt("Randomize Style", RANDOMIZE_STYLE_PERCENTAGE); hash.setInt("Randomize Magnitude", 10);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/Cosine/Amplitude"); hash.setString("Key Name", "Cosine Amplitude");
          hash.setInt("Default Value", 0); hash.setInt("Randomize Style", RANDOMIZE_STYLE_PERCENTAGE); hash.setInt("Randomize Magnitude", 10);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          hash.clear();
          hash.setString("X Path", searchString+stringStream.str()+"/Cosine/Period"); hash.setString("Key Name", "Cosine Period");
          hash.setInt("Default Value", 1000); hash.setInt("Randomize Style", RANDOMIZE_STYLE_PERCENTAGE); hash.setInt("Randomize Magnitude", 10);
          loadIntFromXMLAndPutIntoHash(doc, xpathCtx, positionFormulaSettings, hash);

          pf.clear();
          pf.set(positionFormulaSettings);
          if (loopCounter==0)
            dp.addFormulaX(pf);
          else
            dp.addFormulaY(pf);
        }

      //add default X formula
      positionFormulaSettings.clearParamState();
      intToLoad=60*1024;
      positionFormulaSettings.setInt("Start Time", intToLoad);
      intToLoad=100;
      positionFormulaSettings.setInt("Linear", intToLoad);
      pf.clear();
      pf.set(positionFormulaSettings);
      dp.addFormulaX(pf);

      //done, add the next DefensePoint.
      playerDefenseArray.addDefensePoint(dp);
    }

  //closing xml stuff.
  xmlXPathFreeContext(xpathCtx);
  xmlFreeDoc (doc);
}
