/*******************************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *	   David Schneider, david.schneider@unisys.com - [142500] WTP properties pages fonts don't follow Eclipse preferences
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jst.j2ee.application.internal.operations.ClasspathElement;
import org.eclipse.jst.j2ee.internal.common.ClasspathModel;
import org.eclipse.jst.j2ee.internal.common.ClasspathModelListener;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.frameworks.internal.ui.WorkspaceModifyComposedOperation;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;

public class WebLibDependencyPropertiesPage extends JARDependencyPropertiesPage implements IClasspathTableOwner, Listener, ClasspathModelListener {

	public WebLibDependencyPropertiesPage(final IProject project, final J2EEDependenciesPage page) {
		super(project, page);
	}

	protected ClasspathModel createClasspathModel() {
		return new ClasspathModel(null, true);
	}
	
	public Composite createContents(Composite parent) {
		initialize();
		Composite composite = createBasicComposite(parent);
		if (model.getComponent() != null) {
			if (!isValidWebModule())
				return composite;
			J2EEDependenciesPage.createDescriptionComposite(composite, ManifestUIResourceHandler.Web_Libraries_Desc);
			// createProjectLabelsGroup(composite);
			createListGroup(composite);
			handleWLPSupport();
			setEnablement();
		}
	    Dialog.applyDialogFont(parent);
	    postCreateContents();
		return composite;
	}

	protected void createProjectLabelsGroup(Composite parent) {

		Composite labelsGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		labelsGroup.setLayout(layout);
		labelsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		Label label = new Label(labelsGroup, SWT.NONE);
		label.setText(ManifestUIResourceHandler.Project_name__UI_);

		componentNameText = new Text(labelsGroup, SWT.BORDER);
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		componentNameText.setEditable(false);
		componentNameText.setLayoutData(data);
		componentNameText.setText(project.getName());
	}

	protected void createListGroup(Composite parent) {
		Composite listGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		listGroup.setLayout(layout);
		GridData gData = new GridData(GridData.FILL_BOTH);
		gData.horizontalIndent = 5;
		listGroup.setLayoutData(gData);

		availableDependentJars = new Label(listGroup, SWT.NONE);
		gData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		availableDependentJars.setText(ManifestUIResourceHandler.Available_dependent_JARs__UI_);
		availableDependentJars.setLayoutData(gData);
		createTableComposite(listGroup);
	}

	protected void createTableComposite(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		GridData gData = new GridData(GridData.FILL_BOTH);
		composite.setLayoutData(gData);
		tableManager = new ClasspathTableManager(this, model, validateEditListener);
		tableManager.fillWLPComposite(composite);
	}

	protected boolean isValidWebModule() {
		if (!J2EEProjectUtilities.isDynamicWebProject(project)) {
			propPage.setErrorMessage(ManifestUIResourceHandler.Web_Lib_Error);
			return false;
		}
		return true;
	}
	private boolean equals(final Object obj1, final Object obj2) {
		if (obj1 == obj2) {
			return true;
		} else if (obj1 == null || obj2 == null) {
			return false;
		} else {
			return obj1.equals(obj2);
		}
	}

	protected void setEnablement() {
		if (tableManager.availableJARsViewer.getTable().getItems().length == 0) {
			tableManager.selectAllButton.setEnabled(false);
			tableManager.deselectAllButton.setEnabled(false);
		} else {
			tableManager.selectAllButton.setEnabled(true);
			tableManager.deselectAllButton.setEnabled(true);
		}
	}
	private IProgressMonitor submon(final IProgressMonitor parent, final int ticks) {
		return (parent == null ? null : new SubProgressMonitor(parent, ticks));
	}

	private void handleWLPSupport() {
		availableDependentJars.setText(ManifestUIResourceHandler.WEB_LIB_LIST_DESCRIPTION);
		tableManager.refresh();
	}
	
	@Override
	protected void handleClasspathChange() {
		model.resetClassPathSelectionForWLPs();
		super.handleClasspathChange();
		setEnablement();
	}

	public boolean performOk() {
		if (model.getComponent() == null || !isValidWebModule()) {
			return true;
		}
		if (!isDirty) {
			return true;
		}
		try {
			IProject[] javaProjects = getJavaProjectsWithoutFacets();
			boolean createdFlexProjects = runWLPOp(createFlexProjectOperations());
			
			boolean createdComponentDependency = false;
			if (createdFlexProjects) {
				addTargetRuntimesToNewJavaProjects(javaProjects,new NullProgressMonitor());
				createdComponentDependency = runWLPOp(createComponentDependencyOperations());
				isDirty = false;
			}
			// treat as a classpath change for refresh purposes
			// XXX this refresh is not working - suspect it is because the virtual component dependencies are
			// not consistently being recomputed
			//handleClasspathChange();
			return createdComponentDependency;
		} finally {
			model.dispose();
		}
	}

	private IProject[] getJavaProjectsWithoutFacets() {
		List projectsList = new ArrayList();
		Object[] elements = tableManager.availableJARsViewer.getCheckedElements();
		for (int i = 0; i < elements.length; i++) {
			ClasspathElement element = (ClasspathElement) elements[i];
			IProject elementProject = element.getProject();
			try {
				if (elementProject != null && !elementProject.hasNature(IModuleConstants.MODULE_NATURE_ID))
					projectsList.add(elementProject);
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				J2EEPlugin.getDefault().logError(e);
			}
		}
		return (IProject[])projectsList.toArray(new IProject[projectsList.size()]);
	}

	private boolean runWLPOp(WorkspaceModifyComposedOperation composed) {
		try {
			if (composed != null)
				new ProgressMonitorDialog(propPage.getShell()).run(true, true, composed);
		} catch (InvocationTargetException ex) {
			ex.printStackTrace();
			if (ex.getCause() != null) {
				ex.getCause().printStackTrace();
			}
			String title = ManifestUIResourceHandler.An_internal_error_occurred_ERROR_;
			String msg = title;
			if (ex.getTargetException() != null && ex.getTargetException().getMessage() != null)
				msg = ex.getTargetException().getMessage();
			MessageDialog.openError(propPage.getShell(), title, msg);
			org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ex);
			return false;
		} catch (InterruptedException e) {
			// cancelled
			return false;
		}
		return true;
	}

	private void addTargetRuntimesToNewJavaProjects(IProject[] javaProjects, final IProgressMonitor monitor )

	{
		if (monitor != null) {
			monitor.beginTask("", 1);
		}
		IProject targetProject = project;
		for (int i = 0; i < javaProjects.length; i++) {
			IProject moduleProject = javaProjects[i];

			try {
				final IFacetedProject targetFacetedProject = ProjectFacetsManager.create(targetProject);

				final IRuntime targetRuntime = targetFacetedProject.getRuntime();

				final IFacetedProject moduleFacetedProject = ProjectFacetsManager.create(moduleProject);

				if (moduleFacetedProject != null && !equals(targetRuntime, moduleFacetedProject.getRuntime())) {
					boolean supports = true;

					if (targetRuntime != null) {
						for (Iterator itr = moduleFacetedProject.getProjectFacets().iterator(); itr.hasNext();) {
							final IProjectFacetVersion fver = (IProjectFacetVersion) itr.next();

							if (!targetRuntime.supports(fver)) {
								supports = false;
								break;
							}
						}
					}

					if (supports) {
						moduleFacetedProject.setRuntime(targetRuntime, submon(monitor, 1));
					}
				}
			} catch(CoreException ex) {
				J2EEPlugin.getDefault().logError(ex);
			} finally {
				if (monitor != null) {
					monitor.done();
				}
			}
		}
	}

	private void createRef(String aComponentName){
		IVirtualComponent archive = ComponentCore.createArchiveComponent(model.getComponent().getProject(), aComponentName);

		// To do: check if archive component already exists
		IVirtualReference ref = ComponentCore.createReference(model.getComponent(), archive, new Path("/WEB-INF/lib")); //$NON-NLS-1$
		model.getComponent().addReferences(new IVirtualReference [] { ref });

		ClasspathElement element = createClassPathElement(archive, archive.getName());
//		ClassPathSelection selection = createClassPathSelectionForExternalJar(element);
		model.getClassPathSelectionForWLPs().getClasspathElements().add(element);
	}
	
	public void handleSelectExternalJarButton() {
		if (J2EEProjectUtilities.isDynamicWebProject(project)) {
			IPath[] selected = BuildPathDialogAccess.chooseExternalJAREntries(propPage.getShell());
			if (selected != null) {
				String type = VirtualArchiveComponent.LIBARCHIVETYPE + IPath.SEPARATOR;
				for (int i = 0; i < selected.length; i++) {
					createRef(type + selected[i].toString());
				}
				refresh();
			}
		}
	}

	public void handleSelectVariableButton() {
		if (J2EEProjectUtilities.isDynamicWebProject(project)) {
			IPath existingPath[] = new Path[0];
			IPath[] selected = BuildPathDialogAccess.chooseVariableEntries(propPage.getShell(), existingPath);

			if (selected != null) {
				String type = VirtualArchiveComponent.VARARCHIVETYPE + IPath.SEPARATOR;
				for (int i = 0; i < selected.length; i++) {
					IPath resolvedPath = JavaCore.getResolvedVariablePath(selected[i]);
					java.io.File file = new java.io.File(resolvedPath.toOSString());
					if (file.isFile() && file.exists()) {
						createRef(type + selected[i].toString());
					} else {
						// display error
					}
				}
				refresh();
			}
		}
	}

	private ClasspathElement createClassPathElement(IVirtualComponent archiveComp, String unresolvedName) {

		URI uri = URI.createURI(ModuleURIUtil.getHandleString(archiveComp));
		ClasspathElement element = new ClasspathElement(uri);
		element.setValid(false);
		element.setSelected(true);
		element.setRelativeText(unresolvedName);
		element.setText(unresolvedName);
		element.setEarProject(null);
		return element;
	}

//	private ClassPathSelection createClassPathSelectionForExternalJar(ClasspathElement element) {
//		ClassPathSelection selection = new ClassPathSelection();
//		selection.getClasspathElements().add(element);
//		return selection;
//	}

//	private ClassPathSelection createClassPathSelectionForProjectJar(ClasspathElement element) {
//		ClassPathSelection selection = new ClassPathSelection();
//		selection.getClasspathElements().add(element);
//		return selection;
//	}

	public void handleSelectProjectJarButton() {
		if (J2EEProjectUtilities.isDynamicWebProject(project)) {
			IPath[] selected = BuildPathDialogAccess.chooseJAREntries(propPage.getShell(), project.getLocation(), new IPath[0]);
			if (selected != null) {
				String type = VirtualArchiveComponent.LIBARCHIVETYPE + IPath.SEPARATOR;
				for (int i = 0; i < selected.length; i++) {
					createRef(type + selected[i].makeRelative().toString());
				}
				refresh();
			}
		}

	}
}
