/*
 * 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_toc.h,v 1.17 2002/11/07 09:09:12 pete Exp $
 *
 * ** omd_toc.h - Table of contents stuff
 */


#define OMD_RAW_TRACK_TITLE_MAX	255
#define OMD_TRACK_LENGTH_RAW_SIZE	10
#define OMD_TRACK_BITRATE_RAW_SIZE	8
typedef struct {
    uint8	*title;
    uint8	flags; 		/* Not quite sure what this is */
    omd_time_t	length;		/* Length of track */
    uint8	bitrate;
    uint8	mono;
    uint8	codec;		/* ATRAC version */
    const char	*bitrate_name;	/* Name string for bitrate - const! */
    const char	*codec_name;	/* Name string for CODEC - const! */
    int		group;		/* -1 means not in any group */
    int		loaded;		/* Have we loaded the info yet */
} omd_track_t;

#define OMD_BITRATE_SP		0x90
#define OMD_BITRATE_LP2		0x92
#define OMD_BITRATE_LP4		0x93
#define OMD_FLAG_STEREO		0x00
#define OMD_FLAG_MONO		0x01
#define OMD_CODEC_ATRAC		0x00
#define OMD_CODEC_ATRAC3	0x03

#define OMD_FLAG_LOCKED		0x03 /* XXX not sure */

typedef struct {
    uint8	*name;		/* Name of group	*/
    int		start;		/* First track in group	*/
    int		finish;		/* last track in group	*/
} omd_group_t;

#define OMD_RAW_DISC_TITLE_MAX	255
typedef struct {
    uint8		raw_title[OMD_RAW_DISC_TITLE_MAX + 1];
    uint8		*title;

    int			track_count;
    int			_maxtrack; /* Private */
    omd_track_t		*track;	/* Dynamic array of track info pointers */

    int			group_count;
    int			_maxgroup; /* Private */
    omd_group_t		*group;
} omd_toc_t;

/* Allocate/free functions - always use these rather than allocating/freeing
 * by hand to avoid resource leaks*/
omd_toc_t 	*omd_toc_allocate( );
void 		omd_toc_free( omd_toc_t *toc );


/* Track/group accessors - NB these don't pull anything off the disc */
omd_track_t *omd_toc_get_track( omd_toc_t *toc, int trackid );
omd_group_t *omd_toc_get_group( omd_toc_t *toc, int groupid );

/*
 * Allocate and read a disc's table of contents.  Can either be passed
 * existing disc_info or will read it's own from the unit
 *
 * XXX All the track/group stuff needs rationalising - too much
 * overlap/duplication
 */
omd_toc_t *omd_toc_read( omd_unit_t *unit, omd_disc_info_t *discinfo,
			 int read_groups, int read_tracks );

/* Read or refresh track info from disc into TOC structure */
int omd_toc_read_tracks( omd_unit_t *unit, omd_toc_t *toc, int first,int last);
#define omd_toc_read_all_tracks( unit, toc )				\
	omd_toc_read_tracks( (unit), (toc), 0, (toc)->track_count - 1 )

int omd_toc_refresh_tracks( omd_unit_t *unit, omd_toc_t  *toc,
			    omd_disc_info_t *discinfo );

/* Read or refresh track info from disc into TOC structure */
int omd_toc_read_groups( omd_unit_t *unit, omd_toc_t *toc );


/* 'Lazy' info loading.  Find a track info structure in a TOC, load
 * it from disc only if it is not already in memory */
omd_track_t *omd_toc_track_info( omd_unit_t *unit, omd_toc_t *toc, int track );
/* Invalidate the info in a TOC structure so it gets reloaded from disc */
int omd_toc_invalidate_track( omd_unit_t *unit, omd_toc_t *toc, int track );


/* Read all the info for a track into a pre-allocated omd_track_t */
int	omd_read_track_info(omd_unit_t *unit, int n, omd_track_t *track);

/* Rename a track */
int	omd_rename_track( omd_unit_t *unit, int track,
				  omd_track_t *oldinfo, const char *newname);
/* Move a track */
int	omd_toc_move_track( omd_unit_t *unit,
				    omd_toc_t *toc, int src, int dst );
/* Delete a track */
int	omd_toc_delete_track( omd_unit_t *unit, omd_toc_t *toc, int track );

/* Add a group */
int	omd_toc_add_group( omd_toc_t *toc, int first, int last,
				   const char *name );
/* Delete a group */
int	omd_toc_delete_group( omd_toc_t *toc, int groupidx );

/* Rename a group */
int	omd_toc_rename_group( omd_toc_t *toc, int groupidx,
				      const char *name );
/* Retitle the disc */
int	omd_toc_set_title( omd_toc_t *toc, const char *name );

/* Sort the groups in a toc */
void	omd_toc_sort_groups( omd_toc_t *toc );

/* Generate new disc title and write it out */
int	omd_toc_write_title( omd_unit_t *unit, omd_toc_t *toc );

/* Find the group for a track */
int	omd_toc_group_for_track( omd_toc_t *toc, int trk );

