
// Project: webCDwriter - Network CD Writing
// Author: Jörg Haeger
//	joerg.haeger@Uni-Bielefeld.de

import java.io.*;
import java.text.*;
import javax.swing.*;

public class BurnSession extends Command
{
	final static String
	hintBlankingTOC = "blanking TOC",
	hintCDdetected = "CD detected",
	hintCDrecordStarted = "cdrecord started",
	hintCDwasClosed = "CD was closed",
	hintImageReady = "image ready",
	hintMakingImage = "making image",
	hintWriterReserved = "writer reserved"
	;

	QueueDialog queueDialog;
	JOptionPane optionPane;
	BurnDialog burnDialog;
	int totalKB, oldFreeKB, newFreeKB;
	boolean CDwasClosed = false;
	Object[] options = { i18n("details"), "OK" };
	String burnSessionResult;
	boolean burnSessionResultOK;

	BurnSession()
	{
		burnDialog = new BurnDialog();
	}

	void cancelCommand()
	{
		try {
			writeCommand("noop");
		}
		catch (java.io.IOException e)
		{
			System.out.println("cancelCommand: IOException");
		}
	}

	private JDialog createErrorDialog()
	{
		optionPane = new JOptionPane(
			burnSessionResult,
			JOptionPane.ERROR_MESSAGE,
			JOptionPane.DEFAULT_OPTION,
			null, options);
		return optionPane.createDialog(
			CDcreator.mainWin, i18n("error"));
	}

	private JDialog createSuccessDialog()
	{
		MessageFormat formatter = new MessageFormat("");
		formatter.setLocale(CDcreator.locale);
		if (CDwasClosed)
			formatter.applyPattern(
				i18n("burnSuccessCDwasClosed"));
		else
			formatter.applyPattern(i18n("burnSuccess"));
		Object[] args = {
			new Integer((oldFreeKB-newFreeKB) / 1024),
			new Integer(newFreeKB / 1024),
			new Integer(totalKB / 1024) };

		optionPane = new JOptionPane(
			formatter.format(args),
			JOptionPane.INFORMATION_MESSAGE,
			JOptionPane.DEFAULT_OPTION,
			null, options);
		return optionPane.createDialog(
			CDcreator.mainWin, i18n("titleBurnResult"));
	}

	void parseCapacityHint(String lineStr) throws IOException
	{
		StreamTokenizer tokenizer
			= new StreamTokenizer(
				new StringReader(lineStr));

		tokenizer.nextToken();
		if (!tokenizer.sval.equals("capacity"))
			return;

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			return;
		totalKB = (int)tokenizer.nval;

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			return;
		oldFreeKB = (int)tokenizer.nval;

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			return;
		newFreeKB = (int)tokenizer.nval;
	}

	void parseCDrecordLine(String lineStr) throws IOException
	{
		StreamTokenizer tokenizer
			= new StreamTokenizer(
				new StringReader(lineStr));
		tokenizer.wordChars(':', ':');

		tokenizer.nextToken();
		if (!tokenizer.sval.equals("Track"))
			return;

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			return;
		int track = (int)tokenizer.nval;

		if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)
			return;
		if (!tokenizer.sval.equals(":"))
			return;

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			return;
		int n = (int)tokenizer.nval;

		if (tokenizer.nextToken() != StreamTokenizer.TT_WORD)
			return;
		if (!tokenizer.sval.equals("of"))
			return;

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			return;
		int N = (int)tokenizer.nval;

