/*******************************************************************************
 * Copyright (c) 2003, 2012 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.util.Hashtable;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.carbon.*;
import org.eclipse.swt.internal.cocoa.*;
import org.eclipse.swt.internal.mozilla.*;
import org.eclipse.swt.widgets.*;

class MozillaDelegate {
	Browser browser;
	int embedHandle;
	Listener listener;
	boolean hasFocus;
	static Callback Callback3;
	static Hashtable handles = new Hashtable ();

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

static Browser findBrowser (int handle) {
	LONG value = (LONG)handles.get (new LONG (handle));
	if (value != null) {
		Display display = Display.getCurrent ();
		return (Browser)display.findWidget (value.value);
	}
	return null;
}

static String getCacheParentPath () {
	return getProfilePath ();
}

static String getLibraryName () {
	return "libxpcom.dylib"; //$NON-NLS-1$
}

static String[] getJSLibraryNames () {
	return new String[] {"libxpcom.dylib"}; //$NON-NLS-1$
}

static String getJSLibraryName_Pre4 () {
	return "libmozjs.dylib"; //$NON-NLS-1$
}

static String getProfilePath () {
	String 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) {
	// workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=727616
//	String utilsPath = mozillaPath + Mozilla.SEPARATOR_OS + "libmozutils.dylib"; //$NON-NLS-1$
//	byte[] bytes = MozillaDelegate.wcsToMbcs (null, utilsPath, true);
//	OS.NSAddImage (bytes, OS.NSADDIMAGE_OPTION_RETURN_ON_ERROR | OS.NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME);
}

static char[] mbcsToWcs (String codePage, byte [] buffer) {
	int encoding = OS.CFStringGetSystemEncoding ();
	int cfstring = OS.CFStringCreateWithBytes (OS.kCFAllocatorDefault, buffer, buffer.length, encoding, false);
	char[] chars = null;
	if (cfstring != 0) {
		int length = OS.CFStringGetLength (cfstring);
		chars = new char [length];
		if (length != 0) {
			CFRange range = new CFRange ();
			range.length = length;
			OS.CFStringGetCharacters (cfstring, range, chars);
		}
		OS.CFRelease (cfstring);
	}
	return chars;
}

static boolean needsSpinup () {
	return false;
}

static boolean supportsXULRunner17 () {
	return false;
}

static byte[] wcsToMbcs (String codePage, String string, boolean terminate) {
	char[] chars = new char [string.length()];
	string.getChars (0, chars.length, chars, 0);
	int cfstring = OS.CFStringCreateWithCharacters (OS.kCFAllocatorDefault, chars, chars.length);
	byte[] buffer = null;
	if (cfstring != 0) {
		CFRange range = new CFRange ();
		range.length = chars.length;
		int encoding = OS.CFStringGetSystemEncoding ();
		int[] size = new int[1];
		int numChars = OS.CFStringGetBytes (cfstring, range, encoding, (byte)'?', true, null, 0, size);
		buffer = new byte [size[0] + (terminate ? 1 : 0)];
		if (numChars != 0) {
			numChars = OS.CFStringGetBytes (cfstring, range, encoding, (byte)'?', true, buffer, size[0], size);
		}
		OS.CFRelease (cfstring);
	}
	return buffer;
}

static int eventProc3 (int nextHandler, int theEvent, int userData) {
	Widget widget = Display.getCurrent ().findWidget (userData);
	if (widget instanceof Browser) {
		Browser browser = (Browser) widget;
		switch (OS.GetEventClass (theEvent)) {
			case OS.kEventClassMouse:
				browser.getShell ().forceActive ();
				((Mozilla)browser.webBrowser).Activate ();
				break;
			case OS.kEventClassKeyboard:
				/*
				* Bug in Carbon.  OSX crashes if a HICocoaView is disposed during a key event,
				* presumably as a result of attempting to use it after its refcount has reached
				* 0.  The workaround is to temporarily add an extra ref to the view while the
				* DOM listener is handling the event, in case the Browser gets disposed in a
				* callback.
				*/
				int result = OS.noErr;
				int handle = browser.handle;
				OS.CFRetain (handle);

				/*
				* Pressing the OSX shortcut to put focus into the menu bar does not work in
				* embedded mozilla.  If this shortcut is not handled here then it falls through
				* all of the key handlers for some reason.  The workaround is to detect this
				* shortcut here and put focus into the menu bar.
				*/
				int [] modifiers = new int [1];
				OS.GetEventParameter (theEvent, OS.kEventParamKeyModifiers, OS.typeUInt32, null, modifiers.length * 4, null, modifiers);
				int [] keyCode = new int [1];
				OS.GetEventParameter (theEvent, OS.kEventParamKeyCode, OS.typeUInt32, null, keyCode.length * 4, null, keyCode);
				if (keyCode [0] == 120 /* F2 */ && (modifiers[0] & (OS.controlKey | OS.cmdKey | OS.optionKey)) == OS.controlKey) {
					int[] event = new int[1];
					OS.CreateEvent (0, OS.kEventClassApplication, OS.kEventAppFocusMenuBar, 0.0, 0, event);
					if (event [0] != 0) {
						OS.SetEventParameter (event [0], OS.kEventParamKeyModifiers, OS.typeUInt32, 4, modifiers);
						result = OS.SendEventToEventTarget (event [0], OS.GetApplicationEventTarget ());
						OS.ReleaseEvent (event [0]);
					}
				} else {
					result = OS.CallNextEventHandler (nextHandler, theEvent);
				}

				OS.CFRelease (handle);
				return result;
		}
	}
	return OS.eventNotHandledErr;
}

