package org.omg.lsae.notifications;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class StateEvent extends AnalysisEvent {

	private String newState = "";

	private String previousState = "";

	private final String created = "created";

	private final String running = "running";

	private final String completed = "completed";

	private final String terminated_by_request = "terminated_by_request";

	private final String terminated_by_error = "terminated_by_error";

	public final static int CREATED = 100;

	public final static int RUNNING = 101;

	public final static int COMPLETED = 102;

	public final static int TERMINATED_BY_REQUEST = 103;

	public final static int TERMINATED_BY_ERROR = 104;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.omg.lsae.notifications.AnalysisEvent#isCompleted()
	 */
	public boolean isCompleted() {
		return (newState.equals(completed)
				|| newState.equals(terminated_by_error) || newState
				.equals(terminated_by_request));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.omg.lsae.notifications.AnalysisEvent#toString()
	 */
	public String toString() {
		return "State Changed Event (" + getNewState() + ") - " + getMessage();
	}

	/**
	 * @return the newState
	 */
	public String getNewState() {
		return newState;
	}

	/**
	 * @param newState
	 *            the newState to set
	 */
	public void setNewState(int newState) {
		this.newState = getState(newState);
	}

	/*
	 * a mehtod that given an integer STATE, returns the textual representation
	 * of that state
	 */
	private String getState(int state) {
		String val = "";
		switch (state) {
		case StateEvent.CREATED:
			val = created;
			break;
		case StateEvent.COMPLETED:
			val = completed;
			break;
		case StateEvent.RUNNING:
			val = running;
			break;
		case StateEvent.TERMINATED_BY_ERROR:
			val = terminated_by_error;
			break;
		case StateEvent.TERMINATED_BY_REQUEST:
			val = terminated_by_request;
			break;
		default:
			val = created;
			break;
		}
		return val;
	}

	/**
	 * 
	 * @param state
	 *            the textual representation of the state
	 * @return an integer that maps to the text rep of a state
	 */
	public int getState(String state) {
		if (state.equals(created))
			return CREATED;
		if (state.equals(completed))
			return COMPLETED;
		if (state.equals(running))
			return RUNNING;
		if (state.equals(terminated_by_error))
			return TERMINATED_BY_ERROR;
		if (state.equals(terminated_by_request))
			return TERMINATED_BY_REQUEST;

		return CREATED;
	}

	/**
	 * @return the previousState
	 */
	public String getPreviousState() {
		return previousState;
	}

	/**
	 * @param previousState
	 *            the previousState to set
	 */
	public void setPreviousState(int previousState) {
		this.previousState = getState(previousState);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.omg.lsae.notifications.AnalysisEvent#toXMLString()
	 */
	public String toXMLString() {

		Document doc = createDomDocument();

		Element root = doc.createElement("analysis_event");
		root.setAttribute("timestamp", getTimestamp());
		root.setAttribute("id", getQueryId());

		Element msg = doc.createElement("message");
		msg.setTextContent(getMessage());
		root.appendChild(msg);

		msg = doc.createElement("state_changed");
		msg.setAttribute("previous_state", getPreviousState());
		msg.setAttribute("new_state", getNewState());
		root.appendChild(msg);

		ByteArrayOutputStream buf = new ByteArrayOutputStream();
		TransformerFactory tFactory = TransformerFactory.newInstance();
		Transformer transformer;
		StreamSource stylesource = new StreamSource(new ByteArrayInputStream(
				new String(XSLT).getBytes()));
		try {
			transformer = tFactory.newTransformer(stylesource);
			DOMSource source = new DOMSource(root);
			StreamResult result = new StreamResult(buf);
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
					"yes");
			transformer.transform(source, result);
		} catch (TransformerConfigurationException e1) {
			System.err.println("Couldnt print out DOM "
					+ e1.getLocalizedMessage());
		} catch (TransformerException e) {
			System.err.println("Couldnt print out DOM "
					+ e.getLocalizedMessage());
		}
		return buf.toString();
	}

}
