/*******************************************************************************
 * Copyright (c) 2000, 2005 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.jdt.internal.ui.refactoring;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.text.edits.TextEdit;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.Assert;

import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;

import org.eclipse.ltk.ui.refactoring.LanguageElementNode;
import org.eclipse.ltk.ui.refactoring.TextEditChangeNode;

import org.eclipse.ltk.core.refactoring.TextEditBasedChange;
import org.eclipse.ltk.core.refactoring.TextEditBasedChangeGroup;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.ui.JavaElementLabels;

import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;

public class CompilationUnitChangeNode extends TextEditChangeNode {

	static final ChildNode[] EMPTY_CHILDREN= new ChildNode[0];
	
	private static class JavaLanguageNode extends LanguageElementNode {

		private IJavaElement fJavaElement;
		private static JavaElementImageProvider fgImageProvider= new JavaElementImageProvider();

		public JavaLanguageNode(TextEditChangeNode parent, IJavaElement element) {
			super(parent);
			fJavaElement= element;
			Assert.isNotNull(fJavaElement);
		}
		
		public JavaLanguageNode(ChildNode parent, IJavaElement element) {
			super(parent);
			fJavaElement= element;
			Assert.isNotNull(fJavaElement);
		}
		
		public String getText() {
			return JavaElementLabels.getElementLabel(fJavaElement, JavaElementLabels.ALL_DEFAULT);
		}
		
		public ImageDescriptor getImageDescriptor() {
			return fgImageProvider.getJavaImageDescriptor(
				fJavaElement, 
				JavaElementImageProvider.OVERLAY_ICONS | JavaElementImageProvider.SMALL_ICONS);
		}
		
		public IRegion getTextRange() throws CoreException {
			ISourceRange range= ((ISourceReference)fJavaElement).getSourceRange();
			return new Region(range.getOffset(), range.getLength());
		}	
	}	
	
	public CompilationUnitChangeNode(TextEditBasedChange change) {
		super(change);
	}
	
	protected ChildNode[] createChildNodes() {
		final TextEditBasedChange change= getTextEditBasedChange();
		ICompilationUnit cunit= (ICompilationUnit) change.getAdapter(ICompilationUnit.class);
		if (cunit != null) {
			List children= new ArrayList(5);
			Map map= new HashMap(20);
			TextEditBasedChangeGroup[] changes= getSortedChangeGroups(change);
			for (int i= 0; i < changes.length; i++) {
				TextEditBasedChangeGroup tec= changes[i];
				try {
					IJavaElement element= getModifiedJavaElement(tec, cunit);
					if (element.equals(cunit)) {
						children.add(createTextEditGroupNode(this, tec));
					} else {
						JavaLanguageNode pjce= getChangeElement(map, element, children, this);
						pjce.addChild(createTextEditGroupNode(pjce, tec));
					}
				} catch (JavaModelException e) {
					children.add(createTextEditGroupNode(this, tec));
				}
			}
			return (ChildNode[]) children.toArray(new ChildNode[children.size()]);
		} else {
			return EMPTY_CHILDREN;
		}
	}
	
	private static class OffsetComparator implements Comparator {
		public int compare(Object o1, Object o2) {
			TextEditBasedChangeGroup c1= (TextEditBasedChangeGroup)o1;
			TextEditBasedChangeGroup c2= (TextEditBasedChangeGroup)o2;
			int p1= getOffset(c1);
			int p2= getOffset(c2);
			if (p1 < p2)
				return -1;
			if (p1 > p2)
				return 1;
			// same offset
			return 0;	
		}
		private int getOffset(TextEditBasedChangeGroup edit) {
			return edit.getRegion().getOffset();
		}
	}
	
	private TextEditBasedChangeGroup[] getSortedChangeGroups(TextEditBasedChange change) {
		TextEditBasedChangeGroup[] edits= change.getChangeGroups();
		List result= new ArrayList(edits.length);
		for (int i= 0; i < edits.length; i++) {
			if (!edits[i].getTextEditGroup().isEmpty())
				result.add(edits[i]);
		}
		Comparator comparator= new OffsetComparator();
		Collections.sort(result, comparator);
		return (TextEditBasedChangeGroup[])result.toArray(new TextEditBasedChangeGroup[result.size()]);
	}
	
	private IJavaElement getModifiedJavaElement(TextEditBasedChangeGroup edit, ICompilationUnit cunit) throws JavaModelException {
		IRegion range= edit.getRegion();
		if (range.getOffset() == 0 && range.getLength() == 0)
			return cunit;
		IJavaElement result= cunit.getElementAt(range.getOffset());
		if (result == null)
			return cunit;
		
		try {
			while(true) {
				ISourceReference ref= (ISourceReference)result;
				IRegion sRange= new Region(ref.getSourceRange().getOffset(), ref.getSourceRange().getLength());
				if (result.getElementType() == IJavaElement.COMPILATION_UNIT || result.getParent() == null || coveredBy(edit, sRange))
					break;
				result= result.getParent();
			}
		} catch(JavaModelException e) {
			// Do nothing, use old value.
		} catch(ClassCastException e) {
			// Do nothing, use old value.
		}
		return result;
	}
	
	private JavaLanguageNode getChangeElement(Map map, IJavaElement element, List children, TextEditChangeNode cunitChange) {
		JavaLanguageNode result= (JavaLanguageNode)map.get(element);
		if (result != null)
			return result;
		IJavaElement parent= element.getParent();
		if (parent instanceof ICompilationUnit) {
			result= new JavaLanguageNode(cunitChange, element);
			children.add(result);
			map.put(element, result);
		} else {
			JavaLanguageNode parentChange= getChangeElement(map, parent, children, cunitChange);
			result= new JavaLanguageNode(parentChange, element);
			parentChange.addChild(result);
			map.put(element, result);
		}
		return result;
	}
	
	private boolean coveredBy(TextEditBasedChangeGroup group, IRegion sourceRegion) {
		int sLength= sourceRegion.getLength();
		if (sLength == 0)
			return false;
		int sOffset= sourceRegion.getOffset();
		int sEnd= sOffset + sLength - 1;
		TextEdit[] edits= group.getTextEdits();
		for (int i= 0; i < edits.length; i++) {
			TextEdit edit= edits[i];
			if (edit.isDeleted())
				return false;
			int rOffset= edit.getOffset();
			int rLength= edit.getLength();
			int rEnd= rOffset + rLength - 1;
		    if (rLength == 0) {
				if (!(sOffset < rOffset && rOffset <= sEnd))
					return false;
			} else {
				if (!(sOffset <= rOffset && rEnd <= sEnd))
					return false;
			}
		}
		return true;
	}
}