/*
 * @(#)OptionsDialog.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 javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;

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

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

	class ProjectInfoField {
		JTextField from, to, label, contents;
	}

	ProjectInfoField projectInfoField = new ProjectInfoField();

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

		// projectInfo
		projectInfoField.from
			= createTextField(Options.projectInfo.from, 20);
		projectInfoField.to
			= createTextField(Options.projectInfo.to, 20);
		projectInfoField.label
			= createTextField(Options.projectInfo.label, 20);
		projectInfoField.contents
			= createTextField(Options.projectInfo.contents, 20);

		enterState(0);
		pack();
	}

	void addAskForProjectInfo() {
		panel0.add(Box.createVerticalGlue());
		panel0.add(createHeader(".projectLabel"));

		panel0.add(createLabelItemBox(
				new JLabel(i18n(".initiator")), 110,
				projectInfoField.from));
		projectInfoField.from.requestFocus();

		panel0.add(createLabelItemBox(
				new JLabel(i18n(".addressee")), 110,
				projectInfoField.to));

		panel0.add(createLabelItemBox(
				new JLabel(i18n(".project")), 110,
				projectInfoField.label));

		panel0.add(createLabelItemBox(
				new JLabel(i18n(".contents")), 110,
				projectInfoField.contents));

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

	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 addState2Rejection() {
		panel0.add(Box.createVerticalGlue());
		panel0.add(createHeader(".rejectionOfCDs"));

		// reject
		panel0.add(new JLabel(i18n(".rejectIf")));

		JComponent[] cs = {
			rejectEmptyCDBox,
			rejectWithoutUserIDBox
		};
		waitForSubBox = createVBox(cs);
		panel0.add(createLabelItemBox(
			Box.createHorizontalStrut(20),
			waitForSubBox));

		panel0.add(Box.createVerticalGlue());

		panel0.add(new JLabel(i18n(".rejectWrongUserID")));
		panel0.add(createLabelItemBox(
			Box.createHorizontalStrut(20),
			createLabelItemBox(
				new JLabel(i18n(".userID")),
				acceptField)));

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

	void addState2SaveImage() {
		panel0.add(Box.createVerticalGlue());
		panel0.add(createHeader(".saveISOImageAs"));

		JButton browseButton = new JButton(i18n(".browse"));
		browseButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser chooser = new JFileChooser(
					saveImageAsField.getText());
				if (chooser.showDialog(CDcreator.mainWin, i18n(".select"))
						== JFileChooser.APPROVE_OPTION) {
					String name = chooser.getSelectedFile().getPath();
					if (!name.endsWith(".iso"))
						name = name + ".iso";
					saveImageAsField.setText(name);
				}
			}
		});

		panel0.add(createLabelItemBox(
			Box.createHorizontalStrut(10),
			createLabelItemBox(
				saveImageAsField, browseButton)));

		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 = rejectEmptyCDBox.isSelected();
		Options.rejectWithoutUserID = rejectWithoutUserIDBox.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.writer = (String) writersBox.getSelectedItem();
		Mode.saveImage = Options.writer.indexOf("ISO") >= 0;
		if (Options.writer.equals("auto"))
			Options.writer = "";
		Mode.saveImageAs = saveImageAsField.getText();
		Options.speed = getSpeed(speedBox);
		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;

		if (projectInfoField.to != null)
			Options.projectInfo.to = projectInfoField.to.getText();

		if (projectInfoField.from != null)
			Options.projectInfo.from = projectInfoField.from.getText();

		if (projectInfoField.label != null)
			Options.projectInfo.label = projectInfoField.label.getText();

		if (projectInfoField.contents != null)
			Options.projectInfo.contents
				= projectInfoField.contents.getText();

		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 filesystemGroup = null;
	private JPanel createFilesystemGroup() {
		if (filesystemGroup != null)
			return filesystemGroup;

		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.MD5FileSupport || CDcreator.isNetscapeVM()) {
			MD5FileBox.setEnabled(false);
			MD5FileBox.setSelected(false);
		}
		vbox.add(MD5FileBox);
		hbox.add(vbox);
		hbox.setAlignmentX(LEFT_ALIGNMENT);
		p.add(hbox);
		filesystemGroup = p;
		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 MyBox createLabelItemBox(
			Component label, int width, Component item) {
		if (label instanceof JComponent) {
			Dimension d = label.getPreferredSize();
			d.width = width;
			((JComponent)label).setPreferredSize(d);
		}
		return createLabelItemBox(label, item);
	}

	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 stepsGroup = null;
	private JPanel createStepsGroup() {
		if (stepsGroup != null)
			return stepsGroup;

		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)
			Options.closeCD = true;
		else
		if (Mode.makeISOImage())
			Options.closeCD = false;
		else
		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());

		stepsGroup = p;
		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 writingGroup = null;
	private JPanel createWritingGroup() {
		if (writingGroup != null)
			return writingGroup;

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

		String[] writers = { "auto", i18n(".ISOImageFile") };
		writersBox = new JComboBox(writers);
		if (!Mode.saveImage)
			writersBox.setSelectedIndex(0);
		else
			writersBox.setSelectedIndex(1);
		if (CDcreator.saveImageAs && Mode.makeISOImage()) {
			p.add(createLabelItemBox(
				new JLabel(i18n(".writer")), writersBox));
			p.add(Box.createVerticalStrut(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));

		writingGroup = p;
		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("RejectionOfCDs"));

		validate();
	}

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

		boolean saveImage = writersBox != null
			&& ((String) writersBox.getSelectedItem()).indexOf("ISO") >= 0;

		if (aState == 0)
			addState1();
		else
		if (aState == 1 && saveImage)
			addState2SaveImage();
		else
		if (aState == 1 && CDcreator.askForProjectInfo)
			addAskForProjectInfo();
		else
			addState2Rejection();
		validate();
	}

	static int getSpeed(JComboBox speedBox) {
		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() {
		boolean saveImage = writersBox != null
			&& ((String) writersBox.getSelectedItem()).indexOf("ISO") >= 0;

		int numOfStates = 1;
		if (saveImage)
			numOfStates++;
		else {
			if (CDcreator.askForProjectInfo)
				numOfStates++;
			if (CDcreator.writeProtection)
				numOfStates++;
		}

		return state < numOfStates - 1;
	}

	void initState2() {
		// init accept components
		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 reject components
		rejectEmptyCDBox = new JCheckBox(
			i18n(".rejectEmptyCD"), Options.rejectEmptyCD);
		rejectWithoutUserIDBox = new JCheckBox(
			i18n(".rejectWithoutUserID"), Options.rejectWithoutUserID);

		// 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());

		if (Mode.saveImageAs.length() == 0)
			Mode.saveImageAs = new File(
				System.getProperty("user.home"), "image.iso").getPath();
		saveImageAsField = createTextField(Mode.saveImageAs, 64);
	}
}
