/*******************************************************************************
 * Copyright (c) 203, 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.ui.internal.browser;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.part.EditorPart;
/**
 * An integrated Web browser, defined as an editor to make
 * better use of the desktop.
 */
public class WebBrowserEditor extends EditorPart implements IBrowserViewerContainer {
	public static final String WEB_BROWSER_EDITOR_ID = "org.eclipse.ui.browser.editor"; //$NON-NLS-1$

	protected BrowserViewer webBrowser;
	protected String initialURL;
	protected Image image;

	protected TextAction cutAction;
	protected TextAction copyAction;
	protected TextAction pasteAction;
	
	private boolean disposed;
	private boolean lockName;

	/**
	 * WebBrowserEditor constructor comment.
	 */
	public WebBrowserEditor() {
		super();
	}
	
	/*
	 * Creates the SWT controls for this workbench part.
	 */
	public void createPartControl(Composite parent) {
		WebBrowserEditorInput input = getWebBrowserEditorInput();
		
		int style = 0;
		if (input == null || input.isLocationBarLocal()) {
			style += BrowserViewer.LOCATION_BAR;
		}
		if (input == null || input.isToolbarLocal()) {
			style += BrowserViewer.BUTTON_BAR;
		}
		webBrowser = new BrowserViewer(parent, style);
		
		webBrowser.setURL(initialURL);
		webBrowser.setContainer(this);
		
		if (input == null || input.isLocationBarLocal()) {
			cutAction = new TextAction(webBrowser, TextAction.CUT);
			copyAction = new TextAction(webBrowser, TextAction.COPY);
			pasteAction = new TextAction(webBrowser, TextAction.PASTE);
		}
		
		if (!lockName) {
			PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
				public void propertyChange(PropertyChangeEvent event) {
					if (BrowserViewer.PROPERTY_TITLE.equals(event.getPropertyName())) {
						setPartName((String) event.getNewValue());
					}
				}
			};
			webBrowser.addPropertyChangeListener(propertyChangeListener);
		}
	}
	
	public void dispose() {
		if (image != null && !image.isDisposed())
			image.dispose();
		image = null;

		super.dispose();
		// mark this instance as disposed to avoid stale references
		disposed = true;
	}
	
	public boolean isDisposed() {
		return disposed;
	}
	
	/* (non-Javadoc)
	 * Saves the contents of this editor.
	 */
	public void doSave(IProgressMonitor monitor) {
		// do nothing
	}

	/* (non-Javadoc)
	 * Saves the contents of this editor to another object.
	 */
	public void doSaveAs() {
		// do nothing
	}
	
	/**
	 * Returns the copy action.
	 *
	 * @return org.eclipse.jface.action.IAction
	 */
	public IAction getCopyAction() {
		return copyAction;
	}
	
	/**
	 * Returns the cut action.
	 *
	 * @return org.eclipse.jface.action.IAction
	 */
	public IAction getCutAction() {
		return cutAction;
	}
	
	/**
	 * Returns the web editor input, if available. If the input was of
	 * another type, <code>null</code> is returned.
	 *
	 * @return org.eclipse.ui.internal.browser.IWebBrowserEditorInput
	 */
	protected WebBrowserEditorInput getWebBrowserEditorInput() {
		IEditorInput input = getEditorInput();
		if (input instanceof WebBrowserEditorInput)
			return (WebBrowserEditorInput) input;
		return null;
	}

	/**
	 * Returns the paste action.
	 *
	 * @return org.eclipse.jface.action.IAction
	 */
	public IAction getPasteAction() {
		return pasteAction;
	}

	/* (non-Javadoc)
	 * Initializes the editor part with a site and input.
	 */
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		Trace.trace(Trace.FINEST, "Opening browser: " + input); //$NON-NLS-1$
		if (input instanceof IPathEditorInput) {
			IPathEditorInput pei = (IPathEditorInput) input;
			IPath path = pei.getPath();
			URL url = null;
			try {
				if (path != null)
					url = path.toFile().toURL();
				initialURL = url.toExternalForm();
			} catch (Exception e) {
				Trace.trace(Trace.SEVERE, "Error getting URL to file"); //$NON-NLS-1$
			}
			if (webBrowser != null) {
				if (initialURL != null)
					webBrowser.setURL(initialURL);
				site.getWorkbenchWindow().getActivePage().activate(this);
			}
			
			setPartName(path.lastSegment());
			if (url != null)
				setTitleToolTip(url.getFile());

			Image oldImage = image;
			ImageDescriptor id = ImageResource.getImageDescriptor(ImageResource.IMG_INTERNAL_BROWSER);
			image = id.createImage();

			setTitleImage(image);
			if (oldImage != null && !oldImage.isDisposed())
				oldImage.dispose();
			//addResourceListener(file);
		} else if (input instanceof WebBrowserEditorInput) {
			WebBrowserEditorInput wbei = (WebBrowserEditorInput) input;
			initialURL = null;
			if (wbei.getURL() != null)
				initialURL = wbei.getURL().toExternalForm();
			if (webBrowser != null) {
				webBrowser.setURL(initialURL);
				site.getWorkbenchWindow().getActivePage().activate(this);
			}
	
			setPartName(wbei.getName());
			setTitleToolTip(wbei.getToolTipText());
			lockName = wbei.isNameLocked();

			Image oldImage = image;
			ImageDescriptor id = wbei.getImageDescriptor();
			image = id.createImage();

			setTitleImage(image);
			if (oldImage != null && !oldImage.isDisposed())
				oldImage.dispose();
		} else
			throw new PartInitException(NLS.bind(Messages.errorInvalidEditorInput, input.getName()));
		
		setSite(site);
		setInput(input);
	}
	
	/* (non-Javadoc)
	 * Returns whether the contents of this editor have changed since the last save
	 * operation.
	 */
	public boolean isDirty() {
		return false;
	}
	
	/* (non-Javadoc)
	 * Returns whether the "save as" operation is supported by this editor.
	 */
	public boolean isSaveAsAllowed() {
		return false;
	}

	/**
	 * Open the input in the internal Web browser.
	 */
	public static void open(WebBrowserEditorInput input) {
		IWorkbenchWindow workbenchWindow = WebBrowserUIPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow();
		IWorkbenchPage page = workbenchWindow.getActivePage();

		try {
			IEditorReference[] editors = page.getEditorReferences();
			int size = editors.length;
			for (int i = 0; i < size; i++) {
				if (WEB_BROWSER_EDITOR_ID.equals(editors[i].getId())) {
					IEditorPart editor = editors[i].getEditor(true);
					if (editor != null && editor instanceof WebBrowserEditor) {
						WebBrowserEditor webEditor = (WebBrowserEditor) editor;
						WebBrowserEditorInput input2 = webEditor.getWebBrowserEditorInput();
						if (input2 == null || input.canReplaceInput(input2)) {
							editor.init(editor.getEditorSite(), input);
							return;
						}
					}
				}
			}
			
			page.openEditor(input, WebBrowserEditor.WEB_BROWSER_EDITOR_ID);
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error opening Web browser", e); //$NON-NLS-1$
		}
	}
	
	/*
	 * Asks this part to take focus within the workbench.
	 */
	public void setFocus() {
		if (webBrowser != null)
			webBrowser.setFocus();
	}

	/**
	 * Close the editor correctly.
	 */
	public boolean close() {
        final boolean [] result = new boolean[1];
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				result[0] = getEditorSite().getPage().closeEditor(WebBrowserEditor.this, false);
			}
		});
        return result[0];
	}
	
    public IActionBars getActionBars() {
        return getEditorSite().getActionBars();
    }

    public void openInExternalBrowser(String url) {
        final IEditorInput input = getEditorInput();
        final String id = getEditorSite().getId();
        Runnable runnable = new Runnable() {
            public void run() {
                doOpenExternalEditor(id, input);
            }
        };
        Display display = getSite().getShell().getDisplay();
        close();
        display.asyncExec(runnable);
    }
    
    protected void doOpenExternalEditor(String id, IEditorInput input) {
        IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
        String name = input.getName();
        IEditorDescriptor [] editors = registry.getEditors(name);
        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();

        String editorId = null;
        for (int i = 0; i < editors.length; i++) {
            IEditorDescriptor editor = editors[i];
            if (editor.getId().equals(id))
                continue;
            editorId = editor.getId();
            break;
        } 
        
        IEditorDescriptor ddesc = registry.getDefaultEditor(name);
        if (ddesc!=null && ddesc.getId().equals(id)) {
            int dot = name.lastIndexOf('.');
            String ext = name;
            if (dot!= -1)
                ext = "*."+name.substring(dot+1); //$NON-NLS-1$
            registry.setDefaultEditor(ext, null);
        }
 
         if (editorId==null) {
            // no editor
            // next check with the OS for an external editor
            if (registry.isSystemExternalEditorAvailable(name))
                editorId = IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID;
        }

        if (editorId!=null) {
            try {
                page.openEditor(input, editorId);
                return;
            } catch (PartInitException e) {
					// ignore
            }
        }
        
        // no registered editor - open using browser support
        try {
            URL theURL = new URL(webBrowser.getURL());
            IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
            support.getExternalBrowser().openURL(theURL);
        }
        catch (MalformedURLException e) {
            //TODO handle this
        }
        catch (PartInitException e) {
            //TODO handle this
        }
    }
}