/* Author: Jeff Dalton <J.Dalton@ed.ac.uk>
 * Updated: Tue Dec  4 01:16:46 2001 by Jeff Dalton
 * Copyright: (c) 2001, AIAI, University of Edinburgh
 */

package ix.ideel;

import java.awt.Container;
import java.awt.Component;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.*;

import javax.swing.*;

import java.util.*;

import ix.icore.IXAgent;
import ix.icore.process.Variable;
import ix.iface.util.GridColumn;

import ix.util.*;
import ix.util.lisp.*;

public class BindingViewer implements ActionListener {

    protected IXAgent agent;
    protected Set vars;
    protected Runnable whenFinished;

    protected JFrame frame;
    protected Container contentPane;

    protected VarPanel varPanel;

    protected Map newBindings;	// contains our result when we're done

    public BindingViewer(IXAgent agent,
			 Set vars,
			 Runnable whenFinished) {
	this.agent = agent;
	this.vars = vars;
	this.whenFinished = whenFinished;
	setUpFrame();
    }

    protected void setUpFrame() {
	// /\/: s.b. symbol-name
	frame = new JFrame(agent.getAgentIPCName() + " Variable Binder");
	contentPane = frame.getContentPane();

	// default is equiv to setLayout(new BorderLayout());
	// contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
	contentPane.add(varPanel = new VarPanel(vars), BorderLayout.CENTER);
	contentPane.add(new ButtonPanel(), BorderLayout.SOUTH);

	frame.pack();
	frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
	String command = e.getActionCommand();
	Debug.noteln("BindingViewer action:", command);
	if (command.equals("Bind")) {
	    newBindings = varPanel.getBindings();
	    frame.setVisible(false);
	    whenFinished.run();
	}
	else if (command.equals("Cancel")) {
	    Debug.assert(newBindings == null);
	    frame.setVisible(false);
	    whenFinished.run();
	}
	else
	    Debug.noteln("Nothing to do for", command);
    }

    class VarPanel extends JPanel {

	GridColumn varColumn = new GridColumn("Variable");
	GridColumn valColumn = new GridColumn("Value");

	Map varFields = new HashMap();
	List varList;

	VarPanel(Set vars) {
	    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
	    setBorder(BorderFactory.createTitledBorder("Variables"));
	    add(varColumn);
	    add(Box.createHorizontalStrut(5));
	    add(valColumn);

	    varList = new LinkedList(vars);
	    Collections.sort(varList);
	    for (Iterator i = varList.iterator(); i.hasNext();) {
		Variable v = (Variable)i.next();
		JTextField varText = new JTextField(v.getName().toString());
		JTextField valText = new JTextField(20);

		varText.setEditable(false);
		varFields.put(v, valText);
		varColumn.add(varText);
		valColumn.add(valText);
	    }

	}

	Map getBindings() {
	    Map bindings = new HashMap();
	    for (Iterator i = varList.iterator(); i.hasNext();) {
		Variable var = (Variable)i.next();
		JTextField tf = (JTextField)varFields.get(var);
		String text = tf.getText().trim();
		if (!text.equals("")) {
		    Object val = Lisp.readFromString(text);
		    bindings.put(var, val);
		}
	    }
	    return bindings;
	}

    }

    class ButtonPanel extends JPanel {

	ButtonPanel() {
	    // Stick with default flowlayout for now.
	    add(makeButton("Bind"));
	    add(makeButton("Cancel"));
	}

	protected JButton makeButton(String command) {
	    JButton b = new JButton(command);
	    b.addActionListener(BindingViewer.this);
	    return b;
	}

    }

}
