/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.core;


import java.util.EventObject;

import org.eclipse.debug.internal.core.DebugCoreMessages;

/**
 * A debug event describes an event in a program being debugged or
 * in a running process. Debug models and process implementations
 * are required to generate debug events as specified by this class.
 * <p>
 * The following list defines the events generated for each debug
 * model element.
 * The <code>getSource()</code> method of a debug event
 * returns the element associated with the event.
 * Creation events are guaranteed to occur in a top
 * down order - that is, parents are created before children.
 * Termination events are guaranteed to occur in a bottom up order -
 * that is, children before parents. However, termination events are not guaranteed
 * for all  elements that are created. That is, terminate events can be coalesced - a 
 * terminate event for a parent signals that all children have been terminated.
 * </p>
 * <p>
 * A debug model may define model specific events by specifying a debug event
 * kind of <code>MODEL_SPECIFIC</code>. A model specific event is identified by the
 * event source (i.e. by the debug model that generated the event). The detail of
 * a model specific event is client defined. Note that model specific events are
 * not understood by the debug platform, and are thus ignored.
 * </p>
 * <p>
 * The generic <code>CHANGE</code> event can be fired at any time by any element.
 * Generally, a client of a debug model, such as as a UI, can get sufficient
 * information to update by listening/responding to the other event kinds. However,
 * if a debug model needs to inform clients of a change that is not specified
 * by create/terminate/suspend/resume, the <code>CHANGE</code> event may be used.
 * For example, generally, the only way a thread or any of its children can change
 * state between a suspend and resume operation, is if the thread or owning debug
 * target is terminated. However, if a debug model supports some other operation
 * that would allow a debug element to change state while suspended, the debug model
 * would fire a change event for that element. The valid detail codes for a
 * change event are:<ul>
 * <li><code>STATE</code> - indicates the state of an element has changed, but its
 *  children are not affected. A client would use a state change event to update
 *  a label of the affected element, but would not update any children.</li>
 * <li><code>CONTENT</code> - indicates that a debug element's value or contents have
 *  changed in some way. For example, when the value of a variable is changed
 *  explicitly, the variable should fire a content change event.</li>
 * </ul>
 * </p>
 * <ul>
 * <li><code>IProcess</code>
 *	<ul>
 *	<li><code>CREATE</code> - a process has been created and is executing.</li>
 *	<li><code>TERMINATE</code> - a process has terminated.</li>
 *  </ul>
 * <li><code>IDebugTarget</code>
 *	<ul>
 *	<li><code>CREATE</code> - a debug target has been created and is ready
 *		to begin a debug session.</li>
 *	<li><code>TERMINATE</code> - a debug target has terminated and the debug
 *		session has ended.</li>
 *  <li><code>SUSPEND</code> - a debug target has suspended. Event detail provides
 *		the reason for the suspension:<ul>
 *		<li><code>STEP_END</code> - a request to step has completed</li>
 *		<li><code>BREAKPOINT</code> - a breakpoint has been hit</li>
 *		<li><code>CLIENT_REQUEST</code> - a client request has caused the target to suspend
 * 			(i.e. an explicit call to <code>suspend()</code>)</li>
 * 		<li><code>UNSPECIFIED</code> - the reason for the suspend is not specified</li>
 *		</ul>
 *	</li>
 *  <li><code>RESUME</code> - a debug target has resumed. Event detail provides
 *		the reason for the resume:<ul>
 *		<li><code>STEP_INTO</code> - a target is being resumed because of a request to step into</li>
 * 		<li><code>STEP_OVER</code> - a target is being resumed because of a request to step over</li>
 * 		<li><code>STEP_RETURN</code> - a target is being resumed because of a request to step return</li>
 *		<li><code>CLIENT_REQUEST</code> - a client request has caused the target to be resumed
 * 			(i.e. an explicit call to <code>resume()</code>)</li>
 * 		<li><code>UNSPECIFIED</code> - The reason for the resume is not specified</li>
 *		</ul>
 *	</li>
 *	</ul>
 * </li>
 * <li><code>IThread</code>
 *	<ul>
 *	<li><code>CREATE</code> - a thread has been created in a debug target.</li>
 *	<li><code>TERMINATE</code> - a thread has terminated.</li>
 *	<li><code>SUSPEND</code> - a thread has suspended execution. Event detail provides
 *		the reason for the suspension:<ul>
 *		<li><code>STEP_END</code> - a request to step has completed</li>
 *		<li><code>BREAKPOINT</code> - a breakpoint has been hit</li>
 *		<li><code>CLIENT_REQUEST</code> - a client request has caused the thread to suspend
 * 			(i.e. an explicit call to <code>suspend()</code>)</li>
 * 		<li><code>EVALUATION</code> - an expression evaluation has ended that may
 * 			have had side effects in the debug target.</li>
 * 		<li><code>EVALUATION_IMPLICIT</code> - an expression evaluation has ended that
 * 			had no side effects in the debug target.</li>
 * 		<li><code>UNSPECIFIED</code> - the reason for the suspend is not specified</li>
 *		</ul>
 *	</li>
 *	<li><code>RESUME</code> - a thread has resumed execution. Event detail provides
 *		the reason for the resume:<ul>
 *		<li><code>STEP_INTO</code> - a thread is being resumed because of a request to step into</li>
 * 		<li><code>STEP_OVER</code> - a thread is being resumed because of a request to step over</li>
 * 		<li><code>STEP_RETURN</code> - a thread is being resumed because of a request to step return</li>
 *		<li><code>CLIENT_REQUEST</code> - a client request has caused the thread to be resumed
 * 			(i.e. an explicit call to <code>resume()</code>)</li>
 * 		<li><code>EVALUATION</code> - an expression evaluation has started that may
 * 			have side effects in the debug target.</li>
 * 		<li><code>EVALUATION_IMPLICIT</code> - an expression evaluation has started that
 * 			will have no side effects in the debug target.</li>
 * 		<li><code>UNSPECIFIED</code> - The reason for the resume is not specified</li>
 *		</ul>
 *	</li>
 *    </ul>
 * </li>
 * <li><code>IStackFrame</code> - no events are specified for stack frames.
 *	When a thread is suspended, it has stack frames. When a thread resumes,
 *	stack frames are unavailable.
 * </li>
 * <li><code>IVariable</code> - no events are specified for variables.
 *	When a thread is suspended, stack frames have variables. When a thread resumes,
 *	variables are unavailable.
 * </li>
 * <li><code>IValue</code> - no events are specified for values.
 * </li>
 * </ul>
 * <p>
 * Clients may instantiate this class. Clients are not intended to subclass this class.
 * </p>
 * 
 */
