/*******************************************************************************
 * 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.model.script;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.birt.report.model.api.ColorHandle;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.DimensionHandle;
import org.eclipse.birt.report.model.api.PropertyHandle;
import org.eclipse.birt.report.model.api.metadata.IPropertyType;
import org.eclipse.birt.report.model.metadata.ElementPropertyDefn;
import org.eclipse.birt.report.model.metadata.PropertyDefn;

/**
 * Adapter converting the Model interface of design element handle to script
 * interface.
 */

public class ElementDefinition
{

	/**
	 * Handle of design element
	 */

	DesignElementHandle element;

	/**
	 * Constructs the element definition representing the given design element
	 * handle.
	 * 
	 * @param element
	 *            the handle of design element
	 */

	ElementDefinition( DesignElementHandle element )
	{
		this.element = element;
	}

	/**
	 * Returns the name of this design element. The name maybe is empty.
	 * 
	 * @return the name of this design element
	 */

	String getName( )
	{
		return element.getName( );
	}

	/**
	 * Returns the name of the parent element that this design element extends.
	 * 
	 * @return the parent name of this design element
	 */

	String getExtendsElement( )
	{
		if( element.getExtends( )!= null)
			return element.getExtends( ).getName( );

		return null;
		 
	}

	/**
	 * Returns the map of all property definition, including both BIRT defined
	 * and user-defined properties. The key is property name.
	 * 
	 * @return the map of all property definition of this element
	 */

	Map getPropertyDefns( )
	{
		Map map = new LinkedHashMap( );
		List propList = element.getElement( ).getPropertyDefns( );

		for ( Iterator iter = propList.iterator( ); iter.hasNext( ); )
		{
			PropertyDefn propDefn = (PropertyDefn) iter.next( );
			map.put( propDefn.getName( ), new PropertyDefinition( propDefn ) );
		}
		return map;
	}

	/**
	 * Returns the map of all property values, including both BIRT-defined and
	 * user-defined properties. The key is property name.
	 * 
	 * @return the map of all property values of this element
	 */

	Map getProperties( )
	{
		Map map = new LinkedHashMap( );
		Iterator iter = element.getPropertyIterator( );
		while ( iter.hasNext( ) )
		{
			PropertyHandle propHandle = (PropertyHandle) iter.next( );

			if ( propHandle.getDefn( ).getTypeCode( ) == IPropertyType.COLOR_TYPE )
			{
				Color color = new Color( new ColorHandle( element,
						(ElementPropertyDefn) propHandle.getDefn( ) ) );

				map.put( propHandle.getPropertyDefn( ).getName( ), color );

			}

			else if ( propHandle.getDefn( ).getTypeCode( ) == IPropertyType.DIMENSION_TYPE )
			{

				Dimension dimension = new Dimension( new DimensionHandle(
						element, (ElementPropertyDefn) propHandle.getDefn( ) ) );

				map.put( propHandle.getPropertyDefn( ).getName( ), dimension );
				continue;
			}
			else
				map.put( propHandle.getPropertyDefn( ).getName( ), propHandle
						.getValue( ) );
		}

		return map;
	}

	/**
	 * Returns whether this element supports user properties.
	 * 
	 * @return <code>true</code> if this element supports user properties.
	 */

	boolean allowsUserProperties( )
	{
		return element.getDefn( ).allowsUserProperties( );
	}

	/**
	 * Returns whether this element can have style.
	 * 
	 * @return <code>true</code> if this element can have style
	 */

	boolean hasStyle( )
	{
		return element.getDefn( ).hasStyle( );
	}

	/**
	 * Returns the container that this element is in. If this element has no
	 * container, return <code>null</code>.
	 * 
	 * @return the container that this element is in
	 */

	ElementDefinition getContainer( )
	{
		if ( element.getContainer( ) != null )
			return new ElementDefinition( element.getContainer( ) );

		return null;
	}

	/**
	 * Returns the name of container's slot that this element is in. If this
	 * element has not containter, return empty string.
	 * 
	 * @return the name of container's slot that this element is in
	 */

	String getContainerSlot( )
	{
		if ( element.getContainer( ) != null )
		{
			return element.getContainer( ).getDefn( ).getSlot(
					element.getContainerSlotHandle( ).getSlotID( ) ).getName( );
		}

		return ""; //$NON-NLS-1$
	}

	/**
	 * Returns the value of the given property.
	 * 
	 * @param name
	 *            the property name
	 * @return the value of the given property.
	 */

	Object getProperty( String name )
	{
		return element.getProperty( name );
	}

	/**
	 * Returns the contents in all slots of this element. TODO: Not implmented.
	 * 
	 * @return the contents in all slots of this element.
	 */

	Map getSlots( )
	{
		return null;
	}

	/**
	 * Returns all slot definition of this element. TODO: Not implmented.
	 * 
	 * @return all slot definition of this element.
	 */

	Map getSlotDefns( )
	{
		return null;
	}
}