package de.ugoe.cs.eventbench.jfc.data;

import java.util.HashMap;
import java.util.Map;

import de.ugoe.cs.eventbench.data.IReplayable;
import de.ugoe.cs.eventbench.data.ReplayableEvent;
import de.ugoe.cs.eventbench.jfc.JFCLogParser;

/**
 * <p>
 * This class defines JFC events.
 * </p>
 * 
 * @author Steffen Herbold
 * @version 1.0
 */
public class JFCEvent extends ReplayableEvent<IReplayable> {

	/**
	 * <p>
	 * Id for object serialization.
	 * </p>
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * <p>
	 * Internal map of parameters associated with the event.
	 * </p>
	 */
	private Map<String, String> parameters;

	/**
	 * <p>
	 * Information about the event source.
	 * </p>
	 */
	private Map<String, String> sourceParameters;

	/**
	 * <p>
	 * Information about the parent of the event source.
	 * </p>
	 */
	private Map<String, String> parentParameters;

	/**
	 * <p>
	 * Constructor. Creates a new JFCEvent.
	 * </p>
	 * 
	 * @param type
	 *            type of the event
	 */
	public JFCEvent(String type) {
		super(type);
		parameters = new HashMap<String, String>();
		sourceParameters = new HashMap<String, String>();
		parentParameters = new HashMap<String, String>();
	}

	/**
	 * <p>
	 * Adds a new parameter to the event.
	 * </p>
	 * 
	 * @param name
	 *            name of the parameter
	 * @param value
	 *            value of the parameter
	 */
	public void addParameter(String name, String value) {
		parameters.put(name, value);
	}

	/**
	 * <p>
	 * Retrieves the value of a parameter.
	 * </p>
	 * 
	 * @param name
	 *            name of the parameter
	 * @return value of the parameter
	 */
	public String getParameter(String name) {
		return parameters.get(name);
	}

	/**
	 * <p>
	 * Adds new information about the source of the event.
	 * </p>
	 * 
	 * @param name
	 *            name of the information
	 * @param value
	 *            value of the information
	 */
	public void addSourceInformation(String name, String value) {
		sourceParameters.put(name, value);
	}

	/**
	 * <p>
	 * Retrieves information about the source of the event.
	 * </p>
	 * 
	 * @param name
	 *            name of the information
	 * @return value of the information
	 */
	public String getSourceInformation(String name) {
		return sourceParameters.get(name);
	}

	/**
	 * <p>
	 * Adds new information about the parent of the source of the event.
	 * </p>
	 * 
	 * @param name
	 *            name of the information
	 * @param value
	 *            value of the information
	 */
	public void addParentInformation(String name, String value) {
		parentParameters.put(name, value);
	}

	/**
	 * <p>
	 * Used by the {@link JFCLogParser} to extend the target string of the
	 * current event with a further ancestor. The resulting target string will
	 * have the structure {@code etc.grandparent.parent.eventtarget}.
	 * </p>
	 * 
	 * @param extension
	 *            extension for the target.
	 */
	public void extendTarget(String extension) {
		if (target == null || "".equals(target)) {
			target = extension;
		} else {
			target += "." + extension;
		}
	}

	/**
	 * <p>
	 * Retrieves information about the parent of the source of the event.
	 * </p>
	 * 
	 * @param name
	 *            name of the information
	 * @return value of the information
	 */
	public String getParentInformation(String name) {
		return parentParameters.get(name);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.ugoe.cs.eventbench.data.ReplayableEvent#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object other) {
		if (other == this) {
			return true;
		}
		if (other instanceof JFCEvent) {
			return super.equals(other)
					&& parameters.equals(((JFCEvent) other).parameters);
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.ugoe.cs.eventbench.data.ReplayableEvent#hashCode()
	 */
	@Override
	public int hashCode() {
		int hashCode = super.hashCode();
		hashCode *= parameters.hashCode();
		return hashCode;
	}

}
