#include "shippingHandler.h"

bool shippingHandler :: loadSound (string & keyName)
{
  //simply a front to loadResource.
  if (keyName.empty() || keyName == "NULL_INDEX")
    {
      keyName="NULL_INDEX";
      return false;
    }

  return loadResource (keyName, "sound");
}


bool shippingHandler :: loadSoundHelper (const string & index, AudioBuffer & soun)
{
  //tries to load an AudioBuffer.

  Mix_Chunk * temp=NULL;

  //parse the xml file and find the filename for the given index
  xmlDocPtr doc;
  xmlXPathContextPtr xpathCtx;
  string filename;

  if (!prepareXMLFile (doc, xpathCtx, "resources/SoundManifest.xml", ""))
    {
      writeToErrorLog("LoadSound: Failed to open file or find XPath loading "+index, 0);
      return false;
    }

  xmlChar *keyword;
  keyword = getFirstElementUsingXPath (doc, xpathCtx, "/SoundManifest/Sound[@ID='", index, "']/Filename");

  if (keyword!=NULL)
    filename = (const char *)keyword;
  else
    {
      writeToErrorLog ("loadSoundHelper: No entry found in XML file.", 2);
      writeToErrorLog (index.c_str(), 2);
      xmlXPathFreeContext(xpathCtx);
      xmlFreeDoc(doc);
      return false;
    }

  xmlXPathFreeContext(xpathCtx);
  xmlFreeDoc(doc);
  xmlFree(keyword);

  temp = Mix_LoadWAV(filename.c_str());

  if (temp == NULL){
    writeToErrorLog ("loadSoundHelper: Sound failed to load.", 2);
    writeToErrorLog (index.c_str(), 2);
    return false;
  }

  soun.setSample(temp);
  return true;
}


void shippingHandler :: playSound (const string & keyName, AudioTransformation & at)
{
  if (keyName.empty() || keyName == "NULL_INDEX")
    return;

  map <string, AudioBuffer> :: iterator iter2;
  iter2 = soundBuffers.find (keyName);

  if (iter2 == soundBuffers.end())
    return;

  int soundChannel, fadeInTime, fadeOutTime, loops;
  uint8_t generalVolume, leftSidePan, rightSidePan;

  fadeInTime = at.getFadeInTime();
  fadeOutTime = at.getFadeOutTime();
  loops = at.getNumberOfLoops();
  leftSidePan=at.getLeftPanning();
  rightSidePan=at.getRightPanning();
  generalVolume=at.getVolume();

  if ((at.getTransformFlag()&AUDIO_TRANSFORMATION_FADE_IN)==0)
    {
      soundChannel = Mix_PlayChannel (-1, iter2->second.getSample(), loops);
      Mix_Volume (soundChannel, generalVolume);

      if ((at.getTransformFlag()&AUDIO_TRANSFORMATION_PANNING)>0)
        Mix_SetPanning(soundChannel, leftSidePan, rightSidePan);

      if ((at.getTransformFlag()&AUDIO_TRANSFORMATION_FADE_OUT)>0)
        Mix_FadeOutChannel(soundChannel, fadeOutTime);
    }
  else
    soundChannel = Mix_FadeInChannel (-1, iter2->second.getSample(), loops, fadeInTime);
  return;
}


void shippingHandler :: releaseSound (const string & keyName)
{
  if (keyName.empty() || keyName == "NULL_INDEX")
    return;

  map <string, AudioBuffer> :: iterator iter2;
  iter2 = soundBuffers.find (keyName);

  if (iter2 == soundBuffers.end())
    return;

  iter2->second.decRefCount();

  if (iter2->second.getRefCount()==0)
    {
      Mix_FreeChunk(iter2->second.getSample());
      iter2->second.setSample(NULL);
      soundBuffers.erase(iter2);
    }
}

void shippingHandler :: fadeOutAllAudioBuffers(int tim)
{
  if (tim <= 0)
    haltAllAudioBuffers();
  else
    {
      Mix_FadeOutChannel(-1, tim);
    }
}

void shippingHandler :: haltAllAudioBuffers()
{
  Mix_HaltChannel(-1);
}
