#include "shippingHandler.h"

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

  return loadResource (keyName, "music");
}

bool shippingHandler :: loadMusicHelper (const string & index, AudioStream & mus)
{
  //tries to load an AudioStream.
  Mix_Music * temp;

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

  if (!prepareXMLFile (doc, xpathCtx, "resources/MusicManifest.xml", ""))
    {
      writeToErrorLog("LoadMusic: Failed to open MusicManifest file.", 0);
      return false;
    }

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

  if (keyword!=NULL)
    filename = (const char *)keyword;
  else
    {
      writeToErrorLog ("loadMusicHelper: 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_LoadMUS(filename.c_str());

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

  mus.setStream(temp);
  return true;
}

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

  map <string, AudioStream> :: iterator iter2;
  iter2 = musicBuffers.find (keyName);

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

  int fadeInTime, fadeOutTime, loops;
  uint8_t generalVolume;

  fadeInTime = at.getFadeInTime();
  fadeOutTime = at.getFadeOutTime();
  loops = at.getNumberOfLoops();
  generalVolume=at.getVolume();

  //play music now

  if ((at.getTransformFlag()&AUDIO_TRANSFORMATION_FADE_IN)==0)
    {
      Mix_PlayMusic(iter2->second.getStream(), loops);
      Mix_VolumeMusic(generalVolume);
      if ((at.getTransformFlag()&AUDIO_TRANSFORMATION_START_TIME)>0)
        Mix_SetMusicPosition(at.getStartTime());
    }
  else
    {
      if ((at.getTransformFlag()&AUDIO_TRANSFORMATION_START_TIME)>0)
        Mix_FadeInMusicPos(iter2->second.getStream(), loops, fadeInTime, at.getStartTime());
      else
        Mix_FadeInMusic(iter2->second.getStream(), loops, fadeInTime);
    }
  return;
}

void shippingHandler :: fadeOutMusic(int tim)
{
  Mix_FadeOutMusic(tim);
}

void shippingHandler :: pauseMusic ()
{
  Mix_PauseMusic();
}

void shippingHandler :: resumeMusic ()
{
  Mix_ResumeMusic();
}

void shippingHandler :: stopMusic ()
{
  Mix_HaltMusic();
}

void shippingHandler :: rewindMusic ()
{
  Mix_RewindMusic();
}

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

  map <string, AudioStream> :: iterator iter2;
  iter2 = musicBuffers.find (keyName);

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

  iter2->second.decRefCount();

  if (iter2->second.getRefCount()==0)
    {
      Mix_FreeMusic(iter2->second.getStream());
      iter2->second.setStream(NULL);
      musicBuffers.erase(iter2);
    }
}
