/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.dynamo.script;

import java.util.*;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;

/**
 * The basic "script library" object, which provides certain basic services to all scripts.
 * An instance of this object is automatically declared in every
 * {@link com.silverwrist.dynamo.script.ScriptEngine ScriptEngine} with the name "dynamo",
 * so, for instance, a script can call:
 * <P><CODE>dynamo.scriptReturn(object);</CODE>
 * <P>and the {@link #scriptReturn(java.lang.Object) scriptReturn()} method on this object will be called.
 *
 * @author Eric J. Bowersox &lt;erbo@silcom.com&gt;
 * @version X
 */
public class LibraryDynamo
{
  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private ScriptEngine m_engine;     // engine instance we're associated with

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  /**
   * Constructs a new instance of the library object.
   *
   * @param engine The {@link com.silverwrist.dynamo.script.ScriptEngine ScriptEngine} instance that this
   *               library object is associated with.
   */
  LibraryDynamo(ScriptEngine engine)
  {
    m_engine = engine;

  } // end constructor

  /*--------------------------------------------------------------------------------
   * External operations
   *--------------------------------------------------------------------------------
   */

  /**
   * Returns the current date and time as a <CODE>java.util.Date</CODE> object.
   *
   * @return The current date and time.
   */
  public final java.util.Date currentDate()
  {
    return new java.util.Date();

  } // end currentDate

  /**
   * Returns the current system time in milliseconds, expressed as a long integer.
   *
   * @return The current system timestamp.
   */
  public final long currentTimeMillis()
  {
    return System.currentTimeMillis();

  } // end currentTimeMillis

  /**
   * Returns the message associated with the given exception.
   *
   * @param t An exception object.
   * @return The message associated with the exception.
   */
  public final String exceptionMessage(Throwable t)
  {
    return t.getMessage();

  } // end exceptionMessage

  /**
   * Returns the type of the given exception.
   *
   * @param o Any object, which may or may not be an exception.
   * @return The classname of the exception object, or <CODE>null</CODE> if the object is not an exception.
   * @exception com.silverwrist.dynamo.script.ExitScript If the object is an <CODE>ExitScript</CODE> exception,
   *            we rethrow it, as this represents a desire to exit the script.
   */
  public final String exceptionType(Object o) throws ExitScript
  {
    if (o==null)
      return null;
    if (o instanceof ExitScript)
      throw (ExitScript)o;  // if we want to exit, rethrow this exception
    if (o instanceof Throwable)
      return o.getClass().getName();
    else
      return null;

  } // end exceptionType

  /**
   * Executes a script from within another script.  When that script finishes, control returns to the first script.
   *
   * @param resource_name The fully-qualified resource name of the script to execute.
   * @return The return value from the executed script.
   * @exception com.silverwrist.dynamo.except.ScriptingException If an error occurs in the called script.
   */
  public final Object exec(String resource_name) throws ScriptingException
  {
    Request request = (Request)(m_engine.lookupObject("request"));
    ScriptExecute script = (ScriptExecute)(request.queryService(ScriptExecute.class));
    return script.executeScript(request,resource_name);

  } // end exec

  /**
   * Forces the current script to exit immediately.
   *
   * @exception com.silverwrist.dynamo.script.ExitScript Indicates that we want to exit the script.
   */
  public final void scriptExit() throws ExitScript
  {
    throw new ExitScript();

  } // end scriptExit

  /**
   * Sets the return value of the current script.
   *
   * @param obj The return value to set.
   */
  public final void scriptOutput(Object obj)
  {
    m_engine.setReturnValue(obj);

  } // end scriptOutput

  /**
   * Sets the return value of the current script, and forces it to exit immediately.
   *
   * @param obj The return value to set.
   * @exception com.silverwrist.dynamo.script.ExitScript Indicates that we want to exit the script.
   */
  public final void scriptReturn(Object obj) throws ExitScript
  {
    m_engine.setReturnValue(obj);
    throw new ExitScript();
    
  } // end scriptReturn

  /**
   * Returns the type (classname) of an object.
   *
   * @param o The object to test the type of.
   * @return The classname of the object.  If the object is <CODE>null</CODE>, returns <CODE>null</CODE>.
   */
  public final String typeOf(Object o)
  {
    if (o==null)
      return null;
    else if (o instanceof DynamicObject)
      return ((DynamicObject)o).getDClass().getName();
    else
      return o.getClass().getName();

  } // end typeOf

  /**
   * Unwraps a dynamically-wrapped object, returning the object inside it.
   *
   * @param obj The object to be unwrapped.
   * @return The result of calling the {@link com.silverwrist.dynamo.iface.DynamicWrapper#unwrap() unwrap()}
   *         method on the object.  If the object is not a dynamically-wrapped object, returns the object itself.
   */
  public final Object unwrapObject(Object obj)
  {
    if (obj==null)
      return null;
    if (obj instanceof DynamicWrapper)
      return ((DynamicWrapper)obj).unwrap();
    else
      return obj;

  } // end unwrapObject

} // end class LibraryDynamo
