package scalaSci.math.plot;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;



public class ParametersPanel extends JPanel implements ActionListener {

	private static final long serialVersionUID = 1L;

	private Dimension defaultSize;

	private String[] paramLabels;

	private String[] paramValues;

	private boolean[] isList;

	private int[] paramValuesIndex;

	private String[][] paramChoices;

	private JLabel[] labels;

	private JComboBox[] fields;

	private Runnable action;

	public ParametersPanel(String[] lab, String[] val) {
		this(lab, new int[lab.length], new String[][] { val });
	}

	public ParametersPanel(String[] lab) {
		this(lab, new String[lab.length]);
	}

	public ParametersPanel(String[] lab, int[] selected, String[][] ch) {
		paramLabels = lab;

		isList = new boolean[paramLabels.length];
		for (int i = 0; i < isList.length; i++) {
			isList[i] = true;
		}

		paramValuesIndex = selected;

		paramChoices = ch;

		paramValues = new String[paramLabels.length];
		for (int i = 0; i < paramChoices.length; i++) {
			paramValues[i] = paramChoices[i][paramValuesIndex[i]];
		}

		setComponents();
		setAppearence();
		draw();
	}

	public ParametersPanel(String[] lab, String[][] ch) {
		this(lab, new int[lab.length], ch);
	}

	private void setComponents() {
		labels = new JLabel[paramLabels.length];
		fields = new JComboBox[paramLabels.length];
		for (int i = 0; i < paramLabels.length; i++) {
			labels[i] = new JLabel(paramLabels[i], JLabel.RIGHT);
			if (isList[i]) {
				fields[i] = new JComboBox(paramChoices[i]);
			} else {
				fields[i] = new JComboBox();
			}
			fields[i].setEditable(!isList[i]);
		}
		defaultSize = new Dimension(400, paramLabels.length * 30);
	}

	private void setAppearence() {
		setPreferredSize(defaultSize);
		setSize(defaultSize);
	}

	private void update() {
		updateValues();
		updateValuesIndex();
	}

	private void updateValues() {
		for (int i = 0; i < paramLabels.length; i++) {
			paramValues[i] = (String) (fields[i].getSelectedItem());
		}
	}

	private void updateValuesIndex() {
		for (int i = 0; i < paramLabels.length; i++) {
			if (isList[i]) {
				paramValuesIndex[i] = fields[i].getSelectedIndex();
			}
		}
	}

	public void actionPerformed(ActionEvent e) {
		update();
		new Thread(action, "PanelParameters " + this.toString() + " selection").start();
	}

	public int getValueIndex(int i) {
		if (!isList[i]) {
			throw new IllegalArgumentException("This PanelParameter element is not set to give an Index.");
		}
		update();
		return paramValuesIndex[i];
	}

	public int[] getValuesIndex() {
		update();
		return paramValuesIndex;
	}

	public String[] getValues() {
		update();
		return paramValues;
	}

	public String getValue(int i) {
		update();
		return paramValues[i];
	}

	public void setAction(Runnable t) {
		action = t;
	}

	private void buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) {
		gbc.gridx = gx;
		gbc.gridy = gy;
		gbc.gridwidth = gw;
		gbc.gridheight = gh;
		gbc.weightx = wx;
		gbc.weighty = wy;
	}

	private void draw() {
		JPanel panel = new JPanel();

		GridBagLayout gbl = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		panel.setLayout(gbl);

		for (int i = 0; i < paramLabels.length; i++) {
			fields[i].addActionListener(this);

			buildConstraints(c, 0, i, 1, 1, 50, 20);
			c.anchor = GridBagConstraints.EAST;
			gbl.setConstraints(labels[i], c);
			panel.add(labels[i]);

			buildConstraints(c, 1, i, 1, 1, 50, 20);
			c.fill = GridBagConstraints.HORIZONTAL;
			gbl.setConstraints(fields[i], c);
			panel.add(fields[i]);
		}

		JScrollPane scrollPane = new JScrollPane(panel);

		scrollPane.setPreferredSize(getSize());
		scrollPane.setSize(getSize());

		setLayout(new BorderLayout());
		add(scrollPane, BorderLayout.CENTER);

	}

}