#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif //HAVE_CONFIG_H

#include <glibmm.h>

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <fileref.h>

// Plugin-specific include
#include <taglib.h>
#include <fileref.h>
#include <tfile.h>
#include <tag.h>

#include <oggfile.h>
#include <vorbisfile.h>
#include <vorbisproperties.h>
#include <xiphcomment.h>

#include <flacfile.h>
#include <mpegfile.h>
#include <id3v2tag.h>

#include "bmp/types/types-basic.hh"
#include "bmp/library-ops.hh"

#include "id3v2/reader.hh"
#include "xiph/reader.hh"
#include "common/common.hh"

using namespace Bmp;
using namespace TagLib;
using namespace Glib;

extern "C" int  _plugin_has_accessors;
int  _plugin_has_accessors = 1;

extern "C" int  _plugin_version;
int _plugin_version = PLUGIN_VERSION;

extern "C" const char ** _mimetypes ()
{
  static const char * _types[] =
  {
    "audio/x-flac",
    NULL
  };
  return _types;
}

extern "C"
bool _set (std::string const& filename, Track & track)
{
  FLAC::File opfile (filename.c_str());
  if (!metadata_check_file (&opfile))
    return false;

  Ogg::XiphComment * comment = opfile.xiphComment();
  if (comment)
  {
    metadata_set_common (&opfile, track);

    if (track.mb_album_artist)
      comment->addField (String ("ALBUMARTIST",                         String::UTF8),
                         String (track.mb_album_artist.get(),           String::UTF8));

    if (track.mb_album_artist_id)
      comment->addField (String ("MUSICBRAINZ_ALBUMARTISTID",           String::UTF8),
                         String (track.mb_album_artist_id.get(),        String::UTF8));

    if (track.mb_album_artist_sort_name)
      comment->addField (String ("ALBUMARTISTSORT",                     String::UTF8),
                         String (track.mb_album_artist_sort_name.get(), String::UTF8));

    if (track.mb_track_id)
      comment->addField (String ("MUSICBRAINZ_TRACKID",                 String::UTF8),
                         String (track.mb_track_id.get(),               String::UTF8));

    if (track.mb_album_id)
      comment->addField (String ("MUSICBRAINZ_ALBUMID",                 String::UTF8),
                         String(track.mb_album_id.get(),                String::UTF8));

    if (track.mb_artist_id)
      comment->addField (String ("MUSICBRAINZ_ARTISTID",                String::UTF8),
                         String (track.mb_artist_id.get(),              String::UTF8));

    if (track.mb_artist_sort_name)
      comment->addField (String ("ARTISTSORT",                          String::UTF8),
                         String (track.mb_artist_sort_name.get(),       String::UTF8));

    if (track.mb_release_date)
      comment->addField (String ("DATE", String::UTF8),
                         String (track.mb_release_date.get(), String::UTF8));

    if (track.asin)
      comment->addField (String ("ASIN",            String::UTF8),
                         String (track.asin.get(),  String::UTF8));

    if (track.puid)
      comment->addField (String ("MUSICIP_PUID",   String::UTF8),
                         String (track.puid.get(), String::UTF8));

    opfile.save();
    return true;
  }
  else
  {
    return false;
  }
}

extern "C"
bool _get (std::string const& filename, DB::Row & row)
{
  FLAC::File opfile (filename.c_str());
  if (!metadata_check_file (&opfile))
    return false;

  Ogg::XiphComment *comment = opfile.xiphComment();
  ID3v2::Tag *tag = opfile.ID3v2Tag (false);

  if (comment)
  {
    metadata_get_xiph (comment, row);
    metadata_get_common (&opfile, row);
    return true;
  }

  if (tag)
  {
    metadata_get_id3v2 (tag, row);
    metadata_get_common (&opfile, row);
    return true;
  }

  return false;
}
