//------------------------------------------------------------------------------
// Copyright (c) 2005, 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.views;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLDecoder;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.layout.BrowsingLayoutSettings;
import org.eclipse.epf.library.layout.ElementLayoutManager;
import org.eclipse.epf.library.layout.HtmlBuilder;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationAdapter;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.OpenWindowListener;
import org.eclipse.swt.browser.StatusTextEvent;
import org.eclipse.swt.browser.StatusTextListener;
import org.eclipse.swt.browser.WindowEvent;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;


/**
 * Displays the HTML representation of a Method element in a SWT Browser.
 * 
 * @author Jinhua Xi
 * @author Kelvin Low
 * @since 1.0
 */
public class ElementHTMLViewer {

//	// The default HTML wrappers for disabling the "Display Tree Browser" link
//	// in the HTML content pages.
//	private static final String DEFAULT_CONTENT_WRAPPER_START = "<html><head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"></head><title>Rational Unfied Process</title>" //$NON-NLS-1$
//			+ "<script language=\"javascript\">function init() { parent.ory_toc=\"disable\"; parent.contentframe.location=\""; //$NON-NLS-1$
//
//	private static final String DEFAULT_CONTENT_WRAPPER_END = "\"; }</script></head>" //$NON-NLS-1$
//			+ "<frameset rows=\"100%,*\" frameborder=\"no\" border=\"0\" framespacing=\"0\" id=\"contentframeset\" name=\"contentframeset\">" //$NON-NLS-1$
//			+ "<frame src=\"about:blank\" id=\"contentframe\" name=\"contentframe\" scrolling=\"auto\"/>" //$NON-NLS-1$
//			+ "<frame src=\"about:blank\" id=\"blankframe\" name=\"blankframe\" onload=\"init()\"/>" //$NON-NLS-1$
//			+ "</frameset></html>"; //$NON-NLS-1$

//	// The default HTML wrappers for printing the process content pages.
//	private static final String DEFAULT_PRINT_WRAPPER_START = DEFAULT_CONTENT_WRAPPER_START
//			+ "print();"; //$NON-NLS-1$
//
//	private static final String DEFAULT_PRINT_WRAPPER_END = DEFAULT_CONTENT_WRAPPER_END;
//
//	private static final String PRINT_FILE = "print.html"; //$NON-NLS-1$

	// The HTML wrappers for disabling the "Display Tree Browser" link in the
	// HTML content pages.
//	private String contentWrapperSart;
//
//	private String contentWrapperEnd;

//	// The HTML wrappers for printing the HTML content pages.
//	private String printWrapperSart;
//
//	private String printWrapperEnd;
//
//	// The built-in browser for printing the HTML pages.
//	// don't use a second 
//	private Browser printBrowser;

	protected Browser browser = null;

	protected Composite parent;

	private String currentLocation = null;

	// save the current text from the status listener
	// we need this to open browser with this url 
	// since under linux browser can't be opened automatically, which is really bad
	private String currentText = null;
	private HtmlBuilder htmlBuilder;

	private Cursor waitCursor = null;

	/**
	 * Creates a new instance.
	 */
	public ElementHTMLViewer(Composite parent) {
		this.parent = parent;
		htmlBuilder = new HtmlBuilder();
		createControl();
	}

