/*
 * @(#)MainWin.java
 *
 * This file is part of webCDwriter - Network CD Writing.
 *
 * Copyright (C) 1999-2004 Jörg P. M. Haeger
 *
 * webCDwriter is free software. See CDcreator.java for details.
 */

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.URL;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;

/**
 * The main window of webCDcreator.
 *
 * @version 20040708
 * @author Jörg P. M. Haeger
 */
class MainWin implements ActionListener {
	final static String
		blankCmd = "cmdBlank",
		burnCmd = "burnCmd",
		changePasswordCmd = "cmdChangePassword",
		copyCmd = "cmdCopy",
		downCmd = "down",
		editSettingsCmd = "editSettingsCmd",
		newDirCmd = "newDirCmd",
		newSessionCmd = "cmdNewSession",
		openProjectCmd = "cmdOpenProject",
		openProjectFromServerCmd = "cmdOpenProjectFromServer",
		quitCmd = "quitCmd",
		removeCmd = "removeCmd",
		renameCmd = "cmdRename",
		saveImageAsCmd = "saveImageAsCmd",
		saveProjectCmd = "cmdSaveProject",
		saveProjectOnServerCmd = "cmdSaveProjectOnServer",
		setBootImageCmd = "cmdSetBootImage",
		showHelpCmd = "showHelpCmd",
		showInfoCmd = "showInfoCmd",
		showLogWin = "cmdShowLogWin",
		showStatus = "showStatus",
		transferCmd = ">>",
		upCmd = "up";

	final static String
		catalan = "Catalan",
		chinese = "Chinese",
		dutch = "Nederlands",
		german = "Deutsch",
		english = "English",
		french = "Français",
		hungarian = "Hungarian",
		italian = "Italiano",
		korean = "Korean",
		norwegian = "Norwegian",
		polish = "Polski",
		portuguese = "Português",
		russian = "Russian",
		slovenian = "Slovenian",
		spanish = "Español",
		swedish = "Swedish",
		ukrainian = "Ukrainian";

	static class Locale {
		String name;
		java.util.Locale locale;

		Locale(String aName, String language, String country) {
			name = aName;
			locale = new java.util.Locale(language, country);
		}

		public String toString() {
			return name + " (" + locale + ")";
		}
	}

	final static Locale[] locales = {
		new Locale(catalan, "ca", "ES"),
		new Locale(chinese, "zh", "TW"),
		new Locale(dutch, "nl", "NL"),
		new Locale(english, "en", "US"),
		new Locale(spanish, "es", "ES"),
		new Locale(french, "fr", "FR"),
		new Locale(german, "de", "DE"),
		new Locale(hungarian, "hu", "HU"),
		new Locale(italian, "it", "IT"),
		new Locale(korean, "ko", "KR"),
		new Locale(norwegian, "no", "NO"),
		new Locale(polish, "pl", "PL"),
		new Locale(portuguese, "pt", "BR"),
		new Locale(russian, "ru", "RU"),
		new Locale(slovenian, "sl", "SI"),
		new Locale(swedish, "sv", "SE"),
		new Locale(ukrainian, "uk", "UA") };

	// components
//	private RootPaneContainer rootPaneContainer;
	private JMenuBar menuBar;
	private JMenuItem burnMenuItem;
	private JTree tree, CDTree;
	private JComboBox mediumBox;
	private JLabel mediumLabel;
	private JPanel mediumPanel;
	private CDView theCDView;
	private TreeTableModelAdapter CDViewModel;
	private JScrollPane treeScroller, CDTreeScroller;
	private JButton
		burnButton,
		copyButton,
		downButton,
		newDirButton,
		removeButton,
		setBootImageButton,
		upButton;
	SessionSizeView sessionSizeView;
	private JPanel sessionSizePanel;

	// models
	private DirTreeNode fsNode, homeNode = null;
	private CDNode CDRoot;
	private DefaultTreeModel fsTreeModel, CDTreeModel;

	ActionListener actionListener;
	static DirTreeNode bootImageNode = null;
	MainWin mainWin;
	boolean serverUpToDate = false;

