
// Project: webCDwriter - Network CD Writing
// Author: Jörg Haeger

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class Command implements Runnable
{
	static int filesNum = 0;
	static String sessionID = "";
	static String userID = "";
	static String userPassword = "password";
	Object cancelButton[] = { "Abbrechen" };
	final Object okButton[] = { "OK" };
	public static final int INIT = 0;
	public static final int RUNNING = 1;
	public static final int ERROR = 2;
	public static final int SUCCESS = 3;
	public int status = INIT;
	private volatile javax.swing.JDialog dialog;
	private volatile boolean dialogOpen;
	protected volatile boolean cancel = false, infoWin = false;
	private volatile boolean quit = false;
	String infoStr;
	String lastResult = "unknown";

	public Command()
	{
		if (userID.equals(""))
		{
			userID = CDcreator.userName;
			if (userID.equals(""))
				userID = "unknown";
			userPassword = String.valueOf(
				new java.util.Random().nextInt());
			sessionID = "";
		}
		cancelButton[0] = i18n("cancel");
		infoStr = new String();
	}

	void cancelCommand()
	{
	}

	final public void exec() throws CommandError
	{
		Thread thread = new Thread(this);
		thread.start();

		while (true)
		{
			synchronized(this) {
				while (dialog == null && !quit)
				try {
					wait();
				}
				catch (InterruptedException e)
				{
				}
			}
			if (quit)
				break;

			dialog.setModal(true);
			Version.showDebugInfo(21, "show start");
			dialog.show();
			synchronized(this) {
				Version.showDebugInfo(21, "show end");
				if (dialogOpen)
				{
					Version.showDebugInfo(21,
						"closed by user");
					dialogOpen = false;
					if (infoWin)
						dialog = null;
					else
					{
						if (!cancel)
						{
							cancel = true;
							cancelCommand();
						}
						dialog = getCancelDialog();
					}
					notifyAll();
				}
			}
		}

		try {
			thread.join();
		} catch (InterruptedException e)
		{
		}
		Version.showDebugInfo(21, "exec end");

		showResult();

		if (status == ERROR)
			throw new CommandError();
		if (cancel)
			throw new CommandError();
	}

	protected void execCommand(String cmdStr)
	{
		try {
			status = INIT;
			writeCommand(cmdStr);
			status = RUNNING;
			readResult();
		}
		catch (java.io.IOException e)
		{
			System.out.println("execCommand: IOException");
			lastResult = "error " + e.getLocalizedMessage();
		}
	}

	private JDialog getCancelDialog()
	{
		JDialog dialog = new JOptionPane(i18n("waitForCancel"),
			JOptionPane.INFORMATION_MESSAGE)
			.createDialog(CDcreator.mainWin,
				i18n("titleWaitForCancel"));
		dialog.addWindowListener(
			new WindowAdapter()
			{
				public void windowOpened(WindowEvent e)
				{
					dialogOpen = true;
					Version.showDebugInfo(21,
						"dialogOpened");
					synchronized(Command.this)
					{
						Command.this.notifyAll();
					}
				}
			}
		);
		return dialog;
	}

	protected void hideDialog()
	{
		Version.showDebugInfo(21, "hide start");
		if (dialog == null)
			return;

		synchronized(this) {
			while (cancel && !dialogOpen)
				try {
					wait();
				}
				catch (InterruptedException e)
				{
				}
		}

		synchronized(this) {
			if (dialogOpen)
			{
				Runnable doHide = new Runnable() {
					public void run() {
				Version.showDebugInfo(21, "run gui");
//						dialog.setVisible(false);
						dialog.dispose();
					}
				};
				try {
					SwingUtilities.invokeAndWait(doHide);
				}
				catch (Exception e)
				{
				}
				dialog = null;
				dialogOpen = false;
			}
		}
		Version.showDebugInfo(21, "hide end");
	}

	String i18n(String key)
	{
		return CDcreator.i18n(key);
	}

	protected Integer parse(String str, String key)
	{
		try {
			StreamTokenizer tokenizer
				= new StreamTokenizer(
					new StringReader(str));

			if (tokenizer.nextToken()
				!= StreamTokenizer.TT_WORD)
				return null;
			if (!tokenizer.sval.equals(key))
				return null;

			if (tokenizer.nextToken()
				!= StreamTokenizer.TT_NUMBER)
				return null;

			return new Integer((int)tokenizer.nval);
		}
		catch (IOException e)
		{
			return null;
		}
	}

	protected void replaceDialog(javax.swing.JDialog dialog)
	{
		hideDialog();
		showDialog(dialog);
	}

	boolean lastResultOK()
	{
		return status == SUCCESS;
	}

	void processHint(String str)
	{
	}

	void processInfo(String str)
	{
		if (infoStr.length() > 0)
			infoStr = infoStr.concat("\n");
		infoStr = infoStr.concat(str);
	}

	void processLog(String str)
	{
	}

	void readResult()
		throws java.io.IOException
	{
		while (true)
		{
			String str = CDcreator.inStream.readLine();
			if (str == null)
				break;
			Version.showDebugInfo(5, str);

			String typeStr, tailStr;
			int i = str.indexOf(' ');
			if (i >= 0)
			{
				typeStr = str.substring(0, i);
				tailStr = str.substring(
					i+1, str.length());
			}
			else
			{
				typeStr = str;
				tailStr = "";
			}
			typeStr.toUpperCase();
			if (typeStr.equals("ERR"))
			{
				status = ERROR;
				lastResult = i18n("error_"
					+ tailStr.replace(' ', '_'));
				if (lastResult.startsWith("error_"))
					lastResult = "\"" + tailStr + "\"";
				break;
			}
			else
			if (typeStr.equals("OK"))
			{
				status = SUCCESS;
				lastResult = i18n("success_"
					+ tailStr.replace(' ', '_'));
				break;
			}
			else
			if (typeStr.equals("HINT"))
				processHint(tailStr);
			else
			if (typeStr.equals("INFO"))
				processInfo(tailStr);
			else
			if (typeStr.equals("CDRECORD")
				|| typeStr.equals("MKISOFS"))
			{
				Log.put(tailStr);
				processLog(tailStr);
			}
		}
	}

	public void run()
	{
		synchronized(this) {
			quit = true;
			notifyAll();
		}
	}

	protected void showDialog(javax.swing.JDialog newDialog)
	{
		if (newDialog == null)
			return;

		synchronized(this) {
			while (dialogOpen)
				try {
					wait();
				}
				catch (InterruptedException e)
				{
				}
		}

		dialog = newDialog;
		dialog.addWindowListener(
			new WindowAdapter()
			{
/*				public void windowClosing(WindowEvent e)
				{
					e.getWindow().setVisible(false);
				}
*/				public void windowOpened(WindowEvent e)
				{
					dialogOpen = true;
					Version.showDebugInfo(21,
						"dialogOpened");
					synchronized(Command.this)
					{
						Command.this.notifyAll();
					}
				}
			}
		);

		synchronized(this) {
			notifyAll();
			while (!dialogOpen)
				try {
					wait();
				}
				catch (InterruptedException e)
				{
				}
		}
	}

	protected void showInfoWin(javax.swing.JDialog newDialog)
	{
		synchronized(this) {
			while (dialogOpen)
				try {
					wait();
				}
				catch (InterruptedException e)
				{
				}
		}

		infoWin = true;
		showDialog(newDialog);
	}

	void showResult()
	{
	}

	protected void sleep(int msec)
	{
		try {
			Thread.currentThread().sleep(msec);
		} catch (InterruptedException e)
		{
		}
	}

	/**
	 *	replace " " by "\_" and "\" by "\\"
	*/
	public static String spaceToEsc(String str)
	{
		char str2[] = new char[2 * str.length()];

		int i, j;
		for (i = 0, j = 0; i < str.length(); i++, j++)
		{
			if (str.charAt(i) == ' ')
			{
				str2[j++] = '\\';
				str2[j] = '_';
			}
			else
			if (str.charAt(i) == '\\')
			{
				str2[j++] = '\\';
				str2[j] = '\\';
			}
			else
				str2[j] = str.charAt(i);
		}
		return new String(str2, 0, j);
	}

	protected void writeCommand(String cmdStr)
		throws java.io.IOException
	{
		cmdStr.replace('\n', ' ');
		CDcreator.outStream.writeBytes(cmdStr + '\n');
	}
}
