/*******************************************************************************
 * Copyright (c) 2005, 2006 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
 *******************************************************************************/
/*


 */
package org.eclipse.jem.internal.beaninfo.ui;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.*;
import java.util.List;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.ui.ISharedImages;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;

import org.eclipse.jem.internal.beaninfo.adapters.BeaninfoNature;
import org.eclipse.jem.internal.beaninfo.core.*;
import org.eclipse.jem.internal.ui.core.JEMUIPlugin;

public class BeaninfoPathsBlock {

	//private Shell sShell1 = null;  //  @jve:decl-index=0:visual-constraint="40,19"
	private Composite top = null;
	private TabFolder tabFolder = null;
	private Button enableBeaninfoCheckbox = null;
	private PackagesWorkbookPage packagesWorkbookPage2 = null;
	private SearchpathOrderingWorkbookPage searchpathOrderingWorkbookPage2 = null;
	private BeaninfosWorkbookPage beaninfosPropertyPage2 = null;
	private Control packagesPageControl = null;
	private Control searchpathPageControl = null;
	private Control beaninfosPageControl = null;
	private Image packagesTabImage;
	private Image beaninfosTabImage;
	private Image searchPathTabImage;
	// ...ui
	
	private IWorkspaceRoot workspaceRoot;
	private IStatusChangeListener statusChangeListener;
	private IBuildSearchPage currentPage;
	private IJavaProject javaProject;
	private boolean enableBeaninfo = true;
	
	public BeaninfoPathsBlock(IWorkspaceRoot workspaceRoot, IStatusChangeListener statusChangeListener){
		this.workspaceRoot = workspaceRoot;
		this.statusChangeListener = statusChangeListener;
	}
	
	private void setEnableBeaninfo(boolean enable){
		enableBeaninfo = enable;
		if(enableBeaninfoCheckbox!=null && !enableBeaninfoCheckbox.isDisposed())
			enableBeaninfoCheckbox.setSelection(enable);
	}
	
//	/**
//	 * This method initializes sShell1	
//	 *
//	 */
//	private void createSShell1() {
//		sShell1 = new Shell();
//		sShell1.setLayout(new FillLayout());
//		createTop();
//		sShell1.setSize(new org.eclipse.swt.graphics.Point(403,289));
//	}