	MainWin() {
		getContentPane().setLayout(LM);

		createMenuBar();
		if (CDcreator.frame != null)
			CDcreator.frame.setJMenuBar(menuBar);
		else
			if (CDcreator.applet != null)
				CDcreator.applet.setJMenuBar(menuBar);

		fsNode = new DirTreeNode(i18n("sources"));
		fsTreeModel = new DefaultTreeModel(fsNode, true);

		boolean defaultSources = true;
		try {
			String[] names = {
				System.getProperty("user.home")
					+ File.separatorChar + "webCDcreator.cfg",
				"C:\\webCDcreator.cfg",
				System.getProperty("user.home")
					+ File.separatorChar + ".webCDcreator.cfg",
				"/etc/webCDcreator.cfg"
			};
			for (int i = 0; i < names.length; i++) {
//				System.out.println(names[i]);
				File configFile = new File(names[i]);
				if (!configFile.exists())
					continue;

				BufferedReader reader
					= new BufferedReader(
						new FileReader(configFile));
				while (true) {
					String line = reader.readLine();
					if (line == null)
						break;

					StreamTokenizer tokenizer
						= new StreamTokenizer(
							new StringReader(line));
//					tokenizer.resetSyntax();
//					tokenizer.whitespaceChars(0, 32);
					tokenizer.wordChars(33, 255);
					tokenizer.ordinaryChar('=');
					tokenizer.ordinaryChar(',');

					if (tokenizer.nextToken() != tokenizer.TT_WORD)
						break;
					if (!tokenizer.sval.equals("sources"))
						break;

					if (tokenizer.nextToken() != '=')
						break;

					while (true) {
						if (tokenizer.nextToken() != tokenizer.TT_WORD)
							break;

//						System.out.println(tokenizer.sval);
						defaultSources = false;
						DirTreeNode rootNode = new DirTreeNode(
							new SecFile(tokenizer.sval), true);
						rootNode.setUserObject(tokenizer.sval);
						fsTreeModel.insertNodeInto(
							rootNode, fsNode,
							fsTreeModel.getChildCount(fsNode));

						if (tokenizer.nextToken() != ',')
							break;
					}
				}
				break;
			}
		}
		catch (Exception e) {
		}

		if (true) {
			String sources = Config.get(Config.SOURCES);
			if (sources != null && sources.length() > 0) {
				defaultSources = false;
				sources += ",";
				int p = 0;
				while (true) {
					int p0 = p;
					p = sources.indexOf(",", p0);
					if (p < 0)
						break;
					String name = sources.substring(p0, p);
//					if (new File(name).exists()) {
					if (true) {
						DirTreeNode rootNode = new DirTreeNode(
							new SecFile(name), true);
						rootNode.setUserObject(name);
						fsTreeModel.insertNodeInto(
							rootNode, fsNode,
							fsTreeModel.getChildCount(fsNode));
					}
					p++;
				}
			}
		}

		boolean windowsSystem = false;
		if (defaultSources) {
		if (CDcreator.isNetscapeVM())
		for (char ch = 'C'; ch <= 'Z'; ch++) {
			char chars[] = { ch, ':', File.separatorChar };
			String driveName = new String(chars);
			File drive = new SecFile(driveName);

			if (CDcreator.isNetscapeVM())
				// Netscape File.list() bug workaround
				drive = new SecFile(driveName + ".");

			if (drive.exists()) {
				windowsSystem = true;
				DirTreeNode rootNode = new DirTreeNode(
					drive, true);
				if (ch == 'P')
					rootNode.setUserObject(
						System.getProperty("user.name")
						+ " (" + driveName + ")");
				else
					rootNode.setUserObject(driveName);
				fsTreeModel.insertNodeInto(
					rootNode, fsNode,
					fsTreeModel.getChildCount(fsNode));
			}
		}
		else {
			// add the file system roots
			Version.debug("listRoots", "...");
			File[] roots = File.listRoots();
			Version.debug("listRoots", "done " + roots.length);
			windowsSystem = roots.length > 0
				&& !roots[0].getPath().equals("/");
			if (windowsSystem) {
				String sources = "";
				for (int i = 0; i < roots.length; i++) {
					String driveName = roots[i].getPath();
					Version.debug("listRoots", "<" + driveName + ">");
					DirTreeNode rootNode = new DirTreeNode(
						new SecFile(driveName), true);
					if (driveName.startsWith("P"))
						rootNode.setUserObject(
							System.getProperty("user.name")
							+ " (" + driveName + ")");
					fsTreeModel.insertNodeInto(
						rootNode, fsNode,
						fsTreeModel.getChildCount(fsNode));
					sources += driveName + ",";
				}
				int len = sources.length();
				if (len > 0)
					sources = sources.substring(0, len - 1);
				Config.set(Config.SOURCES, sources);
			}
		}
		}

		if (defaultSources && !windowsSystem) {
			// UNIX
			DirTreeNode rootNode
				= new DirTreeNode(new SecFile("/"));
			rootNode.setUserObject("/");
			fsTreeModel.insertNodeInto(
				rootNode, fsNode,
				fsTreeModel.getChildCount(fsNode));

			if (new File("/home").exists()) {
				homeNode = new DirTreeNode(new SecFile("/home"));
				homeNode.setUserObject(i18n("homeDirs"));
				fsTreeModel.insertNodeInto(
					homeNode, fsNode,
					fsTreeModel.getChildCount(fsNode));
			}
		}

		if (defaultSources) {
			// add the home directory of the JVM
			String homeDir = System.getProperty("user.home");
			if (homeDir.endsWith("/.netscape"))
				homeDir = homeDir.substring(
					0, homeDir.length() - 10);
			DirTreeNode homeDirNode
				= new DirTreeNode(new SecFile(homeDir));
			homeDirNode.setUserObject(homeDir);
			fsTreeModel.insertNodeInto(
				homeDirNode, fsNode,
				fsTreeModel.getChildCount(fsNode));
		}

		tree = new JTree(fsTreeModel);
		tree.setSelectionModel(new DefaultTreeSelectionModel());
		tree.addTreeWillExpandListener(treeWillExpandListener);
		tree.putClientProperty("JTree.lineStyle", "Angled");
		treeScroller = new JScrollPane(tree);
		getContentPane().add(treeScroller);

		copyButton = new JButton(transferCmd);
		copyButton.addActionListener(this);
		copyButton.setToolTipText(i18n("TTcopy"));
		getContentPane().add(copyButton);

		// mediumPanel
		mediumBox = new JComboBox(Mode.media);
		mediumPanel = new JPanel();
		mediumPanel.setLayout(
			new BoxLayout(mediumPanel, BoxLayout.X_AXIS));
		mediumPanel.setBorder(
			BorderFactory.createRaisedBevelBorder());
		mediumPanel.add(Box.createHorizontalStrut(10));
		mediumLabel = new JLabel(i18n("MWMedium"));
		mediumPanel.add(mediumLabel);
		mediumPanel.add(Box.createHorizontalStrut(10));
		mediumPanel.add(mediumBox);
		mediumPanel.add(Box.createHorizontalGlue());
		getContentPane().add(mediumPanel);

		createCDView();

		removeButton = new JButton(getIcon("editdelete.png"));
		removeButton.setActionCommand(removeCmd);
		removeButton.addActionListener(this);
		removeButton.setToolTipText(i18n("TTcut"));
		getContentPane().add(removeButton);

		newDirButton = new JButton(getIcon("folder_new.png"));
		newDirButton.setActionCommand(newDirCmd);
		newDirButton.addActionListener(this);
		newDirButton.setToolTipText(i18n("TTnewDir"));
		getContentPane().add(newDirButton);

		setBootImageButton = new JButton(getIcon("boot.jpg"));
		setBootImageButton.setActionCommand(setBootImageCmd);
		setBootImageButton.addActionListener(this);
		setBootImageButton.setToolTipText(i18n("TTsetBootImage"));
		setBootImageButton.setVisible(false);
		getContentPane().add(setBootImageButton);

		burnButton = new JButton(getIcon("burn.png"));
		burnButton.setActionCommand(burnCmd);
		burnButton.addActionListener(this);
		burnButton.setToolTipText(i18n("burnCmd"));
		getContentPane().add(burnButton);

		upButton = new JButton(getIcon("up.png"));
		upButton.setActionCommand(upCmd);
		upButton.addActionListener(this);
		upButton.setToolTipText(i18n("MainWin.upTip"));
		getContentPane().add(upButton);

		downButton = new JButton(getIcon("down.png"));
		downButton.setActionCommand(downCmd);
		downButton.addActionListener(this);
		downButton.setToolTipText(i18n("MainWin.downTip"));
		getContentPane().add(downButton);

		actionListener = this;
		mainWin = this;
	}

	public void actionPerformed(ActionEvent e) {
		showDebugInfo("action: " + e.getActionCommand());

		if (CDcreator.isNetscapeVM())
		try {
			netscape.security.PrivilegeManager
				.enablePrivilege("UniversalFileRead");
			netscape.security.PrivilegeManager
				.enablePrivilege("UniversalPropertyRead");
		}
		catch (Exception e2) {
		}

		if (e.getActionCommand().equals(blankCmd))
			blank();
		else
		if (e.getActionCommand().equals(burnCmd))
			burnSession();
		else
		if (e.getActionCommand().equals(changePasswordCmd)) {
			if (!login())
				return;

			ChangePasswordDialog dialog = new ChangePasswordDialog();
			center(dialog);
			dialog.show();
			if (dialog.wasCanceled())
				return;

			try {
				new ChangePassword(dialog.getPassword()).exec();
			} catch (CommandError cmdErr) {
			}
		}
		else
		if (e.getActionCommand().equals(copyCmd))
			burnCopy();
		else
		if (e.getActionCommand().equals(editSettingsCmd))
			showSettings();
		else
		if (e.getActionCommand().equals(newDirCmd)) {
			TreePath path;
			if (CDTree.isSelectionEmpty())
//				CDTree.setSelectionRow(0);
				path = new TreePath(
					CDTree.getModel().getRoot());
			else
				path = CDTree.getSelectionPath();
			DirTreeNode CDnode = (DirTreeNode)path
				.getLastPathComponent();
			if (CDnode.isLeaf())
				CDnode = (DirTreeNode)CDnode.getParent();
			if (CDnode == null || CDnode.isLeaf()) {
				JOptionPane.showMessageDialog(
					CDcreator.mainWin,
					i18n("MWDestinationIsNotAFolder"),
					i18n("error"),
					JOptionPane.ERROR_MESSAGE);
				return;
			}

			String name = (String)JOptionPane.showInputDialog(
				CDcreator.mainWin, i18n("NFDName"), i18n("NFDTitle"),
				JOptionPane.QUESTION_MESSAGE, null, null,
				i18n("NFDDefaultNewFolderName"));
			if (name == null || name.length() == 0)
				return;

			int count = CDTreeModel.getChildCount(CDnode);
			for (int i = 0; i < count; i++) {
				if (CDTreeModel.getChild(CDnode, i).toString()
						.equals(name))
					return;
			}

			DirTreeNode newNode = new CDNode(name);
			CDTreeModel.insertNodeInto(newNode, CDnode, count);
			path = path.pathByAddingChild(newNode);
			Project.mkdir(path);
			CDTree.startEditingAtPath(path);
			serverUpToDate = false;
		}
		else
		if (e.getActionCommand().equals(newSessionCmd)) {
			if (typeSelection(true)) {
				State.resetSession();
				copyButton.setEnabled(true);
				getContentPane().doLayout();
				resetCDView();
			}
		}
		else
		if (e.getActionCommand().equals(openProjectCmd)) {
			final JFileChooser chooser = new JFileChooser();
			chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
				public boolean accept(File f) {
					return f.isDirectory() || f.getName().endsWith(".cdw");
				}
				public String getDescription() {
					return "webCDcreator";
				}
			});
			if (chooser.showOpenDialog(CDcreator.mainWin)
					!= JFileChooser.APPROVE_OPTION)
				return;