	/**
	 * Creates the SWT browser controls for viewing and printing the HTML
	 * content pages.
	 */
	private void createControl() {
		try {
			browser = new Browser(parent, SWT.NONE);
			browser.setLayoutData(new GridData(GridData.FILL_BOTH|GridData.GRAB_VERTICAL));
			browser.addLocationListener(new LocationAdapter() {
				public void changed(LocationEvent e) {
					//System.out.println("location changed");
				}

				public void changing(LocationEvent e) {
					//System.out.println("location changing...");
					// Get the current location.
					String location = getElementUrl(e.location);
//					System.out.println("e.location: " + e.location);
//					System.out.println("location: " + location);
					if ( location == null || location.startsWith(ResourceHelper.URL_STR_JAVASCRIPT))
					{
						int ix = e.location.indexOf(".html?proc=");//$NON-NLS-1$
						if (ix > 0) {
							String str =  e.location.substring(0, ix + 5);
//							System.out.println("str: " + str);
							 location = getElementUrl(str);
							 if (location == null) {
								 return;
							 }
						} else {
							return;
						}
					}
					if (isLocationChanged(location)) {
						// Save the current location for printing purposes.
						currentLocation = location;
						generateHtml(currentLocation);
					}
				}
			});

			browser.addStatusTextListener(new StatusTextListener()
			{
				public void changed(StatusTextEvent event)
				{
					// Get the current text.
					String text = event.text;
					if (text != null && text.length() > 0)
					{
						// Save the current text for application launching purposes.
						currentText = text;
						//System.out.println("Status changed: " + text);
					}
				}
			});
			
			browser.addOpenWindowListener(new OpenWindowListener(){

				public void open(WindowEvent event) {
					// handle open window.
					// with mozilla in linux, open window does not work
					//System.out.println("Open window event: " + event);
					
					// windows can launch the browser without problem
					// linux needs more care
					if (SWT.getPlatform().equals("win32")) //$NON-NLS-1$
					{
						return;
					}
					
					Display.getCurrent().asyncExec(new Runnable()
					{
					    public void run()
						{
							try
							{
//								// if the url is a resource with relative path, find the absolute path
//								if ( currentText.startsWith("file:") )
//								{
//									// get the file path from the 
//								}
																
//								// open another swt browser since we have no (simple) way of creating a system default browser
//								// the Eclipse guys hide all the good apis as internal
								Shell shell = new Shell();
								GridLayout layout = new GridLayout();
								layout.marginHeight = 0;
								layout.marginWidth = 0;
								shell.setLayout(layout);
								Browser popup_browser = new Browser(shell, SWT.NONE);
								popup_browser.setLayoutData(new GridData(GridData.FILL_BOTH|GridData.GRAB_HORIZONTAL|GridData.GRAB_VERTICAL));
								popup_browser.setUrl(currentText);
																
								shell.open();

							}
							catch (Exception e)
							{
								e.printStackTrace();
							}
						}
					});
				}});
			
//			// don't use a seperate browser for printing since this will lose the 
//			// states of the current page, for example, the expanded sections, etc.
//			// Jinhua Xi,  3/5/2007
//			// Create the hidden browser used for printing the HTML content
//			// pages.
//			printBrowser = new Browser(parent, SWT.NONE);
//			printBrowser.setSize(1, 1);
//			printBrowser.setVisible(false);
//
//			// Linux: There is unused space in preview/browsing, which is in grey.
//			// this is needed for linux
//			GridData gd = new GridData();
//			gd.heightHint = 1;
//			printBrowser.setLayoutData(gd);
			
			
			// Read the HTML wrappers for disabling the "Display Tree Browser"
			// link in the HTML content pages.
//			contentWrapperSart = HTMLWrappers
//					.getString("CONTENT_WRAPPER_START"); //$NON-NLS-1$
//			if (contentWrapperSart == null) {
//				contentWrapperSart = DEFAULT_CONTENT_WRAPPER_START;
//			}
//			contentWrapperEnd = HTMLWrappers.getString("CONTENT_WRAPPER_END"); //$NON-NLS-1$
//			if (contentWrapperEnd == null) {
//				contentWrapperEnd = DEFAULT_CONTENT_WRAPPER_START;
//			}

//			// Read the HTML wrappers for printing the HTML content pages.
//			printWrapperSart = HTMLWrappers.getString("PRINT_WRAPPER_START"); //$NON-NLS-1$
//			if (printWrapperSart == null) {
//				printWrapperSart = DEFAULT_PRINT_WRAPPER_START;
//			}
//			printWrapperEnd = HTMLWrappers.getString("PRINT_WRAPPER_END"); //$NON-NLS-1$
//			if (printWrapperEnd == null) {
//				printWrapperEnd = DEFAULT_PRINT_WRAPPER_END;
//			}

			waitCursor = parent.getShell().getDisplay().getSystemCursor(
					SWT.CURSOR_WAIT);
		} catch (Exception e) {
			browser = null;
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
	}

	private boolean isLocationChanged(String location) {
		if (location == null || currentLocation == null) {
			return false;
		}

		if (File.separatorChar != '/') {
			location = location.replace(File.separatorChar, '/');
			String oldLocation = getUrl(currentLocation);

			// Some times the current URL is a full path, so just compare the end.
			
			//  bug in IE6, the location in the location change event might be truncated if the url is too long, 
			// could be up to 159 characters.
			
			return oldLocation.indexOf(location) != 0;
		} else {
			return !location.endsWith(currentLocation)
					&& !currentLocation.endsWith(location);
		}

	}

	/**
	 * Returns the SWT browser that displays the HTML content pages.
	 */
	public Browser getBrowser() {
		return browser;
	}

	/**
	 * Sets focus to this control.
	 */
	public void setFocus() {
		if (browser != null) {
			browser.setFocus();
		}
	}

	/**
	 * Returns the HTML Builder.
	 */
	public HtmlBuilder getHtmlBuilder() {
		
		if ( htmlBuilder != null ) {
			BrowsingLayoutSettings.INSTANCE.update(htmlBuilder);
		}
		return htmlBuilder;
	}

	/**
	 * Sets the HTML Builder.
	 */
	public void setHtmlBuilder(HtmlBuilder builder) {
		this.htmlBuilder = builder;
	}

	/**
	 * Sets the Element Layout Manager.
	 */
	public void setLayoutManager(ElementLayoutManager layoutMgr) {
		htmlBuilder.setLayoutManager(layoutMgr);
	}


	
	/**
	 * Displays the HTML representation for a Method element.
	 */
	public void showElementContent(final Object raw_element) {
		final String[] fileUrlHolder = new String[1];
		try {
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {

				public void run(IProgressMonitor monitor)
				throws InvocationTargetException, InterruptedException {
					try {
						monitor.beginTask("Generating HTML...", IProgressMonitor.UNKNOWN);
						fileUrlHolder[0] = generateHtml(raw_element, getHtmlBuilder());
					} finally {
						monitor.done();
					}

				}

			});
		} catch (InvocationTargetException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		} catch (InterruptedException e1) {
			return;
		}
		if(fileUrlHolder[0] != null) {
			// Set the current location to avoid re-generating the HTML file in
			// respond to a location change.
			currentLocation = fileUrlHolder[0];
			browser.setUrl(currentLocation);
		}
	}

