/*******************************************************************************
 * Copyright (c) 2008, 2012 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.jpa.ui.internal.editors;

import java.util.ListIterator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jpt.common.core.JptResourceType;
import org.eclipse.jpt.common.ui.WidgetFactory;
import org.eclipse.jpt.common.ui.internal.widgets.FormWidgetFactory;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.model.value.ListAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.ListPropertyValueModelAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.TransformationPropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.ListValueModel;
import org.eclipse.jpt.common.utility.model.value.ModifiablePropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.context.JpaRootContextNode;
import org.eclipse.jpt.jpa.core.context.persistence.Persistence;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceXml;
import org.eclipse.jpt.jpa.ui.JpaPlatformUi;
import org.eclipse.jpt.jpa.ui.PersistenceXmlResourceUiDefinition;
import org.eclipse.jpt.jpa.ui.details.JpaPageComposite;
import org.eclipse.jpt.jpa.ui.internal.persistence.JptUiPersistenceMessages;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
import org.eclipse.wst.sse.ui.StructuredTextEditor;

/**
 * This is the editor for the JPA Persistence Configuration (persistence.xml).
 * The pages shown before the XML source editor are retrieved from the
 * <code>JpaUiFactory</code>.
 *
 * @version 2.3
 * @since 2.0
 */
