/*******************************************************************************
 * Copyright (c) 2003, 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
 *******************************************************************************/
package org.eclipse.jst.servlet.ui.internal.navigator;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.servlet.ui.internal.plugin.ServletUIPlugin;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.navigator.CommonViewer;
import org.eclipse.ui.navigator.ICommonContentExtensionSite;
import org.eclipse.ui.navigator.INavigatorContentExtension;
import org.eclipse.ui.navigator.INavigatorContentService;
import org.eclipse.ui.navigator.IPipelinedTreeContentProvider;
import org.eclipse.ui.navigator.PipelinedShapeModification;
import org.eclipse.ui.navigator.PipelinedViewerUpdate;

public class WebJavaContentProvider implements IPipelinedTreeContentProvider  {

	private static final Object[] NO_CHILDREN = new Object[0];
	private static final String JAVA_EXTENSION_ID = "org.eclipse.jdt.java.ui.javaContent"; //$NON-NLS-1$

	/*
	 * JDT likes to make it interesting so just one of their viewer types is made internal To avoid
	 * the dependency, we use some reflection here to filter the type.
	 */

	private static Class INTERNAL_CONTAINER_CLASS;
	static {
		try {
			INTERNAL_CONTAINER_CLASS = Class.forName("org.eclipse.jdt.internal.ui.packageview.ClassPathContainer"); //$NON-NLS-1$
		} catch (Throwable t) {
			// ignore if the class has been removed or renamed.
			INTERNAL_CONTAINER_CLASS = null;
		}
	}


	private CommonViewer commonViewer;
	private ITreeContentProvider delegateContentProvider;
	private final Map compressedNodes = new HashMap();

	public void getPipelinedChildren(Object aParent, Set theCurrentChildren) {
		try {
			if (aParent instanceof IProject && ((IProject)aParent).hasNature(JavaCore.NATURE_ID) && JavaEEProjectUtilities.isDynamicWebProject((IProject)aParent)) {
				cleanJavaContribution(theCurrentChildren);
				theCurrentChildren.add(getCompressedNode((IProject)aParent));
			}
		} catch (CoreException e) {
			ServletUIPlugin.log(e);
		} 
	}

	private void cleanJavaContribution(Set theCurrentChildren) {
		IJavaElement element = null;
		for (Iterator iter = theCurrentChildren.iterator(); iter.hasNext();) {
			Object child = iter.next();
			if (child instanceof IResource && ((element = JavaCore.create((IResource) child)) != null) && element.exists())
				iter.remove();
			else if (child instanceof IJavaElement)
				iter.remove();
			else if (INTERNAL_CONTAINER_CLASS != null && INTERNAL_CONTAINER_CLASS.isInstance(child))
				iter.remove();
		}
	}

	private CompressedJavaProject getCompressedNode(IProject project) {
		if (!JavaEEProjectUtilities.isDynamicWebProject(project))
			return null;
		CompressedJavaProject result = (CompressedJavaProject) compressedNodes.get(project);
		if (result == null) {
			compressedNodes.put(project, result = new CompressedJavaProject(commonViewer, project));
		}
		return result;
	}

	public void getPipelinedElements(Object anInput, Set theCurrentElements) { 

	}

	public Object getPipelinedParent(Object anObject, Object aSuggestedParent) {

		try {
			if (anObject instanceof IPackageFragmentRoot) {
				IPackageFragmentRoot root = (IPackageFragmentRoot) anObject;
				if (!root.isExternal()) {
					if( aSuggestedParent instanceof IJavaProject ) {
						return getCompressedNode( ((IJavaProject) aSuggestedParent).getProject() );
					} else if ( aSuggestedParent instanceof IProject && ((IProject)aSuggestedParent).hasNature(JavaCore.NATURE_ID) && JavaEEProjectUtilities.isDynamicWebProject((IProject)aSuggestedParent) ){
						return getCompressedNode( ((IProject) aSuggestedParent) );
					}
				}
			} else if(INTERNAL_CONTAINER_CLASS.isInstance(anObject)) {
				if( aSuggestedParent instanceof IJavaProject ) {
					return getCompressedNode( ((IJavaProject) aSuggestedParent).getProject() ).getCompressedJavaLibraries();
				} else if ( aSuggestedParent instanceof IProject && ((IProject)aSuggestedParent).hasNature(JavaCore.NATURE_ID) && JavaEEProjectUtilities.isDynamicWebProject((IProject)aSuggestedParent)){
					return getCompressedNode( ((IProject) aSuggestedParent) ).getCompressedJavaLibraries();
				} 
			}
		} catch (CoreException e) {
			ServletUIPlugin.log(e);
		}
		
		return null;
	}

	public PipelinedShapeModification interceptAdd(PipelinedShapeModification anAddModification) {
		Object parent = anAddModification.getParent();
		
		if (parent instanceof IPackageFragmentRoot) {
			IPackageFragmentRoot sourceFolder = (IPackageFragmentRoot) parent;
			if (JavaEEProjectUtilities.isDynamicWebProject(sourceFolder.getJavaProject().getProject())) {
				CompressedJavaProject compressedNode = getCompressedNode(sourceFolder.getJavaProject().getProject());
				if(compressedNode.isFlatteningSourceFolder()) {
					anAddModification.setParent(compressedNode);
				}
			}
		} 
		
		return anAddModification;
	}
	

