// {{{ the iWear header
/**
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 * In particular this file is part of the Framework Test Library
 *
 * The iWear Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the
 * Free Software Foundation as in version 2 of the License.

 * 
 * The iWear Framework 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
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
// }}}

#ifndef __PLAYLIST_H
#define __PLAYLIST_H
 
#ifndef __AUDIO_PLAYER_H
#include <iwear_audioplayer/audioplayer.h>
#endif

#ifndef __TEXTDATA_H
#include <iwear_output/textdata.h>
#endif

#ifndef __AUDIODATA_H
#include <iwear_output/audiodata.h>
#endif

#ifndef __TAG_H
#include <iwear_utils/tag.h>
#endif

#include <list>
#include <string> 
#include <fstream>
#include <stdio.h>
#include <iwear/threadlocked.h>

using namespace iwear::utilities;
using namespace iwear::output;

namespace iwear{
    namespace audioplayer{

// forward declaration
class AudioPlayer;

	class Playlist  : virtual public ThreadLocked
{
public: 

    /**
     * The constructor
     */
    Playlist(const string& sound_path, 
	     TextData* text_data, 
	     bool append, 
	     uint32_t max_entries);
    
    /**
     * The Destructor.
     */
    virtual ~Playlist(void);
 
    void parse_playlist(const char* m3u_file, bool append);

    void update_playlist(void);
    
    const string to_string(void);

    /*
    inline const std::ostream& operator<<(std::ostream& content){
	content << this->to_string(25);
	return content;
    }
    */

    const string next_song(void); 
    
    const string back_song(void); 

    inline string get_current_song(void){
	if(this->playlist.empty()){
	    THROW(iwlogic_error, ("Playlist is empty!"));
	}
	
	return this->current_tag->first->get_filename();
    }

    inline const AudioDataType get_audio_data_type(void){
	return this->current_tag->second; 
    }

    inline bool is_empty(void){
	return this->playlist.empty();
    }

    inline const string get_current_playlist_path(void){
	return this->playlist_path;
    }

    inline void set_current_playlist_path(string file_name){
	this->playlist_path = file_name;
    }
    
    string first_max_entries(void);

    string last_max_entries(string content_body);
    
    string in_the_center(string content_body, uint32_t song_counter);

    // TODO: outsourcing

    /**
     * Produce lowercase-only version of the string 
     * given as argument
     */
    string upper_case(string& s);

    /**
     * Produce uppercase-only version of the string
     * given as argument
     */
    string lower_case(string& s);

    inline const string get_playlist_string(void){
	return this->playlist_string;
    }

    /*
    inline const bool get_append_flag(void){
	return this->append_flag;
    }
    */

protected: 

//      virtual void Lock();
//      virtual void Unlock();

private:

    list< pair<Tag*, AudioDataType> > playlist;

    list< pair<Tag*, AudioDataType> >::iterator current_tag;

    string playlist_path;

    string playlist_name;

    TextData* text_data;
    
    // the number of entries (the titles of the songs) which should
    // been shown per page
    uint32_t max_entries;

    // the string which stores the append playlists
    string playlist_string; 
};

    } // namespace audioplayer
} // namespace iwear

#endif // __PLAYLIST