public final class DebugEvent extends EventObject {
	
    /**
     * All serializable objects should have a stable serialVersionUID
     */
    private static final long serialVersionUID = 1L;
    
	/**
	 * Resume event kind.
	 */
	public static final int RESUME= 0x0001;

	/**
	 * Suspend event kind.
	 */
	public static final int SUSPEND= 0x0002;

	/**
	 * Create event kind.
	 */
	public static final int CREATE= 0x0004;

	/**
	 * Terminate event kind.
	 */
	public static final int TERMINATE= 0x0008;
	
	/**
	 * Change event kind.
	 */
	public static final int CHANGE= 0x0010;
	
	/**
	 * Model specific event kind. The detail codes
	 * for a model specific event are client defined.
	 * 
	 * @since 2.1.2
	 */
	public static final int MODEL_SPECIFIC= 0x0020;	

	/**
	 * Step start detail. Indicates a thread was resumed by a step
	 * into action.
	 * @since 2.0
	 */
	public static final int STEP_INTO= 0x0001;
	
	/**
	 * Step start detail. Indicates a thread was resumed by a step
	 * over action.
	 * @since 2.0
	 */
	public static final int STEP_OVER= 0x0002;
	
	/**
	 * Step start detail. Indicates a thread was resumed by a step
	 * return action.
	 * @since 2.0
	 */
	public static final int STEP_RETURN= 0x0004;		