	private String generateHtml(Object raw_element, HtmlBuilder htmlBuilder) {
		return ConfigurationHelper.getDelegate().generateHtml(raw_element, htmlBuilder);
	}

	private void generateHtml(final String url) {
		try {
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {

				public void run(IProgressMonitor monitor)
				throws InvocationTargetException, InterruptedException {
					try {
						monitor.beginTask("Generating HTML...", IProgressMonitor.UNKNOWN);
						getHtmlBuilder().generateHtml(url);
					} finally {
						monitor.done();
					}

				}

			});
		} catch (InvocationTargetException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		} catch (InterruptedException e1) {
			return;
		}
	}

	/**
	 * Returns the element URL.
	 */
	private String getElementUrl(String location) {
		if (location == null || location.length() == 0
				|| location.equals("about:blank")  //$NON-NLS-1$
				|| location.toLowerCase().startsWith(ResourceHelper.URL_STR_JAVASCRIPT)) {
			return null;
		}

		location = getUrl(location);
		if (location.indexOf(ResourceHelper.MISSING_PAGES_FOLDER) >= 0) {
			return null;
		}

		// make sure the url is an element url, check the guid
		if ( ResourceHelper.getGuidFromFileName(location) == null )
		{
			return null;
		}
		return location;
	}

	/**
	 * Returns the URL for the given location.
	 */
	private String getUrl(String location) {
		String publish_dir = getHtmlBuilder().getPublishDir();
		String url = fixPath(location);
		int index = url.toLowerCase().indexOf(
				fixPath(publish_dir).toLowerCase());
		if (index >= 0) {
			url = url.substring(index + publish_dir.length());
		}
		index = url.indexOf("#"); //$NON-NLS-1$
		if (index > 0) {
			url = url.substring(0, index);
		}
		return url;
	}

	private String fixPath(String path) {
		try {
			String platform = SWT.getPlatform();
			if ("win32".equals(platform) || "wpf".equals(platform)) { //$NON-NLS-1$ //$NON-NLS-2$
			// org.eclipse.swt.browser.IE
				path = URLDecoder.decode(path, "ISO-8859-1"); //$NON-NLS-1$
			} else {
				// org.eclipse.swt.browser.Mozilla
				path = URLDecoder.decode(path, "UTF-8"); //$NON-NLS-1$
			}
			if (File.separatorChar != '/') {
				return path.replace(File.separatorChar, '/');
			}
			return path;
		} catch (UnsupportedEncodingException e) {
			return ""; //$NON-NLS-1$
		}
	}

	/**
	 * Prints the current HTML page.
	 */
	public void print() {
		boolean b = this.browser.execute("window.print();"); //$NON-NLS-1$
//		if ( !b ) {
//			final String printFile = htmlBuilder.getPublishDir() + PRINT_FILE;
//			if (currentLocation != null) {
//				StringBuffer wrapperHTML = new StringBuffer();
//				wrapperHTML.append(printWrapperSart).append(currentLocation)
//						.append(printWrapperEnd);
//				String htmlText = wrapperHTML.toString();
//				if (FileUtil.writeUTF8File(printFile, htmlText)) {
//					printBrowser.setUrl(printFile);
//				}
//			}
//		}
	}

	private void startWait() {
		parent.getShell().setCursor(waitCursor);
	}

	private void endWait() {
		parent.getShell().setCursor(null);
	}

	/**
	 * Refreshes the content.
	 * <p>
	 * Regenerates the content before refreshing the browser.
	 * 
	 */
	public void refresh() {
		generateHtml(currentLocation);
		browser.refresh();
	}

}
