#ifndef __CD_LL_H
#define __CD_LL_H

// abstract base class for lowlevel cd functions.

// couple of structs. the lowlevel code for each system converts the
// information from native structs to these before passing the
// information upwards, so the higher-level code only needs to deal
// with these.

// first, an enum type for the possible statuses (sp?)
enum audio_status_t { CD_LL_PLAYING, CD_LL_PAUSED, CD_LL_NO_STATUS,
                      CD_LL_INVALID, CD_LL_PLAY_COMPLETED };

// volume info
struct cd_ll_volume {
    int left,right;   // these are supposed to be in the 0-255 range
};

// table of contents header
// used only for reading the number of tracks on the cd
struct cd_ll_toc_header {
    int tracks;       // number of tracks on the cd
};

// play specified tracks
struct cd_ll_tracks {
    int start_track, end_track; // guess what these are...
};

// information about the current status of the drive
struct cd_ll_status {
    audio_status_t audio_status;   // current status
    int track;                     // currently playing track
};


// then, the actual base class
// subclass this for each system you want to port the program to,
// and implement the needed functionality.
class cd_ll {
public:
    // virtual destructor
    virtual ~cd_ll() { };
    
    // open the device
    virtual void open(void) = 0;

    // close the device
    virtual void close(void) = 0;

    // return open status
    virtual bool is_open(void) = 0;
    
    // read table of contents header
    virtual int read_toc_header(cd_ll_toc_header* toc_hdr) = 0;
    
    // read status information (often called subchannel for some reason)
    virtual int read_status(cd_ll_status* st) = 0;

    // start spinning the drive
    virtual int start(void) = 0;

    // play specified tracks
    virtual int play(cd_ll_tracks* t) = 0;
    
    // stop
    virtual int stop(void) = 0;

    // pause
    virtual int pause(void) = 0;

    // resume
    virtual int resume(void) = 0;

    // eject
    virtual int eject(void) = 0;

    // set volume
    virtual int set_volume(cd_ll_volume* vol) = 0;

    // read volume
    virtual int read_volume(cd_ll_volume* vol) = 0;
};


#endif // __CD_LL_H
