/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

/* This is the CD-audio control API for Simple DirectMedia Layer */

#include "SDL_cdrom.h"
#include "SDL_syscdrom.h"

#if !defined(__MACOS__)
#define CLIP_FRAMES	10	/* Some CD-ROMs won't go all the way */
#endif

static int SDL_cdinitted = 0;
static SDL_CD *default_cdrom;

/* The system level CD-ROM control functions */
struct CDcaps SDL_CDcaps = {
	NULL,					/* Name */
	NULL,					/* Open */
	NULL,					/* GetTOC */
	NULL,					/* Status */
	NULL,					/* Play */
	NULL,					/* Pause */
	NULL,					/* Resume */
	NULL,					/* Stop */
	NULL,					/* Eject */
	NULL,					/* Close */
};
int SDL_numcds;

int SDL_CDROMInit(void)
{
	int retval;

	SDL_numcds = 0;
	retval = SDL_SYS_CDInit();
	if ( retval == 0 ) {
		SDL_cdinitted = 1;
	}
	default_cdrom = NULL;
	return(retval);
}

/* Check to see if the CD-ROM subsystem has been initialized */
static int CheckInit(int check_cdrom, SDL_CD **cdrom)
{
	int okay;

	okay = SDL_cdinitted;
	if ( check_cdrom && (*cdrom == NULL) ) {
		*cdrom = default_cdrom;
		if ( *cdrom == NULL ) {
			SDL_SetError("CD-ROM not opened");
			okay = 0;
		}
	}
	if ( ! SDL_cdinitted ) {
		SDL_SetError("CD-ROM subsystem not initialized");
	}
	return(okay);
}

int SDL_CDNumDrives(void)
{
	if ( ! CheckInit(0, NULL) ) {
		return(-1);
	}
	return(SDL_numcds);
}

const char *SDL_CDName(int drive)
{
	if ( ! CheckInit(0, NULL) ) {
		return(NULL);
	}
	if ( drive >= SDL_numcds ) {
		SDL_SetError("Invalid CD-ROM drive index");
		return(NULL);
	}
	if ( SDL_CDcaps.Name ) {
		return(SDL_CDcaps.Name(drive));
	} else {
		return("");
	}
}

SDL_CD *SDL_CDOpen(int drive)
{
	struct SDL_CD *cdrom;

	if ( ! CheckInit(0, NULL) ) {
		return(NULL);
	}
	if ( drive >= SDL_numcds ) {
		SDL_SetError("Invalid CD-ROM drive index");
		return(NULL);
	}
	cdrom = (SDL_CD *)SDL_malloc(sizeof(*cdrom));
	if ( cdrom == NULL ) {
		SDL_OutOfMemory();
		return(NULL);
	}
	SDL_memset(cdrom, 0, sizeof(*cdrom));
	cdrom->id = SDL_CDcaps.Open(drive);
	if ( cdrom->id < 0 ) {
		SDL_free(cdrom);
		return(NULL);
	}
	default_cdrom = cdrom;
	return(cdrom);
}

CDstatus SDL_CDStatus(SDL_CD *cdrom)
{
	CDstatus status;
	int i;
	Uint32 position;

	/* Check if the CD-ROM subsystem has been initialized */
	if ( ! CheckInit(1, &cdrom) ) {
		return(CD_ERROR);
	}

	/* Get the current status of the drive */
	cdrom->numtracks = 0;
	cdrom->cur_track = 0;
	cdrom->cur_frame = 0;
	status = SDL_CDcaps.Status(cdrom, &i);
	position = (Uint32)i;
	cdrom->status = status;

	/* Get the table of contents, if there's a CD available */
	if ( CD_INDRIVE(status) ) {
		if ( SDL_CDcaps.GetTOC(cdrom) < 0 ) {
			status = CD_ERROR;
		}
		/* If the drive is playing, get current play position */
		if ( (status == CD_PLAYING) || (status == CD_PAUSED) ) {
			for ( i=1; cdrom->track[i].offset <= position; ++i ) {
				/* Keep looking */;
			}
#ifdef DEBUG_CDROM
  fprintf(stderr, "Current position: %d, track = %d (offset is %d)\n",
				position, i-1, cdrom->track[i-1].offset);
#endif
			cdrom->cur_track = i-1;
			position -= cdrom->track[cdrom->cur_track].offset;
			cdrom->cur_frame = position;
		}
	}
	return(status);
}

