/*******************************************************************************
 * Copyright (c) 2006, 2007 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.ui.internal.details;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jpt.core.internal.IAttributeMapping;
import org.eclipse.jpt.core.internal.IJpaContentNode;
import org.eclipse.jpt.core.internal.IPersistentAttribute;
import org.eclipse.jpt.core.internal.JpaCorePackage;
import org.eclipse.jpt.ui.internal.JptUiMessages;
import org.eclipse.jpt.ui.internal.java.details.IAttributeMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.BasicMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.DefaultBasicMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.DefaultEmbeddedMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddedIdMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.EmbeddedMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.IdMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.ManyToManyMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.ManyToOneMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.NullAttributeMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.OneToManyMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.OneToOneMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.TransientMappingUiProvider;
import org.eclipse.jpt.ui.internal.java.mappings.properties.VersionMappingUiProvider;
import org.eclipse.jpt.ui.internal.widgets.CComboViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.part.PageBook;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;

public abstract class PersistentAttributeDetailsPage extends BaseJpaDetailsPage 
{
	private IPersistentAttribute attribute;
	private IAttributeMapping attributeMapping;
	private Adapter persistentAttributeListener;
	private Adapter attributeMappingListener;
	
	private String currentMappingKey;
	
	private CComboViewer mappingCombo;
	
	private Map<String, IJpaComposite<IAttributeMapping>> mappingComposites;
	protected PageBook mappingPageBook;	
	private IJpaComposite<IAttributeMapping> currentMappingComposite;
	
	/**
	 * These IAtttributeMappingUiProviders will be used as elements in the attributeMapping combo
	 * The first element in the combo will be one of the defaultAttributemappingUiProviders or
	 * if none of those apply the nullAttriubteMappingUiProvider will be used. The rest of the elements
	 * will be the attributeMappingUiProviders.  The defaultAttributeMappingUiProvider is
	 * determined by matching its key with the key of the current attriubteMapping.  
	 */
	private Collection<IAttributeMappingUiProvider> attributeMappingUiProviders;
	private Collection<IAttributeMappingUiProvider> defaultAttributeMappingUiProviders;
	private IAttributeMappingUiProvider nullAttributeMappingUiProvider;
	
	public PersistentAttributeDetailsPage(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory) {
		super(parent, SWT.NONE, new BasicCommandStack(), widgetFactory);
		persistentAttributeListener = buildAttributeListener();
		attributeMappingListener = buildAttributeMappingListener();
		mappingComposites = new HashMap<String, IJpaComposite<IAttributeMapping>>();
		this.attributeMappingUiProviders = buildAttributeMappingUiProviders();
		this.defaultAttributeMappingUiProviders = buildDefaultAttributeMappingUiProviders();
		this.nullAttributeMappingUiProvider = buildNullAttributeMappingUiProvider();
	}
	
	protected IAttributeMappingUiProvider buildNullAttributeMappingUiProvider() {
		return NullAttributeMappingUiProvider.instance();
	}
	
	protected Collection<IAttributeMappingUiProvider> buildAttributeMappingUiProviders() {
		Collection<IAttributeMappingUiProvider> providers = new ArrayList<IAttributeMappingUiProvider>();
		providers.add(BasicMappingUiProvider.instance());
		providers.add(EmbeddedMappingUiProvider.instance());
		providers.add(EmbeddedIdMappingUiProvider.instance());
		providers.add(IdMappingUiProvider.instance());			
		providers.add(ManyToManyMappingUiProvider.instance());			
		providers.add(ManyToOneMappingUiProvider.instance());			
		providers.add(OneToManyMappingUiProvider.instance());			
		providers.add(OneToOneMappingUiProvider.instance());
		providers.add(TransientMappingUiProvider.instance());
		providers.add(VersionMappingUiProvider.instance());
		return providers;
	}
	
	protected  Collection<IAttributeMappingUiProvider> attributeMappingUiProviders() {
		return this.attributeMappingUiProviders;
	}
	
	protected Collection<IAttributeMappingUiProvider> buildDefaultAttributeMappingUiProviders() {
		Collection<IAttributeMappingUiProvider> providers = new ArrayList<IAttributeMappingUiProvider>();
		providers.add(DefaultBasicMappingUiProvider.instance());		
		providers.add(DefaultEmbeddedMappingUiProvider.instance());		
		return providers;
	}
	
	protected  Collection<IAttributeMappingUiProvider> defaultAttributeMappingUiProviders() {
		return this.defaultAttributeMappingUiProviders;
	}
	
	private IAttributeMappingUiProvider attributeMappingUiProvider(String key) {
		for (IAttributeMappingUiProvider provider : attributeMappingUiProviders()) {
			if (provider.key() == key) {
				return provider;
			}
		}
		return this.nullAttributeMappingUiProvider;
	}
	private IAttributeMappingUiProvider defaultAttributeMappingUiProvider(String key) {
		for (IAttributeMappingUiProvider provider : defaultAttributeMappingUiProviders()) {
			if (provider.key() == key) {
				return provider;
			}
		}
		return this.nullAttributeMappingUiProvider;
	}
	
	private Adapter buildAttributeListener() {
		return new AdapterImpl() {
			@Override
			public void notifyChanged(Notification notification) {
				persistentAttributeChanged(notification);
			}
		};
	}
	
	void persistentAttributeChanged(Notification notification) {
		switch (notification.getFeatureID(IPersistentAttribute.class)) {
			case JpaCorePackage.IPERSISTENT_ATTRIBUTE__MAPPING:
				Display.getDefault().asyncExec(
					new Runnable() {
						public void run() {
							populate();
						}
					});
				break;
		}
	}
	
	private Adapter buildAttributeMappingListener() {
		return new AdapterImpl() {
			@Override
			public void notifyChanged(Notification notification) {
				attributeMappingChanged(notification);
			}
		};
	}
	
	void attributeMappingChanged(Notification notification) {
//		switch (notification.getFeatureID(IAttributeMapping.class)) {
//			case JpaCorePackage.IATTRIBUTE_MAPPING__DEFAULT:
//				Display.getDefault().asyncExec(
//					new Runnable() {
//						public void run() {
//							populate();
//						}
//					});
//				break;
//		}
	}
		
	protected Label buildMappingLabel(Composite parent) {
		return getWidgetFactory().createLabel(parent, JptUiMessages.PersistentAttributePage_mapAs);
	}
	
	protected CComboViewer buildMappingCombo(Composite parent) {
		CCombo combo = getWidgetFactory().createCCombo(parent);
		mappingCombo = new CComboViewer(combo);
		mappingCombo.setContentProvider(buildContentProvider());
		mappingCombo.setLabelProvider(buildLabelProvider());
		mappingCombo.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				mappingChanged(event);
			}
		});
		return mappingCombo;
	}

	private IContentProvider buildContentProvider() {
		return new IStructuredContentProvider() {
			public void dispose() {
				// do nothing
			}
			
			public Object[] getElements(Object inputElement) {
				if (inputElement == null) {
					return new Object[]{};
				}
				return uiProvidersFor((IPersistentAttribute) inputElement);
			}
			
			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
				// do nothing
			}
		};
	}
	
	protected IAttributeMappingUiProvider[] uiProvidersFor(IPersistentAttribute persistentAttribute) {
		IAttributeMappingUiProvider[] providers = new IAttributeMappingUiProvider[attributeMappingUiProviders().size() +1];
		providers[0] =  this.nullAttributeMappingUiProvider;
		for (IAttributeMappingUiProvider uiProvider : defaultAttributeMappingUiProviders()) {
			if (uiProvider.key() == persistentAttribute.defaultMappingKey()) {
				providers[0] = uiProvider;
				break;
			}
		}
		int i = 1;
		for (IAttributeMappingUiProvider uiProvider : attributeMappingUiProviders()) {
			providers[i++] = uiProvider;
		}
		return providers;
	}

	private IBaseLabelProvider buildLabelProvider() {
		return new LabelProvider() {
			@Override
			public String getText(Object element) {
				return ((IAttributeMappingUiProvider) element).label();
			}
		};
	}
	
	protected PageBook buildMappingPageBook(Composite parent) {
		mappingPageBook = new PageBook(parent, SWT.NONE);
		return mappingPageBook;
	}
	
	protected IJpaComposite<IAttributeMapping> buildMappingComposite(PageBook pageBook, String key) {
		if (this.attributeMapping == null || this.attributeMapping.isDefault()) {
			return defaultAttributeMappingUiProvider(key).buildAttributeMappingComposite(pageBook, this.commandStack, getWidgetFactory());
		}

		return attributeMappingUiProvider(key).buildAttributeMappingComposite(pageBook, this.commandStack, getWidgetFactory());
	}
		
	void mappingChanged(SelectionChangedEvent event) {
		if (isPopulating()) {
			return;
		}
		if (event.getSelection() instanceof StructuredSelection) {
			IAttributeMappingUiProvider provider = (IAttributeMappingUiProvider) ((StructuredSelection) event.getSelection()).getFirstElement();
			String key = (this.defaultAttributeMappingUiProviders().contains(provider) ? null : provider.key());
			attribute.setSpecifiedMappingKey(key);
		}
	}
	
	@Override
	protected void doPopulate(IJpaContentNode persistentAttributeNode) {
		attribute = (IPersistentAttribute) persistentAttributeNode;
		populateMappingComboAndPage();
	}
	
	@Override
	protected void doPopulate() {
		populateMappingComboAndPage();
	}
	
	@Override
	protected void engageListeners() {
		if (attribute != null) {
			attribute.eAdapters().add(persistentAttributeListener);
			if (attributeMapping != null) {
				attributeMapping.eAdapters().add(attributeMappingListener);
			}
		}
	}
	
	@Override
	protected void disengageListeners() {
		if (attribute != null) {
			attribute.eAdapters().remove(persistentAttributeListener);
			if (attributeMapping != null) {
				attributeMapping.eAdapters().remove(attributeMappingListener);
			}
		}
	}
	
	private void populateMappingComboAndPage() {
		if (attribute == null) {
			attributeMapping = null;
			currentMappingKey = null;
			mappingCombo.setInput(null);
			mappingCombo.setSelection(StructuredSelection.EMPTY);
			
			if (currentMappingComposite != null) {
				currentMappingComposite.populate(null);
				currentMappingComposite = null;
			}
			
			return;
		}
		attributeMapping = attribute.getMapping();
		setComboData(attribute.candidateMappingKeys());
		
		populateMappingPage(attributeMapping == null ? null : attributeMapping.getKey());
	}
	
	private void populateMappingPage(String mappingKey) {
		if (currentMappingComposite != null) {
			if (mappingKey == currentMappingKey) {
				if (currentMappingComposite != null) {
					currentMappingComposite.populate(attributeMapping);
					return;
				}
			}
			else {
				currentMappingComposite.populate(null);
				// don't return
			}
		}
		
		currentMappingKey = mappingKey;
		
		IJpaComposite<IAttributeMapping> composite = mappingCompositeFor(mappingKey);
		mappingPageBook.showPage(composite.getControl());
		
		currentMappingComposite = composite;
		currentMappingComposite.populate(attributeMapping);
	}
	
	private void setComboData(Iterator<String> availableMappingKeys) {
		if (attribute != mappingCombo.getInput()) {
			mappingCombo.setInput(attribute);
		}
		if (attributeMapping == null || attributeMapping.isDefault()) {
			mappingCombo.setSelection(new StructuredSelection(mappingCombo.getElementAt(0)));
		}
		else {
			IAttributeMappingUiProvider provider = attributeMappingUiProvider(attribute.mappingKey());
			if (provider != null && ! provider.equals(((StructuredSelection) mappingCombo.getSelection()).getFirstElement())) {
				mappingCombo.setSelection(new StructuredSelection(provider));
			}
		}
	}
	
	private IJpaComposite<IAttributeMapping> mappingCompositeFor(String key) {
		IJpaComposite<IAttributeMapping> composite = mappingComposites.get(key);
		if (composite != null) {
			return composite;
		}
		
		composite = buildMappingComposite(mappingPageBook, key);
		
		if (composite != null) {
			mappingComposites.put(key, composite);
		}
		
		return composite;
	}
		
//TODO focus??
//	public boolean setFocus() {
//		super.setFocus();
//		return mappingCombo.getCombo().setFocus();
//	}
	
	@Override
	public void dispose() {
		disengageListeners();
		for (Iterator<IJpaComposite<IAttributeMapping>> stream = mappingComposites.values().iterator(); stream.hasNext(); ) {
			stream.next().dispose();
		}
		super.dispose();
	}
	
	public IPersistentAttribute getAttribute() {
		return attribute;
	}
	

}
