#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.
 */

/**
 * small and ugly cd-text reading :)
 *
 *  NOTES TO CD-TEXT DATA
 * =======================
 *
 *
 * + 80 Title of album or track              -> t[].name2
 * + 81 Name(s) of the performer(s)          -> t[].name1
 * + 82 Name(s) of the songwriter(s)         -> t[].extd
 * + 83 Name(s) of the composer(s)           -> t[].extd
 * + 84 Name(s) of the arranger(s)           -> t[].extd
 * + 85 Message from content provider        -> t[].extd
 * - 86 Disc Identification and information  -> unused
 * + 87 Genre Identification and information -> t[].genre
 * - 88 Table of Content information         -> unused
 * - 89 Second Table of Content information  -> unused
 * - 8e UPC/EAN code or ISRC code            -> unused
 * - 8f Size information of the block        -> unused
 *
 *
 *
 *  CD-TEXT DATA IS CONVERTED TO CDDB
 * ===================================
 *
 *
 * DISCID:       12345678
 * DYEAR:
 * DGENRE:       0x87
 * PLAYORDER:
 *
 * DTITLE:       0x81 / 0x80
 * TTITLE[0..N]: 0x81 / 0x80
 *
 * EXTD:         0x82 0x83 0x84 0x85 0x86
 * EXTT[0..N]:   0x82 0x83 0x84 0x85 0x86
 *
 * /TR 2006-03-08
 */

#define DB_HAVE_0x80 0x01
#define DB_HAVE_0x81 0x02
#define DB_HAVE_0x82 0x04
#define DB_HAVE_0x83 0x08
#define DB_HAVE_0x84 0x10
#define DB_HAVE_0x85 0x20
#define DB_HAVE_0x86 0x40
#define DB_HAVE_0x87 0x80