void addWindowSubclass () {
}

int createBaseWindow (nsIBaseWindow baseWindow) {
	/*
	* Feature of Mozilla on OSX.  Mozilla replaces the OSX application menu whenever
	* a browser's base window is created.  The workaround is to restore the previous
	* menu after creating the base window. 
	*/
	int application = Cocoa.objc_msgSend (Cocoa.C_NSApplication, Cocoa.S_sharedApplication);
	int mainMenu = Cocoa.objc_msgSend (application, Cocoa.S_mainMenu);
	if (mainMenu != 0) {
		Cocoa.objc_msgSend (mainMenu, Cocoa.S_retain);
	}
	int rc = baseWindow.Create ();
	if (mainMenu != 0) {
		Cocoa.objc_msgSend (application, Cocoa.S_setMainMenu, mainMenu);
		Cocoa.objc_msgSend (mainMenu, Cocoa.S_release);
	}
	return rc;
}

int getHandle () {
    embedHandle = Cocoa.objc_msgSend (Cocoa.C_NSImageView, Cocoa.S_alloc);
	if (embedHandle == 0) {
		browser.dispose ();
		SWT.error (SWT.ERROR_NO_HANDLES);
	}
	NSRect r = new NSRect ();
	embedHandle = Cocoa.objc_msgSend (embedHandle, Cocoa.S_initWithFrame, r);
	int rc;
	int[] outControl = new int[1];
	rc = Cocoa.HICocoaViewCreate (embedHandle, 0, outControl); /* OSX >= 10.5 */
	if (rc == OS.noErr && outControl[0] != 0) {
		Cocoa.objc_msgSend (embedHandle, Cocoa.S_release);
	} else {
		/* will succeed on OSX 10.4 with an updated vm containing HIJavaViewCreateWithCocoaView */
		try {
			System.loadLibrary ("frameembedding"); //$NON-NLS-1$
		} catch (UnsatisfiedLinkError e) {}
		rc = Cocoa.HIJavaViewCreateWithCocoaView (outControl, embedHandle);
		if (!(rc == OS.noErr && outControl[0] != 0)) {
			browser.dispose ();
			SWT.error (SWT.ERROR_NO_HANDLES);
		}
	}
	int subHIView = outControl[0];
	HILayoutInfo newLayoutInfo = new HILayoutInfo ();
	newLayoutInfo.version = 0;
	OS.HIViewGetLayoutInfo (subHIView, newLayoutInfo);
	HISideBinding biding = newLayoutInfo.binding.top;
	biding.toView = 0;
	biding.kind = OS.kHILayoutBindMin;
	biding.offset = 0;
	biding = newLayoutInfo.binding.left;
	biding.toView = 0;
	biding.kind = OS.kHILayoutBindMin;
	biding.offset = 0;
	biding = newLayoutInfo.binding.bottom;
	biding.toView = 0;
	biding.kind = OS.kHILayoutBindMax;
	biding.offset = 0;
	biding = newLayoutInfo.binding.right;
	biding.toView = 0;
	biding.kind = OS.kHILayoutBindMax;
	biding.offset = 0;
	OS.HIViewSetLayoutInfo (subHIView, newLayoutInfo);
	OS.HIViewChangeFeatures (subHIView, OS.kHIViewFeatureIsOpaque, 0);
	OS.HIViewSetVisible (subHIView, true);
	int parentHandle = browser.handle;
	OS.HIViewAddSubview (browser.handle, subHIView);
	CGRect rect = new CGRect ();
	OS.HIViewGetFrame (parentHandle, rect);
	rect.x = rect.y = 0;
	OS.HIViewSetFrame (subHIView, rect);
	handles.put (new LONG (embedHandle), new LONG (browser.handle));

	if (Callback3 == null) Callback3 = new Callback (this.getClass (), "eventProc3", 3); //$NON-NLS-1$
	int callback3Address = Callback3.getAddress ();
	if (callback3Address == 0) {
		browser.dispose ();
		SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
	}
	int [] mask = new int [] {
		OS.kEventClassMouse, OS.kEventMouseDown,
		OS.kEventClassKeyboard, OS.kEventRawKeyDown,
	};
	int controlTarget = OS.GetControlEventTarget (subHIView);
	OS.InstallEventHandler (controlTarget, callback3Address, mask.length / 2, mask, browser.handle, null);

	return embedHandle;
}

long /*int*/ getSiteWindow () {
	return embedHandle;
}

void handleFocus () {
	if (hasFocus) return;
	hasFocus = true;
	((Mozilla)browser.webBrowser).Activate ();
	browser.setFocus ();
	listener = new Listener () {
		public void handleEvent (Event event) {
			if (event.widget == browser) return;
			((Mozilla)browser.webBrowser).Deactivate ();
			hasFocus = false;
			browser.getDisplay ().removeFilter (SWT.FocusIn, this);
			browser.getShell ().removeListener (SWT.Deactivate, this);
			listener = null;
		}
	
	};
	browser.getDisplay ().addFilter (SWT.FocusIn, listener);
	browser.getShell ().addListener (SWT.Deactivate, listener);
}

void handleMouseDown () {
}

boolean hookEnterExit () {
	return true;
}

void init () {
}

void onDispose (int embedHandle) {
	handles.remove (new LONG (embedHandle));
	if (listener != null) {
		browser.getDisplay ().removeFilter (SWT.FocusIn, listener);
		browser.getShell ().removeListener (SWT.Deactivate, listener);
		listener = null;
	}
	browser = null;
}

void removeWindowSubclass () {
}

boolean sendTraverse () {
	return true;
}

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

}
