/*******************************************************************************
 * 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.internal.project.J2EEProjectUtilities;
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) && J2EEProjectUtilities.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 (!J2EEProjectUtilities.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) && J2EEProjectUtilities.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) && J2EEProjectUtilities.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 (J2EEProjectUtilities.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 (J2EEProjectUtilities.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 {
		IJavaProject javaProject = JavaCore.create(child.getProject());
		IPackageFragmentRoot[] packageFragmentRoots = javaProject.getPackageFragmentRoots();
	
		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 (J2EEProjectUtilities.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() && J2EEProjectUtilities.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);
	} 

}
