/*
 * Created on Sep 16, 2003
 * 
 * @author hanson
 */
package com.ibm.able.examples.conversation;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import com.ibm.conversation.Conversation;
import com.ibm.conversation.ConversationContext;
import com.ibm.conversation.ConversationException;
import com.ibm.conversation.DecisionDataHandle;
import com.ibm.conversation.base.BasicDecisionDataHandle;

/**
 * @author hanson
 */
public class AbleChat3Panel extends JPanel implements ActionListener {

	// ================================
	// Class variables
	// ================================

	private static final String SEND = "send";
	private static final String QUIT = "quit";
	private static final int PREFERRED_WIDTH = 400;
	private static final int PREFERRED_HEIGHT = 300;
	
	// ================================
	// Instance variables
	// ================================

	Conversation conv = null;
	boolean inputEnabled = true;
	JTextArea input = null;
	JTextArea transcript = null;
	JButton send = null;
	JButton quit = null;
	// Color selfColor = Color.blue;
	// Color partnerColor = Color.black;

	// ================================
	// Constructors
	// ================================

	public AbleChat3Panel() {
		loadPane();
	}

	public AbleChat3Panel(Conversation newConv) {
		conv = newConv;
		loadPane();
	}

	protected void loadPane() {
		this.setPreferredSize(new Dimension(PREFERRED_WIDTH, PREFERRED_HEIGHT));
		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

		transcript = new JTextArea();
		transcript.setEditable(false);
		JScrollPane transcriptScroll = new JScrollPane(transcript);
		transcriptScroll.setBorder(
			BorderFactory.createTitledBorder("Transcript"));
		this.add(transcriptScroll);

		input = new JTextArea();
		//		input.setActionCommand(SEND);
		//		input.addActionListener(this);
		JScrollPane inputScroll = new JScrollPane(input);
		inputScroll.setBorder(
			BorderFactory.createTitledBorder("Type your messages here"));
		this.add(inputScroll);

		send = new JButton("Send");
		send.setActionCommand(SEND);
		send.addActionListener(this);

		quit = new JButton("Quit");
		quit.setActionCommand(QUIT);
		quit.addActionListener(this);

		JPanel buttonPane = new JPanel();
		buttonPane.add(send);
		buttonPane.add(quit);
		this.add(buttonPane);

	}

	// ================================
	// Properties
	// ================================

	public boolean isInputEnabled() {
		return inputEnabled;
	}

	public void setInputEnabled(boolean newInputEnabled) {
		inputEnabled = newInputEnabled;
		send.setEnabled(inputEnabled);
		quit.setEnabled(inputEnabled);
		input.setEnabled(inputEnabled);
	}

	public String getSelfAlias() {
		return "<self>";
	}

	public String getPartnerAlias() {
		return "<partner>";
	}

	public void appendSelfMessage(String msg) {
		// transcript.setForeground(selfColor);
		transcript.append(getSelfAlias() + msg.trim() + "\n");
	}

	public void appendPartnerMessage(String msg) {
		// transcript.setForeground(partnerColor);
		transcript.append(getPartnerAlias() + msg.trim() + "\n");
	}

	public void clear() {
		transcript.setText("");
	}

	public void ensureVisible() {
		printDebug("ensureVisible");

		Component topComponent = this.getTopLevelAncestor();
		if (topComponent == null) {
			printDebug("unable to show Frame. top level ancestor is null.");
			this.setVisible(true);
		}
		else if (topComponent instanceof Window) {
			Window top = (Window)topComponent;
			top.toFront();
			top.setVisible(true);
		}
		else {
			printDebug(
				"unable to show Frame. top level ancestor is a "
					+ topComponent.getClass().getName());
			this.setVisible(true);
		}
	}

	// ================================
	// Actions
	// ================================

	public void actionPerformed(ActionEvent event) {
		String cmd = event.getActionCommand();
		if (cmd == null) {
		}
		else if (cmd.equals(SEND)) {
			send();
		}
		else if (cmd.equals(QUIT)) {
			quit();
		}
		else {
		}
	}

