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

#include <glibmm.h>

#include <fileref.h>
#include "resolver.h"
#include "mp4file.h"
#include "mp4tag.h"

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

#include "common/common.hh"

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-m4a",
    "audio/mp4",
     NULL 
  };
  return types;
}

using namespace Bmp;
using namespace TagLib;
using namespace TagLib::MP4;
using namespace Glib;

extern "C" bool _set (std::string const& filename, Track & track)
{
  MP4::File opfile (filename.c_str());
  if (!metadata_check_file (&opfile))
    return false;
  
  MP4::Tag* tag;
  if (!(tag = dynamic_cast<MP4::Tag*> (opfile.tag())))
    return false;

  metadata_set_common (&opfile, track);

  MP4::ItemListMap & ItemMap = tag->itemListMap();

  if (track.mb_album_artist)
    ItemMap["aART"] =  StringList (String (track.mb_album_artist.get(), String::UTF8));
                       
  if (track.mb_track_id)
    ItemMap["----:com.apple.iTunes:MusicBrainz Track Id"] = 
                       StringList (String (track.mb_track_id.get(), String::UTF8));

  if (track.mb_album_id)
    ItemMap["----:com.apple.iTunes:MusicBrainz Album Id"] =
                       StringList (String(track.mb_album_id.get(), String::UTF8));

  if (track.mb_artist_id)
    ItemMap["----:com.apple.iTunes:MusicBrainz Artist Id"] = 
                       StringList (String (track.mb_artist_id.get(), String::UTF8));

  if (track.mb_album_artist_id)
    ItemMap["----:com.apple.iTunes:MusicBrainz Album Artist Id"] =
                       StringList (String (track.mb_album_artist_id.get(), String::UTF8));

  if (track.mb_album_artist_sort_name)
    ItemMap["soaa"] =  StringList (String (track.mb_album_artist_sort_name.get(), String::UTF8));
                       
  if (track.mb_artist_sort_name)
    ItemMap["soar"] =  StringList (String (track.mb_artist_sort_name.get(), String::UTF8));

  if (track.mb_release_date)
    ItemMap["\251day"] =  
                       StringList (String (track.mb_release_date.get(), String::UTF8));

  if (track.asin)
    ItemMap["----:com.apple.iTunes:ASIN"] = 
                       StringList (String (track.asin.get(), String::UTF8));

  if (track.puid)
    ItemMap["----:com.apple.ITunes:MusicIP PUID"] = 
                       StringList (String (track.puid.get(), String::UTF8));

  opfile.save ();
  return true;
}

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

  MP4::Tag* tag;
  if (!(tag = dynamic_cast<MP4::Tag*> (opfile.tag())))
      return false;

  MP4::ItemListMap const& ItemMap = tag->itemListMap();

  if (ItemMap.contains ("\251day"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_MB_RELEASE_DATE).id,
                  ItemMap["\251day"].toStringList()[0].toCString (true))); 
  }

  if (ItemMap.contains ("aART"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_MB_ALBUM_ARTIST).id,
                  ItemMap["aART"].toStringList()[0].toCString (true))); 
  }

  if (ItemMap.contains ("soaa"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_MB_ALBUM_ARTIST_SORTNAME).id,
                  ItemMap["soaa"].toStringList()[0].toCString (true))); 
  }

  if (ItemMap.contains ("soar"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_MB_ARTIST_SORTNAME).id,
                  ItemMap["soar"].toStringList()[0].toCString (true))); 
  }

  if (ItemMap.contains ("----:com.apple.iTunes:MusicBrainz Track Id"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_MB_TRACK_ID).id,
                  ItemMap["----:com.apple.iTunes:MusicBrainz Track Id"].toStringList()[0].toCString (true))); 
  }

  if (ItemMap.contains ("----:com.apple.iTunes:MusicBrainz Album Id"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_MB_ALBUM_ARTIST_ID).id,
                  ItemMap["----:com.apple.iTunes:MusicBrainz Album Id"].toStringList()[0].toCString (true))); 
  }

  if (ItemMap.contains ("----:com.apple.iTunes:MusicBrainz Artist Id"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_MB_ARTIST_ID).id,
                  ItemMap["----:com.apple.iTunes:MusicBrainz Artist Id"].toStringList()[0].toCString (true))); 
  }

  if (ItemMap.contains ("----:com.apple.iTunes:ASIN"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_ASIN).id,
                  ItemMap["----:com.apple.iTunes:ASIN"].toStringList()[0].toCString (true))); 
  }

  if (ItemMap.contains ("----:com.apple.iTunes:MusicIP PUID"))
  {
      row.insert (std::make_pair (get_attribute_info(ATTRIBUTE_MUSICIP_PUID).id,
                  ItemMap["----:com.apple.iTunes:MusicIP PUID"].toStringList()[0].toCString (true))); 
  }

  if (0) // album release country
  {
      /* not handled in bmpx atm */
  }

  if (0) // album type
  {
      /* not handled in bmpx atm */
  }

  if (0) // album status
  {
      /* not handled in bmpx atm */
  }

  metadata_get_common (&opfile, row);

  return true;
}

static void _plugin_init (void) __attribute__((constructor));
static void _plugin_init (void)
{
  TagLib::FileRef::addFileTypeResolver(new MP4FileTypeResolver);
}