	public PipelinedShapeModification interceptRemove(PipelinedShapeModification aRemoveModification) {

		Object parent = aRemoveModification.getParent();
		
		Set children = aRemoveModification.getChildren();
		
		for (Object child : children) {
			if (child instanceof IFolder){
				try {
					IPackageFragment locatePackageFragment = locatePackageFragment((IFolder)child);
					if(locatePackageFragment != null){
						aRemoveModification.getChildren().remove(child);
						aRemoveModification.getChildren().add(locatePackageFragment);
						
						return aRemoveModification;
					}
				} catch (JavaModelException e) {
				}
			}
		}
		
		if (parent instanceof IPackageFragmentRoot) {
			IPackageFragmentRoot sourceFolder = (IPackageFragmentRoot) parent;
			if (JavaEEProjectUtilities.isDynamicWebProject(sourceFolder.getJavaProject().getProject())) {
				CompressedJavaProject compressedNode = getCompressedNode(sourceFolder.getJavaProject().getProject());
				if(compressedNode.isFlatteningSourceFolder()) {
					aRemoveModification.setParent(compressedNode);
				}
			}
			
		} 
		
		return aRemoveModification;
	}

	private IPackageFragment locatePackageFragment(IFolder child) throws JavaModelException {
		IJavaElement elem = JavaCore.create(child);
		if (elem instanceof IPackageFragment) {
			IPackageFragment packageFragment = (IPackageFragment)elem;
			for (IJavaElement javaElem = packageFragment ; javaElem != null ; javaElem = javaElem.getParent()) {
				if (javaElem instanceof IPackageFragmentRoot) {
					IPackageFragmentRoot fragmentRoot = (IPackageFragmentRoot)javaElem;
					if (!fragmentRoot.isReadOnly() && !fragmentRoot.isExternal()) {
						return packageFragment;
					}
				}
			}
		}
		return null;
	}

	public boolean interceptRefresh(PipelinedViewerUpdate aRefreshSynchronization) {
		
		Set refreshTargets = aRefreshSynchronization.getRefreshTargets();
		for (Iterator iter = refreshTargets.iterator(); iter.hasNext();) {
			Object refreshTarget = iter.next();
			if (refreshTarget instanceof IPackageFragmentRoot) {
				IPackageFragmentRoot sourceFolder = (IPackageFragmentRoot) refreshTarget;
				if (JavaEEProjectUtilities.isDynamicWebProject(sourceFolder.getJavaProject().getProject())) {
					CompressedJavaProject compressedNode = getCompressedNode(sourceFolder.getJavaProject().getProject());
					if(compressedNode.isFlatteningSourceFolder()) {
						iter.remove(); // voids the iter but is okay because we're done with it
						refreshTargets.add(compressedNode);
						return true;
					}
				}
				
			}
		}
		
		return false;
	}


	public boolean interceptUpdate(PipelinedViewerUpdate anUpdateSynchronization) {
		Set refreshTargets = anUpdateSynchronization.getRefreshTargets();
		for (Iterator iter = refreshTargets.iterator(); iter.hasNext();) {
			Object refreshTarget = iter.next();
			if (refreshTarget instanceof IPackageFragmentRoot) {
				IPackageFragmentRoot sourceFolder = (IPackageFragmentRoot) refreshTarget;
				if (sourceFolder.getJavaProject()!=null && sourceFolder.getJavaProject().exists() && sourceFolder.getJavaProject().isOpen() && JavaEEProjectUtilities.isDynamicWebProject(sourceFolder.getJavaProject().getProject())) {
					CompressedJavaProject compressedNode = getCompressedNode(sourceFolder.getJavaProject().getProject());
					if(compressedNode.isFlatteningSourceFolder()) {
//						iter.remove(); // voids the iterator; but is okay because we're done with it
						refreshTargets.add(compressedNode);
						return true;
					}
				}
			}
		}
		
		return false; 
	}

	public void init(ICommonContentExtensionSite aSite) { 
	}

	public Object[] getChildren(Object parentElement) {
		if (delegateContentProvider != null) {
			if (parentElement instanceof CompressedJavaProject) {
				return ((CompressedJavaProject)parentElement).getChildren(delegateContentProvider);
			} else if (parentElement instanceof CompressedJavaLibraries) { 
				return ((CompressedJavaLibraries)parentElement).getChildren(delegateContentProvider);
			}
		}
		return NO_CHILDREN;
	}

	public Object getParent(Object element) {
		if (element instanceof CompressedJavaProject)
			return ((CompressedJavaProject) element).getProject();
		if (element instanceof CompressedJavaLibraries) 
			return ((CompressedJavaLibraries) element).getCompressedProject();
		return null;
	}

	public boolean hasChildren(Object element) {
		return (element instanceof CompressedJavaProject || element instanceof CompressedJavaLibraries);
	}

	public Object[] getElements(Object inputElement) {
		return NO_CHILDREN;
	}

	public void dispose() { 
		compressedNodes.clear(); 
	}

	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		if (viewer instanceof CommonViewer) {
			commonViewer = (CommonViewer) viewer;
			INavigatorContentService service = commonViewer.getNavigatorContentService();
			INavigatorContentExtension javaext = service.getContentExtensionById(JAVA_EXTENSION_ID);
			if (javaext != null)
				delegateContentProvider = javaext.getContentProvider();
			compressedNodes.clear();
		}

	}

	public void restoreState(IMemento aMemento) {

	}

	public void saveState(IMemento aMemento) {

	}
	
	public boolean isClasspathContainer(Object o) {		
		return INTERNAL_CONTAINER_CLASS != null && INTERNAL_CONTAINER_CLASS.isInstance(o);
	} 

}
