/*
 * This file is part of the QPxTool project.
 * Copyright (C) 2005-2006 Gennady "ShultZ" Kozlov <qpxtool@mail.ru>
 *
 * 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.
 * See the file "COPYING" for the exact licensing terms.
 */

#include <stdio.h>

#include <qpx_mmc.h>
#include <pioneer_spdctl.h>

#include "version.h"

const	unsigned int	FL_HELP			= 0x00000001;
const	unsigned int	FL_SCAN			= 0x00000002;
const	unsigned int	FL_DEVICE		= 0x00000004;
const	unsigned int	FL_CURRENT		= 0x00000008;
const	unsigned int	FL_VERBOSE		= 0x00000010;
const	unsigned int	FL_LIMIT		= 0x00000020;
const	unsigned int	FL_QUIET		= 0x00000040;
const	unsigned int	FL_SAVE			= 0x00000080;

	unsigned int	flags = 0;

int scanbus()
{
	drive_info*	drive;

	int	i, inq;
	int	drvcnt=0;
	char	device[32]="";
 	printf("** scaning IDE/SCSI bus...\n");
	for (i=0; i<_devcnt; i++) {
		strcpy(device,_devtbl[i]);
		drive = new drive_info(device);
//		inq = (*__inquiry)(drive);
		inq = inquiry(drive);
		switch (inq) {
			case 0x00:
				convert_to_ID(drive);
//				strcpy(drvtbl[drvcnt],_devtbl[i]);
				printf("%s [%02d]  %s: %s %s %s\n",(drive->ven_ID == WR_PLEXTOR) ? "*" : " ",
					drvcnt, drive->device, drive->ven, drive->dev, drive->fw);
				drvcnt++;
				break;
			case ERR_NO_DEV:
//				printf("%s: no device found\n",drive->device);
				break;
			case ERR_NO_SCSI:
//				printf("%s: not a valid SCSI device\n",drive->device);
				break;
			case ERR_NO_MMC:
				printf("%s: %s %s %s",drive->device,drive->ven,drive->dev,drive->fw);
				printf(": device is not MMC compliant\n");
				break;
			default:
				printf("%s: ???\n",drive->device);
				break;
			}
		delete drive;
	}
	printf("** Scan compleete: %d device(s) found\n", drvcnt);
	return (drvcnt);
}

int get_device_info(drive_info* drive)
{
	drive->ven_features=0;
	drive->chk_features=0;
	detect_capabilities(drive);
	detect_check_capabilities(drive);
	determine_disc_type(drive);
	if (!pioneer_get_quiet(drive)) drive->ven_features|=PIO_QUIET;
	if ((drive->ven_features & PIO_QUIET) && (flags & FL_CURRENT)) {
		printf("QuietMode setting   : %s\n", pioneer_silent_tbl[(int)drive->pioneer.silent]);
		printf("Speed Limit         : %s\n", drive->pioneer.limit ? "ON" : "OFF" );
	}
	return 0;
}

void usage(char* bin) {
	fprintf (stderr,"\nusage: %s [optinos]\n",bin);
	printf("\t-d <device>                  use this device\n");
	printf("\t--scan, -l                   list drives (scan IDE/SCSI bus)\n");
	printf("\t--help, -h                   show help\n");
	printf("\t--current, -c                show current drive settings\n");
	printf("\t--limit                      limit read speed by 24x for CD and 8x for DVD\n");
	printf("\t--nolimit                    turn off speed limit\n");
	printf("\t--quiet [quiet|perf|std]     select QuietMode setting: Quiet, Performance or Standart (default: quiet)\n");
	printf("\t--save, -s                   save settings to drive (make changes permanent)\n");
	printf("\t--verbose, -v                be verbose\n");
}

