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

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.*;

class MainWin extends JFrame implements ActionListener
{
	static String
		burnCmd = i18n("burnCmd"),
		newDirCmd = i18n("newDirCmd"),
		newSessionCmd = i18n("cmdNewSession"),
		quitCmd = i18n("quitCmd"),
		removeCmd = i18n("removeCmd"),
		renameCmd = "Rename",
		setBootImageCmd = i18n("cmdSetBootImage"),
		showHelpCmd = i18n("showHelpCmd"),
		showInfoCmd = i18n("about") + " " + Version.product + "...";
	final static String transferCmd = ">>";
	final static int filesSession = 1, tracksSession = 2;

	// components
	private JMenuBar menuBar;
	private JTree tree, CDTree;
	private JScrollPane treeScroller, CDTreeScroller;
	private JButton copyButton,
		removeButton, newDirButton, setBootImageButton;
	private SessionSizeView sessionSizeView;
	private JPopupMenu menu;

	// models
	private DirTreeNode CDRoot;
	private DefaultTreeModel CDTreeModel;

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

	MainWin()
	{
		super(Version.product);
		getContentPane().setLayout(LM);
		addWindowListener(new WindowAdapter()
		{
			public void windowClosed(WindowEvent e)
			{
				if (CDcreator.applet == null)
					System.exit(0);
				else
					CDcreator.applet.closeMainWin();
			}
			public void windowClosing(WindowEvent e)
			{
				e.getWindow().dispose();
			}
		});

		createMenuBar();
		setJMenuBar(menuBar);

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

		File driveC = new SecFile("C:\\");
		if (driveC.exists())
		{
			// Windows
			char[] bs = { 'A', ':', '\\', '.' };
			for (char ch = 'C'; ch <= 'Z'; ch++)
			{
			bs[0] = ch;
			String driveName = new String(bs);
			File drive = new SecFile(driveName);
			if (drive.exists())
			{
				DirTreeNode rootNode
					= new DirTreeNode(drive);
				rootNode.setUserObject(driveName);
				fsTreeModel.insertNodeInto(
					rootNode, fsNode,
					fsTreeModel.getChildCount(fsNode));
			}
			}
		}
		else
		{
			// UNIX
			DirTreeNode rootNode
				= new DirTreeNode(new SecFile("/"));
			rootNode.setUserObject("/");
			fsTreeModel.insertNodeInto(
				rootNode, fsNode,
				fsTreeModel.getChildCount(fsNode));

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

		String homeDir = System.getProperty("user.home");
		if (homeDir.endsWith("/.netscape"))
			homeDir = homeDir.substring(
				0, homeDir.length() - 10);
		DirTreeNode homeNode
			= new DirTreeNode(new SecFile(homeDir));
		homeNode.setUserObject(homeDir);
		fsTreeModel.insertNodeInto(
			homeNode, fsNode,
			fsTreeModel.getChildCount(fsNode));

		File driveP = new SecFile("P:\\.");
		if (driveP.exists())
		{
			DirTreeNode rootNode = new DirTreeNode(driveP);
			rootNode.setUserObject(
				System.getProperty("user.name")
				+ " (P:\\)");
			fsTreeModel.insertNodeInto(
				rootNode, fsNode,
				fsTreeModel.getChildCount(fsNode));
		}

		tree = new JTree(fsTreeModel);
		tree.setSelectionModel(new DefaultTreeSelectionModel());
		tree.addTreeWillExpandListener(treeWillExpandListener);
		treeScroller = new JScrollPane(tree);
		getContentPane().add(treeScroller);

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

		resetCDTree();

		removeButton = new JButton(
			new ImageIcon(getURL("icons/cut.gif")));
		removeButton.setActionCommand(removeCmd);
		removeButton.addActionListener(this);
		removeButton.setToolTipText(i18n("TTcut"));
		getContentPane().add(removeButton);

		newDirButton = new JButton(
			new ImageIcon(getURL("icons/folder.gif")));
		newDirButton.setActionCommand(newDirCmd);
		newDirButton.addActionListener(this);
		newDirButton.setToolTipText(i18n("TTnewDir"));
		getContentPane().add(newDirButton);

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

		actionListener = this;
		mainWin = this;
	}

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

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

		if (e.getActionCommand().equals(burnCmd))
		try {
			if (CDcreator.sessionType
				== CDcreator.audioSession)
				Options.closeCD = true;

			OptionsDialog options = new OptionsDialog();
			options.pack();
			center(options);
			options.show();
			if (options.wasCanceled())
				return;
			Command.filesNum = 0;
			if (serverUpToDate)
				new OpenSession().exec();
			else
				new NewSession().exec();

			if (Command.filesNum == 0)
				if (CDcreator.sessionType
					== CDcreator.multiSession)
					new PutFiles(CDRoot,
						1024 * sessionSizeView
						.getKBytesNum()).exec();
				else
					new PutTracks(CDRoot,
						1024 * sessionSizeView
						.getKBytesNum()).exec();

			serverUpToDate = true;
			Log.clear();
			new BurnSession().exec();
			if (Options.offline)
				dispose();
//			else
//				new CloseSession().exec();
		}
		catch (CommandError cmdErr)
		{
			try {
				new CloseSession().exec();
			}
			catch (CommandError cmdErr2)
			{
			}
		}
		else
		if (e.getActionCommand().equals(newDirCmd))
		{
			DirTreeNode newNode
				= new DirTreeNode("");
			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())
			{
				System.out.println(CDnode
					+ " nicht Verzeichnis");
				return;
			}
/*			CDnode.add(newNode);
			int [] is = new int[1];
			is[0] = CDnode.getIndex(newNode);
			((DefaultTreeModel)CDTree.getModel())
				.nodesWereInserted(CDnode, is);
*/			CDTreeModel.insertNodeInto(
				newNode, CDnode,
				CDTreeModel.getChildCount(CDnode));
			CDTree.startEditingAtPath(
				path.pathByAddingChild(newNode));
			serverUpToDate = false;
		}
		else
		if (e.getActionCommand().equals(newSessionCmd))
		{
			Options.reset();
			resetCDTree();
			copyButton.setEnabled(true);
			getContentPane().doLayout();
			typeSelection();
		}
		else
		if (e.getActionCommand().equals(quitCmd))
		{
			if (CDcreator.applet == null)
				System.exit(0);
		}
		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 (CDcreator.sessionType == CDcreator.imageSession
				&& CDRoot.getChildCount() == 0)
				copyButton.setEnabled(true);
		}
		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);
		}
		else
		if (e.getActionCommand().equals(showHelpCmd))
		{
			if (CDcreator.applet == null)
			{
				HelpWin win = new HelpWin();
				win.show();
			}
			else
				CDcreator.applet.getAppletContext()
					.showDocument(
					getURL("doc/index.html"),
					"_blank");
		}
		else
		if (e.getActionCommand().equals(showInfoCmd))
		{
			String translationStr = i18n("translation");
			if (translationStr.equals("translation")
				|| translationStr.equals("Translation:"))
				translationStr = "";
			else
				translationStr = translationStr + "\n";

			JOptionPane.showMessageDialog(this,
				Version.subTitle + "\n"
				+ i18n("version") + ": "
				+ Version.version + "\n"
				+ i18n("author") + ": "
				+ Version.author + "\n"
				+ Version.eMail + "\n"
				+ translationStr + "\n"
				+ i18n("system") + ": "
				+ System.getProperty("os.name") + " "
				+ System.getProperty("os.version")
				+ "\n"
/*				+ "Java VM: "
				+ System.getProperty("java.vm.name")
				+ " "
				+ System.getProperty("java.vm.version")
				+ "\n"
*/				+ i18n("user") + ": "
				+ System.getProperty("user.name"),
				showInfoCmd,
				JOptionPane.INFORMATION_MESSAGE);
		}
		else
		if (e.getActionCommand().equals(transferCmd))
		{
			TreePath paths[] = tree.getSelectionPaths();
			if (paths == null)
				return;
			int n = paths.length;
			if (CDcreator.sessionType == CDcreator.imageSession)
				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 (CDcreator.sessionType == CDcreator.imageSession
				&& CDRoot.getChildCount() > 0)
				copyButton.setEnabled(false);
		}
	}

	public void center(Component c)
	{
		Rectangle r0 = getBounds();
		Rectangle r1 = c.getBounds();
		c.setBounds(r0.x + (r0.width - r1.width) / 2,
			r0.y + (r0.height - r1.height) / 2,
			r1.width, r1.height);
	}

	void checkFile(File f) throws Exception
	{
		if (CDcreator.sessionType == CDcreator.imageSession)
			if (f.isDirectory())
				throw new Exception("no imagefile");

		if (CDcreator.sessionType == CDcreator.audioSession)
		if (f.length() <= 44)
		{
			new JOptionPane(
				f + "\n" + i18n("incompleteAudioFile"),
				JOptionPane.ERROR_MESSAGE,
				JOptionPane.DEFAULT_OPTION)
				.createDialog(CDcreator.mainWin,
					i18n("titleNoAudioFile")).show();
			throw new Exception("no/wrong wav");
		}
		else
		if (!((SecFile)f).isWAV()
			&& (!CDcreator.mp3Support
				|| !f.getName().toLowerCase()
					.endsWith(".mp3")))
		{
			new JOptionPane(
				f + "\n" + i18n("noAudioFile"),
				JOptionPane.ERROR_MESSAGE,
				JOptionPane.DEFAULT_OPTION)
				.createDialog(CDcreator.mainWin,
					i18n("titleNoAudioFile")).show();
			throw new Exception("no/wrong wav");
		}
	}

	void createMenuBar()
	{
		menuBar = new JMenuBar();

		JMenu menu;
		JMenuItem item;

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

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

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

		menuBar.add(menu);

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

		item = new JMenuItem(burnCmd);
		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);
		menu.add(item);

		menuBar.add(menu);
	}

	private int getSessionType()
	{
		DirTreeNode node = CDRoot;
		if (node.getChildCount() < 1)
			return filesSession;

		boolean wav = true;
		for (int i = 0; i < node.getChildCount(); i++)
		{
			DirTreeNode child =
				(DirTreeNode)node.getChildAt(i);
			if (!child.isLeaf())
				return filesSession;
			wav = wav && ((SecFile)child.getFile()).isWAV();
		}

		if (node.getChildCount() > 1 && !wav)
			return filesSession;

		String question;
		if (!wav)
			question = "imageQuestion";
		else
			question = "wavQuestion";

		Object buttons[] = { i18n("yes"), i18n("no") };
		JOptionPane pane = new JOptionPane(
			i18n(question),
			JOptionPane.QUESTION_MESSAGE,
			JOptionPane.DEFAULT_OPTION,
			null, buttons, buttons[1]);
		pane.createDialog(CDcreator.mainWin,
			i18n("titleImageQuestion")).show();

		if (pane.getValue() == null)
			return filesSession;

		if (pane.getValue().equals(buttons[0]))
			return tracksSession;
		else
			return filesSession;
	}

	protected URL getURL(String fileName)
	{
		URL codeBase = CDcreator.codeBase, url;
		if (codeBase == null)
		{
			url = ClassLoader.getSystemResource(fileName);
		}
		else
		try {
			url = new URL(codeBase, fileName);
		}
		catch (java.net.MalformedURLException e) {
			url = null;
		}

//		System.out.println(fileName + " -> " + url);
		return url;
	}

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

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

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

	private void resetCDTree()
	{
		bootImageNode = null;

		CDRoot = new DirTreeNode("CD");
		CDTreeModel = new DefaultTreeModel(CDRoot, true);
		CDTree = new JTree(CDTreeModel);
		CDTree.setCellRenderer(
			new DefaultTreeCellRenderer()
			{
				public Icon getLeafIcon()
				{
					if (isBootImage())
						return new ImageIcon(getURL(
							"icons/boot.jpg"));
					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();
				}
			});
		CDTree.setEditable(true);
		CDTree.setRootVisible(true);
		CDTree.addMouseListener(new MouseAdapter()
		{
			private void showPopup(MouseEvent e)
			{
				mainWin.setSelection(
					e.getX(), e.getY());

				menu = new JPopupMenu();

				JMenuItem item2;
				item2 = new JMenuItem(newDirCmd);
				item2.addActionListener(actionListener);
				menu.add(item2);

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

				item2 = new JMenuItem(setBootImageCmd);
				item2.addActionListener(actionListener);
				menu.add(item2);

				menu.show(CDTree,
					e.getX()-0, e.getY()-0);
			}
			public void mousePressed(MouseEvent e)
			{
				showDebugInfo("mousePressed");
				if (e.isPopupTrigger())
					showPopup(e);
			}
			public void mouseReleased(MouseEvent e)
			{
//				menu.setVisible(false);
				showDebugInfo("mouseReleased");
				if (e.isPopupTrigger())
					showPopup(e);
			}
		});

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

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

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

		sessionSizeView = new SessionSizeView();
		getContentPane().add(sessionSizeView);
	}

	void setSelection(int x, int y)
	{
		CDTree.setSelectionRow(
			CDTree.getRowForLocation(x, y));
	}

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

	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);
		DirTreeNode newNode = new DirTreeNode(file);
		DirTreeNode CDnode = (DirTreeNode)CDTree
			.getSelectionPath()
			.getLastPathComponent();
		if (CDnode.isLeaf())
			return;
		CDTreeModel.insertNodeInto(
			newNode, CDnode,
			CDTreeModel.getChildCount(CDnode));
		sessionSizeView.add(file);
	}

	public void typeSelection()
	{
		TypesDialog dialog = new TypesDialog();
//		do {
			dialog.pack();
			dialog.pack();
//		} while (dialog.getWidth() < 50);
		center(dialog);
		dialog.setVisible(true);
		CDcreator.sessionType = dialog.getResult();
		if (CDcreator.sessionType == CDcreator.multiSession)
		{
			CDRoot.setUserObject(i18n("destDataCD"));
			newDirButton.setEnabled(true);
			setBootImageButton.setEnabled(true);
		}
		else
		{
			newDirButton.setEnabled(false);
			setBootImageButton.setEnabled(false);
			if (CDcreator.sessionType == CDcreator.imageSession)
				CDRoot.setUserObject(i18n("destImageCD"));
			else
				CDRoot.setUserObject(i18n("destAudioCD"));
		}
		CDTree.updateUI();
	}

	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 x = d.width - 10 - 10 - 60 - 10 - 10;
			int y = d.height - 10 - 10;
			treeScroller.setBounds(
				10, 10, x/2, y);
			copyButton.setBounds(
				10 + x/2 + 10, 10 + (y-20) / 2, 60, 30);
			CDTreeScroller.setBounds(
				10 + x/2 + 10 + 60 + 10, 10, x/2, y - 10);
			removeButton.setBounds(
				10 + x/2 + 10 + 60 - 20, 10 + 5, 25, 25);
			newDirButton.setBounds(
				10 + x/2 + 10 + 60 - 20, 10 + 35, 25, 25);
			setBootImageButton.setBounds(
				10 + x/2 + 10 + 60 - 20, 10 + 65, 25, 25);
			sessionSizeView.setBounds(
				10 + x/2 + 10 + 60 + 10, 10 + y - 5, x/2, 14);
		}

		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);
		}
	};
}
