#include "thalia_opus/opus_tag.h"
#include "thalia_opus/opus_entry_point.h"

#include "WDL/wdlutf8.h"

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

THA_OpusTag::~THA_OpusTag()
{
  if (m_of) op_free(m_of);
  if (m_file) delete m_file;
  m_metadata.DeleteAll();
}

bool THA_OpusTag::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;
  }

  int ret;

  m_of = op_open_file(m_fn.Get(), &ret);

  if (m_of)
  {
    const OpusTags *ot = op_tags(m_of, -1);
    if (ot)
    {
      for (int i = 0; i < ot->comments; i++)
      {
        m_strbuf.Set((const char *)ot->user_comments[i]);

        if (!strnicmp(m_strbuf.Get(), "TITLE=", 6))
        {
          m_strbuf.DeleteSub(0, 6);
          m_metadata.Insert("TITLE", strdup(m_strbuf.Get()));
        }
        else if (!strnicmp(m_strbuf.Get(), "ALBUM=", 6))
        {
          m_strbuf.DeleteSub(0, 6);
          m_metadata.Insert("ALBUM", strdup(m_strbuf.Get()));
        }
        else if (!strnicmp(m_strbuf.Get(), "TRACKNUMBER=", 12))
        {
          m_strbuf.DeleteSub(0, 12);
          m_metadata.Insert("TRACKNUMBER", strdup(m_strbuf.Get()));
        }
        else if (!strnicmp(m_strbuf.Get(), "ARTIST=", 7))
        {
          m_strbuf.DeleteSub(0, 7);
          m_metadata.Insert("ARTIST", strdup(m_strbuf.Get()));
        }
        else if (!strnicmp(m_strbuf.Get(), "DESCRIPTION=", 12))
        {
          m_strbuf.DeleteSub(0, 12);
          m_metadata.Insert("DESCRIPTION", strdup(m_strbuf.Get()));
        }
        else if (!strnicmp(m_strbuf.Get(), "GENRE=", 6))
        {
          m_strbuf.DeleteSub(0, 6);
          m_metadata.Insert("GENRE", strdup(m_strbuf.Get()));
        }
        else if (!strnicmp(m_strbuf.Get(), "DATE=", 5))
        {
          m_strbuf.DeleteSub(0, 5);
          m_metadata.Insert("DATE", strdup(m_strbuf.Get()));
        }
      }
      return true;
    }
  }

  return false;
}

const char *THA_OpusTag::GetType() const
{
  return "OPUS";
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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