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

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.birt.report.model.api.extension.IChoiceDefinition;
import org.eclipse.birt.report.model.api.extension.IPropertyDefinition;
import org.eclipse.birt.report.model.api.metadata.IChoiceSet;
import org.eclipse.birt.report.model.api.metadata.IElementDefn;
import org.eclipse.birt.report.model.api.metadata.IStructureDefn;

/**
 * Represents the extension structure member definition. It is used for only
 * those structure member defined by ROM extension element. The instance of this
 * class is read-only, which means that all the "set" methods is forbidden.
 * 
 * TODO: The structure property in extension should be refined.
 */

public class ExtensionStructPropertyDefn extends StructPropertyDefn
{

	/**
	 * The cached effective extension model member definition.
	 */
	
	private IPropertyDefinition extMember = null;

	/**
	 * Constructs the extension structure member property definition with the
	 * given IPropertyDefinition by extension elements.
	 * 
	 * @param extMemberDefn
	 *            the extension structure member definition based
	 */

	public ExtensionStructPropertyDefn( IPropertyDefinition extMemberDefn )
	{
		extMember = extMemberDefn;
		assert extMember != null;
		MetaDataDictionary dd = MetaDataDictionary.getInstance( );
		type = dd.getPropertyType( extMemberDefn.getType( ) );
		name = extMember.getName( );
		defaultValue = extMember.getDefaultValue( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getChoices()
	 */

	public IChoiceSet getChoices( )
	{
		Collection choices = extMember.getChoices( );
		if ( choices == null )
			return null;
		if ( choices.size( ) == 0 )
			return null;
		Choice[] choiceArray = new Choice[choices.size( )];
		Iterator iter = choices.iterator( );
		int i = 0;
		while ( iter.hasNext( ) )
		{
			IChoiceDefinition choice = (IChoiceDefinition) iter.next( );
			ExtensionChoice extChoice = new ExtensionChoice( choice, null );
			choiceArray[i] = extChoice;
			i++;
		}
		assert i == choices.size( );

		ChoiceSet set = new ChoiceSet( );
		set.setChoices( choiceArray );
		details = set;
		return set;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getDefault()
	 */

	public Object getDefault( )
	{
		return extMember.getDefaultValue( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getDisplayName()
	 */

	public String getDisplayName( )
	{
		// TODO:
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getAllowedChoices()
	 */

	public IChoiceSet getAllowedChoices( )
	{
		return getChoices( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getDisplayNameID()
	 */

	public String getDisplayNameID( )
	{
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getName()
	 */

	public String getName( )
	{
		return extMember.getName( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getStructDefn()
	 */

	public IStructureDefn getStructDefn( )
	{
		if ( details instanceof StructureDefn )
			return (StructureDefn) details;
		List members = extMember.getMembers( );
		if ( members == null )
			return null;
		StructureDefn struct = new StructureDefn( );
		Iterator iter = members.iterator( );
		while ( iter.hasNext( ) )
		{
			IPropertyDefinition prop = (IPropertyDefinition) iter.next( );
			try
			{
				struct.addProperty( new ExtensionStructPropertyDefn( prop ) );
			}
			catch ( MetaDataException e )
			{
				assert false;
				return null;
			}
		}
		details = struct;
		return struct;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getTargetElementType()
	 */

	public IElementDefn getTargetElementType( )
	{
		// till now, the extension elements do not support
		// element reference type?
		// TODO: if support element reference type, we should handle

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getType()
	 */

	public PropertyType getType( )
	{
		int typeCode = extMember.getType( );
		MetaDataDictionary dd = MetaDataDictionary.getInstance( );
		return dd.getPropertyType( typeCode );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getTypeCode()
	 */

	public int getTypeCode( )
	{
		PropertyType type = getType( );
		assert type != null;
		return type.getTypeCode( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#isIntrinsic()
	 */

	public boolean isIntrinsic( )
	{
		// all the extension property is not intrinsic

		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#isList()
	 */

	public boolean isList( )
	{
		return extMember.isList( );
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#setAllowedChoices(org.eclipse.birt.report.model.metadata.ChoiceSet)
	 */

	void setAllowedChoices( ChoiceSet allowedChoices )
	{
		assert false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#setDefault(java.lang.Object)
	 */

	protected void setDefault( Object value )
	{
		assert false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#setDetails(java.lang.Object)
	 */

	public void setDetails( Object obj )
	{
		assert false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#setDisplayNameID(java.lang.String)
	 */

	public void setDisplayNameID( String id )
	{
		assert false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#setIntrinsic(boolean)
	 */

	void setIntrinsic( boolean flag )
	{
		assert false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#setIsList(boolean)
	 */

	protected void setIsList( boolean isList )
	{
		assert false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#setName(java.lang.String)
	 */

	public void setName( String theName )
	{
		assert false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#setType(org.eclipse.birt.report.model.metadata.PropertyType)
	 */

	public void setType( PropertyType typeDefn )
	{
		assert false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#isExtended()
	 */

	public boolean isExtended( )
	{
		return true;
	}	

	/* (non-Javadoc)
	 * @see org.eclipse.birt.report.model.metadata.PropertyDefn#getValueType()
	 */
	public int getValueType( )
	{
		return EXTENSION_MODEL_PROPERTY;
	}
}