#include "ecdb.h"

void ecdb_drive_info_free_cb(void *data);

int
ecdb_aquire_drive_info(void)
{
	int ret, i;
	unsigned int drive_num;
	struct burn_drive_info *drives_current;
	struct burn_speed_descriptor *speeds;

	ecdb_burn_init();

	ret = 0;
	if (em->drives)
		ecore_list_destroy(em->drives);

	em->drives = ecore_list_new();
	ecore_list_free_cb_set(em->drives, ecdb_drive_info_free_cb);

	while (!ret)
		ret = burn_drive_scan(&drives_current, &drive_num);

	for (i = 0; i < drive_num; i++)
	{
		Ecdb_Drive_Info *drive;

		drive = calloc(1, sizeof(Ecdb_Drive_Info));

		if (!drive)
			return FALSE;

		/* It would be nice if there was an easier way to do this */
		drive->product = strdup(drives_current[i].product);
		drive->vendor = strdup(drives_current[i].vendor);
		drive->revision = strdup(drives_current[i].revision);
		drive->location = strdup(drives_current[i].location);
		drive->read_dvdram = drives_current[i].read_dvdram;
		drive->read_dvdr = drives_current[i].read_dvdr;
		drive->read_dvdrom = drives_current[i].read_dvdrom;
		drive->read_cdr = drives_current[i].read_cdr;
		drive->read_cdrw = drives_current[i].read_cdrw;
		drive->write_dvdram = drives_current[i].write_dvdram;
		drive->write_dvdr = drives_current[i].write_dvdr;
		drive->write_cdr = drives_current[i].write_cdr;
		drive->write_simulate = drives_current[i].write_simulate;

		burn_drive_get_speedlist(drives_current[i].drive, &speeds);

		drive->profile_name = strdup(speeds->profile_name);
		drive->profile_loaded = speeds->profile_loaded;

		while (speeds->next)
		{
			i++;
			speeds = speeds->next;
		}

		drive->read_speeds = calloc(i + 2, sizeof(int));
		drive->write_speeds = calloc(i + 2, sizeof(int));

		drive->read_speeds[0] = i + 1;
		drive->write_speeds[0] = i + 1;

		for (ret = 1; ret <= i; ret++)
		{
			drive->write_speeds[ret] = speeds->write_speed;
			drive->read_speeds[ret] = speeds->read_speed;
			speeds = speeds->prev;
		}

		burn_drive_free_speedlist(&speeds);
		ecore_list_append(em->drives, drive);
	}

	burn_drive_info_free(drives_current);
	burn_finish();

	return TRUE;
}

void
ecdb_drive_info_free_cb(void *data)
{
	Ecdb_Drive_Info *info;

	info = data;

	FREE(info->read_speeds);
	FREE(info->write_speeds);
	FREE(info->vendor);
	FREE(info->product);
	FREE(info->revision);
	FREE(info->location);
	FREE(info->profile_name);
	FREE(info);
}

void
ecdb_print_drive_info(void)
{
	Ecdb_Drive_Info *drive;
	int j, i, h;

	ecore_list_first_goto(em->drives);
	while ((drive = ecore_list_next(em->drives)))
	{
		printf("Vendor: %s, Product: %s, Revision: %s, "
				"Location: %s\n",
				drive->vendor, drive->product,
				drive->revision, drive->location);
		printf("Profile name: %s, Loaded: %d\n",
				drive->profile_name,
				drive->profile_loaded);
		printf("Read DVDRAM: %d, Read DVDR: %d, Read DVDROM: %d, "
				"Read CDR: %d, Read CDRW: %d\n",
				drive->read_dvdram,
				drive->read_dvdr,
				drive->read_dvdrom,
				drive->read_cdr,
				drive->read_cdrw);
		printf("Write DVDRAM: %d, Write DVDR: %d, Write CDR: %d, "
				"Write Simulate: %d\n",
				drive->write_dvdram,
				drive->write_dvdr,
				drive->write_cdr,
				drive->write_simulate);

		j = drive->read_speeds[0];

		for (i = 1; i < j; i ++)
		{
			if ((h = drive->write_speeds[i]))
				printf("Write: %d\n", h);
			if ((h = drive->read_speeds[i]))
				printf("Read: %d\n", h);
		}
	}
}

int
ecdb_aquire_drive(Ecdb_Project *proj, unsigned int idx)
{
	Ecdb_Drive_Info *info;
	char adr[BURN_DRIVE_ADR_LEN];

	info = ecore_list_index_goto(em->drives, idx);
	if (burn_drive_convert_fs_adr(info->location, adr) <= 0)
	{
		printf("Error: Address doesn't provide cd burner!\n");
		return FALSE;
	}

	if (burn_drive_scan_and_grab(&info->tangible, adr, 1) > 0)
	{
		proj->drive = info;
		return TRUE;
	}
	else
	{
		info->tangible = NULL;
		return FALSE;
	}
}
	