			loadProject(chooser.getSelectedFile());
		}
		else
		if (e.getActionCommand().equals(openProjectFromServerCmd)) {
			if (!login())
				return;

			OpenDialog dialog = new OpenDialog();
			center(dialog);
			dialog.show();
			if (dialog.wasCanceled())
				return;

			Options.reset();
			resetCDView();
			copyButton.setEnabled(true);
			getContentPane().doLayout();
			try {
				new LoadProject().exec();
			} catch (CommandError cmdErr) {}
			updateCDRoot();
			sessionSizeView.recount();
			serverUpToDate = dialog.getNumOfTracks() > 0;
		}
		else
		if (e.getActionCommand().equals(quitCmd)) {
			CDcreator.exit();
		}
		else
		if (e.getActionCommand().equals(removeCmd)) {
			TreePath paths[] = CDTree.getSelectionPaths();
			if (paths == null)
				return;
			for (int i = 0; i < paths.length; i++)
				remove(paths[i]);
			serverUpToDate = false;
			if (Mode.burnImageFile()
				&& CDRoot.getChildCount() == 0)
				copyButton.setEnabled(true);
		}
		else
		if (e.getActionCommand().equals(renameCmd)) {
			if (CDTree.isSelectionEmpty())
				return;

			TreePath path = CDTree.getSelectionPath();
			DirTreeNode CDnode = (DirTreeNode)path
				.getLastPathComponent();

			String name = (String)JOptionPane.showInputDialog(
				CDcreator.mainWin, i18n("RDNewName"), i18n("RDTitle"),
				JOptionPane.QUESTION_MESSAGE, null, null,
				CDnode.toString());
			if (name == null || name.length() == 0)
				return;

			DirTreeNode parent = (DirTreeNode)CDnode.getParent();
			if (parent == null)
				return;
			int count = CDTreeModel.getChildCount(parent);
			for (int i = 0; i < count; i++) {
				if (CDTreeModel.getChild(parent, i).toString()
						.equals(name))
					return;
			}

			Project.rename(CDTree.getSelectionPath(), name);
			CDnode.setUserObject(name);
//			CDView.updateUI();
//			CDViewModel.fireTableRowsUpdated(
//				0, CDViewModel.getRowCount());
			CDTreeModel.nodeChanged(CDnode);
			serverUpToDate = false;
		}
		else
		if (e.getActionCommand().equals(saveImageAsCmd))
			saveImageAs();
		else
		if (e.getActionCommand().equals(saveProjectCmd))
			saveProject();
		else
		if (e.getActionCommand().equals(saveProjectOnServerCmd)) {
			if (!login())
				return;

			SaveDialog dialog = new SaveDialog();
			center(dialog);
			dialog.show();
			if (dialog.wasCanceled())
				return;

			updateCDRoot();
			try {
				new SaveProject(CDRoot).exec();
				if (dialog.isStoreSet()) {
					putSession();
					new CloseSession().exec();
				}
			} catch (CommandError cmdErr) {
				try {
					new CloseSession().exec();
				} catch (CommandError cmdErr2) {}
			}
		}
		else
		if (e.getActionCommand().equals(setBootImageCmd)) {
			TreePath paths[] = CDTree.getSelectionPaths();
			if (paths == null)
				return;
			DirTreeNode CDnode = (DirTreeNode)paths[0]
				.getLastPathComponent();
			if (!CDnode.isLeaf())
				return;
			if (bootImageNode == CDnode)
				bootImageNode = null;
			else
				bootImageNode = CDnode;
			((DefaultTreeModel)CDTree.getModel())
				.nodeChanged(CDnode);
			Options.bootImage = Project.toString(paths[0]);
		}
		else
		if (e.getActionCommand().equals(showHelpCmd))
			CDcreator.showDocument("doc/index.html");
		else
		if (e.getActionCommand().equals(showInfoCmd))
			showAbout();
		else
		if (e.getActionCommand().equals(showLogWin))
			new LogWin().show();
		else
		if (e.getActionCommand().equals(showStatus)) {
			try {
				URL url = new URL("http",
					CDcreator.serverName,
					CDcreator.serverPortNo, "/status.html");
				CDcreator.showDocument(url);
			} catch (java.net.MalformedURLException urlExp) {
			}
		}
		else
		if (e.getActionCommand().equals(transferCmd)) {
			TreePath paths[] = tree.getSelectionPaths();
			if (paths == null)
				return;
			int n = paths.length;
			if (Mode.burnImageFile())
				if (CDRoot.getChildCount() > 0)
					n = 0;
				else
					if (n > 1)
						n = 1;
			try {
				for (int i = 0; i < n; i++)
					transfer(paths[i]);
			} catch (Exception e2) {
			}
			serverUpToDate = false;
			if (Mode.burnImageFile()
				&& CDRoot.getChildCount() > 0)
				copyButton.setEnabled(false);
			sessionSizeView.recount();
		}
		else
		if (e.getActionCommand().equals(upCmd)
			|| e.getActionCommand().equals(downCmd)) {
			if (CDTree.isSelectionEmpty())
				return;

			TreePath path = CDTree.getSelectionPath();
			DirTreeNode CDnode
				= (DirTreeNode)path.getLastPathComponent();

			boolean up = e.getActionCommand().equals(upCmd);
			moveUpOrDown(CDnode, up);

			CDTree.setSelectionPath(path);
			CDTree.scrollPathToVisible(path);
			if (up)
				Project.moveUp(path);
			else
				Project.moveDown(path);
			serverUpToDate = false;
		}
		else {
			for (int i = 0; i < locales.length; i++) {
				if (locales[i].name.equals(e.getActionCommand()))
					setLocale(i);
			}
		}
	}

	public void addServerExports() {
		// add nodes to the software archive on the server
		File[] serverFiles = new ServerFile("/").listFiles();
		for (int i = 0; i < serverFiles.length; i++) {
			DirTreeNode serverNode = new DirTreeNode(serverFiles[i]);
//			serverNode.setUserObject(i18n("archiveOnServer"));
			fsTreeModel.insertNodeInto(
				serverNode, fsNode,
				fsTreeModel.getChildCount(fsNode));
		}
	}

	void blank() {
		JPanel p = new JPanel();
		p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));

		JRadioButton fastBox = new JRadioButton(i18n("ODfast"));
		fastBox.setSelected(true);
		p.add(fastBox);

		JRadioButton allBox = new JRadioButton(i18n("ODall"));
		p.add(allBox);
		p.add(Box.createRigidArea(new Dimension(0, 5)));

		ButtonGroup group = new ButtonGroup();
		group.add(fastBox);
		group.add(allBox);

		JComboBox speedBox = OptionsDialog.createSpeedBox();
		p.add(Dialog.createLabelItemBox(
			new JLabel(i18n("speed")), speedBox));

		String[] options = { i18n("cancel"), i18n("OK") };
		if (JOptionPane.showOptionDialog(CDcreator.mainWin, p,
			i18n(blankCmd),
			JOptionPane.OK_CANCEL_OPTION,
			JOptionPane.QUESTION_MESSAGE,
			null, options, options[1]) != 1)
			return;

		Options.speed = OptionsDialog.getSpeed(speedBox);
		try {
			new Blank(allBox.isSelected()).exec();
		} catch (CommandError cmdErr) {};
	}

	void burnCopy() {
		Mode.source = Mode.copy;
		burnSession();
		Mode.source = Mode.current;
	}

	private void burnSession() {
		if (Mode.source != Mode.copy
				&& CDRoot.getChildCount() == 0) {
			JOptionPane.showMessageDialog(
				CDcreator.mainWin,
				i18n("MainWin.descriptionContainsNoFiles"),
				i18n("error"),
				JOptionPane.ERROR_MESSAGE);
			return;
		}

		if (Project.transferSize / 1024 / 1024
				> CDcreator.maxMBTransferPerProject) {
			JOptionPane.showMessageDialog(
				CDcreator.mainWin,
				createViewer(i18n("MainWin.maxTransferError")),
				i18n("error"),
				JOptionPane.ERROR_MESSAGE);
			return;
		}

		try {
			Options.closeCD = Mode.type == Mode.audio
				|| Mode.source == Mode.copy;

			OptionsDialog options = new OptionsDialog();
			options.pack();
			center(options);
			while (true) {
				options.show();
				if (options.wasCanceled())
					return;

				if (Options.blankTOC || Options.format) {
					String[] options2 = {
						i18n("MainWin.back"),
						i18n("MainWin.continue") };
					int result = JOptionPane.showOptionDialog(
						CDcreator.mainWin,
						i18n("MainWin.wantToOverwrite"),
						i18n("warning"),
						JOptionPane.DEFAULT_OPTION,
						JOptionPane.WARNING_MESSAGE,
						null, options2, options2[0]);
					if (result == 1)
						break;
				}
				else
					break;
			}

			if (!Mode.copyCD())
				putSession();

			Log.clear();
			if (Mode.saveImage) {
				try {
					checkOverwrite(Mode.saveImageAs);
					new CreateImage().exec();
				}
				catch (Exception e) { }
			}
			else
			if (Mode.copyCD())
				new BurnCopy().exec();
			else
				new BurnSession().exec();
//			new CloseSession().exec();
		}
		catch (CommandError cmdErr) {
			try {
				if (!Mode.copyCD())
					new CloseSession().exec();
			}
			catch (CommandError cmdErr2) {
			}
		}
	}

	public static void center(Component dialog) {
		Point p0 = CDcreator.mainWin.getLocationOnScreen();
		CDcreator.appletOrigin = p0;
		Dimension d0 = CDcreator.mainWin.getSize();
		Dimension d1 = dialog.getSize();
		dialog.setLocation(p0.x + (d0.width - d1.width) / 2,
			p0.y + (d0.height - d1.height) / 2);
	}

	private void checkAudioFile(File file) throws Exception {
		if (file.length() <= 44) {
			new JOptionPane(
				file + "\n" + i18n("incompleteAudioFile"),
				JOptionPane.ERROR_MESSAGE,
				JOptionPane.DEFAULT_OPTION)
				.createDialog(CDcreator.mainWin,
					i18n("titleNoAudioFile")).show();
			throw new Exception("no or incomplete audio file");
		}

		if (file instanceof ServerFile) {
			int type = ((ServerFile)file).getType();
			if (type == ServerFile.WAV
					|| (type == ServerFile.MP3 && CDcreator.mp3Support)
					|| (type == ServerFile.OGG && CDcreator.oggSupport))
				return;
			else
				throw new Exception("invalid audio file");
		}

		if (file.getName().toLowerCase().endsWith(".wav")) {
			Wave wave = new Wave(file);
/*			if (wave.bytesPerSample != 4
				|| wave.channels != 2
				|| wave.frequency != 44100)
				throw new Exception("invalid audio file");
*/			return;
		}

		if (file.getName().toLowerCase().endsWith(".mp3")
				&& CDcreator.mp3Support) {
			new MP3(file);
			return;
		}

		if (file.getName().toLowerCase().endsWith(".ogg")
				&& CDcreator.oggSupport) {
			new Ogg(file);
			return;
		}

		new Wave(file);

		throw new Exception("no or unknown audio file");
	}

	private void checkFile(File file) throws Exception {
		if (Mode.burnImageFile()) {
			if (file.isDirectory())
				throw new Exception("no imagefile");
			return;
		}

		if (Mode.audioCD())
			try {
				checkAudioFile(file);
			} catch (Exception e) {
				new JOptionPane(
					file + "\n" + i18n("noAudioFile"),
					JOptionPane.ERROR_MESSAGE,
					JOptionPane.DEFAULT_OPTION)
					.createDialog(CDcreator.mainWin,
						i18n("titleNoAudioFile")).show();
				throw new Exception("no audio file");
			}
	}

	void checkOverwrite(String name) throws Exception {
		if (new File(name).exists())
			if (JOptionPane.showConfirmDialog(CDcreator.mainWin,
					CDcreator.replaceAll(
						i18n("MainWin.reallyWantToOverwrite"),
						"@FILE@", name),
					i18n("titleReallyWantToOverwrite"),
					JOptionPane.YES_NO_OPTION) != 0)
				throw new Exception("checkOverwrite");
	}

	private void createCDView() {
		CDRoot = new CDNode("CD");
		Project.setCDRoot(CDRoot);

		CDTreeModel = new FileSystemModel(CDRoot, true);
		CDTreeModel.addTreeModelListener(new MyTreeModelListener());
		theCDView = new CDView((FileSystemModel)CDTreeModel);
		CDViewModel = (TreeTableModelAdapter)theCDView.getModel();
		SessionSizeView.tableModel
			= (TreeTableModelAdapter)theCDView.getModel();

		theCDView.addMouseListener(new MouseAdapter() {
			private void handle(MouseEvent e) {
				if (!e.isPopupTrigger())
					return;

				int row = theCDView.rowAtPoint(
					new Point(e.getX(), e.getY()));
				theCDView.setRowSelectionInterval(row, row);

				JPopupMenu menu = new JPopupMenu();

				JMenuItem item2;
				item2 = new JMenuItem(i18n(newDirCmd));
				item2.setActionCommand(newDirCmd);
				item2.addActionListener(actionListener);
				item2.setEnabled(Mode.makeISOImage());
				menu.add(item2);

				item2 = new JMenuItem(i18n(removeCmd));
				item2.setActionCommand(removeCmd);
				item2.addActionListener(actionListener);
				menu.add(item2);

				item2 = new JMenuItem(i18n(renameCmd));
				item2.setActionCommand(renameCmd);
				item2.addActionListener(actionListener);
				menu.add(item2);

				item2 = new JMenuItem(i18n(setBootImageCmd));
				item2.setActionCommand(setBootImageCmd);
				item2.addActionListener(actionListener);
				item2.setEnabled(Mode.makeISOImage());
				menu.add(item2);

				menu.show(theCDView, e.getX()-0, e.getY()-0);
			}
			public void mousePressed(MouseEvent e) {
				handle(e);
			}
			public void mouseReleased(MouseEvent e) {
				handle(e);
			}
		});
		theCDView.getColumnModel().getColumn(1).setMaxWidth(70);
		theCDView.setSelectionMode(
			ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		CDTree = theCDView.getTree();
		((javax.swing.JLabel)theCDView.getDefaultRenderer(String.class))
			.setHorizontalAlignment(SwingConstants.RIGHT);

		// renderer
		CDTree.setCellRenderer(
			new DefaultTreeCellRenderer() {
				private Icon icon = MainWin.getIcon("boot.jpg");
				public Icon getLeafIcon() {
					if (isBootImage())
						return icon;
					else
						return super.getLeafIcon();
				}
				public Color getTextNonSelectionColor() {
					if (isBootImage())
						return Color.red;
					else
						return super
						.getTextNonSelectionColor();
				}
				private boolean isBootImage() {
					return bootImageNode != null
					&& super.getText()
						== bootImageNode.toString();
				}
			});

		// editor
//		CDTree.setEditable(true);
		DefaultCellEditor cellEditor = new DefaultCellEditor(
			new MyTextField()) {
				public boolean shouldSelectCell(
					java.util.EventObject event) {
					boolean retValue = super.shouldSelectCell(event);
					getComponent().requestFocus();
					return retValue;
				}
			};
		cellEditor.setClickCountToStart(1);
		CDTree.setCellEditor(
			new DefaultTreeCellEditor(CDTree,
//				(DefaultTreeCellRenderer)CDTree.getCellRenderer(),
				new DefaultTreeCellRenderer(), cellEditor) {
				protected void prepareForEditing() {
					Version.debug("cellEditor", "prepareForEditing()");
					super.prepareForEditing();
					((JTextField)((DefaultCellEditor)realEditor)
						.getComponent()).selectAll();
				}
				public boolean stopCellEditing() {
					Version.debug("cellEditor", "stopCellEditing()");
					return super.stopCellEditing();
				}
			});

		CDTree.setRootVisible(true);
		CDTree.putClientProperty("JTree.lineStyle", "Angled");

		CDTree.addTreeExpansionListener(new TreeExpansionListener() {
			public void treeExpanded(TreeExpansionEvent event) {
				sessionSizeView.recount();
			}
			public void treeCollapsed(TreeExpansionEvent event) {
			}
		});

		if (CDTreeScroller != null)
			getContentPane().remove(CDTreeScroller);

		CDTreeScroller = new JScrollPane(theCDView);
		getContentPane().add(CDTreeScroller);

		if (sessionSizePanel != null)
			getContentPane().remove(sessionSizePanel);

		sessionSizeView = new SessionSizeView();
		sessionSizePanel = new JPanel();
		sessionSizePanel.setLayout(
			new BoxLayout(sessionSizePanel, BoxLayout.X_AXIS));
		sessionSizePanel.setBorder(
			BorderFactory.createRaisedBevelBorder());
		sessionSizePanel.add(Box.createHorizontalStrut(10));
		sessionSizePanel.add(sessionSizeView);
		getContentPane().add(sessionSizePanel);
	}

	void createMenuBar() {
		if (menuBar == null)
			menuBar = new JMenuBar();
		else
			menuBar.removeAll();

		JMenu menu;
		JMenuItem item;

		menu = new JMenu(i18n("file"));

			item = new JMenuItem(newSessionCmd);
			item.addActionListener(this);
			menu.add(item);

			item = new JMenuItem(openProjectCmd);
			item.addActionListener(this);
			menu.add(item);

			item = new JMenuItem(openProjectFromServerCmd);
			item.addActionListener(this);
			menu.add(item);

			menu.add(new JSeparator());

			item = new JMenuItem(saveProjectCmd);
			item.addActionListener(this);
			menu.add(item);

			item = new JMenuItem(saveProjectOnServerCmd);
			item.addActionListener(this);
			menu.add(item);

			menu.add(new JSeparator());

			item = new JMenuItem(quitCmd);
			item.addActionListener(this);
			if (CDcreator.isApplet())
				item.addActionListener(CDcreator.applet);
			menu.add(item);

		menuBar.add(menu);

		menu = new JMenu(i18n("view"));

			item = new JMenuItem(showStatus);
			item.addActionListener(this);
//			item.setEnabled(CDcreator.isApplet());
			menu.add(item);

			item = new JMenuItem(showLogWin);
			item.addActionListener(this);
			menu.add(item);

			JMenu menu2 = new JMenu(i18n("language"));

				for (int i = 0; i < locales.length; i++) {
					item = new JMenuItem(locales[i].name);
					item.addActionListener(this);
					menu2.add(item);
				}

			menu.add(menu2);

		menuBar.add(menu);

		menu = new JMenu(i18n("action"));

			item = new JMenuItem(blankCmd);
			item.addActionListener(this);
			menu.add(item);

			item = new JMenuItem(copyCmd);
			item.addActionListener(this);
			item.setEnabled(CDcreator.copySupport);
			if (CDcreator.cdrdao)
				item.setText(i18n("MainMenu.action.copy"));
			menu.add(item);

			item = new JMenuItem(saveImageAsCmd);
			item.addActionListener(this);
			item.setEnabled(CDcreator.saveImageAs);
			menu.add(item);

			item = new JMenuItem(burnCmd);
			item.addActionListener(this);
			burnMenuItem = item;
			menu.add(item);

		menuBar.add(menu);

		menu = new JMenu(i18n("settings"));

			item = new JMenuItem(changePasswordCmd);
			item.addActionListener(this);
			menu.add(item);

			item = new JMenuItem(editSettingsCmd);
			item.addActionListener(this);
			menu.add(item);

		menuBar.add(menu);

		menu = new JMenu(i18n("help"));

			item = new JMenuItem(showHelpCmd);
			item.addActionListener(this);
			menu.add(item);

			item = new JMenuItem(showInfoCmd);
			item.addActionListener(this);
			item.setText(i18n("about") + " "
				+ Version.product + "...");
			menu.add(item);

		menuBar.add(menu);
		menuBar.updateUI();
	}

	static JComponent createViewer(String msg) {
		int p0 = msg.indexOf("http://");
		if (p0 >= 0 && msg.indexOf("href") < 0) {
			int p1 = msg.indexOf(" ", p0);
			if (p1 < 0)
				p1 = msg.length();
			msg = msg.substring(0, p0) + "<a href=\""
				+ msg.substring(p0, p1) + "\">"
				+ msg.substring(p0, p1) + "</a>"
				+ msg.substring(p1);
		}

		final JEditorPane viewer = new JEditorPane("text/html", msg);
		viewer.setEditable(false);
		viewer.addHyperlinkListener(
			new HyperlinkListener() {
				public void hyperlinkUpdate(HyperlinkEvent e) {
					String str = e.getDescription();
					if (e.getEventType()
							== HyperlinkEvent.EventType.ACTIVATED) {
						CDcreator.showDocument(e.getURL());
					}
				}
		});
		return viewer;
	}

	private String getCDTypeStr() {
		String typeStr;
		if (Mode.makeISOImage()) {
			typeStr = i18n("destDataCD");
			newDirButton.setEnabled(true);
			setBootImageButton.setEnabled(true);
		}
		else {
			newDirButton.setEnabled(false);
			setBootImageButton.setEnabled(false);
			if (Mode.audioCD())
				typeStr = i18n("destAudioCD");
			else
				typeStr = i18n("destImageCD");
		}
		if (State.sessionID != State.none)
			typeStr = typeStr + " \"" + State.sessionID + '"';
		return typeStr;
	}

	public Container getContentPane() {
		if (CDcreator.frame != null)
			return CDcreator.frame.getContentPane();
		else
			return CDcreator.applet.getContentPane();
	}

	static Icon getIcon(String name) {
		if (name.endsWith(".png") && CDcreator.isNetscapeVM())
			name = name.substring(0, name.length() - 3) + "jpg";

		URL url = CDcreator.getURL("icons/" + name);
		if (url == null)
			return null;
		return new ImageIcon(url);
	}

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

	void loadProject(String projectURL) {
		Options.reset();
		resetCDView();
		copyButton.setEnabled(true);
		getContentPane().doLayout();
		try {
			URL project = new URL(projectURL);
			BufferedReader reader
				= new BufferedReader(
					new InputStreamReader(
						project.openStream(), "UTF-8"));
			LoadProject loader = new LoadProject();
			for (int i = 0; ; i++) {
				String line = reader.readLine();
				if (line == null)
					break;
				Version.debug("loadProject", line);
				loader.execute(line);
			}
		}
		catch (Exception e) { }
		updateCDRoot();
		serverUpToDate = false;
		sessionSizeView.recount();
	}

	void loadProject(File file) {
		Options.reset();
		resetCDView();
		copyButton.setEnabled(true);
		getContentPane().doLayout();
		try {
			InputStream project = new FileInputStream(file);
			BufferedReader reader
				= new BufferedReader(
					new InputStreamReader(
						project, "UTF-8"));
			State.sessionID = file.getName();
			if (State.sessionID.endsWith(".cdw"))
				State.sessionID = State.sessionID.substring(
					0, State.sessionID.length() - 4);
			LoadProject loader = new LoadProject();
			for (int i = 0; ; i++) {
				String line = reader.readLine();
				if (line == null)
					break;
				Version.debug("loadProject", line);
				loader.execute(line);
			}
		}
		catch (Exception e) { }
		updateCDRoot();
		serverUpToDate = false;
		sessionSizeView.recount();
	}

	boolean login() {
		if (State.userPassword != State.none)
			return true;

		return LoginDialog.show();
	}

	void moveUpOrDown(DirTreeNode CDnode, boolean up) {
		MutableTreeNode parent = (MutableTreeNode)CDnode.getParent();
		if (parent == null)
			return;

		DefaultTreeModel treeModel = (DefaultTreeModel)CDTree.getModel();
		int p = treeModel.getIndexOfChild(parent, CDnode);
		if (up) {
			if (--p < 0)
				return;
		}
		else
			if (++p >= treeModel.getChildCount(parent))
				return;

		try {
			treeModel.removeNodeFromParent(CDnode);
			treeModel.insertNodeInto(CDnode, parent, p);
		}
		catch (Exception e) {
			Version.debug("upOrDown", "" + e);
		}
	}

	void putSession() throws CommandError {
		State.numOfFiles = 0;
		State.numOfTracks = 0;
		if (Mode.serverSession() || serverUpToDate)
			new OpenSession().exec();
		else
			new NewSession().exec();

		if (State.numOfFiles == 0
			&& State.numOfTracks == 0)
			if (Mode.makeISOImage())
				new PutFiles(CDRoot,
					sessionSizeView.getKBytesNum()).exec();
			else
				new PutTracks(CDRoot,
					sessionSizeView.getKBytesNum()).exec();

		serverUpToDate = !Mode.saveImage;
	}

	void remove(TreePath treePath) {
		showDebugInfo("remove: " + treePath.toString());

		DirTreeNode CDnode = (DirTreeNode)treePath
			.getLastPathComponent();
		if (CDnode.getParent() == null)
			return;
		((DefaultTreeModel)CDTree.getModel())
			.removeNodeFromParent(CDnode);
		Project.remove(treePath);
		sessionSizeView.recount();
	}

	private void resetCDView() {
		bootImageNode = null;
		CDRoot = new CDNode(getCDTypeStr());
		CDTreeModel.setRoot(CDRoot);
//		CDViewModel.fireTableStructureChanged();
		Project.setCDRoot(CDRoot);
		sessionSizeView.recount();
	}

	void saveImageAs() {
		Mode.saveImage = true;
		burnSession();
		Mode.saveImage = false;
	}

	private void saveProject() {
		JFileChooser chooser = new JFileChooser();
		if (chooser.showSaveDialog(CDcreator.mainWin)
				!= JFileChooser.APPROVE_OPTION)
			return;
		String name = chooser.getSelectedFile().getPath();
		if (!name.endsWith(".cdw"))
			name = name + ".cdw";
		try {
			checkOverwrite(name);
			PrintWriter out = new PrintWriter(
				new BufferedWriter(
					new FileWriter(name)));
			String type = null;
			if (Mode.type == Mode.audio)
				type = "audio";
			else
			if (Mode.type == Mode.data)
				if (Mode.makeImage)
					type = "data";
				else
					type = "image";
			if (type != null)
				out.println("type " + type);
			out.println("medium " + Mode.media.getSelectedItem());
			if (Mode.type == Mode.audio) {
				for (int i = 0; i < CDRoot.getChildCount(); i++) {
					out.println("add "
						+ Command.spaceToEsc(
							((CDNode)CDRoot.getChildAt(i))
								.getFile().getPath())
						+ " /");
				}
			}
			else
			for (int i = 0; i < Project.getNumOfCommands(); i++) {
				String cmd = Project.getCommandType(i)
					+ " " + Command.spaceToEsc(Project.getCommandArg1(i));
				if (Project.getCommandArg2(i).length() > 0)
					cmd = cmd + " "
						+ Command.spaceToEsc(Project.getCommandArg2(i));
				out.println(cmd);
			}
			if (Options.bootImage != null)
				out.println("boot " + Command.spaceToEsc(Options.bootImage));
			out.close();
		}
		catch (Exception e2) {
		}
	}

	void setBootImage(String fileName) {
		java.util.StringTokenizer t = new java.util.StringTokenizer(
			fileName, "/");
		DirTreeNode node = CDRoot;
		try {
			while (true) {
				String str = t.nextToken();
				Version.debug("boot", "node = " + node + " " + str);
				int n = node.getChildCount();
				int i;
				for (i = 0; i < n; i++)
					if (((DirTreeNode) node.getChildAt(i)).toString()
						.equals(str))
					break;
				if (i < n)
					node = ((DirTreeNode) node.getChildAt(i));
				else
					break;
			}
		}
		catch (Exception e2) {
			if (node.isLeaf()) {
				bootImageNode = node;
				((DefaultTreeModel) CDTree.getModel())
					.nodeChanged(node);
				Options.bootImage = fileName;
			}
		}
	}

	void setBurnButtonEnabled(boolean enabled) {
		burnButton.setEnabled(enabled);
		burnMenuItem.setEnabled(enabled);
	}

	void setLocale(int no) {
		java.util.Locale locale = locales[no].locale;
		java.util.Locale oldLocale = CDcreator.locale;
		CDcreator.setLocale2(locale);

			try {
				Font font = new JButton().getFont();
				String sample = i18n("FDTextSample");
				int pos = font.canDisplayUpTo(sample);
				if (pos != -1 && pos < sample.length()) {
//					setUIFont(new javax.swing.plaf.FontUIResource(
//						"Dialog", Font.PLAIN, 30));
					new FontDialog().setVisible(true);
					showFontInfo();
					CDcreator.setLocale2(oldLocale);
				}
			} catch (NoSuchMethodError e2) {}

			createMenuBar();
			fsNode.setUserObject(i18n("sources"));
			if (homeNode != null)
				homeNode.setUserObject(i18n("homeDirs"));
			updateCDRoot();
			copyButton.setToolTipText(i18n("TTcopy"));
			mediumLabel.setText(i18n("MWMedium"));
			removeButton.setToolTipText(i18n("TTcut"));
			newDirButton.setToolTipText(i18n("TTnewDir"));
			setBootImageButton.setToolTipText(i18n("TTsetBootImage"));
			burnButton.setToolTipText(i18n("burnCmd"));
			downButton.setToolTipText(i18n("MainWin.downTip"));
			upButton.setToolTipText(i18n("MainWin.upTip"));
			sessionSizeView.setToolTipText(CDcreator.i18n("TTsessionSize"));
		}

	public static void setUIFont(javax.swing.plaf.FontUIResource f) {
		java.util.Enumeration keys = UIManager.getDefaults().keys();
		while (keys.hasMoreElements()) {
			Object key = keys.nextElement();
			Object value = UIManager.get(key);
			if (value instanceof javax.swing.plaf.FontUIResource) {
				System.out.println(key + " <-> " + value);
				UIManager.put(key, f);
			}
		}
	}

	void showAbout() {
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		panel.add(new JLabel(Version.product + " " + Version.version));

		JTabbedPane tabbedPane = new JTabbedPane();
		tabbedPane.setPreferredSize(new Dimension(440, 280));
		tabbedPane.setAlignmentX(Component.LEFT_ALIGNMENT);

		String translators = i18n("translator(s)");
		int p = translators.indexOf("<html>");
		if (p >= 0)
			translators = translators.substring(p + 6);
		p = translators.indexOf("</html>");
		if (p >= 0)
			translators = translators.substring(0, p);

		String translationStr = "<table>"
			+ "<tr bgcolor=\"#A0A0FF\">"
			+ "<th align=\"left\">" + i18n("translation") + "</th></tr>"
			+ "<tr><td bgcolor=\"#C8FFC8\">"
			+ translators
			+ "</td></tr></table>";

		JEditorPane about = new JEditorPane("text/html",
			"<html>"
			+ "<h2 align=\"center\">" + Version.product + "</h2>"
			+ "<h3 align=\"center\">" + i18n("ADAClientOf") + "<br>"
			+ "<a href=\"" + Version.projectHome + "\">"
			+ "webCDwriter</a> - " + Version.subTitle + "</h3>"
//			+ i18n("version") + ": " + Version.version + "<br>"
//			+ i18n("author") + ": " + Version.author + "\n"
			+ "<h3 align=\"center\">" + Version.copyright + "<br>"
//			+ Version.eMail + "<br>"
			+ "<a href=\"" + Version.authorHome + "\">"
			+ Version.authorHome + "</a></h3>"
			+ translationStr
			+ "</html>");
		about.setEditable(false);
		about.addHyperlinkListener(
			new HyperlinkListener() {
				public void hyperlinkUpdate(HyperlinkEvent e) {
					if (e.getEventType()
						== HyperlinkEvent.EventType.ACTIVATED)
						CDcreator.showDocument(e.getURL());
				}
			}
		);
		tabbedPane.add(new JScrollPane(about), i18n("about"));

		JEditorPane systemPane = new JEditorPane("text/html",
			"<html>"
			+ i18n("system") + ": "
			+ System.getProperty("os.name") + " "
			+ System.getProperty("os.version")
			+ "<br><br>"
			+ "Java VM: " + CDcreator.vmName
			+ " " + CDcreator.vmVersion
			+ "<br><br>"
			+ i18n("user") + ": "
			+ System.getProperty("user.name")
			+ "<br><br>"
			+ i18n("user.home") + ": "
			+ System.getProperty("user.home")
			+ "<br><br>"
			+ i18n("config") + ": " + Config.configFile
			+ "</html>");
		systemPane.setEditable(false);
		tabbedPane.add(systemPane, i18n("system"));

		try {
			JEditorPane licensePane = new JEditorPane(
				CDcreator.getURL("gpl.html"));
			licensePane.setEditable(false);

			JScrollPane scroller = new JScrollPane();
			JViewport vp = scroller.getViewport();
			vp.add(licensePane);

			tabbedPane.add(scroller, i18n("ADLicense"));
		} catch (Exception e) {
			tabbedPane.add(new JEditorPane("text/html",
				"GNU GENERAL PUBLIC LICENSE<br>"
				+ "Version 2, June 1991"
				),
				i18n("ADLicense"));
		}

		panel.add(tabbedPane);

		JDialog d = new JOptionPane(
			panel, JOptionPane.INFORMATION_MESSAGE)
			.createDialog(CDcreator.mainWin,
				i18n("about") + " " + Version.product + "...");
		d.setResizable(true);
		d.setVisible(true);
	}

	void showDebugInfo(String str) {
		Version.showDebugInfo(str);
	}

	void showFontInfo() {
		String
			slash = System.getProperty("file.separator"),
			javaHome = System.getProperty("java.home"),
			fontProperties = javaHome + slash + "lib" + slash
				+ "font.properties",
			msg = "The font \""
			+ new JButton().getFont().getFontName()
			+ "\" doesn´t support the locale "
			+ CDcreator.locale + ".\n"
			+ "Try to edit or replace the file "
			+ fontProperties + ".\n"
			+ "See " + Version.projectHome + "font.properties.html"
			+ " for details.";
		JOptionPane.showMessageDialog(CDcreator.mainWin, msg, "Fonts",
			JOptionPane.ERROR_MESSAGE);
	}

	/**
	 *
	 */
	public void showSettings() {
		JPanel vbox = new JPanel();
		vbox.setLayout(new BoxLayout(vbox, BoxLayout.Y_AXIS));
		vbox.add(new JLabel(i18n("sources")
			+ " (\"C:\\,D:\\data\" or \"/home,/usr/local\")"));
		vbox.add(Box.createVerticalStrut(10));
		JTextField tf = OptionsDialog.createTextField(
			Config.get(Config.SOURCES), 1000);
		tf.setAlignmentX(JLabel.LEFT_ALIGNMENT);
		tf.setColumns(40);
		vbox.add(tf);
		JOptionPane pane = new JOptionPane(vbox,
			JOptionPane.PLAIN_MESSAGE,
			JOptionPane.OK_CANCEL_OPTION);
		JDialog win = pane.createDialog(
			CDcreator.mainWin, i18n("settings"));
		win.setVisible(true);
		Object res = pane.getValue();
		if (res != null)
			if (res instanceof Integer)
				if (((Integer)res).intValue() == JOptionPane.OK_OPTION)
					Config.set(Config.SOURCES, tf.getText());
	}

	void transfer(TreePath treePath) throws Exception {
		showDebugInfo("transfer: " + treePath.toString());

		if (CDTree.isSelectionEmpty())
			CDTree.setSelectionRow(0);
		showDebugInfo("-> "
			+ CDTree.getSelectionPath().toString());

		File file = ((DirTreeNode)treePath
			.getLastPathComponent()).getFile();
		checkFile(file);
		CDNode newNode = new CDNode(file);
		TreePath CDPath = CDTree.getSelectionPath();
		DirTreeNode CDnode = (DirTreeNode)CDPath.getLastPathComponent();
		int p = CDTreeModel.getChildCount(CDnode);
		if (CDnode.isLeaf()) {
			p = CDTreeModel.getIndexOfChild(CDnode.getParent(), CDnode);
			CDnode = (DirTreeNode)CDnode.getParent();
		}
		if (CDnode == null || CDnode.isLeaf())
			return;
		int n = CDTreeModel.getChildCount(CDnode);
		if (Mode.type == Mode.audio)
			n = 0;
		for (int i = 0; i < n; i++) {
			if (CDTreeModel.getChild(CDnode, i).toString()
					.equals(newNode.toString()))
				return;
		}
		CDTreeModel.insertNodeInto(newNode, CDnode, p);
		Project.add(newNode, CDPath);
	}

	public boolean typeSelection(boolean canBeCancelled) {
		NewProjectDialog dialog = new NewProjectDialog(canBeCancelled);
		dialog.pack();
		center(dialog);
//		if (CDcreator.audioCDSupport)
		dialog.setVisible(true);
		if (canBeCancelled && dialog.wasCanceled())
			return false;
		updateCDRoot();
		return true;
	}

	private void updateCDRoot() {
		CDRoot.setUserObject(getCDTypeStr());
//		theCDView.updateUI();
//		CDTreeModel.nodeChanged(CDRoot);
		CDTreeModel.reload();
	}

	LayoutManager LM = new LayoutManager() {
		public void addLayoutComponent(String name, Component comp) {
			System.out.println("addLayoutComponent: " + name);
		}

		public void layoutContainer(Container parent) {
			Dimension d = parent.getSize();
			int xB = 5;
			int x = d.width - xB - xB - 60 - xB - xB;
			int y = d.height - 10 - 10;
			final int bs = 22 + 6;
			treeScroller.setBounds(
				xB, 10, x/2, y);
			copyButton.setBounds(
				xB + x/2 + xB, 10 + (y-20) / 2, 60, 30);
			burnButton.setBounds(
				xB + x/2 + xB + 11, 10 + 3 * (y-38) / 4 - 19, 38, 38);

			int mediumBoxHeight = mediumBox.getPreferredSize().height;
			mediumPanel.setBounds(
				xB + x/2 + xB + 60 + xB, 5, x/2, mediumBoxHeight);
			int y0 = 5 + mediumBoxHeight + 2;
			y = d.height - 2 * y0;
			CDTreeScroller.setBounds(
				xB + x/2 + xB + 60 + xB, y0, x/2, y);
			Rectangle bounds = new Rectangle(
				xB + x/2 + xB + 60 + xB - xB - bs, y0 + 5, bs, bs);
			removeButton.setBounds(bounds);
			bounds.translate(0, bs + 5);
			newDirButton.setBounds(bounds);
			bounds.translate(0, bs + 5);
			setBootImageButton.setBounds(bounds);

			bounds.y = y0 + y - 2 * (bs + 5);
			upButton.setBounds(bounds);
			bounds.translate(0, bs + 5);
			downButton.setBounds(bounds);
			sessionSizePanel.setBounds(
				xB + x/2 + xB + 60 + xB, y0 + y + 2,
				x/2, mediumBoxHeight);
		}

		public Dimension minimumLayoutSize(Container parent) {
			return new Dimension(100, 100);
		}

		public Dimension preferredLayoutSize(Container parent) {
			return new Dimension(400, 400);
		}

		public void removeLayoutComponent(Component comp) {
		}
	};

	TreeWillExpandListener treeWillExpandListener
		= new TreeWillExpandListener() {
		public void treeWillCollapse(TreeExpansionEvent event) {
		}
		public void treeWillExpand(TreeExpansionEvent event) {
			DirTreeNode CDnode = (DirTreeNode)
				event.getPath()
				.getLastPathComponent();
			CDnode.resetExpanded();
			((DefaultTreeModel)tree.getModel()).reload(CDnode);
		}
	};

	class MyTreeModelListener implements TreeModelListener {
		public void treeNodesChanged(TreeModelEvent e) {
			DirTreeNode node;
			node = (DirTreeNode)
				(e.getTreePath().getLastPathComponent());
			if (e.getChildIndices() != null) {
				int index = e.getChildIndices()[0];
				node = (DirTreeNode)
					(node.getChildAt(index));
			}
			System.out.println("New value: " + node);
		}
		public void treeNodesInserted(TreeModelEvent e) {
		}
		public void treeNodesRemoved(TreeModelEvent e) {
		}
		public void treeStructureChanged(TreeModelEvent e) {
		}
	}

	class MyTextField extends JTextField {
		protected void processKeyEvent(KeyEvent e) {
//			System.out.println(e.toString());
			if (e.getKeyCode() == KeyEvent.VK_ENTER) {
				Version.debug("cellEditor",
					"-> " + CDTree.getEditingPath());
				if (getText().equals("")) {
					JOptionPane.showMessageDialog(
						CDcreator.mainWin,
						i18n("MWEmptyFileName"),
						i18n("error"),
						JOptionPane.ERROR_MESSAGE);
				}
				else {
					Project.rename(CDTree.getEditingPath(), getText());
					super.processKeyEvent(e);
				}
			}
			else
				super.processKeyEvent(e);
		}
	}

//	private static Font font = new Font("Bitstream Cyberbit", 0, 12);

/*	class JMenu extends javax.swing.JMenu {
		JMenu(String s) {
			super(s);
			try {
				if (getFont().canDisplayUpTo(s) < s.length())
					if (font != null)
						setFont(font);
			} catch (NoSuchMethodError e) {}
		}
	}
*/
	class JMenuItem extends javax.swing.JMenuItem {
		JMenuItem(String s) {
			super(i18n(s));
			setActionCommand(s);
/*			try {
				String s2 = i18n(s);
				if (getFont().canDisplayUpTo(s2) < s2.length())
					if (font != null)
						setFont(font);
			} catch (NoSuchMethodError e) {}
*/		}
	}
}
