/*******************************************************************************
 * Copyright (c) 2003, 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.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.ui.PlatformUI;
/**
 * Utility class for the Web browser tools.
 */
public class WebBrowserUtil {
	private static final String BROWSER_PACKAGE_NAME = "org.eclipse.swt.browser.Browser"; //$NON-NLS-1$

	public static Boolean isInternalBrowserOperational;

	private static final char STYLE_SEP = '-';

	private static final int DEFAULT_STYLE = BrowserViewer.BUTTON_BAR
			| BrowserViewer.LOCATION_BAR;

	/**
	 * WebBrowserUtil constructor comment.
	 */
	public WebBrowserUtil() {
		super();
	}

	/**
	 * Returns true if we're running on Windows.
	 * 
	 * @return boolean
	 */
	public static boolean isWindows() {
		String os = System.getProperty("os.name"); //$NON-NLS-1$
		if (os != null && os.toLowerCase().indexOf("win") >= 0) //$NON-NLS-1$
			return true;
		return false;
	}

	/**
	 * Returns true if we're running on linux.
	 * 
	 * @return boolean
	 */
	public static boolean isLinux() {
		String os = System.getProperty("os.name"); //$NON-NLS-1$
		if (os != null && os.toLowerCase().indexOf("lin") >= 0) //$NON-NLS-1$
			return true;
		return false;
	}

	/**
	 * Open a dialog window.
	 * 
	 * @param message
	 *            java.lang.String
	 */
	public static void openError(String message) {
		Display d = Display.getCurrent();
		if (d == null)
			d = Display.getDefault();

		Shell shell = d.getActiveShell();
		MessageDialog.openError(shell, Messages.errorDialogTitle, message);
	}

	/**
	 * Open a dialog window.
	 * 
	 * @param message
	 *            java.lang.String
	 */
	public static void openMessage(String message) {
		Display d = Display.getCurrent();
		if (d == null)
			d = Display.getDefault();

		Shell shell = d.getActiveShell();
		MessageDialog.openInformation(shell, Messages.searchingTaskName,
				message);
	}

	/**
	 * Returns whether it should be possible to use the internal browser or not,
	 * based on whether or not the org.eclipse.swt.Browser class can be
	 * found/loaded. If it can it means is is supported on the platform in which
	 * this plugin is running. If not, disable the ability to use the internal
	 * browser. This method checks to see if it can new up a new
	 * ExternalBrowserInstance. If the SWT widget can not be bound to the
	 * particular operating system it throws an SWTException. We catch that and
	 * set a boolean flag which represents whether or not we were successfully
	 * able to create a ExternalBrowserInstance instance or not. If not, don't
	 * bother adding the Internal Web ExternalBrowserInstance that uses this
	 * widget. Designed to be attemped only once and the flag set used
	 * throughout.
	 * 
	 * @return boolean
	 */
	public static boolean canUseInternalWebBrowser() {
		// if we have already figured this out, don't do it again.
		if (isInternalBrowserOperational != null)
			return isInternalBrowserOperational.booleanValue();

		// check for the class
		try {
			Class.forName(BROWSER_PACKAGE_NAME);
		} catch (ClassNotFoundException e) {
			isInternalBrowserOperational = new Boolean(false);
			return false;
		}

		// try loading it
		Shell shell = null;
		try {
			shell = new Shell(PlatformUI.getWorkbench().getDisplay());
			new Browser(shell, SWT.NONE);
			isInternalBrowserOperational = new Boolean(true);
			return true;
		} catch (Throwable t) {
			WebBrowserUIPlugin.getInstance().getLog().log(
					new Status(IStatus.WARNING, WebBrowserUIPlugin.PLUGIN_ID,
							0, "Internal browser is not available: " + t.getMessage(), null)); //$NON-NLS-1$
			isInternalBrowserOperational = new Boolean(false);
			return false;
		} finally {
			if (shell != null)
				shell.dispose();
		}
	}

	public static boolean canUseSystemBrowser() {
		// Disabling system browser on Solaris due to bug 94497
		if (Platform.OS_SOLARIS.equals(Platform.getOS()))
			return false;
		return Program.findProgram("html") != null; //$NON-NLS-1$
	}

