/***************************************************************************
 * copyright            : (C) 2006 Ian Monroe <ian@monroe.nu>              *
 **************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#ifndef DAAPREADER_H
#define DAAPREADER_H

#include <tqobject.h>

#include <kurl.h>

class TQString;

template <class T>
class TQPtrList;
class MetaBundle;
class ServerItem;
class TQHttpResponseHeader;

namespace Daap
{
    typedef TQPtrList< MetaBundle >     TrackList;
    typedef TQMap< TQString, TrackList > AlbumList;
    typedef TQMap< TQString, AlbumList > SongList;

//typedef TQMap<TQString, TQMap<TQString, TQPtrList<MetaBundle> > > SongList;

    enum ContentTypes { INVALID = 0, CHAR = 1, SHORT = 2, LONG = 5, LONGLONG = 7,
                        STRING = 9, DATE = 10, DVERSION = 11, CONTAINER = 12 };
    struct Code
    {
        Code() : type(INVALID) { }
        Code( const TQString& nName, ContentTypes nType ) : name( nName ), type( nType ) { }
        ~Code() { }
        TQString name;
        ContentTypes type;
    };



    /**
        The nucleus of the DAAP client; composes queries and parses responses.
        @author Ian Monroe <ian@monroe.nu>
    */
    class Reader : public TQObject
    {
        Q_OBJECT
  

        public:
            Reader( const TQString& host, TQ_UINT16 port, ServerItem* root,
                    const TQString& password, TQObject* parent, const char* name );
           ~Reader();

            //TQPtrList<MetaBundle> getSongList();
            enum Options { SESSION_ID = 1, SERVER_VERSION = 2  };
            void loginRequest();
            void logoutRequest();
            ServerItem* rootMediaItem() const { return m_root; }

            int sessionId() const { return m_sessionId; }
            TQString host() const { return m_host; }
            TQ_UINT16 port() const { return m_port; }
        public slots:
            void logoutRequest(int, bool );
            void loginHeaderReceived( const TQHttpResponseHeader& resp );
            void loginFinished( int id , bool error );
            void updateFinished( int id , bool error );
            void databaseIdFinished( int id , bool error );
            void songListFinished( int id, bool error );
            void fetchingError( const TQString& error );

        signals:
            void daapBundles( const TQString& host, Daap::SongList bundles );
            void httpError( const TQString& );
            void passwordRequired();

        private:
            /**
            * Make a map-vector tree out of the DAAP binary result
            * @param raw stream of DAAP reply
            * @param containerLength length of the container (or entire result) being analyzed
            */
            static TQStringVariantMap parse( TQDataStream &raw, uint containerLength, bool first = false );
            static void addElement( TQStringVariantMap &parentMap, char* tag, TQVariant element ); //! supporter function for parse
            static TQ_UINT32 getTagAndLength( TQDataStream &raw, char tag[5] );

            static TQMap<TQString, Code> s_codes;

            TQString m_host;
            TQ_UINT16 m_port;
            TQString m_loginString;
            TQString m_databaseId;
            int m_sessionId;
            ServerItem* m_root;
            TQString m_password;

    };

}

#endif
