package lpv.gui;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.prefs.Preferences;

public class LPVSizeDialog extends JDialog {
	
	private JSlider widthSlider;
	private JSlider heightSlider;
	private JSlider depthSlider;
	private JLabel widthLabel;
	private JLabel heightLabel;
	private JLabel depthLabel;
	private JButton okButton;
	private JButton cancelButton;
	protected boolean submitted;
	protected int width;
	protected int height;
	protected int depth;

	public LPVSizeDialog() {
		super((Frame)null, "Light propagation volume size", true);
		
		submitted = false;
		width = 0;
		height = 0;
		depth = 0;
		
		setLayout(new BorderLayout());
		
		final Preferences pref = Preferences.userNodeForPackage(LPVSizeDialog.class);
		
		JPanel sizePanel = new JPanel();
		sizePanel.setLayout(new GridLayout(3, 3, 5, 5));
		sizePanel.add(widthLabel = new JLabel("Width: " + pref.getInt("lpv.width", 16)));
		sizePanel.add(heightLabel = new JLabel("Height: " + pref.getInt("lpv.height", 16)));
		sizePanel.add(depthLabel = new JLabel("Depth: " + pref.getInt("lpv.depth", 16)));
		
		sizePanel.add(widthSlider = new JSlider(JSlider.HORIZONTAL, 0, 64, pref.getInt("lpv.width", 16)));
		widthSlider.setMajorTickSpacing(16);
		widthSlider.setMinorTickSpacing(2);
		widthSlider.setPaintLabels(true);
		widthSlider.setPaintTicks(true);
		widthSlider.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent arg0) {
				widthLabel.setText("Width: " + Math.max(1, widthSlider.getValue()));
			}});
		
		sizePanel.add(heightSlider = new JSlider(JSlider.HORIZONTAL, 0, 64, pref.getInt("lpv.height", 16)));
		heightSlider.setMajorTickSpacing(16);
		heightSlider.setMinorTickSpacing(2);
		heightSlider.setPaintLabels(true);
		heightSlider.setPaintTicks(true);
		heightSlider.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent arg0) {
				heightLabel.setText("Height: " + Math.max(1, heightSlider.getValue()));
			}});
		
		sizePanel.add(depthSlider = new JSlider(JSlider.HORIZONTAL, 0, 64, pref.getInt("lpv.depth", 16)));
		depthSlider.setMajorTickSpacing(16);
		depthSlider.setMinorTickSpacing(2);
		depthSlider.setPaintLabels(true);
		depthSlider.setPaintTicks(true);
		depthSlider.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent arg0) {
				depthLabel.setText("Depth: " + Math.max(1, depthSlider.getValue()));
			}});
		
		sizePanel.add(new JLabel());
		sizePanel.add(new JLabel());
		sizePanel.add(new JLabel("<html>Note: Depth is not directly <br />visible in the simulator.</html>"));
		
		
		add(sizePanel, BorderLayout.CENTER);
		
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		
		buttonPanel.add(okButton = new JButton("Ok"));
		okButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				submitted = true;
				width = Math.max(1, widthSlider.getValue());
				height = Math.max(1, heightSlider.getValue());
				depth = Math.max(1, depthSlider.getValue());
				
				pref.putInt("lpv.width", width);
				pref.putInt("lpv.height", height);
				pref.putInt("lpv.depth", depth);
				
				setVisible(false);
			}});
		
		buttonPanel.add(cancelButton = new JButton("Cancel"));
		cancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				submitted = false;
				setVisible(false);
			}});
		
		add(buttonPanel, BorderLayout.SOUTH);
		
		pack();
	}

	public boolean isSubmitted() {
		return submitted;
	}

	public int getSubmittedWidth() {
		return width;
	}

	public int getSubmittedHeight() {
		return height;
	}

	public int getSubmittedDepth() {
		return depth;
	}
	
}