		if (n == 0)
			burnDialog.setRange(0, N);
		burnDialog.setProgress(n);
	}

	void parseMkisofsHint(String lineStr) throws IOException
	{
		StreamTokenizer tokenizer
			= new StreamTokenizer(
				new StringReader(lineStr));

		tokenizer.nextToken();
		if (!tokenizer.sval.equals("mkisofsPercentDone"))
			return;

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			return;
		burnDialog.setProgress((int)tokenizer.nval);
	}

	void parseRankHint(String lineStr) throws IOException
	{
		StreamTokenizer tokenizer
			= new StreamTokenizer(
				new StringReader(lineStr));

		tokenizer.nextToken();
		if (!tokenizer.sval.equals("rank"))
			return;

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			return;
		int rank = (int)tokenizer.nval;
		queueDialog.setRank(rank);
	}

	void processHint(String str)
	{
//		System.out.println("processHint " + str);
		try
		{
			if (str.startsWith("rank"))
				parseRankHint(str);
			else
			if (str.startsWith("mkisofsPercentDone"))
				parseMkisofsHint(str);
			else
			if (str.startsWith("Track"))
				parseCDrecordLine(str);
			else
			if (str.startsWith("capacity"))
				parseCapacityHint(str);
		}
		catch (IOException e)
		{
		}

		if (str.equals(hintWriterReserved))
		{
			hideDialog();
			optionPane = new JOptionPane(
				infoStr,
				JOptionPane.INFORMATION_MESSAGE,
				JOptionPane.DEFAULT_OPTION,
				null, cancelButton);
			JDialog dialog = optionPane.createDialog(
				CDcreator.mainWin, i18n("titleInsertCD"));
			showDialog(dialog);
		}
		else
		if (str.equals(hintCDdetected))
		{
			Log.put("CD detected");
			burnDialog.setTitle(i18n("titleBurnSessionControl"));
			burnDialog.setRange(0, 100);
			replaceDialog(burnDialog);
		}
		else
		if (str.equals(hintBlankingTOC))
		{
			Log.put("");
			Log.put("cdrecord blank=fast started ==>");
			burnDialog.setMessage(i18n("blankingTOC"));
		}
		else
		if (str.equals(hintMakingImage))
		{
			Log.put("");
			Log.put("mkisofs started ==>");
			burnDialog.setTitle(i18n("titleCreateImage"));
			burnDialog.setMessage(i18n("createImage"));
		}
		else
		if (str.equals(hintCDrecordStarted))
		{
			Log.put("");
			Log.put("cdrecord started ==>");
//			hideDialog();
			burnDialog.setTitle(i18n("titleBurn"));
			burnDialog.setMessage(i18n("burn"));
			burnDialog.setProgress(0);
//			showDialog(burnDialog);
		}
		else
		if (str.equals(hintCDwasClosed))
		{
			CDwasClosed = true;
		}
	}

	void processInfo(String str)
	{
		super.processInfo(str);
		if (optionPane != null)
			optionPane.setMessage(infoStr);
	}

	public void run()
	{
		queueDialog = new QueueDialog(
			CDcreator.mainWin, i18n("titleReserve"),
			i18n("reserve"));
		showDialog(queueDialog);

		if (CDcreator.sessionType
			== CDcreator.multiSession)
		{
			if (!Options.volumeID.equals(""))
				execCommand("setVolumeID "
					+ spaceToEsc(Options.volumeID));
			if (Options.joliet)
				execCommand("setJoliet");
			if (Options.rockRidge)
				execCommand("setRockRidge");
			if (Options.HFS)
				execCommand("setHFS");
			if (Options.bootImage != null)
				execCommand("setBootImage "
					+ spaceToEsc(Options.bootImage));
		}

		execCommand("setSpeed " + Options.speed);
		if (Options.simulate)
			execCommand("setLaserOff");
		if (Options.blankTOC)
			execCommand("setBlankTOC");
		if (Options.closeCD)
			execCommand("setCloseCD");
		if (Options.offline)
			execCommand("setBurnOffline");

		execCommand("burnSession");
		burnSessionResult = lastResult;
		burnSessionResultOK = lastResultOK();

		hideDialog();

		if (Options.offline)
		{
			JOptionPane pane = new JOptionPane(
				infoStr + "\n"
				+ Version.product + " "
				+ i18n("willNowExit"),
				JOptionPane.INFORMATION_MESSAGE,
				JOptionPane.DEFAULT_OPTION,
				null, okButton);
			JDialog dialog = pane.createDialog(
				CDcreator.mainWin, i18n("titleInsertCD"));
			showInfoWin(dialog);
			super.run();
			return;
		}

		try {
			if (cancel)
				readResult();
		}
		catch (java.io.IOException e)
		{
			System.out.println("BurnSession: IOException");
		}

		super.run();
	}

	void showResult()
	{
		if (cancel || Options.offline)
			return;

		JDialog dialog;
		if (burnSessionResultOK)
			dialog = createSuccessDialog();
		else
			dialog = createErrorDialog();

		while (true)
		{
			optionPane.setInitialValue(options[1]);
			optionPane.setValue(
				JOptionPane.UNINITIALIZED_VALUE);
			dialog.show();
			if (optionPane.getValue() == options[0])
				new LogWin().show();
			else
				break;
		}
	}
}

