#include "thalia_waveform/waveform_tag.h"
#include "thalia_waveform/waveform_entry_point.h"

#include "WDL/wdlutf8.h"

THA_WaveFormTag::THA_WaveFormTag()
  : m_file(NULL)
  , m_metadata(false, WDL_StringKeyedArray<char *>::freecharptr)
  , m_sndfile(NULL)
{}

THA_WaveFormTag::~THA_WaveFormTag()
{
  if (m_sndfile) sf.close(m_sndfile);
  if (m_file) delete m_file;
  m_metadata.DeleteAll();
}

bool THA_WaveFormTag::Open(const char *filename)
{
  m_fn.Set(filename);

  int rmode, rbufsize, rnbufs;
  THA_GetDiskReadMode(&rmode, &rbufsize, &rnbufs);
  m_file = new WDL_NEW WDL_FileRead(filename, rmode, rbufsize, rnbufs);

  if (!m_file || !m_file->IsOpen())
  {
    return false;
  }

  m_vio.get_filelen = sf_filelength;
  m_vio.seek = sf_seek;
  m_vio.read = sf_read;
  m_vio.write = sf_write;
  m_vio.tell = sf_tell;

  m_sndfile = sf.open_virtual(&m_vio, SFM_READ, &m_sfinfo, m_file);

#ifdef _WIN32
  //WDL_WCHAR fn[2048];
  //WDL_MBtoWideStr(fn, m_fn.Get(), sizeof(fn));
  //m_sndfile = sf.wchar_open(fn, SFM_READ, &m_sfinfo);
#else
  //m_sndfile = sf.open(m_fn.Get(), SFM_READ, &m_sfinfo);
#endif

  if (m_sndfile)
  {
    WDL_FastString strbuf;
    strbuf.Set(sf.get_string(m_sndfile, SF_STR_TITLE));
    if (strbuf.GetLength()) m_metadata.Insert("Title", strdup(strbuf.Get()));
    strbuf.Set(sf.get_string(m_sndfile, SF_STR_ARTIST));
    if (strbuf.GetLength()) m_metadata.Insert("Artist", strdup(strbuf.Get()));
    strbuf.Set(sf.get_string(m_sndfile, SF_STR_ALBUM));
    if (strbuf.GetLength()) m_metadata.Insert("Album", strdup(strbuf.Get()));
    strbuf.Set(sf.get_string(m_sndfile, SF_STR_DATE));
    if (strbuf.GetLength()) m_metadata.Insert("Year", strdup(strbuf.Get()));
    strbuf.Set(sf.get_string(m_sndfile, SF_STR_GENRE));
    if (strbuf.GetLength()) m_metadata.Insert("Genre", strdup(strbuf.Get()));
    strbuf.Set(sf.get_string(m_sndfile, SF_STR_COMMENT));
    if (strbuf.GetLength()) m_metadata.Insert("Comment", strdup(strbuf.Get()));
    strbuf.Set(sf.get_string(m_sndfile, SF_STR_TRACKNUMBER));
    if (strbuf.GetLength()) m_metadata.Insert("Track", strdup(strbuf.Get()));
    return true;
  }

  return false;
}

const char *THA_WaveFormTag::GetType() const
{
  if (!wdl_filename_cmp(m_fn.get_fileext(), ".wav")) return "WAV";
  else if (!wdl_filename_cmp(m_fn.get_fileext(), ".aiff")) return "AIFF";
  return "UNK";
}

const char *THA_WaveFormTag::GetTitle() const
{
  return m_metadata.Get("Title", "");
}

const char *THA_WaveFormTag::GetArtist() const
{
  return m_metadata.Get("Artist", "");
}

const char *THA_WaveFormTag::GetAlbum() const
{
  return m_metadata.Get("Album", "");
}

const char *THA_WaveFormTag::GetGenre() const
{
  return m_metadata.Get("Genre", "");
}

const char *THA_WaveFormTag::GetTrack() const
{
  return m_metadata.Get("Track", "");
}

const char *THA_WaveFormTag::GetYear() const
{
  return m_metadata.Get("Year", "");
}

const char *THA_WaveFormTag::GetComment() const
{
  return m_metadata.Get("Comment", "");
}

WDL_INT64 THA_WaveFormTag::GetFileSize() const
{
  return m_file->GetSize();
}

const char *THA_WaveFormTag::GetFileName() const
{
  return m_fn.get_filepart();
}

const char *THA_WaveFormTag::GetFilePath() const
{
  return m_fn.Get();
}

const char *THA_WaveFormTag::GetFileExtension() const
{
  return m_fn.get_fileext();
}

void THA_WaveFormTag::SetTitle(const char *val)
{
  m_metadata.Insert("Title", strdup(val));
}

void THA_WaveFormTag::SetArtist(const char *val)
{
  m_metadata.Insert("Artist", strdup(val));
}

void THA_WaveFormTag::SetAlbum(const char *val)
{
  m_metadata.Insert("Album", strdup(val));
}

void THA_WaveFormTag::SetGenre(const char *val)
{
  m_metadata.Insert("Genre", strdup(val));
}

void THA_WaveFormTag::SetTrack(const char *val)
{
  m_metadata.Insert("Track", strdup(val));
}

void THA_WaveFormTag::SetYear(const char *val)
{
  m_metadata.Insert("Year", strdup(val));
}

void THA_WaveFormTag::SetComment(const char *val)
{
  m_metadata.Insert("Comment", strdup(val));
}

bool THA_WaveFormTag::Save()
{
  return false;
}