int SDL_CDPlayTracks(SDL_CD *cdrom,
			int strack, int sframe, int ntracks, int nframes)
{
	int etrack, eframe;
	int start, length;

	/* Check if the CD-ROM subsystem has been initialized */
	if ( ! CheckInit(1, &cdrom) ) {
		return(CD_ERROR);
	}

	/* Determine the starting and ending tracks */
	if ( (strack < 0) || (strack >= cdrom->numtracks) ) {
		SDL_SetError("Invalid starting track");
		return(CD_ERROR);
	}
	if ( ! ntracks && ! nframes ) {
		etrack = cdrom->numtracks;
		eframe = 0;
	} else {
		etrack = strack+ntracks;
		if ( etrack == strack ) {
			eframe = sframe + nframes;
		} else {
			eframe = nframes;
		}
	}
	if ( etrack > cdrom->numtracks ) {
		SDL_SetError("Invalid play length");
		return(CD_ERROR);
	}

	/* Skip data tracks and verify frame offsets */
	while ( (strack <= etrack) &&
			(cdrom->track[strack].type == SDL_DATA_TRACK) ) {
		++strack;
	}
	if ( sframe >= (int)cdrom->track[strack].length ) {
		SDL_SetError("Invalid starting frame for track %d", strack);
		return(CD_ERROR);
	}
	while ( (etrack > strack) &&
			(cdrom->track[etrack-1].type == SDL_DATA_TRACK) ) {
		--etrack;
	}
	if ( eframe > (int)cdrom->track[etrack].length ) {
		SDL_SetError("Invalid ending frame for track %d", etrack);
		return(CD_ERROR);
	}

	/* Determine start frame and play length */
	start = (cdrom->track[strack].offset+sframe);
	length = (cdrom->track[etrack].offset+eframe)-start;
#ifdef CLIP_FRAMES
	/* I've never seen this necessary, but xmcd does it.. */
	length -= CLIP_FRAMES;	/* CLIP_FRAMES == 10 */
#endif
	if ( length < 0 ) {
		return(0);
	}

	/* Play! */
#ifdef DEBUG_CDROM
  fprintf(stderr, "Playing %d frames at offset %d\n", length, start);
#endif
	return(SDL_CDcaps.Play(cdrom, start, length));
}

int SDL_CDPlay(SDL_CD *cdrom, int sframe, int length)
{
	/* Check if the CD-ROM subsystem has been initialized */
	if ( ! CheckInit(1, &cdrom) ) {
		return(CD_ERROR);
	}

	return(SDL_CDcaps.Play(cdrom, sframe, length));
}

int SDL_CDPause(SDL_CD *cdrom)
{
	CDstatus status;
	int retval;

	/* Check if the CD-ROM subsystem has been initialized */
	if ( ! CheckInit(1, &cdrom) ) {
		return(CD_ERROR);
	}

	status = SDL_CDcaps.Status(cdrom, NULL);
	switch (status) {
		case CD_PLAYING:
			retval = SDL_CDcaps.Pause(cdrom);
			break;
		default:
			retval = 0;
			break;
	}
	return(retval);
}

int SDL_CDResume(SDL_CD *cdrom)
{
	CDstatus status;
	int retval;

	/* Check if the CD-ROM subsystem has been initialized */
	if ( ! CheckInit(1, &cdrom) ) {
		return(CD_ERROR);
	}

	status = SDL_CDcaps.Status(cdrom, NULL);
	switch (status) {
		case CD_PAUSED:
			retval = SDL_CDcaps.Resume(cdrom);
		default:
			retval = 0;
			break;
	}
	return(retval);
}

int SDL_CDStop(SDL_CD *cdrom)
{
	CDstatus status;
	int retval;

	/* Check if the CD-ROM subsystem has been initialized */
	if ( ! CheckInit(1, &cdrom) ) {
		return(CD_ERROR);
	}

	status = SDL_CDcaps.Status(cdrom, NULL);
	switch (status) {
		case CD_PLAYING:
		case CD_PAUSED:
			retval = SDL_CDcaps.Stop(cdrom);
		default:
			retval = 0;
			break;
	}
	return(retval);
}

int SDL_CDEject(SDL_CD *cdrom)
{
	/* Check if the CD-ROM subsystem has been initialized */
	if ( ! CheckInit(1, &cdrom) ) {
		return(CD_ERROR);
	}
	return(SDL_CDcaps.Eject(cdrom));
}

void SDL_CDClose(SDL_CD *cdrom)
{
	/* Check if the CD-ROM subsystem has been initialized */
	if ( ! CheckInit(1, &cdrom) ) {
		return;
	}
	SDL_CDcaps.Close(cdrom);
	SDL_free(cdrom);
	default_cdrom = NULL;
}

void SDL_CDROMQuit(void)
{
	SDL_SYS_CDQuit();
	SDL_cdinitted = 0;
}