void db_cdtext(void)
{
	stralloc sa80, sa81, sa82, sa83, sa84, sa85, sa86, sa87;
	int size, found=0, i;
	u8 *data, *text;
	char *x;

	stralloc_init(&sa80);
	stralloc_init(&sa81);
	stralloc_init(&sa82);
	stralloc_init(&sa83);
	stralloc_init(&sa84);
	stralloc_init(&sa85);
	stralloc_init(&sa86);
	stralloc_init(&sa87);

	cd->cd_stop();

	scmd_ready(10,2);
#if DEBUG_CDB
	if (!stralloc_copys(&cdb.name, "READ TOC/PMA/ATIP COMMAND (10) / REQUEST SIZE OF CD-TEXT")) die_nomem();
#endif
	cdb.cmd.s[0]=0x43; /* read toc/atip */
	cdb.cmd.s[2]=0x05; /* read cd-text */
	cdb.cmd.s[8]=0x02; /* first two bytes */
	cdb.flags=D_READ;
	if (cd->cmd(&cdb) == -1) return;

	data=(u8*)cdb.buf.s;
	size=(data[0]<<8) | (data[1]);

	if (size < 3) return; /* to small */
	if (size > 8*255*18) return; /* max size a cd-text may have */

	scmd_ready(10, size);
#if DEBUG_CDB
	if (!stralloc_copys(&cdb.name, "READ TOC/PMA/ATIP COMMAND (10) / REQUEST CD-TEXT")) die_nomem();
#endif
	cdb.cmd.s[0]=0x43; /* read toc/atip */
	cdb.cmd.s[2]=0x05; /* read cd-text */
	cdb.cmd.s[7]=size >> 8;
	cdb.cmd.s[8]=size; /* full length */
	cdb.flags=D_READ;
	if (cd->cmd(&cdb) == -1) return;
	text=(u8*)cdb.buf.s;

	/* cd-text:
	 * data[0-4]   => header (only used a bit)
	 * data[5-16]  => data
	 * data[17-18] => crc (currently not used)
	 */
	for (i=0; i < size; i+=18) {
		data=text+4+i;

		/* we don't understand double byte character code! */
		if ((data[2] & 0x80) >> 7) return;

		switch (data[0]) {
		case 0x80: /* Title of album or track */
			set(found, DB_HAVE_0x80);
			if (!stralloc_catb(&sa80, (char*)data+4, 12))
				die_nomem();
			break;
		case 0x81: /* Name(s) of the performer(s) */
			set(found, DB_HAVE_0x81);
			if (!stralloc_catb(&sa81, (char*)data+4, 12))
				die_nomem();
			break;
		case 0x82: /* Name(s) of the songwriter(s) */
			set(found, DB_HAVE_0x82);
			if (!stralloc_catb(&sa82, (char*)data+4, 12))
				die_nomem();
			break;
		case 0x83: /* Name(s) of the composer(s) */
			set(found, DB_HAVE_0x83);
			if (!stralloc_catb(&sa83, (char*)data+4, 12))
				die_nomem();
			break;
		case 0x84: /* Name(s) of the arranger(s) */
			set(found, DB_HAVE_0x84);
			if (!stralloc_catb(&sa84, (char*)data+4, 12))
				die_nomem();
			break;
		case 0x85: /* Message from content provider and/or artist */
			set(found, DB_HAVE_0x85);
			if (!stralloc_catb(&sa85, (char*)data+4, 12))
				die_nomem();
			break;
		case 0x86: /* Disc Identification and information */
			set(found, DB_HAVE_0x86);
			if (!stralloc_catb(&sa86, (char*)data+4, 12))
				die_nomem();
			break;
		case 0x87: /* Genre Identification and information */
			set(found, DB_HAVE_0x87);
			if (!stralloc_catb(&sa87, (char*)data+4, 12))
				die_nomem();
			break;
		}
	}

#if 0
	buffer_puts(buffer_2, "\n0x80: "); buffer_putsa(buffer_2, &sa80);
	buffer_puts(buffer_2, "\n0x81: "); buffer_putsa(buffer_2, &sa81);
	buffer_puts(buffer_2, "\n0x82: "); buffer_putsa(buffer_2, &sa82);
	buffer_puts(buffer_2, "\n0x83: "); buffer_putsa(buffer_2, &sa83);
	buffer_puts(buffer_2, "\n0x84: "); buffer_putsa(buffer_2, &sa84);
	buffer_puts(buffer_2, "\n0x85: "); buffer_putsa(buffer_2, &sa85);
	buffer_puts(buffer_2, "\n0x86: "); buffer_putsa(buffer_2, &sa86);
	buffer_puts(buffer_2, "\n0x87: "); buffer_putsa(buffer_2, &sa87);
	buffer_flush(buffer_2);
#endif

	/* we can save 'artist / title' */
	if (isset(found, DB_HAVE_0x80) && isset(found, DB_HAVE_0x81)) {
		x = sa80.s;
		for (i=0; i <= cd->titles; i++) {
			if (!stralloc_copys(&cd->t[i].name, x)) die_nomem();
			x+=str_len(x)+1;
			if (!stralloc_cats(&cd->t[i].name, " / ")) die_nomem();
		}
		x = sa81.s;
		for (i=0; i <= cd->titles; i++) {
			if (!stralloc_cats(&cd->t[i].name, x)) die_nomem();
			cd->t[i].name.s[cd->t[i].name.len]=0;
			x+=str_len(x)+1;
		}
	}

	data=0;
	if (!stralloc_copys(&cd->t[0].extd, "")) die_nomem();
	if (isset(found, DB_HAVE_0x82)) {
		if (!stralloc_cat(&cd->t[0].extd, &sa82)) die_nomem();
		cd->t[0].extd.s[cd->t[0].extd.len]=0;
		data++;
	}

	if (isset(found, DB_HAVE_0x83)) {
		if (data) if (!stralloc_cats(&cd->t[0].extd, " / ")) die_nomem();
		if (!stralloc_cat(&cd->t[0].extd, &sa83)) die_nomem();
		cd->t[0].extd.s[cd->t[0].extd.len]=0;
		data++;
	}

	if (isset(found, DB_HAVE_0x84)) {
		if (data) if (!stralloc_cats(&cd->t[0].extd, " / ")) die_nomem();
		if (!stralloc_cat(&cd->t[0].extd, &sa84)) die_nomem();
		cd->t[0].extd.s[cd->t[0].extd.len]=0;
		data++;
	}

	if (isset(found, DB_HAVE_0x85)) {
		if (data) if (!stralloc_cats(&cd->t[0].extd, " / ")) die_nomem();
		if (!stralloc_cat(&cd->t[0].extd, &sa85)) die_nomem();
		cd->t[0].extd.s[cd->t[0].extd.len]=0;
		data++;
	}

	if (isset(found, DB_HAVE_0x86)) {
		if (data) if (!stralloc_cats(&cd->t[0].extd, " / ")) die_nomem();
		if (!stralloc_cat(&cd->t[0].extd, &sa86)) die_nomem();
		cd->t[0].extd.s[cd->t[0].extd.len]=0;
		data++;
	}

	if (isset(found, DB_HAVE_0x87)) {
		if (data) if (!stralloc_cats(&cd->t[0].extd, " / ")) die_nomem();
		if (!stralloc_copy(&cd->genre, &sa87)) die_nomem();
		cd->genre.s[cd->genre.len]=0;
	}

	stralloc_free(&sa80);
	stralloc_free(&sa81);
	stralloc_free(&sa82);
	stralloc_free(&sa83);
	stralloc_free(&sa84);
	stralloc_free(&sa85);
	stralloc_free(&sa86);
	stralloc_free(&sa87);
	cd->db=DB_CDDB;

	return;
}