	/**
	 * Step end detail. Indicates a thread was suspended due
	 * to the completion of a step action.
	 */
	public static final int STEP_END= 0x0008;
	
	/**
	 * Breakpoint detail. Indicates a thread was suspended by
	 * a breakpoint.
	 */
	public static final int BREAKPOINT= 0x0010;
	
	/**
	 * Client request detail. Indicates a thread was suspended due
	 * to a client request.
	 */
	public static final int CLIENT_REQUEST= 0x0020;
	
	/**
	 * Evaluation detail. Indicates that a thread was resumed or
	 * suspended to perform an expression evaluation.
	 * 
	 * @since 2.0
	 */
	public static final int EVALUATION = 0x0040;
	
	/**
	 * Evaluation detail. Indicates that a thread was resumed or
	 * suspended to perform an implicit expression evaluation.
	 * An implicit evaluation is an evaluation that is performed
	 * as an indirect result of a user action.
	 * Clients may use this detail event to decide whether or not
	 * to alert the user that an evaluation is taking place..
	 * 
	 * @since 2.0
	 */
	public static final int EVALUATION_IMPLICIT = 0x0080;

	/**
	 * State change detail. Indicates the state of a single 
	 * debug element has changed. Only valid for <code>CHANGE</code>
	 * events.
	 * 
	 * @since 2.0
	 */
	public static final int STATE = 0x0100;
	
	/**
	 * Content change detail. Indicates the content of a debug element
	 * (and potentially its children) has changed. Only valid for
	 * <code>CHANGE</code> events.
	 * 
	 * @since 2.0
	 */
	public static final int CONTENT = 0x0200;	
			
	/**
	 * Constant indicating that the kind or detail of a debug
	 * event is unspecified.
	 */
	public static final int UNSPECIFIED = 0;
	
	/**
	 * The kind of event - one of the kind constants defined by
	 * this class.
	 */
	private int fKind= UNSPECIFIED;

	/**
	 * The detail of the event - one of the detail constants defined by
	 * this class.
	 */
	private int fDetail= UNSPECIFIED;
	
	/**
	 * Client defined data field.
	 * 
	 * @since 2.1.2
	 */
	private Object fData = null;
	
	/**
	 * Constructs a new debug event of the given kind with a detail code of
	 * <code>UNSPECIFIED</code>.
	 *
	 * @param eventSource the object associated with the event
	 * @param kind the kind of debug event (one of the
	 *	kind constants defined by this class)
	 */
	public DebugEvent(Object eventSource, int kind) {
		this(eventSource, kind, UNSPECIFIED);
	}

	/**
	 * Constructs a new debug event of the given kind with the given detail.
	 *
	 * @param eventSource the object associated with the event
	 * @param kind the kind of debug event (one of the
	 *	kind constants defined by this class)
	 * @param detail extra information about the event (one of the
	 *	detail constants defined by this class or a client defined detail if this is a model specific event)
	 */
	public DebugEvent(Object eventSource, int kind, int detail) {
		super(eventSource);
		if ((kind & (RESUME | SUSPEND | CREATE | TERMINATE | CHANGE | MODEL_SPECIFIC)) == 0)
			throw new IllegalArgumentException(DebugCoreMessages.DebugEvent_illegal_kind); 
		if (kind != MODEL_SPECIFIC && detail != UNSPECIFIED && (detail & (STEP_END | STEP_INTO | STEP_OVER | STEP_RETURN | BREAKPOINT | CLIENT_REQUEST |EVALUATION | EVALUATION_IMPLICIT | STATE | CONTENT)) == 0)
			throw new IllegalArgumentException(DebugCoreMessages.DebugEvent_illegal_detail); 
		fKind= kind;
		fDetail= detail;
	}

	/**
	 * Returns a constant describing extra detail about the event - either one
	 * of the detail constants defined by this class, possibly
	 * <code>UNSPECIFIED</code>, or a client defined detail if this is a model specific event.
	 *
	 * @return the detail code
	 */
	public int getDetail() {
		return fDetail;
	}