	public static List getExternalBrowserPaths() {
		List paths = new ArrayList();
		Iterator iterator = BrowserManager.getInstance().getWebBrowsers()
				.iterator();
		while (iterator.hasNext()) {
			IBrowserDescriptor wb = (IBrowserDescriptor) iterator.next();
			if (wb != null && wb.getLocation() != null)
				paths.add(wb.getLocation().toLowerCase());
		}
		return paths;
	}

	/**
	 * Add any supported EXTERNAL web browsers found after an arbitrary check in
	 * specific paths
	 */
	public static void addFoundBrowsers(List list) {
		List paths = getExternalBrowserPaths();

		String os = Platform.getOS();
		File[] roots = getUsableDrives(File.listRoots());
		int rootSize = roots.length;

		// Math.min(roots.length, 2); // just check the first two drives

		IBrowserExt[] browsers = WebBrowserUIPlugin.getBrowsers();
		int size = browsers.length;
		for (int i = 0; i < size; i++) {
			if (browsers[i].getDefaultLocations() != null
					&& browsers[i].getOS().toLowerCase().indexOf(os) >= 0) {
				for (int k = 0; k < rootSize; k++) {
					int size2 = browsers[i].getDefaultLocations().length;
					for (int j = 0; j < size2; j++) {
						String location = browsers[i].getDefaultLocations()[j];
						try {
							File f = new File(roots[k], location);
							if (!paths.contains(f.getAbsolutePath()
									.toLowerCase())) {
								if (f.exists()) {
									BrowserDescriptor browser = new BrowserDescriptor();
									browser.name = browsers[i].getName();
									browser.location = f.getAbsolutePath();
									browser.parameters = browsers[i]
											.getParameters();
									list.add(browser);
									j += size2;
								}
							}
						} catch (Exception e) {
							// ignore
						}
					}
				}
			}
		}
	}

	private static File[] getUsableDrives(File[] roots) {
		if (!Platform.getOS().equals(Platform.OS_WIN32))
			return roots;
		ArrayList list = new ArrayList();
		for (int i = 0; i < roots.length; i++) {
			String path = roots[i].getAbsolutePath();
			if (path != null
					&& (path.toLowerCase().startsWith("a:") || path.toLowerCase().startsWith("b:"))) //$NON-NLS-1$ //$NON-NLS-2$
				continue;
			list.add(roots[i]);
		}
		return (File[]) list.toArray(new File[list.size()]);
	}

	/**
	 * Create an external Web browser if the file matches the default (known)
	 * browsers.
	 * 
	 * @param file
	 * @return an external browser working copy
	 */
	public static IBrowserDescriptorWorkingCopy createExternalBrowser(File file) {
		if (file == null || !file.isFile())
			return null;

		String executable = file.getName();
		IBrowserExt[] browsers = WebBrowserUIPlugin.getBrowsers();
		int size = browsers.length;
		for (int i = 0; i < size; i++) {
			if (executable.equals(browsers[i].getExecutable())) {
				IBrowserDescriptorWorkingCopy browser = BrowserManager
						.getInstance().createExternalWebBrowser();
				browser.setName(browsers[i].getName());
				browser.setLocation(file.getAbsolutePath());
				browser.setParameters(browsers[i].getParameters());
				return browser;
			}
		}

		return null;
	}

	/**
	 * Encodes browser style in the secondary id as id-style
	 * 
	 * @param browserId
	 * @param style
	 * @return secondaryId
	 */
	public static String encodeStyle(String browserId, int style) {
		return browserId + STYLE_SEP + style;
	}

	/**
	 * Decodes secondary id into a browser style.
	 * 
	 * @param secondaryId
	 * @return style
	 */
	public static int decodeStyle(String secondaryId) {
		if (secondaryId != null) {
			int sep = secondaryId.lastIndexOf(STYLE_SEP);
			if (sep != -1) {
				String stoken = secondaryId.substring(sep + 1);
				try {
					return Integer.parseInt(stoken);
				} catch (NumberFormatException e) {
					// ignore
				}
			}
		}
		return DEFAULT_STYLE;
	}

	public static String decodeId(String encodedId) {
		int sep = encodedId.lastIndexOf(STYLE_SEP);
		if (sep != -1) {
			return encodedId.substring(0, sep);
		}
		return encodedId;
	}
}