	public void send() {
		if (conv == null) {
			return;
		}

		ConversationContext context = conv.getContext();
		//		String cpName = context.getActivePolicyName();
		String selfRole = context.getActiveSelfRole();
		String currState = context.getActiveStateName();
		String msg = input.getText();

		if (currState == null || selfRole == null) {
			return;
		}
		else if (currState.equals("start") && selfRole.equals("Role1")) {
			begin(msg);
			appendSelfMessage(msg);
			input.setText("");
		}
		else if (currState.equals("role1Active") && selfRole.equals("Role1")) {
			continue1(msg);
			appendSelfMessage(msg);
			input.setText("");
		}
		else if (currState.equals("role2Active") && selfRole.equals("Role2")) {
			continue2(msg);
			appendSelfMessage(msg);
			input.setText("");
		}
		else {
			printDebug("send: illegal state.");
		}
	}

	public void quit() {
		if (conv == null) {
			return;
		}

		ConversationContext context = conv.getContext();
		//		String cpName = context.getActivePolicyName();
		String selfRole = context.getActiveSelfRole();
		String currState = context.getActiveStateName();

		if (currState == null || selfRole == null) {
			printDebug("quit: null pointers.");
			return;
		}
		else if (currState.equals("role1Active") && selfRole.equals("Role1")) {
			halt1();
			input.setText("");
			setInputEnabled(false);
		}
		else if (currState.equals("role2Active") && selfRole.equals("Role2")) {
			halt2();
			input.setText("");
			setInputEnabled(false);
		}
		else {
			printDebug("quit: illegal state.");
		}
	}

	// ================================
	// Triggered by GUI input.
	// ================================

	protected void begin(String chatMsg) {
		String decisionName = "begin";
		Object[] decisionArgs = new Object[] { chatMsg };
		DecisionDataHandle ddh2 =
			new BasicDecisionDataHandle(decisionName, decisionArgs);
		try {
			conv.processDecision(ddh2);
		}
		catch (ConversationException ex) {
			printDebug(ex.getMessage());
			// logException("start", ex);
		}
	}

	protected void continue1(String chatMsg) {
		String decisionName = null;
		Object[] decisionArgs = null;

		decisionName = "continue1";
		decisionArgs = new Object[] { chatMsg };
		//			logMessage(Able.MSG_INFO, "role1Active", "Sending message \"" + chatMsg + "\"");

		DecisionDataHandle ddh2 =
			new BasicDecisionDataHandle(decisionName, decisionArgs);
		try {
			conv.processDecision(ddh2);
		}
		catch (ConversationException ex) {
			printDebug(ex.getMessage());
			//			logException("role1Active", ex);
		}
	}

	protected void halt1() {
		String decisionName = null;
		Object[] decisionArgs = null;

		decisionName = "halt1";
		String byeMsg = "bye for now";
		decisionArgs = new Object[] { byeMsg };
		//			logMessage(Able.MSG_INFO, "role1Active", "Signing off with message \"" + byeMsg + "\"");

		DecisionDataHandle ddh2 =
			new BasicDecisionDataHandle(decisionName, decisionArgs);
		try {
			conv.processDecision(ddh2);
		}
		catch (ConversationException ex) {
			printDebug(ex.getMessage());
			//			logException("role1Active", ex);
		}
	}

	protected void continue2(String chatMsg) {
		String decisionName = null;
		Object[] decisionArgs = null;

		decisionName = "continue2";
		decisionArgs = new Object[] { chatMsg };

		DecisionDataHandle ddh2 =
			new BasicDecisionDataHandle(decisionName, decisionArgs);
		try {
			conv.processDecision(ddh2);
		}
		catch (ConversationException ex) {
			printDebug(ex.getMessage());
			//			logException("role2Active", ex);
		}
	}

	protected void halt2() {
		String decisionName = null;
		Object[] decisionArgs = null;

		decisionName = "halt2";
		String byeMsg = "bye for now";
		decisionArgs = new Object[] { byeMsg };

		DecisionDataHandle ddh2 =
			new BasicDecisionDataHandle(decisionName, decisionArgs);
		try {
			conv.processDecision(ddh2);
		}
		catch (ConversationException ex) {
			printDebug(ex.getMessage());
			//			logException("role2Active", ex);
		}
	}

	// ========================================
	// Debugging
	// ========================================

	public void printDebug(String msg) {
		System.out.println("AbleChat3Panel: " + msg);
	}

	public static void main(String[] args) {

		AbleChat3Panel pane = new AbleChat3Panel();

		JFrame frame = new JFrame("AbleChatPane");
		frame.setContentPane(pane);
		frame.pack();
		frame.setVisible(true);
	}
}
