/*
 *************************************************************************
 * Copyright (c) 2006 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.data.adapter.internal.script;

import java.math.BigDecimal;
import java.util.Date;

import org.eclipse.birt.core.data.DataType;
import org.eclipse.birt.core.data.DataTypeUtil;
import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.report.model.api.ModuleHandle;
import org.eclipse.birt.report.model.api.ParameterHandle;
import org.eclipse.birt.report.model.api.ScalarParameterHandle;
import org.eclipse.birt.report.model.api.elements.DesignChoiceConstants;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

/**
 * Implements the "params" scriptable object to access report parameter values
 */
public class ParamsObject extends ScriptableObject
{
	ModuleHandle module;
	
	private static final long serialVersionUID = 423299092113453L;
	
	public ParamsObject( ModuleHandle module )
	{
		assert module != null;
		this.module = module;
	}
	
	public String getClassName()
	{
		return "BirtParams";
	}
	
    public boolean has( String name, Scriptable start )
    {
    	if ( super.has(name, start))
    		return true;
    	
    	if ( module.findParameter(name) != null)
    		return true;
    	return false;
    }

    public Object get( String name, Scriptable start )
    {
    	Object val = super.get(name, start);
    	if ( val != NOT_FOUND )
    		return val;
    	
    	if ( name.equals("length"))
    		return new Integer( module.getAllParameters().size() );
    	
   		ParameterHandle param = module.findParameter( name );
   		if ( param != null )
   		{
   			val = getParamDefaultValue( param );
   		}

    	return val;
    }
    
    /**
     * Gets the default value of a parameter. If a usable default value is defined,
     * use it; otherwise use a default value appropriate for the data type
     */
    private Object getParamDefaultValue( ParameterHandle param )
    {
    	if ( ! (param instanceof ScalarParameterHandle ) )
    		return null;
    	
    	ScalarParameterHandle sp = (ScalarParameterHandle) param;
    	String defaultValue = sp.getDefaultValue();
    	String type = sp.getDataType();
    	if ( defaultValue == null)
    	{
    		// No default value; if param allows null value, null is used
    		if ( sp.allowNull() )
    			return null;
    		
    		// Return a fixed default value appropriate for the data type
    		if ( DesignChoiceConstants.PARAM_TYPE_STRING.equals(type) )
    		{
    			if (sp.allowBlank())
    				return "";
    			else
    				return "null";
    		}
    		if ( DesignChoiceConstants.PARAM_TYPE_FLOAT.equals(type) )
    			return new Double(0);
    		if ( DesignChoiceConstants.PARAM_TYPE_DECIMAL.equals(type) )
    			return new BigDecimal( (double) 0 );
    		if ( DesignChoiceConstants.PARAM_TYPE_DATETIME.equals(type) )
    			return new Date(0);
    		if ( DesignChoiceConstants.PARAM_TYPE_BOOLEAN.equals(type) )
    			return Boolean.FALSE;
    		
    		// unknown parameter type; unexpected
    		assert false;
    		return null;
    	}
    	
    	// Convert default value to the correct data type
    	int typeNum = DataType.ANY_TYPE;
		if ( DesignChoiceConstants.PARAM_TYPE_STRING.equals(type) )
			typeNum = DataType.STRING_TYPE;
		else if ( DesignChoiceConstants.PARAM_TYPE_FLOAT.equals(type) )
			typeNum = DataType.DOUBLE_TYPE;
		else if ( DesignChoiceConstants.PARAM_TYPE_DECIMAL.equals(type) )
			typeNum = DataType.DECIMAL_TYPE;
		else if ( DesignChoiceConstants.PARAM_TYPE_DATETIME.equals(type) )
			typeNum = DataType.DATE_TYPE;
		else if ( DesignChoiceConstants.PARAM_TYPE_BOOLEAN.equals(type) )
			typeNum = DataType.BOOLEAN_TYPE;
    	
		try
		{
			return DataTypeUtil.convert(defaultValue, typeNum);
		}
		catch (BirtException e)
		{
			return null;
		}
   	}
}
