/*
 * Copyright (c) 2002, Peter Bentley
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 *   Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 
 *   Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 
 *   The name Peter Bentley may not be used to endorse or promote
 * products derived from this software without specific prior
 * written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: omd_unit.h,v 1.13 2003/08/25 17:13:06 pete Exp $
 *
 */

/* Busy callback (for GUIs */
typedef void (*omd_busy_handler)( void *userdata, int isbusy );

/*
 * Structure holding all the info needed to access a unit over USB
 */
typedef struct omd_unit_info omd_unit_info_t;
typedef struct {
    /* Private members: Use at your own risk - implementation may change */
    struct usb_device		*device;
    usb_dev_handle		*handle;
    int				busid;   	/* Which bus? (used for ID) */
    int				devid;   	/* Position on bus */
    int				open;	 	/* Opened?*/
    int				marked;	 	/* Used to detect detaches */
    int				changed; 	/* Changed on last USB scan? */

    omd_busy_handler		busy_handler;	/* Busy/idle callback */
    void			*busy_data;

    /* Public members (read-only though) XXX provide accessor macors */
    const omd_unit_info_t	*info;
    const char			*vendor;	/* As reported by device */
    const char			*product;	/* As reported by device */
    int				vendorid;
    int				productid;
    int				present; 	/* Still there? */

    /* Public (for application convenience) */
    void			*userdata;
    
} omd_unit_t;

/*
 * Structure describing what we know about a NetMD unit
 */
struct omd_unit_info {
    unsigned int	vendor_id;
    unsigned int	product_id;
    const char		*vendor;	/* In our opinion... */
    const char		*model;
};

/*
 * Structure to hold a netmd unit's status.  We're not entirely
 * sure what the raw data holds, although we're reasonably sure
 * about the "disk inserted" flag
 */
#define OMD_UNIT_STATUS_RAW_SIZE	7
typedef struct {
    uint8		raw[OMD_UNIT_STATUS_RAW_SIZE];
    int			disc_inserted;
} omd_unit_status_t;

/*
 * structures to hold playback status... still not sure what all the
 * numbers mean
 */
#define OMD_PLAYBACK_STATUS_A_RAW_SIZE	12
typedef struct {
    uint8		raw[OMD_PLAYBACK_STATUS_A_RAW_SIZE];
} omd_playback_status_a_t;

#define OMD_PLAYBACK_STATUS_B_RAW_SIZE	6
typedef struct {
    uint8		raw[OMD_PLAYBACK_STATUS_B_RAW_SIZE];
    uint16		playback_mode;
} omd_playback_status_b_t;

/* Values for playback_mode */
#define OMD_PAUSED	0xc37d
#define OMD_PLAY	0xc375
#define OMD_FFORWARD	0xc33f
#define OMD_REWIND	0xc34f
#define OMD_STOPPED	0xc5ff
#define OMD_TOC_SYNC	0xff24

#define OMD_PLAYBACK_POSITION_RAW_SIZE	11
typedef struct {
    uint8		raw[OMD_PLAYBACK_POSITION_RAW_SIZE];
    int			track;
    omd_time_t		position;
} omd_playback_position_t;
    


int omd_open_unit( omd_unit_t *unit );
void omd_close_unit( omd_unit_t *unit );
int omd_num_devices( void );

/* Release all NetMD devices - returns 0 on sucess, -1 on failure */
int omd_close_all_devices();

/* Get a pointer to the entry for the nth unit, or NULL on error */
omd_unit_t *omd_get_unit( int no );
omd_unit_t *omd_open_default_unit(  );
int omd_scan_usb();
int omd_probe_all();

/* Get various status - if status param is NULL, a struct will be malloced */
omd_unit_status_t *omd_get_unit_status( omd_unit_t *unit,
					omd_unit_status_t *status);

omd_playback_status_a_t *omd_get_playback_status_a( omd_unit_t *unit,
						    omd_playback_status_a_t
						    *status);

omd_playback_status_b_t *omd_get_playback_status_b( omd_unit_t *unit,
						    omd_playback_status_b_t
						    *status);

omd_playback_position_t *omd_get_playback_position( omd_unit_t *unit,
						    omd_playback_position_t
						    *status);

/* Set playback track and position */
int omd_set_playback_track( omd_unit_t *unit, int track );
int omd_set_playback_position( omd_unit_t *unit,omd_playback_position_t *pos);

/* Busy handler */
void omd_unit_set_busy_handler( omd_unit_t *unit, omd_busy_handler handler, void *userdata);
void omd_unit_busy( omd_unit_t *unit );
void omd_unit_idle( omd_unit_t *unit );



