/*******************************************************************************
 * Copyright (c) 2001, 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     Pete Carapetyan/Genuitec - 244835 - Enable/Disable breakpoint action does not refresh its label
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.debug;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.ITextEditorExtension;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.breakpoint.IBreakpointProvider;


public abstract class BreakpointRulerAction extends Action implements IUpdate {

	protected class MouseUpdater implements MouseListener {
		public void mouseDoubleClick(MouseEvent e) {
			// do nothing (here)
		}

		public void mouseDown(MouseEvent e) {
			update();
		}

		public void mouseUp(MouseEvent e) {
			// do nothing
		}
	}

	public static final String getFileExtension(IEditorInput input) {
		IPath path = null;
		if (input instanceof IStorageEditorInput) {
			try {
				path = ((IStorageEditorInput) input).getStorage().getFullPath();
			} catch (CoreException e) {
				Logger.logException(e);
			}
		}
		if (path != null) {
			return path.getFileExtension();
		}
		String name = input.getName();
		int index = name.lastIndexOf('.');
		if (index == -1)
			return null;
		if (index == (name.length() - 1))
			return ""; //$NON-NLS-1$
		return name.substring(index + 1);
	}

	public static final IResource getResource(IEditorInput input) {
		IResource resource = null;

		if (input instanceof IFileEditorInput)
			resource = ((IFileEditorInput) input).getFile();
		if (resource == null)
			resource = (IResource) input.getAdapter(IFile.class);
		if (resource == null)
			resource = (IResource) input.getAdapter(IResource.class);

		IEditorPart editorPart = null;
		if (resource == null) {
			IWorkbench workbench = SSEUIPlugin.getDefault().getWorkbench();
			if (workbench != null) {
				IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
				if (window != null) {
					IPartService service = window.getPartService();
					if (service != null) {
						Object part = service.getActivePart();
						if (part != null && part instanceof IEditorPart) {
							editorPart = (IEditorPart) part;
							if (editorPart != null) {
								IStructuredModel model = null;
								ITextEditor textEditor = null;
								try {
									if (editorPart instanceof ITextEditor) {
										textEditor = (ITextEditor) editorPart;
									}
									if (textEditor == null) {
										textEditor = (ITextEditor) editorPart.getAdapter(ITextEditor.class);
									}
									if (textEditor != null) {
										IDocument textDocument = textEditor.getDocumentProvider().getDocument(input);
										model = StructuredModelManager.getModelManager().getExistingModelForRead(textDocument);
										if (model != null) {
											resource = BreakpointProviderBuilder.getInstance().getResource(input, model.getContentTypeIdentifier(), getFileExtension(input));
										}
									}
									if (resource == null) {
										IBreakpointProvider[] providers = BreakpointProviderBuilder.getInstance().getBreakpointProviders(editorPart, null, getFileExtension(input));
										for (int i = 0; i < providers.length && resource == null; i++) {
											resource = providers[i].getResource(input);
										}
									}
								} catch (Exception e) {
									Logger.logException(e);
								} finally {
									if (model != null) {
										model.releaseFromRead();
									}
								}
							}

						}
					}
				}

			}
		}
		return resource;
	}

	protected MouseListener fMouseListener = null;

	protected IVerticalRulerInfo fRulerInfo = null;
	protected ITextEditor fTextEditor = null;

	private IMenuListener menuListener;

	public BreakpointRulerAction(ITextEditor editor, IVerticalRulerInfo rulerInfo) {
		super();
		fTextEditor = editor;
		if (rulerInfo != null) {
			fRulerInfo = rulerInfo;
			fMouseListener = new MouseUpdater();
			rulerInfo.getControl().addMouseListener(fMouseListener);
		}
		if (editor instanceof ITextEditorExtension) {
			ITextEditorExtension extension = (ITextEditorExtension) editor;
			menuListener = new IMenuListener() {
				public void menuAboutToShow(IMenuManager manager) {
					update();
				}
			};
			extension.addRulerContextMenuListener(menuListener);
		}
	}

	/**
	 * Returns the <code>AbstractMarkerAnnotationModel</code> of the
	 * editor's input.
	 * 
	 * @return the marker annotation model
	 */
	protected AbstractMarkerAnnotationModel getAnnotationModel() {
		IDocumentProvider provider = fTextEditor.getDocumentProvider();
		IAnnotationModel model = provider.getAnnotationModel(fTextEditor.getEditorInput());
		if (model instanceof AbstractMarkerAnnotationModel)
			return (AbstractMarkerAnnotationModel) model;
		return null;
	}

	protected IBreakpoint[] getBreakpoints(IMarker[] markers) {
		IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager();
		List breakpoints = new ArrayList(markers.length);
		for (int i = 0; i < markers.length; i++) {
			IBreakpoint breakpoint = manager.getBreakpoint(markers[i]);
			if (breakpoint != null) {
				breakpoints.add(breakpoint);
			}
		}
		return (IBreakpoint[]) breakpoints.toArray(new IBreakpoint[0]);
	}

	/**
	 * Returns the <code>IDocument</code> of the editor's input.
	 * 
	 * @return the document of the editor's input
	 */
	protected IDocument getDocument() {
		IDocumentProvider provider = fTextEditor.getDocumentProvider();
		return provider.getDocument(fTextEditor.getEditorInput());
	}

	/**
	 * Returns all markers which include the ruler's line of activity.
	 * 
	 * @return an array of markers which include the ruler's line of activity
	 */
	protected IMarker[] getMarkers() {
		List markers = new ArrayList();

		IResource resource = getResource();
		IDocument document = getDocument();
		AbstractMarkerAnnotationModel annotationModel = getAnnotationModel();

		if (resource != null && annotationModel != null && resource.exists()) {
			try {
				IMarker[] allMarkers = resource.findMarkers(IBreakpoint.BREAKPOINT_MARKER, true, IResource.DEPTH_ZERO);
				if (allMarkers != null) {
					for (int i = 0; i < allMarkers.length; i++) {
						if (includesRulerLine(annotationModel.getMarkerPosition(allMarkers[i]), document)) {
							markers.add(allMarkers[i]);
						}
					}
				}
			} catch (CoreException x) {
				//
			}
		}

		return (IMarker[]) markers.toArray(new IMarker[0]);
	}

	protected IResource getResource() {
		IEditorInput input = getTextEditor().getEditorInput();
		IResource resource = getResource(input);
		return resource;
	}

	/**
	 * @return Returns the rulerInfo.
	 */
	public IVerticalRulerInfo getRulerInfo() {
		return fRulerInfo;
	}

	/**
	 * @return Returns the textEditor.
	 */
	public ITextEditor getTextEditor() {
		return fTextEditor;
	}

	protected boolean hasMarkers() {
		IResource resource = getResource();
		IDocument document = getDocument();
		AbstractMarkerAnnotationModel model = getAnnotationModel();

		if (resource != null && model != null && resource.exists()) {
			try {
				IMarker[] allMarkers = resource.findMarkers(IBreakpoint.LINE_BREAKPOINT_MARKER, true, IResource.DEPTH_ZERO);
				if (allMarkers != null) {
					for (int i = 0; i < allMarkers.length; i++) {
						if (includesRulerLine(model.getMarkerPosition(allMarkers[i]), document)) {
							return true;
						}
					}
				}
			} catch (CoreException x) {
				//
			}
		}
		return false;
	}

	/**
	 * Checks whether a position includes the ruler's line of activity.
	 * 
	 * @param position
	 *            the position to be checked
	 * @param document
	 *            the document the position refers to
	 * @return <code>true</code> if the line is included by the given
	 *         position
	 */
	protected boolean includesRulerLine(Position position, IDocument document) {
		if (position != null && fRulerInfo != null) {
			try {
				int markerLine = document.getLineOfOffset(position.getOffset());
				int line = getRulerInfo().getLineOfLastMouseButtonActivity();
				if (line == markerLine)
					return true;
				// commented because of "1GEUOZ9: ITPJUI:ALL - Confusing UI
				// for
				// multiline Bookmarks and Tasks"
				// return (markerLine <= line && line <=
				// document.getLineOfOffset(position.getOffset() +
				// position.getLength()));
			} catch (BadLocationException x) {
				//
			}
		}
		return false;
	}
}