	/**
	 * This method initializes top	
	 *
	 */
	public Control createControl(Composite parent) {
		top = new Composite(parent, SWT.NONE);
		top.setLayout(new GridLayout());
		createTabFolder();
		enableBeaninfoCheckbox = new Button(top, SWT.CHECK);
		enableBeaninfoCheckbox.setText(BeanInfoUIMessages.BeaninfoPathsBlock_UI__enablebeaninfo);
		enableBeaninfoCheckbox.addSelectionListener(new org.eclipse.swt.events.SelectionListener() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				enableBeaninfo = enableBeaninfoCheckbox.getSelection();
				packagesWorkbookPage2.setBeaninfoEnabled(enableBeaninfo);
				beaninfosPropertyPage2.setBeaninfoEnabled(enableBeaninfo);
				searchpathOrderingWorkbookPage2.setBeaninfoEnabled(enableBeaninfo);
			}
			public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {
				widgetSelected(e);
			}
		});
		enableBeaninfoCheckbox.setSelection(enableBeaninfo);
		if(javaProject!=null){
			getPackagesPage().init(javaProject);
			getBeaninfosPage().init(javaProject);
			getSearchpathOrderingPage().init(javaProject);
		}
		return top;
	}

	/**
	 * This method initializes tabFolder	
	 *
	 */
	private void createTabFolder() {
		GridData gridData = new org.eclipse.swt.layout.GridData();
		gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace = true;
		gridData.verticalAlignment = org.eclipse.swt.layout.GridData.FILL;
		tabFolder = new TabFolder(top, SWT.NONE);
		tabFolder.setLayoutData(gridData);
		createPackagesWorkbookPage2();
		createBeaninfosPropertyPage2();
		createSearchpathOrderingWorkbookPage2();
		tabFolder.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
			public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
				tabChanged(e.item);
			}
		});
				
		TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setText(BeanInfoUIMessages.BeanInfoPathsBlock_Page_Tab_Packages);
		tabItem.setImage(getPackagesTabImage());
		tabItem.setControl(packagesPageControl);
		TabItem tabItem1 = new TabItem(tabFolder, SWT.NONE);
		tabItem1.setText(BeanInfoUIMessages.BeanInfoPathsBlock_Page_Tab_Classes);
		tabItem1.setImage(getBeaninfosTabImage());
		tabItem1.setControl(beaninfosPageControl);
		TabItem tabItem2 = new TabItem(tabFolder, SWT.NONE);
		tabItem2.setImage(getSearchPathTabImage());
		tabItem2.setText(BeanInfoUIMessages.BeaninfoPathsBlock_UI__serachpath_tab_order);
		tabItem2.setControl(searchpathPageControl);
		tabFolder.setSelection(2);
	}

	private Image getSearchPathTabImage() {
		if(searchPathTabImage==null)
			searchPathTabImage = JEMUIPlugin.imageDescriptorFromPlugin(JEMUIPlugin.getPlugin().getBundle().getSymbolicName(), "icons/cp_order_obj.gif").createImage(); //$NON-NLS-1$
		return searchPathTabImage;
	}

	private Image getPackagesTabImage() {
		if(packagesTabImage==null)
			packagesTabImage = JavaUI.getSharedImages().getImage(ISharedImages.IMG_OBJS_PACKAGE);
		return packagesTabImage;
	}
	
	private Image getBeaninfosTabImage(){
		if(beaninfosTabImage==null){
			URL imageURL = FileLocator.find(JEMUIPlugin.getPlugin().getBundle(), new Path("icons/javabean.gif"), null); //$NON-NLS-1$
			if (imageURL != null) 
				beaninfosTabImage = ImageDescriptor.createFromURL(imageURL).createImage();
			else
				beaninfosTabImage = ImageDescriptor.getMissingImageDescriptor().createImage();
		}
		return beaninfosTabImage;
	}

	/**
	 * This method initializes packagesWorkbookPage2	
	 *
	 */
	private void createPackagesWorkbookPage2() {
		packagesPageControl = getPackagesPage().createControl(tabFolder);
	}

	/**
	 * This method initializes searchpathOrderingWorkbookPage2	
	 *
	 */
	private void createSearchpathOrderingWorkbookPage2() {
		searchpathPageControl = getSearchpathOrderingPage().createControl(tabFolder);
		searchpathPageControl.addDisposeListener(new org.eclipse.swt.events.DisposeListener() {
			public void widgetDisposed(org.eclipse.swt.events.DisposeEvent e) {
				if(searchPathTabImage!=null){
					if(!searchPathTabImage.isDisposed())
						searchPathTabImage.dispose();
					searchPathTabImage=null;
				}
			}
		});
	}

	/**
	 * This method initializes beaninfosPropertyPage2	
	 *
	 */
	private void createBeaninfosPropertyPage2() {
		beaninfosPageControl = getBeaninfosPage().createControl(tabFolder);
		beaninfosPageControl.addDisposeListener(new org.eclipse.swt.events.DisposeListener() {
			public void widgetDisposed(org.eclipse.swt.events.DisposeEvent e) {
				if(beaninfosTabImage!=null){
					if(!beaninfosTabImage.isDisposed())
						beaninfosTabImage.dispose();
					beaninfosTabImage=null;
				}
			}
		});
	}

	PackagesWorkbookPage getPackagesPage(){
		if(packagesWorkbookPage2==null)
			packagesWorkbookPage2 = new PackagesWorkbookPage(workspaceRoot, this);
		return packagesWorkbookPage2;
	}
	
	BeaninfosWorkbookPage getBeaninfosPage(){
		if(beaninfosPropertyPage2==null)
			beaninfosPropertyPage2 = new BeaninfosWorkbookPage(workspaceRoot, this);
		return beaninfosPropertyPage2;
	}
	
	SearchpathOrderingWorkbookPage getSearchpathOrderingPage(){
		if(searchpathOrderingWorkbookPage2==null)
			searchpathOrderingWorkbookPage2 = new SearchpathOrderingWorkbookPage(this);
		return searchpathOrderingWorkbookPage2;
	}
	
	private void tabChanged(Widget widget) {
		if (widget instanceof TabItem) {
			IBuildSearchPage newPage = (IBuildSearchPage) ((TabItem) widget).getData();
			if (currentPage != null) {
				List selection = currentPage.getSelection();
				if (!selection.isEmpty()) {
					newPage.setSelection(selection);
				}
			}
			currentPage = newPage;
		}
	}	
	
	/**
	 * Creates a runnable that sets the configured build paths.
	 */
	public IRunnableWithProgress getRunnable() {
		final boolean wantNature = enableBeaninfo;
		final List searchPathEntries = wantNature ? getSearchpathOrderingPage().getElements() : null;

		return new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InvocationTargetException {
				if (monitor == null) {
					monitor = new NullProgressMonitor();
				}
				monitor.beginTask(
					BeanInfoUIMessages.BeaninfoPathsBlock_UI__searchpath_operationdescription, 
					10);
				try {
					setBeaninfoSearchpath(wantNature, searchPathEntries, monitor);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				} finally {
					monitor.done();
				}
			}
		};
	}

	private void setBeaninfoSearchpath(
			boolean wantNature,
			List searchPathEntries,
			IProgressMonitor monitor)
			throws CoreException {

		if (wantNature) {
			// create beaninfo nature
			if (!javaProject.getProject().hasNature(BeaninfoNature.NATURE_ID)) {
				addNatureIDToProject(javaProject.getProject(), BeaninfoNature.NATURE_ID, monitor);
			}

			BeaninfoNature nature = BeaninfoNature.getRuntime(javaProject.getProject());
			// Now build/set the search path.
			if (searchPathEntries.size() > 0) {
				IBeaninfosDocEntry[] sparray = new IBeaninfosDocEntry[searchPathEntries.size()];
				Iterator itr = searchPathEntries.iterator();
				int i = 0;
				while (itr.hasNext()) {
					BPListElement elem = (BPListElement) itr.next();
					sparray[i++] = elem.getEntry();
				}
				nature.setSearchPath(new BeaninfosDoc(sparray), monitor);
			} else
				nature.setSearchPath(null, monitor);
		} else {
			// Remove the nature, no longer wanted.
			removeNatureIDFromProject(javaProject.getProject(), BeaninfoNature.NATURE_ID, monitor);
		}
	}

	/**
	 * Initializes the classpath for the given project. Multiple calls to init are allowed,
	 * but all existing settings will be cleared and replace by the given or default paths.
	 * @param project The java project to configure.
	 */
	public void init(IJavaProject jproject) {
		this.javaProject = jproject;
		//TODO: labelProvider.setJavaProject(jproject);

		try {
			// If we have a config file, we will assume we have a nature. It will add it automatically
			// when we ask for the information. Even if we didn't have the nature, as soon as someone
			// asks for it, we would create it anyhow, and it would use the existing config file.
			// If we don't have a config file, we could have the nature, so we will check for that too.
			boolean haveConfigFile = jproject.getProject().getFile(BeaninfoNature.P_BEANINFO_SEARCH_PATH).exists();
			boolean haveNature = javaProject.getProject().hasNature(BeaninfoNature.NATURE_ID);
			enableBeaninfo = haveConfigFile || haveNature;
			if (haveNature || haveConfigFile) {
				BeaninfosDoc doc = BeaninfoNature.getRuntime(javaProject.getProject()).getSearchPath();
				IClasspathEntry[] raw = javaProject.getRawClasspath();

				List newSearchpath = new ArrayList();
				if (doc != null) {
					IBeaninfosDocEntry[] sp = doc.getSearchpath();
					for (int i = 0; i < sp.length; i++) {
						IBeaninfosDocEntry curr = sp[i];
						boolean isMissing = false;
						BPListElement elem = null;
						if (curr instanceof BeaninfoEntry) {
							BeaninfoEntry be = (BeaninfoEntry) curr;

							// get the resource, this tells if the beaninfos exist or not.
							Object[] paths = be.getClasspath(javaProject);
							if (paths != null && paths.length > 0) {
								for (int j = 0; !isMissing && j < paths.length; j++) {
									Object path = paths[j];
									if (path instanceof IProject)
										isMissing = !((IProject) path).exists();
									else if (path instanceof String) {
										File f = new File((String) path);
										isMissing = !f.exists();
									} else if (path instanceof IPath) {
										isMissing = true;	// Plugins are invalid in BeaninfoConfig. They only apply within contributions.
									} else
										isMissing = true; // Invalid, so isMissing.
								}								
							} else
								isMissing = true;

							elem = new BPBeaninfoListElement(be, getInitialSearchpaths(be), isMissing);
						} else {
							// Searchpath entry, see if we can find the raw classpath entry that it is for.
							boolean isExported = false;
							boolean isPackageMissing = true;
							isMissing = true;	// Initially missing until we find it.
							SearchpathEntry ce = (SearchpathEntry) curr;
							int kind = ce.getKind();
							IPath path = ce.getPath();
							for (int j = 0; j < raw.length; j++) {
								if (raw[j].getEntryKind() == kind && raw[j].getPath().equals(path)) {
									isMissing = false;
									isExported = raw[j].isExported() || raw[j].getEntryKind() == IClasspathEntry.CPE_SOURCE;
									String packageName = ce.getPackage();
									if (packageName != null) {
										IPackageFragmentRoot[] roots = javaProject.findPackageFragmentRoots(raw[j]);
										for (int k = 0; k < roots.length; k++) {
											IPackageFragmentRoot iroot = roots[k];
											if (iroot.getPackageFragment(packageName).exists()) {
												isPackageMissing = false;
												break;
											}
										}
									} else
										isPackageMissing = false;
									break;
								}
							}
							elem = new BPSearchListElement(ce, isMissing, isPackageMissing, isExported);
						}

						newSearchpath.add(elem);
					}
				}

				// inits the dialog field
				setSearchOrderElements(newSearchpath);

				if (getPackagesPage() != null) {
					getPackagesPage().init(javaProject);
					getBeaninfosPage().init(javaProject);
					getSearchpathOrderingPage().init(javaProject);
				}
			} else {
				// No nature, disable,
				setEnableBeaninfo(false);
			}
		} catch (JavaModelException e) {
			setEnableBeaninfo(false);
		} catch (CoreException e) {
			setEnableBeaninfo(false);
		}

//		listenForClasspathChange();
		doStatusLineUpdate();
	}

	/**
	 * Adds a nature to a project
	 */
	private void addNatureIDToProject(IProject proj, String natureId, IProgressMonitor monitor)
		throws CoreException {
		IProjectDescription description = proj.getDescription();
		String[] prevNatures = description.getNatureIds();
		String[] newNatures = new String[prevNatures.length + 1];
		System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
		newNatures[prevNatures.length] = natureId;
		description.setNatureIds(newNatures);
		proj.setDescription(description, monitor);
	}

	private void removeNatureIDFromProject(IProject proj, String natureId, IProgressMonitor monitor)
		throws CoreException {
		IProjectDescription description = proj.getDescription();
		String[] prevNatures = description.getNatureIds();
		int indx = -1;
		for (int i = 0; i < prevNatures.length; i++) {
			if (prevNatures[i].equals(natureId)) {
				indx = i;
				break;
			}
		}
		if (indx == -1)
			return;

		String[] newNatures = new String[prevNatures.length - 1];
		if (newNatures.length != 0) {
			System.arraycopy(prevNatures, 0, newNatures, 0, indx);
			if (indx < newNatures.length)
				System.arraycopy(prevNatures, indx + 1, newNatures, indx, newNatures.length - indx);
		}
		description.setNatureIds(newNatures);
		proj.setDescription(description, monitor);
	}
	
	void doStatusLineUpdate() {
		statusChangeListener.statusChanged(getSearchpathOrderingPage().getStatus());
	}
	
	/*
	 * searchOrder dialog must never have all of elements set
	 * directly. Must come through here first so that we can
	 * make sure updates occur in correct sequence, else
	 * we will wind up with entries being marked as unexported
	 * when they really are exported. 
	 */
	public void setSearchOrderElements(List newElements) {
		ArrayList exportedEntries = new ArrayList(newElements.size());
		for (Iterator iter = newElements.iterator(); iter.hasNext();) {
			BPListElement element = (BPListElement) iter.next();
			if (element.isExported())
				exportedEntries.add(element);
		}
		
		getSearchpathOrderingPage().setElements(newElements);
		getSearchpathOrderingPage().setCheckedElements(exportedEntries);
	}
	
	/*
	 * Create the Searchpath elements for a BeaninfoElement.
	 * Return null if not to update.
	 */
	private BPSearchListElement[] getInitialSearchpaths(BeaninfoEntry infoEntry) {

		// We can only verify the existence of packages within beaninfos that are 
		// located within a project on the desktop. Otherwise we can't find out what
		// packages are in them.
		IPackageFragmentRoot[] roots = null;

		if (infoEntry.getKind() != BeaninfoEntry.BIE_PLUGIN) {
			IClasspathEntry resolved = JavaCore.getResolvedClasspathEntry(infoEntry.getClasspathEntry());
			IResource res = workspaceRoot.findMember(resolved.getPath());
			if (res != null && res.exists()) {
				if (res instanceof IProject) {
					// It is a project itself.
					IJavaProject jp = (IJavaProject) JavaCore.create(res);
					try {
						if (jp != null)
							roots = jp.getPackageFragmentRoots(); // All of the roots in the project are applicable.
					} catch (JavaModelException e) {
					}
				} else {
					// It is within another project
					IProject containingProject = res.getProject();
					IJavaProject jp = JavaCore.create(containingProject);
					if (jp != null) {
						// The roots if this is in the classpath of this project
						try {
							IPackageFragmentRoot root = jp.findPackageFragmentRoot(resolved.getPath());
							if (root != null)
								roots = new IPackageFragmentRoot[] { root };
						} catch (JavaModelException e) {
						}
					}
				}
			}
		}

		SearchpathEntry[] entries = infoEntry.getSearchPaths();
		BPSearchListElement[] packageElements = new BPSearchListElement[entries.length];
		for (int i = 0;
			i < entries.length;
			i++) { // Searchpath entry, see if we can find the raw classpath entry that it is for.
			boolean isPackageMissing = roots != null;
			// If roots is null, then the package isn't missing because we can't test for it.
			SearchpathEntry ce = entries[i];
			if (roots != null) {
				String packageName = ce.getPackage();
				for (int k = 0; k < roots.length; k++) {
					IPackageFragmentRoot iroot = roots[k];
					if (iroot.getPackageFragment(packageName).exists()) {
						isPackageMissing = false;
						break;
					}
				}
			}
			packageElements[i] = new BPSearchListElement(ce, false, isPackageMissing, false);
		}

		return packageElements;
	}
	
	
	public static List getSelectedList(ISelection selection){
		List selectedList = null;
		if(selection!=null && !selection.isEmpty() && selection instanceof IStructuredSelection){
			IStructuredSelection structuredSelection = (IStructuredSelection) selection;
			selectedList = new ArrayList(Arrays.asList(structuredSelection.toArray()));
		}
		return selectedList;
	}
	
	public boolean isBeaninfoEnabled(){
		return enableBeaninfo;
	}
}
