/*******************************************************************************
 * Copyright (c) 2000, 2008 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.wst.jsdt.internal.ui.compare;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.eclipse.compare.EditionSelectionDialog;
import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
import org.eclipse.wst.jsdt.core.IMember;
import org.eclipse.wst.jsdt.core.IParent;
import org.eclipse.wst.jsdt.core.IType;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.BodyDeclaration;
import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
import org.eclipse.wst.jsdt.core.dom.EnumDeclaration;
import org.eclipse.wst.jsdt.core.dom.FieldDeclaration;
import org.eclipse.wst.jsdt.core.dom.ImportDeclaration;
import org.eclipse.wst.jsdt.core.dom.PackageDeclaration;
import org.eclipse.wst.jsdt.core.dom.TypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.wst.jsdt.core.dom.rewrite.ListRewrite;
import org.eclipse.wst.jsdt.internal.corext.dom.ASTNodes;
import org.eclipse.wst.jsdt.internal.corext.util.Resources;
import org.eclipse.wst.jsdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
import org.eclipse.wst.jsdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.wst.jsdt.internal.ui.util.ExceptionHandler;
import org.eclipse.wst.jsdt.ui.IWorkingCopyManager;


class JavaAddElementFromHistoryImpl extends JavaHistoryActionImpl {
	
	private static final String BUNDLE_NAME= "org.eclipse.wst.jsdt.internal.ui.compare.AddFromHistoryAction"; //$NON-NLS-1$
	
	JavaAddElementFromHistoryImpl() {
		super(true);
	}
	
	public void run(ISelection selection) {
		
		String errorTitle= CompareMessages.AddFromHistory_title; 
		String errorMessage= CompareMessages.AddFromHistory_internalErrorMessage; 
		Shell shell= getShell();
		
		IJavaScriptUnit cu= null;
		IParent parent= null;
		IMember input= null;
		
		// analyze selection
		if (selection.isEmpty()) {
			// no selection: we try to use the editor's input
			JavaEditor editor= getEditor();
			if (editor != null) {
				IEditorInput editorInput= editor.getEditorInput();
				IWorkingCopyManager manager= JavaScriptPlugin.getDefault().getWorkingCopyManager();
				if (manager != null) {
					cu= manager.getWorkingCopy(editorInput);
					parent= cu;
				}
			}
		} else {
			input= getEditionElement(selection);
			if (input != null) {
				cu= input.getJavaScriptUnit();
				parent= input;
				input= null;

			} else {
				if (selection instanceof IStructuredSelection) {
					Object o= ((IStructuredSelection)selection).getFirstElement();
					if (o instanceof IJavaScriptUnit) {
						cu= (IJavaScriptUnit) o;
						parent= cu;
					}
				}
			}
		}
		
		if (parent == null || cu == null) {
			String invalidSelectionMessage= CompareMessages.AddFromHistory_invalidSelectionMessage; 
			MessageDialog.openInformation(shell, errorTitle, invalidSelectionMessage);
			return;
		}
		
		IFile file= getFile(parent);
		if (file == null) {
			MessageDialog.openError(shell, errorTitle, errorMessage);
			return;
		}
				
		boolean inEditor= beingEdited(file);

		IStatus status= Resources.makeCommittable(file, shell);
		if (!status.isOK()) {
			return;
		}
		
		// get the document where to insert the text
		IPath path= file.getFullPath();
		ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager();
		ITextFileBuffer textFileBuffer= null;
		try {
			bufferManager.connect(path, LocationKind.IFILE, null);
			textFileBuffer= bufferManager.getTextFileBuffer(path, LocationKind.IFILE);
			IDocument document= textFileBuffer.getDocument();
			
			// configure EditionSelectionDialog and let user select an edition
			ITypedElement target= new JavaTextBufferNode(file, document, inEditor);
			ITypedElement[] editions= buildEditions(target, file);
											
			ResourceBundle bundle= ResourceBundle.getBundle(BUNDLE_NAME);
			EditionSelectionDialog d= new EditionSelectionDialog(shell, bundle);
			d.setAddMode(true);
			d.setHelpContextId(IJavaHelpContextIds.ADD_ELEMENT_FROM_HISTORY_DIALOG);
			ITypedElement selected= d.selectEdition(target, editions, parent);
			if (selected == null)
				return;	// user cancel
								
			IJavaScriptUnit cu2= cu;
			if (parent instanceof IMember)
				cu2= ((IMember)parent).getJavaScriptUnit();
			
			JavaScriptUnit root= parsePartialCompilationUnit(cu2);
			ASTRewrite rewriter= ASTRewrite.create(root.getAST());
			
			ITypedElement[] results= d.getSelection();
			for (int i= 0; i < results.length; i++) {
				
			    // create an AST node
				ASTNode newNode= createASTNode(rewriter, results[i], TextUtilities.getDefaultLineDelimiter(document), cu.getJavaScriptProject());
				if (newNode == null) {
					MessageDialog.openError(shell, errorTitle, errorMessage);
					return;	
				}
				
				// now determine where to put the new node
				if (newNode instanceof PackageDeclaration) {
				    rewriter.set(root, JavaScriptUnit.PACKAGE_PROPERTY, newNode, null);
				    
				} else if (newNode instanceof ImportDeclaration) {
					ListRewrite lw= rewriter.getListRewrite(root, JavaScriptUnit.IMPORTS_PROPERTY);
					lw.insertFirst(newNode, null);
					
				} else {	// class, interface, enum, annotation, method, field
					
					if (parent instanceof IJavaScriptUnit) {	// top level
						ListRewrite lw= rewriter.getListRewrite(root, JavaScriptUnit.TYPES_PROPERTY);
						int index= ASTNodes.getInsertionIndex((BodyDeclaration)newNode, root.types());
						lw.insertAt(newNode, index, null);
						
					} else if (parent instanceof IType) {
						ASTNode declaration= getBodyContainer(root, (IType)parent);
						if (declaration instanceof TypeDeclaration || declaration instanceof AnnotationTypeDeclaration) {
							List container= ASTNodes.getBodyDeclarations(declaration);
							int index= ASTNodes.getInsertionIndex((BodyDeclaration)newNode, container);
							ListRewrite lw= rewriter.getListRewrite(declaration, ASTNodes.getBodyDeclarationsProperty(declaration));
							lw.insertAt(newNode, index, null);
						} else if (declaration instanceof EnumDeclaration) {
							List container= ((EnumDeclaration)declaration).enumConstants();
							int index= ASTNodes.getInsertionIndex((FieldDeclaration)newNode, container);
							ListRewrite lw= rewriter.getListRewrite(declaration, EnumDeclaration.ENUM_CONSTANTS_PROPERTY);
							lw.insertAt(newNode, index, null);
						}
					} else {
						JavaScriptPlugin.logErrorMessage("JavaAddElementFromHistoryImpl: unknown container " + parent); //$NON-NLS-1$
					}
					
				}
			}
			
			Map options= null;
			IJavaScriptProject javaProject= cu2.getJavaScriptProject();
			if (javaProject != null)
				options= javaProject.getOptions(true);
			applyChanges(rewriter, document, textFileBuffer, shell, inEditor, options);

	 	} catch(InvocationTargetException ex) {
			ExceptionHandler.handle(ex, shell, errorTitle, errorMessage);
			
		} catch(InterruptedException ex) {
			// shouldn't be called because is not cancelable
			Assert.isTrue(false);
			
		} catch(CoreException ex) {
			ExceptionHandler.handle(ex, shell, errorTitle, errorMessage);
			
		} finally {
			try {
				if (textFileBuffer != null)
					bufferManager.disconnect(path, LocationKind.IFILE, null);
			} catch (CoreException e) {
				JavaScriptPlugin.log(e);
			}
		}
	}
	
	/**
	 * Creates a place holder ASTNode for the given element.
	 * @param rewriter
	 * @param element
	 * @param delimiter the line delimiter
	 * @param project 
	 * @return a ASTNode or null
	 * @throws CoreException
	 */
	private ASTNode createASTNode(ASTRewrite rewriter, ITypedElement element, String delimiter, IJavaScriptProject project) throws CoreException {
		if (element instanceof IStreamContentAccessor) {
			String content= JavaCompareUtilities.readString((IStreamContentAccessor)element);
			if (content != null) {
				content= trimTextBlock(content, delimiter, project);
				if (content != null) {
				    int type= getPlaceHolderType(element);
				    if (type != -1)
				        return rewriter.createStringPlaceholder(content, type);
				}
			}
		}
		return null;
	}
	
	/**
	 * Returns the corresponding place holder type for the given element.
	 * @return a place holder type (see ASTRewrite) or -1 if there is no corresponding placeholder
	 */
	private int getPlaceHolderType(ITypedElement element) {
		
		if (element instanceof DocumentRangeNode) {
			JavaNode jn= (JavaNode) element;
			switch (jn.getTypeCode()) {
				
			case JavaNode.PACKAGE:
			    return ASTNode.PACKAGE_DECLARATION;

			case JavaNode.CLASS:
			case JavaNode.INTERFACE:
				return ASTNode.TYPE_DECLARATION;
				
			case JavaNode.ENUM:
				return ASTNode.ENUM_DECLARATION;
				
			case JavaNode.ANNOTATION:
				return ASTNode.ANNOTATION_TYPE_DECLARATION;
				
			case JavaNode.CONSTRUCTOR:
			case JavaNode.METHOD:
				return ASTNode.FUNCTION_DECLARATION;
				
			case JavaNode.FIELD:
				return ASTNode.FIELD_DECLARATION;
				
			case JavaNode.INIT:
				return ASTNode.INITIALIZER;

			case JavaNode.IMPORT:
			case JavaNode.IMPORT_CONTAINER:
				return ASTNode.IMPORT_DECLARATION;

			case JavaNode.CU:
			    return ASTNode.JAVASCRIPT_UNIT;
			}
		}
		return -1;
	}

	protected boolean isEnabled(ISelection selection) {
		
		if (selection.isEmpty()) {
			JavaEditor editor= getEditor();
			if (editor != null) {
				// we check whether editor shows JavaScriptUnit
				IEditorInput editorInput= editor.getEditorInput();
				IWorkingCopyManager manager= JavaScriptPlugin.getDefault().getWorkingCopyManager();
				return manager.getWorkingCopy(editorInput) != null;
			}
			return false;
		}
		
		if (selection instanceof IStructuredSelection) {
			Object o= ((IStructuredSelection)selection).getFirstElement();
			if (o instanceof IJavaScriptUnit)
				return true;
		}
		
		return super.isEnabled(selection);
	}
}
