/*******************************************************************************
 * Copyright (c) 2005, 2013 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.swt.browser;

import java.io.File;
import java.util.*;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.mozilla.*;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.widgets.*;

class MozillaDelegate {
	Browser browser;
	Vector<Composite> childWindows = new Vector<Composite> (9);
	static long /*int*/ MozillaProc;
	static Callback SubclassProc;
	
	static Boolean IsXULRunner24;
	static final String LIB_XPCOM = "xpcom.dll"; //$NON-NLS-1$
	static final String LIB_XUL = "xul.dll"; //$NON-NLS-1$

MozillaDelegate (Browser browser) {
	super ();
	this.browser = browser;
}

static Browser findBrowser (long /*int*/ handle) {
	Display display = Display.getCurrent ();
	return (Browser)display.findWidget (handle);
}

static String getCacheParentPath () {
	/* Use the character encoding for the default locale */
	TCHAR buffer = new TCHAR (0, OS.MAX_PATH);
	if (OS.SHGetFolderPath (0, OS.CSIDL_LOCAL_APPDATA, 0, OS.SHGFP_TYPE_CURRENT, buffer) == OS.S_OK) {
		return buffer.toString (0, buffer.strlen ()) + Mozilla.SEPARATOR_OS + "eclipse"; //$NON-NLS-1$
	}
	return getProfilePath ();
}

static String[] getJSLibraryNames () {
	return new String[] {"mozjs.dll", "xul.dll"}; //$NON-NLS-1$ //$NON-NLS-2$
}

static String getJSLibraryName_Pre10 () {
	return "js3250.dll"; //$NON-NLS-1$
}

static String getLibraryName (String mozillaPath) {
	/*
	 * The name of the Gecko library to glue to changed between the XULRunner 10 and
	 * 24 releases.  However it's not possible to programmatically know the version
	 * of a XULRunner that's being used before it has been glued.  To determine the
	 * appropriate Gecko library name to return, look for the presence of an "xpcom"
	 * library in the mozilla path, which is present in all supported XULRunner releases
	 * prior to XULRunner 24.  If this library is there then return it, and if it's not
	 * there then assume that XULRunner 24 is being used and return the new library name
	 * instead ("xul").
	 */
	if (IsXULRunner24 == null) { /* IsXULRunner24 not yet initialized */
		IsXULRunner24 = new File (mozillaPath, LIB_XPCOM).exists () ? Boolean.FALSE : Boolean.TRUE;
	}
	return IsXULRunner24.booleanValue () ? LIB_XUL : LIB_XPCOM;
}

static String getProfilePath () {
	String baseDir;
	/* Use the character encoding for the default locale */
	TCHAR buffer = new TCHAR (0, OS.MAX_PATH);
	if (OS.SHGetFolderPath (0, OS.CSIDL_APPDATA, 0, OS.SHGFP_TYPE_CURRENT, buffer) == OS.S_OK) {
		baseDir = buffer.toString (0, buffer.strlen ());
	} else {
		baseDir = System.getProperty("user.home"); //$NON-NLS-1$
	}
	return baseDir + Mozilla.SEPARATOR_OS + "Mozilla" + Mozilla.SEPARATOR_OS + "eclipse"; //$NON-NLS-1$ //$NON-NLS-2$
}

static String getSWTInitLibraryName () {
	return "swt-xulrunner"; //$NON-NLS-1$
}

static void loadAdditionalLibraries (String mozillaPath, boolean isGlued) {
}

static char[] mbcsToWcs (String codePage, byte[] buffer) {
	char[] chars = new char[buffer.length];
	int charCount = OS.MultiByteToWideChar (OS.CP_ACP, OS.MB_PRECOMPOSED, buffer, buffer.length, chars, chars.length);
	if (charCount == chars.length) return chars;
	char[] result = new char[charCount];
	System.arraycopy (chars, 0, result, 0, charCount);
	return result;
}

static boolean needsSpinup () {
	return false;
}

static byte[] wcsToMbcs (String codePage, String string, boolean terminate) {
	int byteCount;
	char[] chars = new char[string.length()];
	string.getChars (0, chars.length, chars, 0);
	byte[] bytes = new byte[byteCount = chars.length * 2 + (terminate ? 1 : 0)];
	byteCount = OS.WideCharToMultiByte (OS.CP_ACP, 0, chars, chars.length, bytes, byteCount, null, null);
	if (terminate) {
		byteCount++;
	} else {
		if (bytes.length != byteCount) {
			byte[] result = new byte[byteCount];
			System.arraycopy (bytes, 0, result, 0, byteCount);
			bytes = result;
		}
	}
	return bytes;
}

static long /*int*/ windowProc (long /*int*/ hwnd, long /*int*/ msg, long /*int*/ wParam, long /*int*/ lParam) {
	switch ((int)/*64*/msg) {
		case OS.WM_UPDATEUISTATE:
			/*
			 * In XULRunner 17, calling the default windowProc for WM_UPDATEUISTATE message
			 * terminates the program. Workaround is to prevent the call to default windowProc.
			 */
			return 0;
		case OS.WM_ERASEBKGND:
			RECT rect = new RECT ();
			OS.GetClientRect (hwnd, rect);
			OS.FillRect (wParam, rect, OS.GetSysColorBrush (OS.COLOR_WINDOW));
			break;
	}
	return OS.CallWindowProc (MozillaProc, hwnd, (int)/*64*/msg, wParam, lParam);
}

