/**
 * File:    AbstractSingleStaticAspectPropertySection.java
 * Created: 28.07.2008
 *
 *
/*******************************************************************************
 * Copyright (c) 2008-2009 Open Wide SA <www.openwide.fr>
 *
 * 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:
 *    Marc Dutoo, Open Wide, Lyon, France
 *      - creation and implementation
 *******************************************************************************/

package org.eclipse.jwt.we.conf.we.editors.properties.tabbedPage.helpers;

import java.util.List;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jwt.we.conf.model.AspectInstance;
import org.eclipse.jwt.we.conf.model.aspects.AspectManager;
import org.eclipse.jwt.we.editors.properties.CustomAdapterFactoryContentProvider;
import org.eclipse.jwt.we.editors.properties.ModelPropertySourceProvider;
import org.eclipse.jwt.we.editors.properties.singlePage.ModelPropertySheetPage;
import org.eclipse.jwt.we.editors.properties.tabbedPage.TabbedModelPropertySheetPage;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

/**
 * This class defines a tab property section dedicated to displaying, of the
 * selected extensible model element, the first static (generated) aspect
 * instance whose class is an instance of the class returned by the
 * getAspectInstanceClass() method, which has to be overriden. More specific
 * behaviour can be supported by overriding getAspectInstance() .
 * 
 * @version $Id: AbstractSingleStaticAspectPropertySection.java,v 1.2 2009/12/16
 *          16:11:57 chsaad Exp $
 * @author Marc Dutoo, Open Wide SA, France <www.openwide.fr>
 * @since 0.6
 */
public abstract class AbstractSingleStaticAspectPropertySection extends
		AbstractPropertySection
{

	/**
	 * The Property Sheet Page.
	 */
	protected PropertySheetPage page;


	/**
	 * @see org.eclipse.ui.views.properties.tabbed.ISection#createControls(org.eclipse.swt.widgets.Composite,
	 *      org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
	 */
	public void createControls(Composite parent,
			TabbedPropertySheetPage tabbedPropertySheetPage)
	{
		super.createControls(parent, tabbedPropertySheetPage);
		Composite composite = getWidgetFactory().createFlatFormComposite(parent);
		TabbedModelPropertySheetPage tabbedModelPropertySheetPage = (TabbedModelPropertySheetPage) tabbedPropertySheetPage;
		AdapterFactory tabbedModelPropertySheetPageAf = tabbedModelPropertySheetPage
				.getAdapterFactory();
		page = new ModelPropertySheetPage(tabbedModelPropertySheetPageAf);

		page.createControl(composite);
		FormData data = new FormData();
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(100, 0);
		data.top = new FormAttachment(0, 0);
		data.bottom = new FormAttachment(100, 0);
		page.getControl().setLayoutData(data);

		page.setPropertySourceProvider(new ModelPropertySourceProvider(
				new CustomAdapterFactoryContentProvider(tabbedModelPropertySheetPageAf)));

	}


	/**
	 * @see org.eclipse.ui.views.properties.tabbed.ISection#setInput(org.eclipse.ui.IWorkbenchPart,
	 *      org.eclipse.jface.viewers.ISelection)
	 */
	public void setInput(IWorkbenchPart part, ISelection selection)
	{
		ISelection subselection = null;
		if (selection instanceof IStructuredSelection)
		{
			Object selectedObject = ((IStructuredSelection) selection).getFirstElement();
			if (selectedObject instanceof EObject)
			{ // TODO aspects marker
				EObject modelElement = (EObject) selectedObject;
				AspectInstance aspectInstance = getAspectInstance(modelElement);
				if (aspectInstance != null)
				{
					subselection = new StructuredSelection(aspectInstance);
				}
			}
		}
		if (subselection == null)
		{
			subselection = new StructuredSelection();
		}
		super.setInput(part, subselection);
		page.selectionChanged(part, subselection);
	}


	/**
	 * Use by the default behaviour of getAspectInstance()
	 * 
	 * @return the class of the static aspect to display
	 */
	@SuppressWarnings("unchecked")
	protected abstract Class getAspectInstanceClass();


	/**
	 * Can be overriden to fully customize wich aspect instance of the given
	 * extensible element is displayed in this section. By default, displays the
	 * first aspect instance that is an instance of the class returned by
	 * getAspectInstanceClass().
	 * 
	 * @param extensibleElement
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected AspectInstance getAspectInstance(EObject modelElement)
	{
		List<AspectInstance> aspectInstances = AspectManager.INSTANCE
				.getAspectInstances(modelElement);
		Class aspectInstanceClass = getAspectInstanceClass();
		for (AspectInstance aspectInstance : aspectInstances)
		{
			// checking the class and not the aspect id so it works whatever the
			// id
			if (aspectInstanceClass.isInstance(aspectInstance))
			{
				return aspectInstance;
			}
		}
		return null;
	}


	/**
	 * @see org.eclipse.ui.views.properties.tabbed.ISection#refresh()
	 */
	public void refresh()
	{
		page.refresh();
	}


	/**
	 * @see org.eclipse.ui.views.properties.tabbed.ISection#shouldUseExtraSpace()
	 */
	public boolean shouldUseExtraSpace()
	{
		return true;
	}


	/**
	 * @see org.eclipse.ui.views.properties.tabbed.ISection#dispose()
	 */
	public void dispose()
	{
		super.dispose();

		if (page != null)
		{
			page.dispose();
			page = null;
		}
	}
}