/*******************************************************************************
 * 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.engine.executor;

import java.util.Map;

import org.eclipse.birt.core.script.BaseScriptable;
import org.eclipse.birt.report.engine.api.impl.ParameterAttribute;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Wrapper;

public class ScriptableParameter extends BaseScriptable implements Wrapper
{

	private Map parameters;
	private String parameterName;

	private final static String JS_CLASS_NAME = "ScriptableParameters";

	public final static String FIELD_VALUE = "value";
	public final static String FIELD_DISPLAY_TEXT = "displayText";
	public static Scriptable jsStrPrototype = null;

	public ScriptableParameter( Map parameters, String parameterName, Scriptable parent )
	{
		setParentScope( parent );
		this.parameters = parameters;
		this.parameterName = parameterName;
	}

	public Object get( String name, Scriptable scope )
	{
		Object value = parameters.get( parameterName );
		if ( value == null )
		{
			return null;
		}
		assert value instanceof ParameterAttribute;
		ParameterAttribute parameter = (ParameterAttribute) value;
		if ( FIELD_VALUE.equals( name ) )
		{
			return parameter.getValue( );
		}
		else if ( FIELD_DISPLAY_TEXT.equals( name ) )
		{
			return parameter.getDisplayText( );
		}
		value = parameter.getValue( );
		Scriptable jsStr = Context.toObject( value, scope );
		if ( jsStr != null )
		{
			return jsStr.getPrototype( ).get( name, jsStr );
		}
		return null;
	}

	public Object getDefaultValue( Class hint )
	{
		Object value = parameters.get( parameterName );
		if ( value == null )
		{
			return null;
		}
		assert value instanceof ParameterAttribute;
		ParameterAttribute parameter = (ParameterAttribute) value;
		return parameter.getValue( );
	}

	public boolean has( String name, Scriptable scope )
	{
		if ( FIELD_VALUE.equals( name ) || FIELD_DISPLAY_TEXT.equals( name ) )
		{
			return true;
		}
		if ( jsStrPrototype == null )
		{
			jsStrPrototype = Context.toObject( "", scope );
			if ( jsStrPrototype != null )
			{
				jsStrPrototype = jsStrPrototype.getPrototype( );
			}
		}
		return jsStrPrototype.has( name, scope );
	}

	public void put( String name, Scriptable scope, Object value )
	{
		Object parameterValue = parameters.get( parameterName );
		if ( parameterValue == null )
		{
			return;
		}
		assert parameterValue instanceof ParameterAttribute;
		ParameterAttribute parameter = (ParameterAttribute) parameterValue;
		if ( FIELD_VALUE.equals( name ) )
		{
			parameter.setValue( value );
		}
		else if ( FIELD_DISPLAY_TEXT.equals( name ) )
		{
			parameter.setDisplayText( (String) value );
		}
	}

	public String getClassName( )
	{
		return JS_CLASS_NAME;
	}

	public Object unwrap( )
	{
		Object value = parameters.get( parameterName );
		if ( value != null )
		{
			return ( (ParameterAttribute) value ).getValue( );
		}
		return null;
	}
}
