//ff_vclt.c:

/*
 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014
 *
 *  This file is part of RoarAudio PlayList Daemon,
 *  a playlist management daemon for RoarAudio.
 *  See README for details.
 *
 *  This file is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 3
 *  as published by the Free Software Foundation.
 *
 *  RoarAudio is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this software; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 *
 */

#include "rpld.h"

int ff_vclt_pl_export(struct fformat_handle * handle, struct roar_vio_calls * vio, struct rpld_playlist  * pl) {
 struct rpld_playlist_entry * cur = rpld_pl_get_first(pl);
 ssize_t i;
 char uuid[37];
 const char * filename;
 const char * key;
 enum rpld_filename_type filenametype;
 ssize_t num;

 (void)handle;

 while ( cur != NULL ) {
  roar_uuid2str(uuid, cur->uuid, sizeof(uuid));
  roar_vio_printf(vio, "HASH={UUID}%s\n", uuid);

  num = rpld_ple_num_filename(cur);
  for (i = 0; i < num; i++) {
   filename = rpld_ple_get_filename(cur, i, &filenametype);
   if ( filename != NULL ) {
    switch (filenametype) {
     case RPLD_TYPE_STREAMURL: key = "STREAMURL"; break;
     case RPLD_TYPE_FILENAME:  key = "FILENAME"; break;
     case RPLD_TYPE_FILEURL:   key = "FILEURL"; break;
     default: key = "FILENAME"; break;
    }
    roar_vio_printf(vio, "%s=%s\n", key, filename);
   }
  }

  if ( cur->meta.album[0] )
   roar_vio_printf(vio, "ALBUM=%s\n", cur->meta.album);
  if ( cur->meta.title[0] )
   roar_vio_printf(vio, "TITLE=%s\n", cur->meta.title);
  if ( cur->meta.artist[0] )
   roar_vio_printf(vio, "ARTIST=%s\n", cur->meta.artist);
  if ( cur->meta.performer[0] )
   roar_vio_printf(vio, "PERFORMER=%s\n", cur->meta.performer);
  if ( cur->meta.version[0] )
   roar_vio_printf(vio, "VERSION=%s\n", cur->meta.version);

  if ( cur->meta.genre != -1 )
   roar_vio_printf(vio, "GENRE=%s\n", roar_meta_strgenre(cur->meta.genre));

  if ( cur->meta.tracknum )
   roar_vio_printf(vio, "TRACKNUMBER=%i\n", cur->meta.tracknum);
  if ( cur->meta.discid )
   roar_vio_printf(vio, "DISCID=%.8x\n", cur->meta.discid);

  if ( cur->length )
   roar_vio_printf(vio, "LENGTH=%s\n", rpld_ple_time_hr(cur));

  if ( cur->codec != -1 )
   roar_vio_printf(vio, "SIGNALINFO=codec:%s\n", roar_codec2str(cur->codec));

  if ( cur->wallclock_start != RPLD_PLE_WALLCLOCK_INVALID )
   roar_vio_printf(vio, "X-RPLD-WALLCLOCK-START=%" __ll "i\n", (__longlong)cur->wallclock_start);

  roar_vio_printf(vio, "LIKENESS=%f\n", (double)cur->likeness);

  for (i = 0; i < cur->meta.extra.kvlen && cur->meta.extra.kv[i].key != NULL && cur->meta.extra.kv[i].value != NULL; i++) {
   roar_vio_printf(vio, "%s=%s\n", cur->meta.extra.kv[i].key, cur->meta.extra.kv[i].value);
  }

  roar_vio_printf(vio, "==\n");
  cur = cur->list.next;
 }

 return 0;
}

