
#ifndef CDRECORD_H
#define CDRECORD_H

#include <time.h>
#include "Process.h"

struct CDstatus
{
	int blocks0, blocks1, blocks2;
	int blockSize;
	int imageSizeInBlocks;
	int isClosed, isRW;
	int extentsWrittenKB;
	int manufacturerIndex;
	int speed;

	CDstatus()
	{
		blocks0 = blocks1 = blocks2 = 0;
		blockSize = 2 * 1024;
		imageSizeInBlocks = 0;
		isClosed = 0;
		isRW = 0;
		extentsWrittenKB = 0;
		manufacturerIndex = -1;
		speed = 1;
	}

	int blocksToKBytes(int blocks)
	{
		return ((blockSize / 512) * blocks) / 2;
	}

	const char *getCapacityStr(char *str)
	{
		// lead-in
		int free = blocks2 - 4500;
		if (blocks1 == blocks0)
			// first lead-out
			free -= 6750;
		else
			// subsequent lead-outs
			free -= 2250;
		if (free < 0)
			free = 0;

		sprintf(str, "capacity %d %d %d",
			blocksToKBytes(blocks0),
			blocksToKBytes(blocks1),
			blocksToKBytes(free));
		return str;
	}

	const char *getLogStr(char *str)
	{
		sprintf(str, "%-4d %4d %4d %14s %2s %6d %6d %6d %2d",
			manufacturerIndex, -1, -1,
			"unknown", isRW? "RW": "R",
			blocks0, blocks1, blocks2, speed);
		return str;
	}
};

class Cdrecord: public Process
{
public:
	enum LineType { none, capacity, progress };

private:
	struct
	{
		int key, code, qual;
		char *str;
	} results[256];
	int firstError, lastCommand, lastError;
	int key, code, qual;
	int cannotReadTOC, cannotReadSessionOffset;
	int fixating, mayNotFit, mediumNotPresent;
	enum LineType lineType;
	struct CDstatus *CDstatus;
	int fifoPercent, MBwritten, MBofTrackWritten, MBtotal;
	time_t t0, t1, t2;

public:
	Cdrecord(struct CDstatus *CDstatus = NULL);
	~Cdrecord();
	int getFifoPercent() { return fifoPercent; }
	const char *getFirstError();
	const char *getLastError();
	enum LineType getLineType() { return lineType; }
	void getProgress(int &current, int &total);
	int isBlankDisk();
	int isDriveReady();
	int isInProcessOfBecomingReady();
	int isMediumNotPresent();
	int isTrayClosed();
	const char *readLine();
};

#endif