	/**
	 * Returns this event's kind - one of the kind constants defined by this class.
	 * 
	 * @return the kind code
	 */
	public int getKind() {
		return fKind;
	}
	
	/**
	 * Returns whether this event's detail indicates the
	 * beginning of a step event. This event's detail is one
	 * of <code>STEP_INTO</code>, <code>STEP_OVER</code>, or
	 * <code>STEP_RETURN</code>.
	 * 
	 * @return whether this event's detail indicates the beginning
	 *  of a step event.
	 * @since 2.0
	 */
	public boolean isStepStart() {
		return (getDetail() & (STEP_INTO | STEP_OVER | STEP_RETURN)) > 0;
	}
	
	/**
	 * Returns whether this event's detail indicates an
	 * evaluation. This event's detail is one
	 * of <code>EVALUATION</code>, or <code>EVALUATION_IMPLICIT</code>.
	 * 
	 * @return whether this event's detail indicates an evaluation.
	 * @since 2.0
	 */
	public boolean isEvaluation() {
		return (getDetail() & (EVALUATION | EVALUATION_IMPLICIT)) > 0;
	}	
	
	/**
	 * Sets this event's application defined data.
	 * 
	 * @param data application defined data
	 * @since 2.1.2
	 */
	public void setData(Object data) {
		fData = data;
	}
	
	/**
	 * Returns this event's application defined data, or <code>null</code> if none
	 * 
	 * @return application defined data, or <code>null</code> if none
	 * @since 2.1.2
	 */
	public Object getData() {
		return fData;
	}
	
	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		StringBuffer buf = new StringBuffer("DebugEvent["); //$NON-NLS-1$
		if (getSource() != null) {
			buf.append(getSource().toString());
		} else {
			buf.append("null"); //$NON-NLS-1$
		}
		buf.append(", "); //$NON-NLS-1$
		switch (getKind()) {
			case CREATE:
				buf.append("CREATE"); //$NON-NLS-1$
				break;
			case TERMINATE:
				buf.append("TERMINATE"); //$NON-NLS-1$
				break;
			case RESUME:
				buf.append("RESUME"); //$NON-NLS-1$
				break;
			case SUSPEND:
				buf.append("SUSPEND"); //$NON-NLS-1$
				break;				
			case CHANGE:
				buf.append("CHANGE"); //$NON-NLS-1$
				break;
			case UNSPECIFIED:
				buf.append("UNSPECIFIED"); //$NON-NLS-1$
				break;
			case MODEL_SPECIFIC:
				buf.append("MODEL_SPECIFIC"); //$NON-NLS-1$
				break;
		}
		buf.append(", "); //$NON-NLS-1$
		switch (getDetail()) {
			case BREAKPOINT:
				buf.append("BREAKPOINT"); //$NON-NLS-1$
				break;
			case CLIENT_REQUEST:
				buf.append("CLIENT_REQUEST"); //$NON-NLS-1$
				break;
			case STEP_END:
				buf.append("STEP_END"); //$NON-NLS-1$
				break;
			case STEP_INTO:
				buf.append("STEP_INTO"); //$NON-NLS-1$
				break;
			case STEP_OVER:
				buf.append("STEP_OVER"); //$NON-NLS-1$
				break;
			case STEP_RETURN:
				buf.append("STEP_RETURN"); //$NON-NLS-1$
				break;
			case EVALUATION:
				buf.append("EVALUATION"); //$NON-NLS-1$
				break;
			case EVALUATION_IMPLICIT:
				buf.append("EVALUATION_IMPLICIT"); //$NON-NLS-1$
				break;								
			case STATE:
				buf.append("STATE"); //$NON-NLS-1$
				break;			
			case CONTENT:
				buf.append("CONTENT"); //$NON-NLS-1$
				break;					
			case UNSPECIFIED:
				buf.append("UNSPECIFIED"); //$NON-NLS-1$
				break;
			default:
				// model specific
				buf.append(getDetail());
				break;
		}
		buf.append("]"); //$NON-NLS-1$
		return buf.toString();
	}
}

