/*
 * @(#)OptionsDialog.java
 *
 * This file is part of webCDwriter - Network CD Writing.
 *
 * Copyright (C) 1999-2003 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 javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;

/**
 * This is a dialog which allows the user to choose the options.
 *
 * @version 20030807
 * @author Jörg P. M. Haeger
 */
public class OptionsDialog extends SequenceDialog {
	protected JPanel panel0;
	private JCheckBox
		offlineBox,
		acceptEmptyCDBox,
		acceptKeyBox,
		acceptUnprotectedCDBox,
		blankTOCBox,
		closeCDBox,
		DAOBox,
		DVDVideoBox,
		formatBox,
		HFSBox,
		jolietBox,
		MD5FileBox,
		overburnBox,
		protectionBox,
		rockRidgeBox,
		simulateBox,
		verifyBox;

	private MyBox waitForSubBox;
	private JButton defaultButton;
	private JComboBox speedBox;
	private MySpinner copiesSpinner;
	private JTextField
		acceptField,
		protectionField,
		volumeIDField;

	public OptionsDialog() {
		super("titleOptions");

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				cancelPressed();
			}
		});

		panel0 = new JPanel();
		panel0.setLayout(new BoxLayout(panel0, BoxLayout.Y_AXIS));
		panel0.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));
		getContentPane().add(panel0, BorderLayout.CENTER);

		OKButton.setText(i18n("MainWin.continue"));

		initState2();

		enterState(0);
		pack();
	}

	void addState1() {
		JPanel hp = new JPanel();
		hp.setLayout(new BoxLayout(hp, BoxLayout.X_AXIS));
		hp.setAlignmentX(LEFT_ALIGNMENT);

		hp.add(createStepsGroup());
		hp.add(Box.createVerticalStrut(5));

		// right column
		JPanel rc = new JPanel();
		rc.setLayout(new BoxLayout(rc, BoxLayout.Y_AXIS));
		rc.add(createWritingGroup());
		rc.add(createCopiesGroup());
		hp.add(rc);

		panel0.add(hp);

		if (Mode.makeISOImage()) {
			panel0.add(Box.createVerticalStrut(5));
			panel0.add(createFilesystemGroup());
		}
	}

	void addState2() {
		// accept
		panel0.add(createHeader(".accept"));

		JComponent[] cs = {
			acceptEmptyCDBox,
			acceptUnprotectedCDBox,
			createLabelItemBox(
				acceptKeyBox, acceptField)
		};
		waitForSubBox = createVBox(cs);
		panel0.add(createLabelItemBox(
			Box.createHorizontalStrut(20),
			waitForSubBox));
		panel0.add(new JLabel(i18n(".acceptNote")));

		panel0.add(Box.createVerticalGlue());

		if (Mode.makeISOImage()) {
			// write protection
			panel0.add(createHeader(".writeProtection"));
			panel0.add(createLabelItemBox(
				Box.createHorizontalStrut(20),
				createLabelItemBox(protectionBox, protectionField)));
			panel0.add(new JLabel(i18n(".writeProtectionNote")));
		}

		panel0.add(Box.createVerticalGlue());
	}

	public boolean apply() {
		if (CDcreator.writeProtection && acceptField.isEnabled())
			Options.acceptKey = acceptField.getText();
		else
			Options.acceptKey = "";
		if (blankTOCBox != null)
			Options.blankTOC = blankTOCBox.isSelected();
		Options.rejectEmptyCD = !acceptEmptyCDBox.isSelected();
		Options.rejectUnprotectedCD = !acceptUnprotectedCDBox.isSelected();
		if (closeCDBox != null)
			Options.closeCD = closeCDBox.isSelected();
		if (CDcreator.writeProtection && protectionBox.isSelected())
			Options.writeProtection = protectionField.getText();
		else
			Options.writeProtection = "";
		Options.copies = ((Integer)copiesSpinner.getValue()).intValue();
		Options.DAO = DAOBox.isSelected();
		if (formatBox != null)
			Options.format = formatBox.isSelected();
		if (overburnBox != null)
			Options.overburn = overburnBox.isSelected();
		Options.simulate = simulateBox.isSelected();
		Options.speed = getSpeed();
		Options.verify = verifyBox.isSelected();

		if (Mode.makeISOImage()) {
			if (DVDVideoBox != null)
				Options.DVDVideo = DVDVideoBox.isSelected();
			Options.HFS = HFSBox.isSelected();
			Options.joliet = jolietBox.isSelected();
			Options.MD5File = MD5FileBox.isSelected();
			Options.rockRidge = rockRidgeBox.isSelected();
			Options.volumeID = volumeIDField.getText();
		}
		else
			Options.MD5File = false;
		return true;
	}

	private JPanel createControlPanel() {
		JPanel p = new JPanel();
		p.setLayout(new FlowLayout());

		JButton cancel = new JButton(i18n("cancel"));
		cancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cancelPressed();
			}
		});
		p.add(cancel);

		JButton ok = new JButton(i18n("continue"));
		ok.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				OKPressed();
			}
		});
		p.add(ok);
		defaultButton = ok;

		return p;
	}

	private JPanel createCopiesGroup() {
		JPanel p = new JPanel();
		p.setLayout(
			new BoxLayout(p, BoxLayout.Y_AXIS));
		p.setBorder(
			BorderFactory.createCompoundBorder(
			BorderFactory.createTitledBorder(
			BorderFactory.createLineBorder(Color.black),
			i18n(".copiesGroup")),
			BorderFactory.createEmptyBorder(5, 5, 5, 5)));

//		System.out.println(getClass());
		copiesSpinner = new MySpinner(
			1, 1, CDcreator.maxCopies, 1);
		copiesSpinner.setValue(new Integer(Options.copies));

		Dimension d = new JLabel("A").getMaximumSize();
		Dimension d2 = copiesSpinner.getComponent().getMaximumSize();
		d.width = d2.width; // 10 * d.width + d.height + 6;
		d.height += 6;
		copiesSpinner.getComponent().setMaximumSize(d);

		p.add(createLabelItemBox(
			new JLabel(i18n(".copies")),
			copiesSpinner.getComponent()));

		p.add(Box.createHorizontalStrut(0));

		return p;
	}

	private JPanel createFilesystemGroup() {
		JPanel p = new JPanel();
		p.setLayout(
			new BoxLayout(p, BoxLayout.Y_AXIS));
		p.setBorder(
			BorderFactory.createCompoundBorder(
			BorderFactory.createTitledBorder(
			BorderFactory.createLineBorder(Color.black),
			i18n("filesystemGroup")),
			BorderFactory.createEmptyBorder(5, 5, 5, 5)));

		volumeIDField = createTextField(Options.volumeID, 32);
		p.add(createLabelItemBox(
			new JLabel(i18n("volumeID")),
			volumeIDField));

		MyBox hbox = new MyBox(BoxLayout.X_AXIS);
		Box vbox = Box.createVerticalBox();
		jolietBox = new JCheckBox(
			i18n("jolietOption"), Options.joliet);
		vbox.add(jolietBox);

		rockRidgeBox = new JCheckBox(
			i18n("rockRidgeOption"), Options.rockRidge);
		vbox.add(rockRidgeBox);

		HFSBox = new JCheckBox(
			i18n("HFSOption"), Options.HFS);
		vbox.add(HFSBox);
		hbox.add(vbox);
//		hbox.add(new JSeparator(JSeparator.VERTICAL));
		hbox.add(Box.createHorizontalGlue());

		vbox = Box.createVerticalBox();
		if (Mode.isMediumDVD()) {
			DVDVideoBox = new JCheckBox("DVD Video", Options.DVDVideo);
			vbox.add(DVDVideoBox);
		}

		MD5FileBox = new JCheckBox(
			i18n(".MD5File"), Options.MD5File);
		MD5FileBox.setToolTipText(i18n(".MD5FileTip"));
		if (CDcreator.isNetscapeVM()) {
			MD5FileBox.setEnabled(false);
			MD5FileBox.setSelected(false);
		}
		vbox.add(MD5FileBox);
		hbox.add(vbox);
		hbox.setAlignmentX(LEFT_ALIGNMENT);
		p.add(hbox);
		return p;
	}

	static MyBox createLabelItemBox(Component label, Component item) {
		if (label instanceof JLabel)
			((JLabel)label).setLabelFor(item);
		MyBox box = new MyBox(BoxLayout.X_AXIS);
		box.setAlignmentX(LEFT_ALIGNMENT);
		box.add(label);
		box.add(Box.createHorizontalStrut(10));
		box.add(item);
		box.add(Box.createHorizontalGlue());
		return box;
	}

	static JComboBox createSpeedBox() {
		String[] dvdSpeeds = { "auto", "1x", "2.4x", "4x" };
		String[] speeds = new String[CDcreator.maxSpeed / 2 + 1];
		speeds[0] = "1x";
		for (int i = 2; i <= CDcreator.maxSpeed; i += 2)
			// add speed x row
			speeds[i / 2] = i + "x";
		if (Mode.isMediumDVD())
			speeds = dvdSpeeds;
		JComboBox speedBox = new JComboBox(speeds);
		if (!Mode.isMediumDVD() && Options.speed <= CDcreator.maxSpeed)
			speedBox.setSelectedIndex(Options.speed / 2);
		speedBox.setToolTipText(CDcreator.i18n("TTspeedBox"));

		Dimension d = new JLabel("A").getMaximumSize();
		d.width = 10 * d.width + d.height + 6;
		d.height += 6;
		speedBox.setMaximumSize(d);

		return speedBox;
	}

	private JPanel createStepsGroup() {
		JPanel p = new JPanel();
		p.setLayout(
			new BoxLayout(p, BoxLayout.Y_AXIS));
		p.setBorder(
			BorderFactory.createCompoundBorder(
			BorderFactory.createTitledBorder(
			BorderFactory.createLineBorder(Color.black),
			i18n("stepsGroup")),
			BorderFactory.createEmptyBorder(5, 5, 5, 5)));

		if (Mode.isMediumDVDRW()) {
			formatBox = new JCheckBox(
				i18n(".format"), Options.format);
			formatBox.setToolTipText(i18n(".formatTip"));
			p.add(formatBox);
		}

		blankTOCBox = new JCheckBox(
			i18n(".blankTOC"), Options.blankTOC);
		blankTOCBox.setToolTipText(i18n(".blankTOCTip"));
		p.add(blankTOCBox);

		p.add(new JLabel(i18n(".writeData")));

		if (!Mode.copyCD() || !CDcreator.cdrdao)
		if (Mode.medium.startsWith("CD-R")) {
			closeCDBox = new JCheckBox(
				i18n("closeCD"), Options.closeCD);
			closeCDBox.setToolTipText(i18n("TTcloseCDBox"));
			p.add(closeCDBox);
		}

		verifyBox = new JCheckBox(
			i18n("verifyOption"), Options.verify);
		verifyBox.setToolTipText(i18n("TTverifyOption"));
		verifyBox.setEnabled(CDcreator.verifySupport);
		if (!Mode.audioCD())
			p.add(verifyBox);

//		p.add(Box.createHorizontalStrut(0));
		p.add(Box.createVerticalGlue());

		return p;
	}

	static JTextField createTextField(String value, final int maxLength) {
		Document doc = new PlainDocument() {
			public void insertString(int offset, String str,
					AttributeSet a) throws BadLocationException {
				int free = maxLength - getLength();
				if (free < 0)
					return;
				if (free < str.length())
					str = str.substring(0, free);
				super.insertString(offset, str, a);
			}
		};
		JTextField tf = new JTextField(doc, value, maxLength);
		tf.setColumns(maxLength);

		Dimension d = new JLabel("012345mimi").getMaximumSize();
		d.width = maxLength * d.width / 10;
		d.height += 6;
		tf.setMaximumSize(d);

		return tf;
	}

	static MyBox createVBox(JComponent[] items) {
		MyBox box = new MyBox(BoxLayout.Y_AXIS);
		for (int i = 0; i < items.length; i++) {
			box.setAlignmentX(LEFT_ALIGNMENT);
			box.add(items[i]);
		}
		return box;
	}

	private JPanel createWritingGroup() {
		JPanel p = new JPanel();
		p.setLayout(
			new BoxLayout(p, BoxLayout.Y_AXIS));
		p.setBorder(
			BorderFactory.createCompoundBorder(
			BorderFactory.createTitledBorder(
			BorderFactory.createLineBorder(Color.black),
			i18n("burnGroup")),
			BorderFactory.createEmptyBorder(5, 5, 5, 5)));

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

		// Add simulate box
		simulateBox = new JCheckBox(
			i18n("optionSimulate"), Options.simulate);
		simulateBox.setToolTipText(i18n("optionSimulateTip"));
		p.add(simulateBox);

		DAOBox = new JCheckBox(i18n("optionDAO"), Options.DAO);
		DAOBox.setToolTipText(i18n("optionDAOTip"));
		if (Mode.audioCD())
			p.add(DAOBox);

		if (CDcreator.overburnSupport && Mode.medium.equals("CD-R")) {
			overburnBox = new JCheckBox(i18n(".overburn"),
				Options.overburn);
			overburnBox.setToolTipText(i18n(".overburnTip"));
			p.add(overburnBox);
		}

		p.add(Box.createHorizontalStrut(0));

		return p;
	}

	protected void enterHelpState(int aState) {
		panel0.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		panel0.removeAll();

		if (aState == 0)
			panel0.add(CDcreator.getHelp("BurnOptions"));
		else
		if (aState == 1)
			panel0.add(CDcreator.getHelp("BurnProtection"));

		validate();
	}

	protected void enterState(int aState) {
		panel0.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		panel0.removeAll();
		if (aState == 0)
			addState1();
		else
			addState2();
		validate();
	}

	private int getSpeed() {
		try {
			StreamTokenizer tokenizer
			= new StreamTokenizer(
				new StringReader(
				(String)speedBox.getSelectedItem()));

		if (tokenizer.nextToken() != StreamTokenizer.TT_NUMBER)
			if (Mode.isMediumDVD())
				return 0;
			else
				return 1;
		else
			return (int)tokenizer.nval;
		} catch (Exception e)
		{
			return 1;
		}
	}

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

		String name = System.getProperty("user.name");
		if (name.length() > 20)
			name = name.substring(0, 20);
		return name;
	}

	protected boolean hasHelp(int aState) {
		return true;
	}

	protected boolean hasMore() {
		return state < 1 && CDcreator.writeProtection;
	}

	void initState2() {
		// init accept components
		acceptEmptyCDBox = new JCheckBox(
			i18n(".acceptEmptyCD"), !Options.rejectEmptyCD);
		acceptUnprotectedCDBox = new JCheckBox(
			i18n(".acceptUnprotectedCD"), !Options.rejectUnprotectedCD);
		acceptKeyBox = new JCheckBox(
			i18n(".acceptKey"), true);
		acceptKeyBox.addChangeListener(
			new javax.swing.event.ChangeListener() {
				public void stateChanged(
						javax.swing.event.ChangeEvent e) {
					acceptField.setEnabled(
						acceptKeyBox.isSelected());
				}
			});
		if (Options.acceptKey.length() == 0)
			Options.acceptKey = getUserName();
		acceptField = createTextField(Options.acceptKey, 20);
		acceptField.setEnabled(acceptKeyBox.isSelected());

		// init write protection pane
		protectionBox = new JCheckBox(
			i18n(".writeProtectionBy"), Mode.makeISOImage());
		protectionBox.addChangeListener(
			new javax.swing.event.ChangeListener() {
				public void stateChanged(
						javax.swing.event.ChangeEvent e) {
					protectionField.setEnabled(protectionBox.isSelected());
				}
			});
		if (Options.writeProtection.length() == 0)
			Options.writeProtection = getUserName();
		protectionField = createTextField(Options.writeProtection, 20);
		protectionField.setEnabled(protectionBox.isSelected());
	}
}
