#include "mcdp.h"

/**
 * Copyright (C) 2001-2006 Tino Reichardt
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2, as
 * published by the Free Software Foundation.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* READ TOC/PMA/ATIP COMMAND (10)
 *
 * 0 = op code (0x43)
 * 1 = 1=time, all other=reserved
 * 2 = 3210=format
 * 3 = reserved
 * 4 = reserved
 * 5 = reserved
 * 6 = track number (hex)
 * 7 = allocation len (msb)
 * 8 = allocation len (lsb)
 * 9 = control
 */

static inline u32 cd_cddbsum(register int n);

static inline u32 cd_cddbsum(register int n)
{
	register u32 ret=0;

	while (n>0) {
		ret += (n % 10);
		n /= 10;
	}

	return ret;
}

void scmd_initdisc(void)
{
	int i=0, full, off;
	u32 n;
	u16 t;
	u8 *x;

	scmd_ready(10, 4);
#if DEBUG_CDB
	if (!stralloc_copys(&cdb.name, "READ TOC/PMA/ATIP COMMAND (10)")) die_nomem();
#endif

	cdb.cmd.s[0]=0x43;
	cdb.cmd.s[8]=0x04; /* readtoc, format=0 */
	cdb.flags=D_READ;
	cd->cmd(&cdb);

	x=(u8*)cdb.buf.s;
	cd->titles = (x[3] - x[2] + 1);
	if ((cd->titles > MCDP_CDAUDIO_MAX) || (cd->titles == 0)) {
		cd->ds=DS_NODISC;
		return;
	}
	full=4+(cd->titles+1)*8; /* header(4) + tracks(11) + leadout(11) */

	scmd_ready(10, full);
	cdb.cmd.s[0]=0x43;
	cdb.cmd.s[8]=full; /* readtoc, format=0 */
	cdb.flags=D_READ;
	cd->cmd(&cdb);

	x=(u8*)cdb.buf.s;
	for (off=4; off<full; off+=8,i++) {
		t=x[off+2];
		if (t == 0xaa) t=0;

		n= (x[off+7])
		 + (x[off+6]<<8)
		 + (x[off+5]<<16)
		 + (x[off+4]<<24);

		cd->t[t].copy =x[off+1] & 0x02; /* can we copy ? */
		cd->t[t].audio=x[off+1] & 0x04; /* is it audio? */

		cd->t[t].lba=n;
		cd->t[t].cddb=n+150;
	}

	for (i=0; i <= cd->titles; i++) {
		/* calculate len of each track */
		if (i == cd->titles) {
			/* last two tracks */
			cd->t[i-1].len=cd->t[i].lba - cd->t[i-1].lba;
			cd->t[i].len=cd->t[0].lba - cd->t[i].lba; /* -> last one */
		} else if (i == 0) {
			/* track 1 */
			cd->t[i].len=cd->t[1].lba;
		} else {
			/* all other tracks */
			cd->t[i-1].len=cd->t[i].lba - cd->t[i-1].lba;
		}
	}
	
	/* calculate cddb discid */
	for (n=0, i=1; i <= cd->titles; i++) {
		n+=cd_cddbsum(cd->t[i].cddb/75);
	}

	cd->discid=((n%0xff) << 24
		| (cd->t[0].cddb/75 - cd->t[1].cddb/75) << 8 | cd->titles);

	if (!stralloc_copys(&cd->cddbfile, mcdp_env_cddb_path)) die_nomem();
	if (!stralloc_cats(&cd->cddbfile, "/")) die_nomem();
	if (!stralloc_cat_x32pw(&cd->cddbfile, cd->discid, 8, '0')) die_nomem();
	if (!stralloc_0(&cd->cddbfile)) die_nomem();

	/* open trackdate, if possible */
	db_free();
	db_cddb();
	if (isset(cd->db, DB_CDDB)) return;

	db_free();
	db_wmdb();
	if (isset(cd->db, DB_CDDB)) return;

	return;
}

