
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <glob.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "mecha.h"

#include "iplaylist.h"
#include "playlist.h"

#include "list_iterator.h"

#include "queue_playlist_engine.h"


static void queue_playlist_engine_destroy (IPlaylist *inst);
static const char * queue_playlist_engine_get_name (IPlaylist *inst);
static const char * queue_playlist_engine_get_type (MECHA_UNUSED_ARGUMENT IPlaylist *inst);
static int queue_playlist_engine_get_next (IPlaylist *inst);
static bool queue_playlist_engine_add_file (IPlaylist *inst, int fileId);
static bool queue_playlist_engine_remove_file (IPlaylist *inst, int fileId);
static IIterator * queue_playlist_engine_get_list_iterator (IPlaylist *inst);


struct s_QueuePlaylistEngine
{
    IPlaylist interface;

    char *playlist_name;

    lstTlist *filelist;
};

QueuePlaylistEngine *
queue_playlist_engine_init (const char *playlistName)
{
   QueuePlaylistEngine *instance = (QueuePlaylistEngine *) malloc (sizeof (QueuePlaylistEngine));

   instance->interface.destroy = queue_playlist_engine_destroy;

   instance->interface.get_name = queue_playlist_engine_get_name;
   instance->interface.get_type = queue_playlist_engine_get_type;

   instance->interface.get_next = queue_playlist_engine_get_next;
   instance->interface.add_file = queue_playlist_engine_add_file;
   instance->interface.remove_file = queue_playlist_engine_remove_file;

   instance->interface.get_list_iterator = queue_playlist_engine_get_list_iterator;
   instance->interface.get_next_iterator = queue_playlist_engine_get_list_iterator;

   instance->playlist_name = strFcopy (playlistName);
   instance->filelist = lstFlist_create (NULL);

   return (instance);
}

static void
queue_playlist_engine_destroy (IPlaylist *inst)
{
    QueuePlaylistEngine *instance = (QueuePlaylistEngine *) inst;

    free (instance->playlist_name);

    lstFlist_free (instance->filelist);

    free (instance);
}

static const char *
queue_playlist_engine_get_name (IPlaylist *inst)
{
    QueuePlaylistEngine *instance = (QueuePlaylistEngine *) inst;

    return (instance->playlist_name);
}

static const char *
queue_playlist_engine_get_type (MECHA_UNUSED_ARGUMENT IPlaylist *inst)
{
    return ("queue");
}

static int
queue_playlist_engine_get_next (IPlaylist *inst)
{
    QueuePlaylistEngine *instance = (QueuePlaylistEngine *) inst;
    int retFileId;

    if (lstFlist_size (instance->filelist) == 0)
    {
        return (-1);
    }

   lstFlist_remove (instance->filelist, lstFlist_head (instance->filelist), 
           (void **) &retFileId);

   return (retFileId);
}

static bool
queue_playlist_engine_add_file (IPlaylist *inst, int fileId)
{
    QueuePlaylistEngine *instance = (QueuePlaylistEngine *) inst;

    lstFlist_add_next (instance->filelist, lstFlist_tail (instance->filelist), (void *) fileId);

    return (true);
}

static bool
queue_playlist_engine_remove_file (IPlaylist *inst, int fileId)
{
    QueuePlaylistEngine *instance = (QueuePlaylistEngine *) inst;

    bool retRemoved = false;

    lstTlist_elem *elem = lstFlist_head (instance->filelist);

    while (elem)
    {
        lstTlist_elem *next = lstFlist_next (elem);

        if ((int) lstFlist_data (elem) == fileId)
        {
            lstFlist_remove (instance->filelist, elem, NULL);

            retRemoved = true;
        }

        elem = next;
    }

    return (retRemoved);
}

static IIterator *
queue_playlist_engine_get_list_iterator (IPlaylist *inst)
{
    QueuePlaylistEngine *instance = (QueuePlaylistEngine *) inst;

    return ((IIterator *) list_iterator_new (instance->filelist));
}