void addWindowSubclass () {
	long /*int*/ hwndChild = OS.GetWindow (browser.handle, OS.GW_CHILD);
	if (SubclassProc == null) {
		SubclassProc = new Callback (MozillaDelegate.class, "windowProc", 4); //$NON-NLS-1$
		MozillaProc = OS.GetWindowLongPtr (hwndChild, OS.GWL_WNDPROC);
	}
	OS.SetWindowLongPtr (hwndChild, OS.GWL_WNDPROC, SubclassProc.getAddress ());
}

int createBaseWindow (nsIBaseWindow baseWindow) {
	return baseWindow.Create ();
}

long /*int*/ getHandle () {
	return browser.handle;
}

Point getNativeSize (int width, int height) {
	return new Point (width, height);
}

long /*int*/ getSiteWindow () {
	/*
	* As of XULRunner 4, XULRunner's printing facilities on Windows destroy
	* the HWND that is returned from here once the print dialog is dismissed
	* (originating bug: https://bugzilla.mozilla.org/show_bug.cgi?id=588735 ).
	* For this scenario it is now expected that the handle that is returned
	* here is a child of the browser handle, not the browser handle itself.
	*
	* The other scenario that requests this handle is the Mozilla.getBrowser()
	* implementation.  This method's GetSiteWindow() invocation is surrounded
	* by boolean flags to help differentiate it from the printing scenario,
	* since Mozilla.getBrowser() does not destroy the handle it receives back.
	*
	* All children that are created here are stored and then destroyed once
	* the current page is left.  This is guard code that should only be needed
	* if Mozilla.getSiteWindow() is ever invoked by a path other than one of
	* the two described above. 
	*/
	if (!MozillaVersion.CheckVersion (MozillaVersion.VERSION_XR10) || Mozilla.IsGettingSiteWindow) {
		return getHandle ();
	}

	Composite child = new Composite (browser, SWT.NONE);
	childWindows.add (child);
	return child.handle;
}

void handleFocus () {
}

void handleMouseDown () {
}

boolean hookEnterExit () {
	return true;
}

void init () {
	if (MozillaVersion.CheckVersion (MozillaVersion.VERSION_XR10)) {
		/*
		* In XULRunner versions > 4, sending WM_GETDLGCODE to a WM_KEYDOWN's MSG hwnd answers 0
		* instead of the expected DLGC_WANTALLKEYS.  This causes the default traversal framework
		* perform traversals outside of the Browser when it should not.  Hook a Traverse listener
		* to work around these problems.
		*/
		browser.addListener (SWT.Traverse, new Listener () {
			public void handleEvent (Event event) {
				switch (event.detail) {
					case SWT.TRAVERSE_RETURN:
					case SWT.TRAVERSE_ESCAPE: {
						/* always veto the traversal */
						event.doit = false;
						break;
					}
					case SWT.TRAVERSE_TAB_NEXT:
					case SWT.TRAVERSE_TAB_PREVIOUS: {
						/* veto the traversal whenever an element in the browser has focus */
						long /*int*/[] result = new long /*int*/[1];
						int rc = XPCOM.NS_GetServiceManager (result);
						if (rc != XPCOM.NS_OK) Mozilla.error (rc);
						if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE);
						nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
						result[0] = 0;
						byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_FOCUSMANAGER_CONTRACTID, true);
						rc = serviceManager.GetServiceByContractID (aContractID, IIDStore.GetIID (nsIFocusManager.class, MozillaVersion.VERSION_XR10), result);
						serviceManager.Release ();

						if (rc == XPCOM.NS_OK && result[0] != 0) {
							nsIFocusManager focusManager = new nsIFocusManager (result[0]);
							result[0] = 0;
							rc = focusManager.GetFocusedElement (result);
							focusManager.Release ();
							event.doit = result[0] == 0;
							if (rc == XPCOM.NS_OK && result[0] != 0) {
								new nsISupports (result[0]).Release ();
							}
						}
						break;
					}
				}
			}
		});

		/* children created in getSiteHandle() should be destroyed whenever a page is left */
		browser.addLocationListener (new LocationAdapter () {
			public void changing (LocationEvent event) {
				Iterator<Composite> it = childWindows.iterator ();
				while (it.hasNext ()) {
					it.next ().dispose ();
				}
				childWindows.clear ();
			}
		});
	}
}

void onDispose (long /*int*/ embedHandle) {
	if (SubclassProc == null) return;
	long /*int*/ hwndChild = OS.GetWindow (browser.handle, OS.GW_CHILD);
	OS.SetWindowLongPtr (hwndChild, OS.GWL_WNDPROC, MozillaProc);
	childWindows = null;
	browser = null;
}

void removeWindowSubclass () {
	long /*int*/ hwndChild = OS.GetWindow (browser.handle, OS.GW_CHILD);
	if (SubclassProc != null) {
		OS.SetWindowLongPtr (hwndChild, OS.GWL_WNDPROC, MozillaProc);
	}
}

boolean sendTraverse () {
	return false;
}

void setSize (long /*int*/ embedHandle, int width, int height) {
}
}
