/*******************************************************************************
 * Copyright (c) 2004 Actuate Corporation.
 * 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:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.debug.internal.script.model;

import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;

/**
 * ScriptDebugThread
 */
public class ScriptDebugThread extends ScriptDebugElement implements IThread
{

	private static String NAME = "Thread [main]"; //$NON-NLS-1$
	private IBreakpoint[] fBreakpoints;
	private boolean isStepping;

	/**
	 * Constuctor
	 * 
	 * @param target
	 */
	public ScriptDebugThread( ScriptDebugTarget target )
	{
		super( target );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IThread#getName()
	 */
	public String getName( ) throws DebugException
	{
		return NAME + renderState( );
	}

	private String renderState( )
	{
		if ( isTerminated( ) )
		{
			return " (Terminated)"; //$NON-NLS-1$
		}

		if ( isSuspended( ) )
		{
			return " (Suspended)"; //$NON-NLS-1$
		}

		if ( isStepping( ) )
		{
			return " (Stepping)"; //$NON-NLS-1$
		}

		return " (Running)"; //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IThread#getPriority()
	 */
	public int getPriority( ) throws DebugException
	{
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IThread#getStackFrames()
	 */
	public IStackFrame[] getStackFrames( ) throws DebugException
	{
		IStackFrame[] retValue;
		if ( isSuspended( ) )
		{
			retValue = ( (ScriptDebugTarget) getDebugTarget( ) ).getStackFrames( );
		}
		else
		{
			retValue = new IStackFrame[0];
		}
		return retValue;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IThread#getTopStackFrame()
	 */
	public IStackFrame getTopStackFrame( ) throws DebugException
	{
		IStackFrame[] frames = getStackFrames( );
		if ( frames.length > 0 )
		{
			return frames[0];
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IThread#hasStackFrames()
	 */
	public boolean hasStackFrames( ) throws DebugException
	{
		return isSuspended( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
	 */
	public boolean canResume( )
	{
		return !isTerminated( ) && isSuspended( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
	 */
	public boolean canSuspend( )
	{
		return !isTerminated( ) && !isSuspended( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
	 */
	public boolean isSuspended( )
	{
		return getDebugTarget( ).isSuspended( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#resume()
	 */
	public void resume( ) throws DebugException
	{
		getDebugTarget( ).resume( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
	 */
	public void suspend( ) throws DebugException
	{
		getDebugTarget( ).suspend( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IStep#canStepInto()
	 */
	public boolean canStepInto( )
	{
		return canStep( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IStep#canStepOver()
	 */
	public boolean canStepOver( )
	{
		return canStep( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IStep#canStepReturn()
	 */
	public boolean canStepReturn( )
	{
		return canStep( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IStep#isStepping()
	 */
	public boolean isStepping( )
	{
		return isStepping;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IStep#stepInto()
	 */
	public void stepInto( ) throws DebugException
	{
		( (ScriptDebugTarget) getDebugTarget( ) ).stepInto( );

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IStep#stepOver()
	 */
	public void stepOver( ) throws DebugException
	{
		( (ScriptDebugTarget) getDebugTarget( ) ).stepOver( );

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IStep#stepReturn()
	 */
	public void stepReturn( ) throws DebugException
	{
		( (ScriptDebugTarget) getDebugTarget( ) ).stepReturn( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
	 */
	public boolean canTerminate( )
	{
		return !isTerminated( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
	 */
	public boolean isTerminated( )
	{
		return getDebugTarget( ).isTerminated( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.ITerminate#terminate()
	 */
	public void terminate( ) throws DebugException
	{
		getDebugTarget( ).terminate( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.core.model.IThread#getBreakpoints()
	 */
	public IBreakpoint[] getBreakpoints( )
	{
		if ( fBreakpoints == null )
		{
			return new IBreakpoint[0];
		}
		return fBreakpoints;
	}

	/**
	 * @param breakpoints
	 */
	protected void setBreakpoints( IBreakpoint[] breakpoints )
	{
		fBreakpoints = breakpoints;
	}

	/**
	 * @return
	 */
	protected boolean canStep( )
	{
		try
		{
			return isSuspended( )
					&& !isStepping( )
					&& getTopStackFrame( ) != null;
		}
		catch ( DebugException e )
		{
			return false;
		}
	}

	/**
	 * @param stepping
	 */
	protected void setStepping( boolean stepping )
	{
		isStepping = stepping;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.debug.internal.script.model.ScriptDebugElement#getDisplayName()
	 */
	public String getDisplayName( )
	{
		try
		{
			return getName( );
		}
		catch ( DebugException e )
		{
			return NAME;
		}
	}
}
