/*
 * cdda_cddb.h: The cddb acccess implementation
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id: cdda_cddb.h,v 1.11 2005/12/22 10:40:41 cm Exp $
 */

#ifndef __CDDACDDB_H
#define __CDDACDDB_H

#include <vdr/thread.h>
#include <netinet/in.h>
#include <unistd.h>
#include "cdda_device.h"

class cCddaCddbCommon {
  private:
    char *FixString(char *string);
    char *ConCatString(const char *first, const char *second);
  protected:
    cCddaCddbCommon();
    ~cCddaCddbCommon();
    enum eGenre { cgBlues = 0, cgClassical, cgCountry, cgData, cgFolk, cgJazz,
                  cgNewAge, cgReggae, cgRock, cgSoundtrack, cgMisc, cgMAX };
    static const char *Genre[];
    char *Read(int fd, int &length);
    void Parse(cCddaTag *tag[], int num, const char *genre, const char *key, const char *value);
    void Store(cCddaDisc *disc, cCddaTag *tag[], int num);
};

class cCddaCddbCache : public cCddaCddbCommon {
  private:
    char *mp_directory;
    cCddaDisc *mpo_disc;
    bool TestDirectory(const char *dir);
  public:
    cCddaCddbCache(cCddaDisc *disc, const char *dir);
    ~cCddaCddbCache();
    bool Write(unsigned long id, const char *genre, const char *data, int length);
    bool Query(unsigned long id);
    bool Delete(unsigned long id, const char *genre);
};

class cCddaCddbServer : public cCddaCddbCommon {
  private:
    int m_sockfd;
    struct sockaddr_in m_serverAddr;
    char *mp_fqdn;
    static const char * const g_username;
    static const char * const g_hostname;
    static const char * const g_clientname;
    static const char * const g_version;
    cCddaDisc *mpo_disc;
    cCddaCddbCache *mpo_cache;
    bool LookupHost(void);
  public:
    cCddaCddbServer(cCddaDisc *disc, const char *fqdn, unsigned int port);
    ~cCddaCddbServer();
    bool Connect(void);
    void Disconnect(void);
    bool isConnected(void) const { return -1 != m_sockfd; };
    bool Query(unsigned long id, unsigned char numTracks, unsigned int length, int offsets[]);
    void SetCache(cCddaCddbCache *cache);
};

class cCddaCddb : cThread {
  private:
    cCddaDevice *mpo_device;
    static cCddaCddb *gpo_cddb;
    void Action();
    cCddaCddb();
  public:
    static cCddaCddb& GetInstance(void);
    ~cCddaCddb();
    bool Query(cCddaDevice *device);
    bool Delete(unsigned long id, const char *genre);
};

#endif
