/* Mednafen - Multi-system Emulator
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <string.h>
#include <sys/types.h>
#include <cdio/cdio.h>
#include "mednafen.h"
#include "cdromif.h"
#include "cdromfile.h"
#include "general.h"

typedef struct __TRACK_INFO
{
        lba_t LSN;
        track_format_t Format;
} TRACK_INFO;

typedef struct __CD_INFO
{
        track_t NumTracks;
        track_t FirstTrack;
        TRACK_INFO Tracks[100]; // Track #0(HMM?) through 99
} CD_INFO;

static CD_INFO CD_Info;
static CDRFile *p_cdrfile = NULL;

bool CDIF_ReadAudioSector(int16 *buffer, uint32 read_sec)
{
 return(cdrfile_read_audio_sector(p_cdrfile, buffer, read_sec));
}

bool CDIF_Open(const char *device_name)
{
 MDFN_printf(_("Loading %s...\n\n"), device_name ? device_name : _("PHYSICAL CDROM DISC"));
 MDFN_indent(1);

 if(!(p_cdrfile = cdrfile_open(device_name)))
 {
  MDFN_indent(-1);
  return(0);
 }

 CD_Info.NumTracks = cdrfile_get_num_tracks(p_cdrfile);
 if(CD_Info.NumTracks < 1 || CD_Info.NumTracks > 100)
 {
  MDFN_indent(-1);
  return(0);
 }

 CD_Info.FirstTrack = cdrfile_get_first_track_num(p_cdrfile);

 for(track_t track = CD_Info.FirstTrack; track < CD_Info.FirstTrack + CD_Info.NumTracks; track++)
 {
  CD_Info.Tracks[track].LSN = cdrfile_get_track_lsn(p_cdrfile, track);
  CD_Info.Tracks[track].Format = cdrfile_get_track_format(p_cdrfile, track);
  MDFN_printf(_("Track %2d, LSN: %6d %s\n"), track, CD_Info.Tracks[track].LSN, track_format2str[CD_Info.Tracks[track].Format]);
 }
 MDFN_indent(-1);
 return(1);
}

bool CDIF_Close(void)
{
 cdrfile_destroy(p_cdrfile);
 p_cdrfile = NULL;

 return(1);
}

bool CDIF_Init(void)
{
 return(1);
}

void CDIF_Deinit(void)
{

}

int32 CDIF_GetFirstTrack()
{
 return(CD_Info.FirstTrack);
}

int32 CDIF_GetLastTrack()
{
 return(CD_Info.FirstTrack + CD_Info.NumTracks - 1);
}

uint32 CDIF_GetTrackStartPositionMSF(int32 track)
{
 uint32          lba;
 uint8           min;
 uint8           sec;
 uint8           frame;
 uint8           datatrack;

 if(track < CD_Info.FirstTrack || track >= (CD_Info.FirstTrack + CD_Info.NumTracks))
  return(0);

 lba   = CD_Info.Tracks[track].LSN + 150;
 min   = (uint8)(lba / 75 / 60);
 sec   = (uint8)((lba - (uint32)min * 75 * 60) / 75);
 frame = (uint8)(lba - ((uint32)min * 75 * 60) - ((uint32)sec * 75));

 datatrack = (CD_Info.Tracks[track].Format == TRACK_FORMAT_AUDIO) ? 0 : 4;

 return (min << 24) + (sec << 16) + (frame << 8) + datatrack;
}

uint32 CDIF_GetSectorCountLBA(void)
{
 return(cdrfile_stat_size(p_cdrfile));
}

uint32 CDIF_GetTrackStartPositionLBA(int32 track)
{
 if(track < CD_Info.FirstTrack || track >= (CD_Info.FirstTrack + CD_Info.NumTracks))
  return(0);
 return(CD_Info.Tracks[track].LSN + 150);
}

bool CDIF_ReadSector(uint8* pBuf, uint32 lsn_sector, uint32 nSectors)
{
 return(cdrfile_read_mode1_sectors(p_cdrfile, pBuf, lsn_sector, false, nSectors));
}

/*-----------------------------------------------------------------------------
	[ReadSubChannelQ]
		Ｑサブチャネルを読み出します。
-----------------------------------------------------------------------------*/
bool CDIF_ReadSubChannelQ(
	int8*		pBuf,		// 10-byte buffer
	bool		bCallback)
{
 //puts("Read subchannel Q");
 return(1);
}
