// A class that holds parameters pertaining to various recognisers and
// a dialog to change them
//
// Copyright (c) 2000 Markus Demleitner <mdemleitner@head-cfa.harvard.edu>
//  This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// tabsize=2

import java.util.*;

import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.*;

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

class IntSlider extends JSlider
{
	static final long serialVersionUID=20060308L;

	public IntSlider(int min, int max, int init) {	
		super(JSlider.HORIZONTAL, min, max, init);
		this.setMajorTickSpacing((max-min)/5);
		this.setPaintTicks(true);
		this.setPaintLabels(true);
	}

	public int getCurValue() {
		return this.getModel().getValue();
	}
}


class DoubleSlider extends JSlider
{
	static final long serialVersionUID=20060318L;
	double world0, worldRange;
	int numPix=100;

	public DoubleSlider(double min, double max, double init)
	{	
		super(JSlider.HORIZONTAL);
		this.setMinimum(0);
		this.setMaximum(this.numPix);

		Hashtable<Integer,JLabel> labels = new Hashtable<Integer,JLabel>();
		labels.put(0, new JLabel(Fmt.fmt(min)));
		labels.put(this.numPix/2, new JLabel(Fmt.fmt((max-min)/2)));
		labels.put(this.numPix, new JLabel(Fmt.fmt(max)));
		this.setLabelTable(labels);

		this.setPaintTicks(true);
		this.setPaintLabels(true);

		this.world0 = min;
		this.worldRange = max-min;
	}

	protected int toPix(double val) {
		return (int)Math.round((val-this.world0)/this.worldRange*this.numPix);
	}

	protected double toWorld(int pix) {
		return (pix*1./this.numPix)*this.worldRange+this.world0;

	}

	protected String valString() {
		return Fmt.fmt(this.getCurValue(), 3, 2);
	}

	public double getCurValue() {
		return this.toWorld(this.getModel().getValue());
	}

	public void setValue(double val) {
		super.setValue(this.toPix(val));
	}
}


public class RecogniserSettings extends JFrame
	implements ActionListener, ChangeListener
{	
	Hashtable<String,Number> properties=new Hashtable<String,Number>();
	IntSlider lineTracerSpacingField;
	DoubleSlider pointFinderThreshField;
	static final long serialVersionUID=20060308L;

	WindowAdapter winAd = new WindowAdapter()
	{	
		public void windowClosing(WindowEvent e)
		{
			close();
		}
	};


	public RecogniserSettings()
	{	
		this.setDefaults();
		this.makeDialog();
		this.setTitle("Dexter Recogniser Settings");
		this.setResizable(false);
	}


	private void setDefaults() {
		this.setIntProp("LineTracerSpacing", 0);
		this.setDoubleProp("PointFinderThresh", 0.15);
		this.setIntProp("blackThresh", 110);
		this.setIntProp("weightThresh", 50);
		if (this.isVisible())
			this.fillInValues();
	}


	public void setProp(String key, Number ob)
	{	
		this.properties.put(key, ob);
	}

	
	public void setIntProp(String key, int val)
	{
		this.setProp(key, Integer.valueOf(val));
	}


	public void setDoubleProp(String key, double val)
	{
		this.setProp(key, Double.valueOf(val));
	}


	public Object getProp(String key)
	{
		return this.properties.get(key);
	}


	public int getIntProp(String key)
	{
		return ((Integer)this.getProp(key)).intValue();
	}


	public double getDoubleProp(String key)
	{
		return ((Double)this.getProp(key)).doubleValue();
	}


	public void makeDialog()
	{	
		JPanel settings = new JPanel();
		GridBagLayout layout = new GridBagLayout();
		Font baseFont = new Font("Helvetica",Font.PLAIN,10);
		Font boldFont = new Font("Helvetica",Font.BOLD,10);

		this.setFont(baseFont);
		this.setLayout(new BorderLayout());
		settings.setLayout(layout);
		GridBagConstraints c = new GridBagConstraints();
		
		JLabel l = new JLabel("Line Tracer Settings");
		l.setFont(boldFont);
		c.gridy = 0;
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.anchor = GridBagConstraints.WEST;
		layout.setConstraints(l,c);
		settings.add(l);

		l = new JLabel("Point Spacing (0 for automatic): ");
		c.gridy = 1;
		c.gridwidth = 1;
		c.anchor = GridBagConstraints.WEST;
		layout.setConstraints(l,c);
		settings.add(l);

		lineTracerSpacingField = new IntSlider(
			0, 150,
			getIntProp("LineTracerSpacing"));
		lineTracerSpacingField.addChangeListener(this);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.anchor = GridBagConstraints.WEST;
		layout.setConstraints(lineTracerSpacingField,c);
		settings.add(lineTracerSpacingField);

		l = new JLabel("Point Finder Settings");
		l.setFont(boldFont);
		c.gridy = 2;
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.anchor = GridBagConstraints.WEST;
		layout.setConstraints(l,c);
		settings.add(l);

		l = new JLabel("Distance Threshold: ");
		c.gridy = 3;
		c.gridwidth = 1;
		c.anchor = GridBagConstraints.WEST;
		layout.setConstraints(l,c);
		settings.add(l);

		pointFinderThreshField = new DoubleSlider(0, 0.66,
			getDoubleProp("PointFinderThresh"));
		pointFinderThreshField.addChangeListener(this);
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.anchor = GridBagConstraints.WEST;
		layout.setConstraints(pointFinderThreshField,c);
		settings.add(pointFinderThreshField);

		settings.validate();
		this.add(settings,"Center");

		JPanel buts = new JPanel();
		buts.setLayout(new FlowLayout());
		JButton defaultsButton = new JButton("Defaults");
		buts.add(defaultsButton);
		defaultsButton.addActionListener(this);
		JButton closeButton = new JButton("Close");
		buts.add(closeButton);
		closeButton.addActionListener(this);

		this.add(buts,"South");

		pack();
	}


	public void fillInValues() {	
		int lineTracerSpacing = this.getIntProp("LineTracerSpacing");
		double pointFinderThresh = this.getDoubleProp("PointFinderThresh");

		this.lineTracerSpacingField.setValue(lineTracerSpacing);
		this.pointFinderThreshField.setValue(pointFinderThresh);
	}


	public void open()
	{
		if (this.isShowing())
			return;
		this.fillInValues();
		this.setVisible(true); 
		this.validate();
		this.addWindowListener(winAd);
	}

	public void close()
	{
		if (!this.isShowing())
			return;
		this.setVisible(false);
		this.removeWindowListener(winAd);
	}
	

	public void actionPerformed(ActionEvent e)
	{
		if (e.getActionCommand()=="Close")
			this.close();

		if (e.getActionCommand()=="Defaults") {	
			this.setDefaults();
			this.fillInValues();
		}

	}

	public void stateChanged(ChangeEvent e) {	
		int lineTracerSpacing = this.lineTracerSpacingField.getCurValue();
		double pointFinderThresh = this.pointFinderThreshField.getCurValue();

		this.setProp("LineTracerSpacing", lineTracerSpacing);
		this.setProp("PointFinderThresh", pointFinderThresh);
	}

}

// vim: ts=2