int main(int argc, char* argv[])
{
	int	i;
	int	drvcnt=0;
	char	device[32]="";
	drive_info* drive;

	char	silent = PIO_SILENT_QUIET;
	bool	limit  = false;
	bool	save   = false;

	printf("**  PioQuiet  v%s    (c)  Gennady \"ShultZ\" Kozlov  **\n", VERSION);

	for (i=1; i<argc; i++) {
//		printf("arg[%02d]: %s\n",i,argv[i]);
		if     (!strcmp(argv[i],"-h")) flags |= FL_HELP;
		else if(!strcmp(argv[i],"--help")) flags |= FL_HELP;
		else if(!strcmp(argv[i],"-c")) flags |= FL_CURRENT;
		else if(!strcmp(argv[i],"--current")) flags |= FL_CURRENT;
		else if(!strcmp(argv[i],"-l")) flags |= FL_SCAN;
		else if(!strcmp(argv[i],"--scan")) flags |= FL_SCAN;
		else if(!strcmp(argv[i],"-s")) { flags |= FL_SAVE; save = true; }
		else if(!strcmp(argv[i],"--save")) { flags |= FL_SAVE; save = true; }
		else if(!strcmp(argv[i],"-d")) {
			if (argc>(i+1)) {
				i++;
				flags |= FL_DEVICE;
				strcpy(device, argv[i]);
			} else {
				printf("option %s needs parameter!\n", argv[i]);
				return 5;
			}
		}
		else if(!strcmp(argv[i],"--limit"))
			{ flags |= FL_LIMIT; limit = true; }
		else if(!strcmp(argv[i],"--nolimit"))
			{ flags |= FL_LIMIT; limit = false; }

		else if(!strcmp(argv[i],"--quiet")) {
			flags |= FL_QUIET;
			if (argc>(i+1)) {
				i++;
				if      (!strcmp(argv[i],"quiet")) silent = PIO_SILENT_QUIET;
				else if (!strcmp(argv[i],"perf"))  silent = PIO_SILENT_PERF;
				else if (!strcmp(argv[i],"std"))   silent = PIO_SILENT_STD;
				else
					printf("invalid --quiet parameter: %s\n", argv[i]);
			} else {
				printf("option %s needs parameter!\n", argv[i]);
				return 5;
			}
		}
		else if(!strcmp(argv[i],"-v")) flags |= FL_VERBOSE;
		else if(!strcmp(argv[i],"--verbose")) flags |= FL_VERBOSE;
		else {
			printf("unknown option: %s\n", argv[i]);
			return 6;
		}
	}


	if (flags & FL_HELP) {
		usage(argv[0]);
		return 0;
	}
	if (!flags) {
		usage(argv[0]);
		return 1;
	}
	if (flags & FL_SCAN) {
		drvcnt = scanbus();
		if (!drvcnt) printf("ERR: no drives found!\n");
		return 2;
	}
	if (!(flags & FL_DEVICE)) {
		printf("** ERR: no device selected\n");
		return 3;
	}

//	printf("____________________________\n");
	printf("Device : %s\n", device);
	drive = new drive_info(device);
	if (drive->err) {
		printf("%s: device open error!\n", argv[0]);
		delete drive;
		return 4;
	}
	inquiry(drive);
	convert_to_ID(drive);
	printf("Vendor : '%s'\n",drive->ven);
	printf("Model  : '%s'\n",drive->dev);
	printf("F/W    : '%s'\n",drive->fw);
	if (!(flags & FL_VERBOSE)) drive->silent++;
	if (get_drive_serial_number(drive)) printf("Serial#: %s\n",drive->serial);

	if (flags) {
//	if (flags & FL_VERBOSE) {
		printf("\nPioQuiet flags : ");
		if (flags & FL_DEVICE)		printf(" DEVICE");
		if (flags & FL_HELP)		printf(" HELP");
		if (flags & FL_CURRENT)		printf(" CURRENT");
		if (flags & FL_SCAN)		printf(" SCAN");
		if (flags & FL_QUIET)		printf(" QUIET");
		if (flags & FL_LIMIT)		printf(" LIMIT");
		if (flags & FL_VERBOSE)		printf(" VERBOSE");
		if (flags & FL_SAVE)		printf(" SAVE");
		printf("\n\n");
	}
	get_device_info(drive);
	if (!(drive->ven_features & PIO_QUIET)) {
		printf("PIONEER QuietMode not supported by selected drive!\n");
		return 1;
	}
	if (flags & FL_QUIET) {
		pioneer_set_silent(drive, silent, save);
	}
	if (flags & FL_LIMIT) {
		pioneer_set_spdlim(drive, limit, save);
	}
	if (flags & (FL_QUIET | FL_LIMIT)) {
		printf("Drive settings changed...\n");
		flags |= FL_CURRENT;
		get_device_info(drive);
	}
//	printf("____________________________\n");
	if (!(flags & FL_VERBOSE)) drive->silent--;
	delete drive;
	return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1