/*
 *************************************************************************
 * 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.lang.reflect.InvocationTargetException;
import org.eclipse.birt.core.script.CoreJavaScriptInitializer;
import org.eclipse.birt.report.model.api.ModuleHandle;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.Scriptable;

/**
 * Top-level scope created by Data Adaptor. This scope provides implementation of some
 * report level script object (e.g., "params")
 */
public class DataAdapterTopLevelScope extends ImporterTopLevel
{
	private static final long serialVersionUID = 4230948829384l;
	
	private static final String PROP_PARAMS = "params";
	private static final String PROP_REPORTCONTEXT = "reportContext";
	private ModuleHandle designModule;
	private Scriptable paramsProp;
	private Object reportContextProp;

	
	/**
	 * Constructor; initializes standard objects in scope
	 * @param cx Context used to initialze scope
	 * @param module Module associated with this scope; can be null
	 */
	public DataAdapterTopLevelScope( Context cx, ModuleHandle module )
	{
		super(cx);
		// init BIRT native objects
		new CoreJavaScriptInitializer( ).initialize( cx, this );
		designModule = module;
	}
	
    public boolean has(String name, Scriptable start) 
    {
    	if ( super.has(name, start) )
    		return true;
    	// "params" is available only if we have a module
    	if ( designModule != null && PROP_PARAMS.equals(name) )
    		return true;
    	
    	if ( PROP_REPORTCONTEXT.equals( name ) )
			return true;
    	return false;
    }

    public Object get(String name, Scriptable start) 
    {
        Object result = super.get(name, start);
        if (result != NOT_FOUND)
            return result;
        
    	if ( designModule != null && PROP_PARAMS.equals(name) )
    	{
    		return getParamsScriptable();
    	}
    	
    	if ( PROP_REPORTCONTEXT.equals( name ) )
			return getReportContext( );
    	
    	return NOT_FOUND;
    }
    
    /**
     * Gets a object which implements the "reportContext" property
     * @throws InvocationTargetException 
     * @throws InstantiationException 
     * @throws IllegalAccessException 
     */
    private Object getReportContext()
    {
		if ( reportContextProp != null )
			return reportContextProp;

		assert designModule != null;
		
		reportContextProp = new ReportContextObject( designModule );
		
		return reportContextProp;
    }
    
    /**
     * Gets a scriptable object which implements the "params" property
     */
    private Scriptable getParamsScriptable()
    {
		if ( paramsProp != null )
			return paramsProp;

		assert designModule != null;
		
		paramsProp = new ParamsObject( designModule );
		return paramsProp;
    }
	
    	
}