int ff_vclt_pl_import(struct fformat_handle * handle, struct roar_vio_calls * vio, struct rpld_playlist  * pl) {
 struct rpld_playlist_entry * plent = NULL;
 struct roar_audio_info       info;
 char buf[1024];
 char * s, * delm;
 char * dst;
 size_t dst_len;
 size_t len;
 int    meta;
 ssize_t extra_index = 0;
 void * extra_buf;
 ssize_t extra_len;
 roar_uuid_t uuid;
 enum rpld_filename_type filenametype;

 (void)handle;

 while ((s = roar_vio_fgets(vio, buf, sizeof(buf))) != NULL ) {
  len = strlen(s);

  for (s += len - 1; s > buf && (*s == '\r' || *s == '\n'); s--)
   *s = 0;

  if ( !*buf )
   continue;

  if ( !strcmp(buf, "==") ) {
   if ( plent != NULL )
    rpld_pl_push(pl, plent);

   plent = NULL;

   continue;
  }

  if ( (delm = strstr(buf, "=")) == NULL )
   continue;

  *delm = 0;
   delm++;

  if ( plent == NULL )
   if ( (plent = rpld_ple_new()) == NULL )
    return -1;

  if ( !strcasecmp(buf, "X-RPLD-WALLCLOCK-START") ) {
   plent->wallclock_start = atoi(delm);
   continue;
  }

  meta = roar_meta_inttype(buf);

  dst = NULL;
  dst_len = 0;

  switch (meta) {
   case ROAR_META_TYPE_FILENAME:
   case ROAR_META_TYPE_FILEURL:
   case ROAR_META_TYPE_STREAMURL:
     filenametype = rpld_ple_get_filenametype(buf);
     rpld_ple_push_filename(plent, delm, filenametype, 0);
     continue;
    break;
   case ROAR_META_TYPE_ALBUM:
     dst = plent->meta.album;
     dst_len = sizeof(plent->meta.album);
    break;
   case ROAR_META_TYPE_TITLE:
     dst = plent->meta.title;
     dst_len = sizeof(plent->meta.title);
    break;
   case ROAR_META_TYPE_ARTIST:
     dst = plent->meta.artist;
     dst_len = sizeof(plent->meta.artist);
    break;
   case ROAR_META_TYPE_PERFORMER:
     dst = plent->meta.performer;
     dst_len = sizeof(plent->meta.performer);
    break;
   case ROAR_META_TYPE_VERSION:
     dst = plent->meta.version;
     dst_len = sizeof(plent->meta.version);
    break;
   case ROAR_META_TYPE_LENGTH:
     rpld_ple_set_time_hr(plent, delm);
     continue;
    break;
   case ROAR_META_TYPE_AUDIOINFO:
      if ( roar_meta_parse_audioinfo(&info, delm) != -1 ) {
       plent->codec = info.codec;
      }
     continue;
    break;
   case ROAR_META_TYPE_TRACKNUMBER:
     plent->meta.tracknum = atoi(delm);
     continue;
    break;
   case ROAR_META_TYPE_GENRE:
     plent->meta.genre = roar_meta_intgenre(delm);
     continue;
    break;
   case ROAR_META_TYPE_DISCID:
     sscanf(delm, "%8x", &(plent->meta.discid));
     continue;
    break;
#ifdef ROAR_META_TYPE_LIKENESS
   case ROAR_META_TYPE_LIKENESS:
     plent->likeness = atof(delm);
     continue;
    break;
#endif
   case ROAR_META_TYPE_HASH:
     if ( !strncasecmp(delm, "{UUID}", 6) ) {
      if ( roar_str2uuid(uuid, delm+6) == 0 ) {
       memcpy(plent->uuid, uuid, sizeof(plent->uuid));
      }
     }
     continue;
    break;
   default:
     if ( plent->meta.extra.kvlen == -1 )
      plent->meta.extra.kvlen = 0;
     if ( plent->meta.extra.kv_storelen == -1 )
      plent->meta.extra.kv_storelen = 0;

     if ( extra_index == plent->meta.extra.kvlen ) {
      extra_buf = roar_mm_realloc(plent->meta.extra.kv, sizeof(struct roar_keyval)*(extra_index + 8));
      if ( extra_buf == NULL )
       continue;
      plent->meta.extra.kvlen += 8;
      plent->meta.extra.kv = extra_buf;
      memset(extra_buf+sizeof(struct roar_keyval)*extra_index, 0, sizeof(struct roar_keyval)*8);
     }

     extra_len = roar_mm_strlen(buf) + roar_mm_strlen(delm) + 2;
     extra_buf = roar_mm_realloc(plent->meta.extra.kv_store, plent->meta.extra.kv_storelen + extra_len);
     if ( extra_buf == NULL )
      continue;

     plent->meta.extra.kv[extra_index].key = extra_buf + plent->meta.extra.kv_storelen;
     strcpy(plent->meta.extra.kv[extra_index].key, buf);
     plent->meta.extra.kv[extra_index].value = extra_buf + plent->meta.extra.kv_storelen + roar_mm_strlen(buf) + 1;
     strcpy(plent->meta.extra.kv[extra_index].value, delm);
     plent->meta.extra.kv_store = extra_buf;
     plent->meta.extra.kv_storelen += extra_len;

     continue;
    break;
  }

  strncpy(dst, delm, dst_len);
  dst[dst_len-1] = 0;
 }

 if ( plent != NULL )
  rpld_pl_push(pl, plent);

 return 0;
}

//ll
