#include "thalia_flac/flac_tag.h"
#include "thalia_flac/flac_entry_point.h"

#include "WDL/win32_utf8.h"

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

THA_FlacTag::~THA_FlacTag()
{
  if (m_file) delete m_file;
  m_metadata.DeleteAll();
}

bool THA_FlacTag::Open(const char *filename)
{
  bool res = false;
  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;
  }

#ifdef _WIN32
  flac_internal_set_utf8_filenames(true);
#endif

  FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new();
  if (FLAC__metadata_chain_read(chain, m_fn.Get()))
  {
    FLAC__Metadata_Iterator *it = FLAC__metadata_iterator_new();
    FLAC__metadata_iterator_init(it, chain);

    WDL_FastString ss;
    while (FLAC__metadata_iterator_next(it))
    {
      FLAC__StreamMetadata *meta = FLAC__metadata_iterator_get_block(it);
      if (meta->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
      {
        for (int i = 0; i < (int)meta->data.vorbis_comment.num_comments; i++)
        {
          ss.SetRaw((const char *)meta->data.vorbis_comment.comments[i].entry,
            meta->data.vorbis_comment.comments[i].length);

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

  FLAC__metadata_chain_delete(chain);

  return res;
}

const char *THA_FlacTag::GetType() const
{
  return "FLAC";
}

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

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

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

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

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

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

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

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

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

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

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

void THA_FlacTag::SetTitle(const char *val)
{}

void THA_FlacTag::SetArtist(const char *val)
{}

void THA_FlacTag::SetAlbum(const char *val)
{}

void THA_FlacTag::SetGenre(const char *val)
{}

void THA_FlacTag::SetTrack(const char *val)
{}

void THA_FlacTag::SetYear(const char *val)
{}

void THA_FlacTag::SetComment(const char *val)
{}

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