@SuppressWarnings("nls")
public class PersistenceEditor
	extends FormEditor
{
	/**
	 * The XML text editor.
	 */
	private StructuredTextEditor editor;

	/**
	 * The root of the holders used to retrieve the persistence unit and be
	 * notified when it changes.
	 */
	private ModifiablePropertyValueModel<IFileEditorInput> editorInputHolder;

	/**
	 * The factory used to create the various widgets.
	 */
	private WidgetFactory widgetFactory;

	final ResourceManager resourceManager;

	/**
	 * Creates a new <code>PersistenceEditor</code>.
	 */
	public PersistenceEditor() {
		super();
		this.resourceManager = new LocalResourceManager(JFaceResources.getResources());
		initialize();
	}

	/**
	 * Delegate to the {@link #editor} if necessary.
	 */
	@Override
	public Object getAdapter(@SuppressWarnings("rawtypes") Class adapterClass) {
		Object adapter = super.getAdapter(adapterClass);
		return (adapter != null) ? adapter : this.editor.getAdapter(adapterClass);
	}

	@Override
	protected void addPages() {
		addPersistenceUnitPages();
		addXMLEditorPage();
	}

	/**
	 * Adds the pages that show the properties of the persistence configuration
	 * or its persistence units.
	 */
	private void addPersistenceUnitPages() {

		JpaProject jpaProject = getJpaProject();

		// The project doesn't have JPA
		if (jpaProject == null) {
			return;
		}

		PersistenceXml persistenceXml = jpaProject.getRootContextNode().getPersistenceXml();
		if (persistenceXml == null) {
			return;
		}
		JptResourceType resourceType = persistenceXml.getResourceType();
		if (resourceType == null) {
			return;  // might not ever get here... (if we have a p.xml, it probably has a resource type...)
		}
		JpaPlatformUi jpaPlatformUI = (JpaPlatformUi) jpaProject.getJpaPlatform().getAdapter(JpaPlatformUi.class);
		PersistenceXmlResourceUiDefinition definition = 
			(PersistenceXmlResourceUiDefinition) jpaPlatformUI.getResourceUiDefinition(resourceType);

		ListIterator<JpaPageComposite> puPages = definition.buildPersistenceUnitComposites(
			buildPersistenceUnitHolder(),
			getContainer(),
			this.widgetFactory
		);

		while (puPages.hasNext()) {
			JpaPageComposite page = puPages.next();

			try {
				FormPage formPage = new Page(page);
				addPage(formPage);
			}
			catch (PartInitException e) {
				// TODO
			}
		}
	}

	/**
	 * Adds the page containing the XML editor.
	 */
	private void addXMLEditorPage() {
		try {
			editor = new StructuredTextEditor();
			editor.setEditorPart(this);
			int index = addPage(editor, getEditorInput());
			setPageText(index, JptUiPersistenceMessages.PersistenceEditor_sourceTab);
		}
		catch (PartInitException e) {
			// TODO
		}
	}

	private ModifiablePropertyValueModel<IFileEditorInput> buildEditorInputHolder() {
		return new SimplePropertyValueModel<IFileEditorInput>();
	}

	private PropertyValueModel<JpaProject> buildJpaProjectHolder() {
		return new TransformationPropertyValueModel<IFileEditorInput, JpaProject>(this.editorInputHolder) {
			@Override
			protected JpaProject transform_(IFileEditorInput fileEditorInput) {
				return PersistenceEditor.this.getJpaProject(fileEditorInput.getFile().getProject());
			}
		};
	}

	private PropertyValueModel<Persistence> buildPersistenceHolder() {
		return new PropertyAspectAdapter<PersistenceXml, Persistence>(buildPersistenceXmlHolder(), PersistenceXml.PERSISTENCE_PROPERTY) {
			@Override
			protected Persistence buildValue_() {
				return subject.getPersistence();
			}
		};
	}

	private PropertyValueModel<PersistenceUnit> buildPersistenceUnitHolder() {
		return new ListPropertyValueModelAdapter<PersistenceUnit>(buildPersistenceUnitListHolder()) {
			@Override
			protected PersistenceUnit buildValue() {
				return listModel.size() > 0 ? (PersistenceUnit) listModel.get(0) : null;
			}
		};
	}

	private ListValueModel<PersistenceUnit> buildPersistenceUnitListHolder() {
		return new ListAspectAdapter<Persistence, PersistenceUnit>(buildPersistenceHolder(), Persistence.PERSISTENCE_UNITS_LIST) {
			@Override
			protected ListIterable<PersistenceUnit> getListIterable() {
				return subject.getPersistenceUnits();
			}

			@Override
			protected int size_() {
				return subject.getPersistenceUnitsSize();
			}
		};
	}

	private PropertyValueModel<PersistenceXml> buildPersistenceXmlHolder() {
		return new PropertyAspectAdapter<JpaRootContextNode, PersistenceXml>(buildRootContextNodeHolder(), JpaRootContextNode.PERSISTENCE_XML_PROPERTY) {
			@Override
			protected PersistenceXml buildValue_() {
				return subject.getPersistenceXml();
			}
		};
	}

	private PropertyValueModel<JpaRootContextNode> buildRootContextNodeHolder() {
		return new TransformationPropertyValueModel<JpaProject, JpaRootContextNode>(buildJpaProjectHolder()) {
			@Override
			protected JpaRootContextNode transform_(JpaProject jpaProject) {
				return jpaProject.getRootContextNode();
			}
		};
	}

	private WidgetFactory buildWidgetFactory() {
		return new FormWidgetFactory(
			new TabbedPropertySheetWidgetFactory()
		);
	}

	@Override
	public void dispose() {
		this.editorInputHolder.setValue(null);
		this.resourceManager.dispose();
		super.dispose();
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		getEditor(getPageCount() - 1).doSave(monitor);
	}

	@Override
	public void doSaveAs() {
		// do nothing
	}

	@Override
	public IFileEditorInput getEditorInput() {
		return (IFileEditorInput) super.getEditorInput();
	}

	@Override
	public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
		Assert.isLegal(editorInput instanceof IFileEditorInput, "Invalid Input: Must be IFileEditorInput");
		super.init(site, editorInput);

		setPartName(editorInput.getName());
		editorInputHolder.setValue(getEditorInput());
	}

	/**
	 * Initializes this multi-page editor.
	 */
	private void initialize() {

		widgetFactory      = buildWidgetFactory();
		editorInputHolder  = buildEditorInputHolder();
	}

	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	/**
	 * Retrieves the JPA project associated with the project owning the editor
	 * intput file.
	 *
	 * @return The JPA project
	 */
	protected JpaProject getJpaProject() {
		return this.getJpaProject(getEditorInput().getFile().getProject());
	}

	protected JpaProject getJpaProject(IProject project) {
		return (JpaProject) project.getAdapter(JpaProject.class);
	}

	/**
	 * This extension over <code>FormPage</code> simply complete the layout by
	 * using the <code>JpaPageComposite</code>'s control as its form content.
	 */
	class Page
		extends FormPage
	{
		/**
		 * The wrapped page that actually contains the widgets to show with this
		 * form page.
		 */
		private final JpaPageComposite page;

		private ImageDescriptor imageDescriptor;

		/**
		 * Creates a new <code>Page</code>.
		 *
		 * @param page The wrapped <code>JpaPageComposite</code>
		 */
		Page(JpaPageComposite page) {

			super(PersistenceEditor.this,
			      page.getClass().getName(),
			      page.getPageText());

			this.page = page;
		}

		@Override
		protected void createFormContent(IManagedForm managedForm) {

			ScrolledForm form = managedForm.getForm();
			managedForm.getToolkit().decorateFormHeading(form.getForm());

			// Update the text and image
			updateForm(form);

			// Update the layout
			updateBody(form);

			// This will finish the initialization of the buttons
			updateHelpButton();
			form.updateToolBar();
		}

		@Override
		public void dispose() {
			this.page.dispose();
			if (this.imageDescriptor != null) {
				PersistenceEditor.this.resourceManager.destroyImage(this.imageDescriptor);
			}
			super.dispose();
		}

		@Override
		public void setFocus() {
			this.page.getControl().setFocus();
		}

		/**
		 * Adds the page's control to this page.
		 *
		 * @param form The form containing the composite with which the page's
		 * control is parented
		 */
		private void updateBody(ScrolledForm form) {

			Composite body = form.getBody();

			body.setLayout(new TableWrapLayout());

			TableWrapData wrapData = new TableWrapData(
				TableWrapData.FILL_GRAB,
				TableWrapData.FILL_GRAB
			);

			this.page.getControl().setLayoutData(wrapData);
			this.page.getControl().setParent(body);
		}

		/**
		 * Updates the text and image of the form.
		 *
		 * @param form The form to have its title bar updated by setting the text
		 * and image, the image can be <code>null</code>
		 */
		private void updateForm(ScrolledForm form) {
			form.setText(this.page.getPageText());

			this.imageDescriptor = this.page.getPageImageDescriptor();
			if (this.imageDescriptor != null) {
				form.setImage(PersistenceEditor.this.resourceManager.createImage(this.imageDescriptor));
			}
		}

		/**
		 * Adds a help button to the page's toolbar if a help ID exists.
		 */
		private void updateHelpButton() {

			String helpID = this.page.getHelpID();

			if (helpID != null) {
				Action helpAction = new HelpAction(helpID);

				ScrolledForm form = getManagedForm().getForm();
				IToolBarManager manager = form.getToolBarManager();
				manager.add(helpAction);
			}
		}

		private class HelpAction
			extends Action
		{
			final String helpID;

			HelpAction(String helpID) {
				super(JptUiPersistenceMessages.PersistenceEditor_page_help,
				      JFaceResources.getImageRegistry().getDescriptor(Dialog.DLG_IMG_HELP));

				this.helpID = helpID;
			}

			@Override
			public void run() {
				BusyIndicator.showWhile(getManagedForm().getForm().getDisplay(), new Runnable() {
					public void run() {
						PlatformUI.getWorkbench().getHelpSystem().displayHelp(helpID);
					}
				});
			}
		}
	}
}