/* Author: Jeff Dalton <J.Dalton@ed.ac.uk>
 * Updated: Mon Dec  3 02:51:24 2001 by Jeff Dalton
 * Copyright: (c) 2001, AIAI, University of Edinburgh
 */

package ix.itest;

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.FlowLayout;
import java.awt.Component;
import java.awt.event.*;

import javax.swing.*;

import java.util.*;

import ix.iface.util.RadioButtonBox;
import ix.iface.util.ComboChoice;
import ix.iface.util.GridColumn;
import ix.iface.util.XML;	// for debugging output

import ix.icore.*;

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


/**
 * I-TEST panel for sending messages.
 */
public class SendPanel extends JPanel implements ActionListener {

    BasicItest itest;

    JTextArea contentText = new JTextArea(2, 40);

    RadioButtonBox typeSelector = makeTypeControl();
    RadioButtonBox prioritySelector = makePriorityControl();

    ComboChoice destinationChoice;

    ComboChoice reportTypeChoice
        = new ComboChoice(new Object[]{"success", "failure", "progress"});

    JCheckBox reportCheck = new JCheckBox("Report Back - Ref =");
    ComboChoice refChoice = new ComboChoice();

    public SendPanel(BasicItest itest) {
	this.itest = itest;
	setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
	setBorder(BorderFactory.createTitledBorder("Send"));
	add(new JScrollPane(contentText));
	add(makeControlPanel());
    }

    public void actionPerformed(ActionEvent e) {
	String command = e.getActionCommand();
	Debug.noteln("I-TEST send action:", command);
	if (command.equals("Send to ILEED")) {
	    sendTo("ILEED");
	}
	else if (command.equals("Send to IDEEL")) {
	    sendTo("IDEEL");
	}
	else if (command.equals("Send to")) {
	    sendTo(destinationChoice.getSelectedString());
	}
	else
	    Debug.noteln("Nothing to do for", command);
    }

    /**
     * Construct an object from the current state of the GUI
     * and send it to the specified destination.
     *
     * @see ix.util.IPC#exceptionlessSend(Object, Object)
     */
    protected void sendTo(String destination) {
	Object content = objectFromControls();

	Debug.noteln("Sending to", destination);
	Debug.noteln("Contents as XML:",
		     XML.objectToXML(content));

	IPC.exceptionlessSend(destination, content);
    }

    /**
     * Construct an object from the current state of the GUI.
     * The object will be an Issue or Report.
     */
    protected Object objectFromControls() {
	String type = typeSelector.getSelection();
	if (type.equals("Issue"))
	    return issueFromControls();
	else if (type.equals("Report"))
	    return reportFromControls();
	else
	    throw new Error("Unexpected message type " + type);
    }

    /**
     * Construct an issue from the current state of the GUI.
     */
    protected Issue issueFromControls() {
	String text = contentText.getText().trim();
	String priority = prioritySelector.getSelection();
	String ref = refChoice.getSelectedString();
	boolean reportBack = reportCheck.isSelected();

	BasicIssue issue = new BasicIssue(text);
	issue.setSenderId((String)itest.getAgentIPCName());
	issue.setPriority(priorityFromControls());
	if (!ref.equals(""))
	    issue.setRef(ref);
	if (reportBack)
	    issue.setReportBack(true);
	return issue;
    }

    /**
     * Construct a report from the current state of the GUI.
     */
    protected Report reportFromControls() {
	String text = contentText.getText().trim();
	String ref = refChoice.getSelectedString();
	String type = reportTypeChoice.getSelectedString();

	Report report = new Report(text);
	report.setSenderId((String)itest.getAgentIPCName());
	if (!ref.equals(""))
	    report.setRef(ref);
	if (!type.equals(""))
	    report.setReportType(type);

	return report;
    }

    /**
     * Obtain a priority from the current state of the GUI.
     */
    protected int priorityFromControls() {
	LList values =
	    Lisp.list("Low Priority", "No Priority",
		      "Medium Priority", "High Priority");
	String selected = prioritySelector.getSelection();
	int pos = values.indexOf(selected);
	if (pos >= 0)
	    return pos;
	else
	    throw new Error("Unexpected priority " + selected);
    }


    /*
     * Details of GUI construction
     */

    protected JPanel makeControlPanel() {
	JPanel panel = new JPanel();
	panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));

	panel.add(typeSelector);
	panel.add(prioritySelector);

	panel.add(Box.createHorizontalGlue());

	panel.add(makeSendControls());

	return panel;
    }

    protected RadioButtonBox makeTypeControl() {
	RadioButtonBox box = RadioButtonBox.createVerticalBox();

	JRadioButton issueButton = new JRadioButton("Issue");
	JRadioButton activityButton = new JRadioButton("Activity");
	JRadioButton constraintButton = new JRadioButton("Constraint");
	JRadioButton reportButton = new JRadioButton("Report");

	issueButton.setSelected(true);
	activityButton.setEnabled(false);
	constraintButton.setEnabled(false);

	box.add(issueButton);
	box.add(activityButton);
	box.add(constraintButton);
	box.add(reportButton);

	box.add(Box.createVerticalGlue());

	return box;	
    }

    protected RadioButtonBox makePriorityControl() {
	RadioButtonBox box = RadioButtonBox.createVerticalBox();

	box.add(new JRadioButton("High Priority"));
	box.add(new JRadioButton("Medium Priority", true));
	box.add(new JRadioButton("Low Priority"));
	box.add(new JRadioButton("No Priority"));

	box.add(Box.createVerticalGlue());

	return box;
    }

    protected JPanel makeSendControls() {
	// /\/: Or just have a class and call new?

	JPanel panel = new JPanel();
	panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));

	GridColumn left = new GridColumn();
	GridColumn right = new GridColumn();

	panel.add(left);
	panel.add(right);

	destinationChoice = new ComboChoice(itest.builtinDestinations);

	left.add(reportCheck);
	right.add(refChoice);

	JLabel typeLabel = new JLabel("Report Type =");
	typeLabel.setForeground(Color.black); 		// metal theme? /\/
	left.add(typeLabel);
	right.add(reportTypeChoice);

	left.add(makeButton("Send to"));
	right.add(destinationChoice);
		 
	return makeFlowPanel(panel);

    }

    protected JButton makeButton(String text) {
	JButton button = new JButton(text);
	button.setHorizontalAlignment(SwingConstants.LEFT);
	button.addActionListener(this);
	return button;
    }

    /**
     * Puts a component in a JPanel that has a flow layout to protect it
     * from the layout manager of the container to which the component
     * would otherwise have been added directly.
     */
    static public JPanel makeFlowPanel(Component c) {
	// FlowLayout is the default, but we want to specify some
	// things about it.
	JPanel panel = new JPanel();
	// Use constructor FlowLayout(int align, int hgap, int vgap).
	panel.setLayout(new FlowLayout(FlowLayout.RIGHT, 0, 5));
	panel.add(c);
	return panel;
    }
	
}
