/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

var g_logger;

/////////////////////////////////////////////////////////////////////////////
// class StringBuilder
//
function StringBuilder(initStr) {
    this.strings = new Array("");
    this.append(initStr);
}

StringBuilder.prototype = {
	append : function (str) {
	    if (str) {
	        this.strings.push(str);
	    }
	    return this;
	},

	clear : function() {
	    this.strings.length = 1;
	    return this;
	},

	toString: function() {
	    return this.strings.join("");
	}
};


function getCurrentLanguage() {
	if(acceptLanguages) {
		var tokens = acceptLanguages.split(',');
		if(tokens.length > 0)
			return tokens[0];

		return "en-us";
	} else {
		return "en-us";
	}
}

/////////////////////////////////////////////////////////////////////////////
// class KeyboardMapper
//
function KeyboardMapper() {
	this.mappedInput = [];
	this.jsX11KeysymMap = [];
	this.jsKeyPressX11KeysymMap = [];
}

//
// RAW keyboard
// 		Primarily translates KeyDown/KeyUp event, either as is (if there is no mapping entry)
// 		or through mapped result.
//
// 		For KeyPress event, it translates it only if there exist a mapping entry
// 		in jsX11KeysymMap map and the entry meets the condition
//
// COOKED keyboard
//		Primarily translates KeyPress event, either as is or through mapped result
//		It translates KeyDown/KeyUp only there exists a mapping entry, or if there
//		is no mapping entry, translate when certain modifier key is pressed (i.e.,
//		CTRL or ALT key
//
// Mapping entry types
//		direct		:	will be directly mapped into the entry value with the same event type
//		boolean		:	only valid for jsX11KeysymMap, existence of this type, no matter true or false
//						in value, corresponding KeyDown/KeyUp event will be masked
//		array		:	contains a set of conditional mapping entry
//
// Conditional mapping entry
//
//		{
//			type: <event type>, code: <mapped key code>, modifiers: <modifiers>,
//		  	shift : <shift state match condition>,		-- match on shift state
//			guestos : <guest os match condition>,		-- match on guestos type
//			browser: <browser type match condition>,	-- match on browser
//			browserVersion: <brower version match condition>	-- match on browser version
//		}
//
KeyboardMapper.KEYBOARD_TYPE_RAW = 0;
KeyboardMapper.KEYBOARD_TYPE_COOKED = 1;
KeyboardMapper.KEYBOARD_TYPE_UK = 2;
KeyboardMapper.KEYBOARD_TYPE_FR = 3;

KeyboardMapper.prototype = {

	setKeyboardType : function(keyboardType) {
		this.keyboardType = keyboardType;
		if(keyboardType == KeyboardMapper.KEYBOARD_TYPE_COOKED || keyboardType == KeyboardMapper.KEYBOARD_TYPE_UK || keyboardType == KeyboardMapper.KEYBOARD_TYPE_FR) {
			// initialize mapping for COOKED keyboard
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_CAPSLOCK] 		= AjaxViewer.X11_KEY_CAPSLOCK;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_BACKSPACE] 		= AjaxViewer.X11_KEY_BACKSPACE;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_TAB] 				= AjaxViewer.X11_KEY_TAB;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_ENTER] 			= AjaxViewer.X11_KEY_ENTER;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_ESCAPE] 			= AjaxViewer.X11_KEY_ESCAPE;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_INSERT] 			= AjaxViewer.X11_KEY_INSERT;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_DELETE] 			= AjaxViewer.X11_KEY_DELETE;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_HOME] 			= AjaxViewer.X11_KEY_HOME;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_END] 				= AjaxViewer.X11_KEY_END;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEUP] 			= AjaxViewer.X11_KEY_PAGEUP;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_PAGEDOWN] 		= AjaxViewer.X11_KEY_PAGEDOWN;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_LEFT] 			= AjaxViewer.X11_KEY_LEFT;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_UP] 				= AjaxViewer.X11_KEY_UP;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_RIGHT] 			= AjaxViewer.X11_KEY_RIGHT;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_DOWN] 			= AjaxViewer.X11_KEY_DOWN;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F1] 				= AjaxViewer.X11_KEY_F1;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F2] 				= AjaxViewer.X11_KEY_F2;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F3] 				= AjaxViewer.X11_KEY_F3;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F4] 				= AjaxViewer.X11_KEY_F4;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F5] 				= AjaxViewer.X11_KEY_F5;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F6] 				= AjaxViewer.X11_KEY_F6;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F7] 				= AjaxViewer.X11_KEY_F7;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F8] 				= AjaxViewer.X11_KEY_F8;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F9] 				= AjaxViewer.X11_KEY_F9;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F10] 				= AjaxViewer.X11_KEY_F10;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F11] 				= AjaxViewer.X11_KEY_F11;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_F12] 				= AjaxViewer.X11_KEY_F12;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_SHIFT] 			= AjaxViewer.X11_KEY_SHIFT;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_CTRL] 			= AjaxViewer.X11_KEY_CTRL;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_ALT] 				= AjaxViewer.X11_KEY_ALT;
			this.jsX11KeysymMap[AjaxViewer.JS_KEY_SELECT_KEY] 		= AjaxViewer.X11_KEY_SELECT_KEY;
			//this.jsX11KeysymMap[AjaxViewer.JS_KEY_DECIMAL_POINT] 	= AjaxViewer.X11_KEY_DECIMAL_POINT;
			this.jsKeyPressX11KeysymMap[45] 				= [{type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SUBSTRACT, modifiers: 0, shift: true },
															   {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SUBSTRACT, modifiers: 0, shift: true },
															   {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SUBSTRACT, modifiers: 0, shift: false },
															   {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SUBSTRACT, modifiers: 0, shift: false }];
			this.jsKeyPressX11KeysymMap[47] 				= [{type: AjaxViewer.KEY_DOWN, code: 0x2f, modifiers: 0, shift: true },
															   {type: AjaxViewer.KEY_UP, code: 0x2f, modifiers: 0, shift: true },
															   {type: AjaxViewer.KEY_DOWN, code: 0x2f, modifiers: 0, shift: false },
															   {type: AjaxViewer.KEY_UP, code: 0x2f, modifiers: 0, shift: false }];
		}
	},
	RawkeyboardInputHandler : function(eventType, code, modifiers, guestos, browser, browserVersion) {
		if(eventType == AjaxViewer.KEY_DOWN || eventType == AjaxViewer.KEY_UP) {

			// special handling for Alt + Ctrl + Ins, convert it into Alt-Ctrl-Del
			if(code == AjaxViewer.JS_KEY_INSERT) {
				if((modifiers & AjaxViewer.ALT_KEY_MASK) != 0 && (modifiers & AjaxViewer.CTRL_KEY_MASK) != 0) {
					this.mappedInput.push({type : eventType, code: 0xffff, modifiers: modifiers});
					return;
				}
			}

			var X11Keysym = code;
			if(this.jsX11KeysymMap[code] != undefined && (guestos == 'windows' || modifiers != AjaxViewer.SHIFT_KEY_MASK || code == AjaxViewer.JS_KEY_CAPSLOCK)) {
				X11Keysym = this.jsX11KeysymMap[code];
				if(typeof this.jsX11KeysymMap[code] == "boolean") {
					return;
				} else if($.isArray(X11Keysym)) {
					for(var i = 0; i < X11Keysym.length; i++) {
					// How to set the guestos, browser, version value??? add later
						if(this.isConditionalEntryMatched(eventType, code, modifiers, X11Keysym[i], guestos, browser, browserVersion)) {
							this.mappedInput.push(X11Keysym[i]);
						}
					}
				} else {
					this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers});
				}
			} else if(guestos == 'windows' || ((modifiers & (AjaxViewer.CTRL_KEY_MASK | AjaxViewer.ALT_KEY_MASK)) != 0)){
				this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers});
			}

			// special handling for ALT/CTRL key
			if(eventType == AjaxViewer.KEY_UP && (code == AjaxViewer.JS_KEY_ALT || code == AjaxViewer.JS_KEY_CTRL))
				this.mappedInput.push({type : eventType, code: this.jsX11KeysymMap[code], modifiers: modifiers});

		} else if(eventType == AjaxViewer.KEY_PRESS && guestos == 'null') {
			// ENTER/BACKSPACE key should already have been sent through KEY DOWN/KEY UP event
			if(code == AjaxViewer.JS_KEY_ENTER || code == AjaxViewer.JS_KEY_BACKSPACE)
				return;

			var X11Keysym = code;
			X11Keysym = this.jsKeyPressX11KeysymMap[code];
			if(X11Keysym) {
				if($.isArray(X11Keysym)) {
					for(var i = 0; i < X11Keysym.length; i++) {
						if(this.isConditionalEntryMatched(eventType, code, modifiers, X11Keysym[i], guestos, browser))
							this.mappedInput.push(X11Keysym[i]);
					}
				} else {
					this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: X11Keysym, modifiers: modifiers});
					this.mappedInput.push({type : AjaxViewer.KEY_UP, code: X11Keysym, modifiers: modifiers});
				}
			} else if(!(code == 48 && modifiers == AjaxViewer.SHIFT_KEY_MASK) && !(code == 95 && modifiers == 0)){
				this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: code, modifiers: modifiers});
				this.mappedInput.push({type : AjaxViewer.KEY_UP, code: code, modifiers: modifiers});
			}
		}
	},

	CookedKeyboardInputHandler : function(eventType, code, modifiers, guestos, browser, browserVersion) {
		if(eventType == AjaxViewer.KEY_DOWN || eventType == AjaxViewer.KEY_UP) {

			// special handling for Alt + Ctrl + Ins, convert it into Alt-Ctrl-Del
			if(code == AjaxViewer.JS_KEY_INSERT) {
				if((modifiers & AjaxViewer.ALT_KEY_MASK) != 0 && (modifiers & AjaxViewer.CTRL_KEY_MASK) != 0) {
					this.mappedInput.push({type : eventType, code: 0xffff, modifiers: modifiers});
					return;
				}
			}

			var X11Keysym = code;
			if(this.jsX11KeysymMap[code] != undefined) {
				X11Keysym = this.jsX11KeysymMap[code];
				if(typeof this.jsX11KeysymMap[code] == "boolean") {
					return;
				} else if($.isArray(X11Keysym)) {
					for(var i = 0; i < X11Keysym.length; i++) {
						if(this.isConditionalEntryMatched(eventType, code, modifiers, X11Keysym[i], guestos, browser, browserVersion)) {
							this.mappedInput.push(X11Keysym[i]);
						}
					}
				} else {
					this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers});
				}
			} else {
				if((modifiers & (AjaxViewer.CTRL_KEY_MASK | AjaxViewer.ALT_KEY_MASK)) != 0) {
					this.mappedInput.push({type : eventType, code: X11Keysym, modifiers: modifiers});
				}
			}

			// special handling for ALT/CTRL key
			if(eventType == AjaxViewer.KEY_UP && (code == AjaxViewer.JS_KEY_ALT || code == code == AjaxViewer.JS_KEY_CTRL)) {
				this.mappedInput.push({type : eventType, code: this.jsX11KeysymMap[code], modifiers: modifiers});
			}
		} else if(eventType == AjaxViewer.KEY_PRESS) {
			// special handling for * and + key on number pad
			if(code == AjaxViewer.JS_NUMPAD_MULTIPLY) {
				this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers});
				this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: 42, modifiers: modifiers});
				this.mappedInput.push({type : AjaxViewer.KEY_UP, code: 42, modifiers: modifiers});
				this.mappedInput.push({type : AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers});
				return;
			}

			if(code == AjaxViewer.JS_NUMPAD_PLUS) {
				this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers});
				this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: 43, modifiers: modifiers});
				this.mappedInput.push({type : AjaxViewer.KEY_UP, code: 43, modifiers: modifiers});
				this.mappedInput.push({type : AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: modifiers});
				return;
			}

			// ENTER/BACKSPACE key should already have been sent through KEY DOWN/KEY UP event
			if(code == AjaxViewer.JS_KEY_ENTER || code == AjaxViewer.JS_KEY_BACKSPACE)
				return;
			if(code > 0) {
				var X11Keysym = code;
				X11Keysym = this.jsKeyPressX11KeysymMap[code];
				if(X11Keysym) {
					if($.isArray(X11Keysym)) {
						for(var i = 0; i < X11Keysym.length; i++) {
							if(this.isConditionalEntryMatched(eventType, code, modifiers, X11Keysym[i], guestos, browser))
								this.mappedInput.push(X11Keysym[i]);
						}
					} else {
						this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: X11Keysym, modifiers: modifiers});
						this.mappedInput.push({type : AjaxViewer.KEY_UP, code: X11Keysym, modifiers: modifiers});
					}
				} else {
					// if there is no mappting entry, use the JS keypress code directly
					this.mappedInput.push({type : AjaxViewer.KEY_DOWN, code: code, modifiers: modifiers});
					this.mappedInput.push({type : AjaxViewer.KEY_UP, code: code, modifiers: modifiers});
				}
			}
		}
	},

	inputFeed : function(eventType, code, modifiers, guestos, browser, browserVersion) {
		if(this.keyboardType == KeyboardMapper.KEYBOARD_TYPE_RAW)
			this.RawkeyboardInputHandler(eventType, code, modifiers, guestos, browser, browserVersion);
		else
			this.CookedKeyboardInputHandler(eventType, code, modifiers, guestos, browser, browserVersion);
	},

	getMappedInput : function() {
		var mappedInput = this.mappedInput;
		this.mappedInput = [];
		return mappedInput;
	},

	isConditionalEntryMatched : function(eventType, code, modifiers, entry, guestos, browser, browserVersion) {
		if(eventType == AjaxViewer.KEY_DOWN || eventType == AjaxViewer.KEY_UP) {
			// for KeyDown/KeyUp events, we require that the type in entry should match with
			// the real input
			if(entry.type != eventType)
				return false;
		}

		// check conditional match
		if(entry.shift != undefined) {
			var shift = ((modifiers & AjaxViewer.SHIFT_KEY_MASK) != 0 ? true : false);
			if(entry.shift ^ shift)
				return false;
		}

                // Consider Alt+Ctrl as AltGr
                if(entry.altgr != undefined){
                        var altgr = ((modifiers & AjaxViewer.ALT_KEY_MASK) && (modifiers & AjaxViewer.CTRL_KEY_MASK)) != 0 ? true : false;
                        if(entry.altgr ^ altgr)
                                return false;
                }

		if(entry.guestos != undefined) {
			if(entry.guestos != guestos)
				return false;
		}

		if(entry.browser != undefined) {
			if(entry.browser != browser)
				return false;
		}

		if(entry.browserVersion != undefined) {
			if(entry.browserVersion != browserVersion)
				return false;
		}

		return true;
	},

	isModifierInput : function(code) {
		return $.inArray(code, [AjaxViewer.ALT_KEY_MASK, AjaxViewer.SHIFT_KEY_MASK, AjaxViewer.CTRL_KEY_MASK, AjaxViewer.META_KEY_MASK]) >= 0;
	}
};

/////////////////////////////////////////////////////////////////////////////
// class AjaxViewer
//
function AjaxViewer(panelId, imageUrl, updateUrl, locale, guestos, tileMap, width, height, tileWidth, tileHeight) {
	// logging is disabled by default so that it won't have negative impact on performance
	// however, a back door key-sequence can trigger to open the logger window, it is designed to help
	// trouble-shooting
	g_logger = new Logger();

	// g_logger.enable(true);
	// g_logger.open();

	var ajaxViewer = this;
	this.imageLoaded = false;
	this.fullImage = true;
	this.imgUrl = imageUrl;
	this.img = new Image();
	$(this.img).attr('src', imageUrl).load(function() {
		ajaxViewer.imageLoaded = true;
	});

	this.updateUrl = updateUrl;
	this.tileMap = tileMap;
	this.guestos = guestos;
	this.dirty = true;
	this.width = width;
	this.height = height;
	this.tileWidth = tileWidth;
	this.tileHeight = tileHeight;
	this.maxTileZIndex = 1;

	if (locale == AjaxViewer.KEYBOARD_TYPE_UK_ENGLISH || locale == AjaxViewer.KEYBOARD_TYPE_JAPANESE || locale == AjaxViewer.KEYBOARD_TYPE_FRENCH)
		this.currentKeyboard = locale;
	else
		this.currentKeyboard = AjaxViewer.KEYBOARD_TYPE_ENGLISH;

	this.keyboardMappers = [];

	this.timer = 0;
	this.eventQueue = [];
	this.sendingEventInProgress = false;

	this.lastClickEvent = { x: 0, y: 0, button: 0, modifiers: 0, time: new Date().getTime() };

	if(window.onStatusNotify == undefined)
		window.onStatusNotify = function(status) {};

	this.panel = this.generateCanvas(panelId, width, height, tileWidth, tileHeight);
//	this.setupKeyboardTranslationle();
	this.setupKeyboardTranslationTable(this.keyboardMappers);
	this.setupUIController();
}

// client event types
AjaxViewer.MOUSE_MOVE = 1;
AjaxViewer.MOUSE_DOWN = 2;
AjaxViewer.MOUSE_UP = 3;
AjaxViewer.KEY_PRESS = 4;
AjaxViewer.KEY_DOWN = 5;
AjaxViewer.KEY_UP = 6;
AjaxViewer.EVENT_BAG = 7;
AjaxViewer.MOUSE_DBLCLK = 8;
AjaxViewer.MOUSE_SCROLL = 9;

// use java AWT key modifier masks
AjaxViewer.SHIFT_KEY_MASK = 64;
AjaxViewer.CTRL_KEY_MASK = 128;
AjaxViewer.META_KEY_MASK = 256;
AjaxViewer.ALT_KEY_MASK = 512;
AjaxViewer.LEFT_SHIFT_MASK = 1024;
AjaxViewer.LEFT_CTRL_MASK = 2048;
AjaxViewer.LEFT_ALT_MASK = 4096;

AjaxViewer.EVENT_QUEUE_MOUSE_EVENT = 1;
AjaxViewer.EVENT_QUEUE_KEYBOARD_EVENT = 2;

AjaxViewer.STATUS_RECEIVING = 1;
AjaxViewer.STATUS_RECEIVED = 2;
AjaxViewer.STATUS_SENDING = 3;
AjaxViewer.STATUS_SENT = 4;

AjaxViewer.KEYBOARD_TYPE_ENGLISH = "us";
AjaxViewer.KEYBOARD_TYPE_UK_ENGLISH = "uk";
AjaxViewer.KEYBOARD_TYPE_JAPANESE = "jp";
AjaxViewer.KEYBOARD_TYPE_FRENCH = "fr";

AjaxViewer.JS_KEY_BACKSPACE = 8;
AjaxViewer.JS_KEY_TAB = 9;
AjaxViewer.JS_KEY_ENTER = 13;
AjaxViewer.JS_KEY_SHIFT = 16;
AjaxViewer.JS_KEY_CTRL = 17;
AjaxViewer.JS_KEY_ALT = 18;
AjaxViewer.JS_KEY_PAUSE = 19;
AjaxViewer.JS_KEY_CAPSLOCK = 20;
AjaxViewer.JS_KEY_ESCAPE = 27;
AjaxViewer.JS_KEY_PAGEUP = 33;
AjaxViewer.JS_KEY_PAGEDOWN = 34;
AjaxViewer.JS_KEY_END = 35;
AjaxViewer.JS_KEY_HOME = 36;
AjaxViewer.JS_KEY_LEFT = 37;
AjaxViewer.JS_KEY_UP = 38;
AjaxViewer.JS_KEY_RIGHT = 39;
AjaxViewer.JS_KEY_DOWN = 40;
AjaxViewer.JS_KEY_INSERT = 45;
AjaxViewer.JS_KEY_DELETE = 46;
AjaxViewer.JS_KEY_LEFT_WINDOW_KEY = 91;
AjaxViewer.JS_KEY_RIGHT_WINDOW_KEY = 92;
AjaxViewer.JS_KEY_SELECT_KEY = 93;
AjaxViewer.JS_KEY_NUMPAD0 = 96;
AjaxViewer.JS_KEY_NUMPAD1 = 97;
AjaxViewer.JS_KEY_NUMPAD2 = 98;
AjaxViewer.JS_KEY_NUMPAD3 = 99;
AjaxViewer.JS_KEY_NUMPAD4 = 100;
AjaxViewer.JS_KEY_NUMPAD5 = 101;
AjaxViewer.JS_KEY_NUMPAD6 = 102;
AjaxViewer.JS_KEY_NUMPAD7 = 103;
AjaxViewer.JS_KEY_NUMPAD8 = 104;
AjaxViewer.JS_KEY_NUMPAD9 = 105;
AjaxViewer.JS_KEY_MULTIPLY = 106;
AjaxViewer.JS_KEY_ADD = 107;
AjaxViewer.JS_KEY_SUBSTRACT = 109;
AjaxViewer.JS_KEY_DECIMAL_POINT = 110;
AjaxViewer.JS_KEY_DIVIDE = 111;
AjaxViewer.JS_KEY_F1 = 112;
AjaxViewer.JS_KEY_F2 = 113;
AjaxViewer.JS_KEY_F3 = 114;
AjaxViewer.JS_KEY_F4 = 115;
AjaxViewer.JS_KEY_F5 = 116;
AjaxViewer.JS_KEY_F6 = 117;
AjaxViewer.JS_KEY_F7 = 118;
AjaxViewer.JS_KEY_F8 = 119;
AjaxViewer.JS_KEY_F9 = 120;
AjaxViewer.JS_KEY_F10 = 121;
AjaxViewer.JS_KEY_F11 = 122;
AjaxViewer.JS_KEY_F12 = 123;
AjaxViewer.JS_KEY_NUMLOCK = 144;
AjaxViewer.JS_KEY_SCROLLLOCK = 145;
AjaxViewer.JS_KEY_SEMI_COLON = 186;			// ;
AjaxViewer.JS_KEY_EQUAL_SIGN = 187;			// =
AjaxViewer.JS_KEY_COMMA = 188;				// ,
AjaxViewer.JS_KEY_DASH = 189;				// -
AjaxViewer.JS_KEY_PERIOD = 190;				// .
AjaxViewer.JS_KEY_FORWARD_SLASH = 191;		// /
AjaxViewer.JS_KEY_GRAVE_ACCENT = 192;		// `
AjaxViewer.JS_KEY_OPEN_BRACKET = 219;		// [
AjaxViewer.JS_KEY_BACK_SLASH = 220;			// \
AjaxViewer.JS_KEY_CLOSE_BRACKET = 221;		// ]
AjaxViewer.JS_KEY_SINGLE_QUOTE = 222;		// '
AjaxViewer.JS_NUMPAD_PLUS = 43;
AjaxViewer.JS_NUMPAD_MULTIPLY = 42;
AjaxViewer.JS_KEY_NUM8 = 56;

// keycode from Japanese keyboard
AjaxViewer.JS_KEY_JP_COLON = 222;			// :* on JP keyboard
AjaxViewer.JS_KEY_JP_CLOSE_BRACKET = 220;	// [{ on JP keyboard
AjaxViewer.JS_KEY_JP_AT_SIGN = 219;			// @` on JP keyboard
AjaxViewer.JS_KEY_JP_OPEN_BRACKET = 221;	// [{ on JP keyboard
AjaxViewer.JS_KEY_JP_BACK_SLASH = 193;		// \| on JP keyboard
AjaxViewer.JS_KEY_JP_YEN_MARK = 255;

AjaxViewer.JS_KEY_JP_EQUAL = 109;			// -= ON JP keyboard
AjaxViewer.JS_KEY_JP_ACUTE = 107;			// ^~ on JP keyboard

// X11 keysym definitions
AjaxViewer.X11_KEY_CAPSLOCK = 0xffe5;
AjaxViewer.X11_KEY_BACKSPACE = 0xff08;
AjaxViewer.X11_KEY_TAB = 0xff09;
AjaxViewer.X11_KEY_ENTER = 0xff0d;
AjaxViewer.X11_KEY_ESCAPE = 0xff1b;
AjaxViewer.X11_KEY_INSERT = 0xff63;
AjaxViewer.X11_KEY_DELETE = 0xffff;
AjaxViewer.X11_KEY_HOME = 0xff50;
AjaxViewer.X11_KEY_END = 0xff57;
AjaxViewer.X11_KEY_PAGEUP = 0xff55;
AjaxViewer.X11_KEY_PAGEDOWN = 0xff56;
AjaxViewer.X11_KEY_LEFT = 0xff51;
AjaxViewer.X11_KEY_UP = 0xff52;
AjaxViewer.X11_KEY_RIGHT = 0xff53;
AjaxViewer.X11_KEY_DOWN = 0xff54;
AjaxViewer.X11_KEY_F1 = 0xffbe;
AjaxViewer.X11_KEY_F2 = 0xffbf;
AjaxViewer.X11_KEY_F3 = 0xffc0;
AjaxViewer.X11_KEY_F4 = 0xffc1;
AjaxViewer.X11_KEY_F5 = 0xffc2;
AjaxViewer.X11_KEY_F6 = 0xffc3;
AjaxViewer.X11_KEY_F7 = 0xffc4;
AjaxViewer.X11_KEY_F8 = 0xffc5;
AjaxViewer.X11_KEY_F9 = 0xffc6;
AjaxViewer.X11_KEY_F10 = 0xffc7;
AjaxViewer.X11_KEY_F11 = 0xffc8;
AjaxViewer.X11_KEY_F12 = 0xffc9;
AjaxViewer.X11_KEY_SHIFT = 0xffe1;
AjaxViewer.X11_KEY_CTRL = 0xffe3;
AjaxViewer.X11_KEY_ALT = 0xffe9;
AjaxViewer.X11_KEY_SELECT_KEY = 0xff67;
AjaxViewer.X11_KEY_GRAVE_ACCENT = 0x60;
AjaxViewer.X11_KEY_SUBSTRACT = 0x2d;
AjaxViewer.X11_KEY_ADD = 0x2b;
AjaxViewer.X11_KEY_OPEN_BRACKET = 0x5b;
AjaxViewer.X11_KEY_CLOSE_BRACKET = 0x5d;
AjaxViewer.X11_KEY_BACK_SLASH = 0x7c;
AjaxViewer.X11_KEY_REVERSE_SOLIUS = 0x5c;			// another back slash (back slash on JP keyboard)
AjaxViewer.X11_KEY_SINGLE_QUOTE = 0x22;
AjaxViewer.X11_KEY_COMMA = 0x3c;
AjaxViewer.X11_KEY_PERIOD = 0x3e;
AjaxViewer.X11_KEY_FORWARD_SLASH = 0x3f;
AjaxViewer.X11_KEY_DASH = 0x2d;
AjaxViewer.X11_KEY_COLON = 0x3a;
AjaxViewer.X11_KEY_SEMI_COLON = 0x3b;
AjaxViewer.X11_KEY_NUMPAD0 = 0x30;
AjaxViewer.X11_KEY_NUMPAD1 = 0x31;
AjaxViewer.X11_KEY_NUMPAD2 = 0x32;
AjaxViewer.X11_KEY_NUMPAD3 = 0x33;
AjaxViewer.X11_KEY_NUMPAD4 = 0x34;
AjaxViewer.X11_KEY_NUMPAD5 = 0x35;
AjaxViewer.X11_KEY_NUMPAD6 = 0x36;
AjaxViewer.X11_KEY_NUMPAD7 = 0x37;
AjaxViewer.X11_KEY_NUMPAD8 = 0x38;
AjaxViewer.X11_KEY_NUMPAD9 = 0x39;
AjaxViewer.X11_KEY_DECIMAL_POINT = 0x2e;
AjaxViewer.X11_KEY_DIVIDE = 0x3f;
AjaxViewer.X11_KEY_TILDE = 0x7e;				// ~
AjaxViewer.X11_KEY_CIRCUMFLEX_ACCENT = 0x5e;	// ^
AjaxViewer.X11_KEY_YEN_MARK = 0xa5;				// Japanese YEN mark
AjaxViewer.X11_KEY_ASTERISK = 0x2a;

AjaxViewer.getEventName = function(type) {
	switch(type) {
	case AjaxViewer.MOUSE_MOVE :
		return "MOUSE_MOVE";

	case AjaxViewer.MOUSE_DOWN :
		return "MOUSE_DOWN";

	case AjaxViewer.MOUSE_UP :
		return "MOUSE_UP";

	case AjaxViewer.KEY_PRESS :
		return "KEY_PRESS";

	case AjaxViewer.KEY_DOWN :
		return "KEY_DOWN";

	case AjaxViewer.KEY_UP :
		return "KEY_UP";

	case AjaxViewer.EVENT_BAG :
		return "EVENT_BAG";

	case AjaxViewer.MOUSE_DBLCLK :
		return "MOUSE_DBLCLK";
	}

	return "N/A";
};

AjaxViewer.prototype = {
	setDirty: function(value) {
		this.dirty = value;
	},

	isDirty: function() {
		return this.dirty;
	},

	isImageLoaded: function() {
		return this.imageLoaded;
	},

	refresh: function(imageUrl, tileMap, fullImage) {
		var ajaxViewer = this;
		var img = $(this.img);
		this.fullImage = fullImage;
		this.imgUrl=imageUrl;

		img.attr('src', imageUrl).load(function() {
			ajaxViewer.imageLoaded = true;
		});
		this.tileMap = tileMap;
	},

	resize: function(panelId, width, height, tileWidth, tileHeight) {
		$(".canvas_tile", document.body).each(function() {
			$(this).remove();
		});
		$("table", $("#" + panelId)).remove();

		this.width = width;
		this.height = height;
		this.tileWidth = tileWidth;
		this.tileHeight = tileHeight;
		this.panel = this.generateCanvas(panelId, width, height, tileWidth, tileHeight);
	},

	start: function() {
		var ajaxViewer = this;
		this.timer = setInterval(function() { ajaxViewer.heartbeat(); }, 50);

		$(document).bind("ajaxError", function(event, XMLHttpRequest, ajaxOptions, thrownError) {
			ajaxViewer.onAjaxError(event, XMLHttpRequest, ajaxOptions, thrownError);
		});

		this.eventQueue = [];	// reset event queue
		this.sendingEventInProgress = false;
		ajaxViewer.installMouseHook();
		ajaxViewer.installKeyboardHook();
		ajaxViewer.panel.parent().focus();

		$(window).bind("resize", function() {
			ajaxViewer.onWindowResize();
		});
	},

	stop: function() {
		clearInterval(this.timer);
		this.deleteCanvas();

		this.uninstallMouseHook();
		this.uninstallKeyboardHook();
		this.eventQueue = [];
		this.sendingEventInProgress = false;

		$(document).unbind("ajaxError");
		$(window).unbind("resize");
	},

	sendMouseEvent: function(event, x, y, whichButton, modifiers) {
		this.eventQueue.push({
			type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT,
			event: event,
			x: x,
			y: y,
			code: whichButton,
			modifiers: modifiers
		});
		this.checkEventQueue();
	},
//NEW  insert the keyboard tables file here
// ajaxKeys.js

	setupKeyboardTranslationTable : function() {
		this.keyboardMappers = [];

		var mapper = new KeyboardMapper();
		this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_ENGLISH] = mapper;
		mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_COOKED);

		var mapper = new KeyboardMapper();
		this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_UK_ENGLISH] = mapper;
		mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_UK);

		mapper = new KeyboardMapper();
		this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_JAPANESE] = mapper;
		mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_RAW);

                var mapper = new KeyboardMapper();
                this.keyboardMappers[AjaxViewer.KEYBOARD_TYPE_FRENCH] = mapper;
                mapper.setKeyboardType(KeyboardMapper.KEYBOARD_TYPE_FR);

		// JP keyboard plugged in a English host OS
/*
		mapper.jsX11KeysymMap[AjaxViewer.JS_KEY_JP_COLON] = AjaxViewer.X11_KEY_COLON;
		mapper.jsX11KeysymMap[AjaxViewer.JS_KEY_JP_CLOSE_BRACKET] = AjaxViewer.X11_KEY_CLOSE_BRACKET;
		mapper.jsX11KeysymMap[AjaxViewer.JS_KEY_JP_AT_SIGN] = AjaxViewer.X11_KEY_GRAVE_ACCENT;
		mapper.jsX11KeysymMap[AjaxViewer.JS_KEY_JP_OPEN_BRACKET] = AjaxViewer.X11_KEY_OPEN_BRACKET;
		mapper.jsX11KeysymMap[AjaxViewer.JS_KEY_JP_BACK_SLASH] = AjaxViewer.X11_KEY_REVERSE_SOLIUS;		// X11 REVERSE SOLIDUS
		mapper.jsX11KeysymMap[AjaxViewer.JS_KEY_JP_YEN_MARK] = AjaxViewer.X11_KEY_YEN_MARK;				// X11 YEN SIGN
		mapper.jsKeyPressX11KeysymMap[61] = [
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_CIRCUMFLEX_ACCENT, modifiers: 0 },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_CIRCUMFLEX_ACCENT, modifiers: 0 },
	];

		mapper.jsKeyPressX11KeysymMap[43] = [
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false },
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false },
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_TILDE, modifiers: 0, shift: true },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_TILDE, modifiers: 0, shift: true }
        ];
*/

/* Old
		// JP keyboard plugged in a Japanese host OS
		mapper.jsX11KeysymMap[222] = AjaxViewer.X11_KEY_CIRCUMFLEX_ACCENT;
		mapper.jsX11KeysymMap[220] = AjaxViewer.X11_KEY_YEN_MARK;
		mapper.jsX11KeysymMap[219] = AjaxViewer.X11_KEY_OPEN_BRACKET;
		mapper.jsX11KeysymMap[221] = AjaxViewer.X11_KEY_CLOSE_BRACKET;
		mapper.jsX11KeysymMap[59] = AjaxViewer.X11_KEY_COLON;					// Firefox
		mapper.jsX11KeysymMap[186] = AjaxViewer.X11_KEY_COLON;					// Chrome
		mapper.jsX11KeysymMap[226] = AjaxViewer.X11_KEY_REVERSE_SOLIUS;			// \| key left to right SHIFT on JP keyboard
		mapper.jsX11KeysymMap[240] = [
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_CAPSLOCK, modifiers: 0 },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_CAPSLOCK, modifiers: 0 },
	];

		// for keycode 107, keypress 59
		mapper.jsKeyPressX11KeysymMap[59] = [
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SEMI_COLON, modifiers: 0 },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SEMI_COLON, modifiers: 0 },
	];

		// for keycode 107, keypress 43
		mapper.jsKeyPressX11KeysymMap[43] = [
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false },
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: false },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_SHIFT, modifiers: 0, shift: false },
	    {type: AjaxViewer.KEY_DOWN, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: true },
	    {type: AjaxViewer.KEY_UP, code: AjaxViewer.X11_KEY_ADD, modifiers: 0, shift: true },
        ];

*/
	// create the mapping table based on the tables input
	if (keyboardTables != undefined ) {

		for(var i = 0; i < keyboardTables.length; i++) {
			var mappingTbl = keyboardTables[i];
			var keyboardType = mappingTbl.keyboardType;
			var mappings = mappingTbl.mappingTable;
			var x11Maps = mappings.X11;
			for (var j = 0; j < x11Maps.length; j++) {
				var code = x11Maps[j].keycode;
				var mappedEntry = x11Maps[j].entry;
				if(x11Maps[j].guestos == undefined || x11Maps[j].guestos == this.guestos) {
					this.keyboardMappers[keyboardType].jsX11KeysymMap[code] = mappedEntry;
				}
			}
			var keyPressMaps = mappings.keyPress;
			for (var j = 0; j < keyPressMaps.length; j++) {
				var code = keyPressMaps[j].keycode;
				var mappedEntry = keyPressMaps[j].entry;
				if(keyPressMaps[j].guestos == undefined || keyPressMaps[j].guestos == this.guestos) {
					this.keyboardMappers[keyboardType].jsKeyPressX11KeysymMap[code] = mappedEntry;
				}
			}
		}
	}

	}, // end of the setupKeyboardTranslationTable function

	getCurrentKeyboardMapper : function() {
		return this.keyboardMappers[this.currentKeyboard];
	},

	setupUIController : function() {
		var ajaxViewer = this;
		var pullDownElement = $("#toolbar").find(".pulldown");
		pullDownElement.hover(
			function(e) {
				var subMenu = pullDownElement.find("ul");
				var offset = subMenu.parent().offset();
				subMenu.css("left", offset.left);

				$("li.current").removeClass("current");
				$("li:has(a[cmd$=" + ajaxViewer.currentKeyboard + "])", subMenu).addClass("current");
				subMenu.css("z-index", "" + ajaxViewer.maxTileZIndex + 1).show();
				return false;
			},

			function(e) {
				pullDownElement.find("ul").hide();
				return false;
			}
		);

		$("[cmd]", "#toolbar").each(function(i, val) {
			$(val).click(function(e) {
				var cmd = $(e.target).attr("cmd");
				if(cmd)
					ajaxViewer.onCommand(cmd);
				else {
					var cmdLink = $(e.target).closest("a");

					if(cmdLink.attr("cmd")) {
						var cmd = cmdLink.attr("cmd");
						ajaxViewer.onCommand(cmd);
					}
				}
			});
		});
	},

	onCommand : function(cmd) {
		if(cmd == "keyboard_jp") {
			$("#toolbar").find(".pulldown").find("ul").hide();
			this.currentKeyboard = AjaxViewer.KEYBOARD_TYPE_JAPANESE;
		} else if(cmd == "keyboard_us") {
			$("#toolbar").find(".pulldown").find("ul").hide();
			this.currentKeyboard = AjaxViewer.KEYBOARD_TYPE_ENGLISH;
		} else if(cmd == "keyboard_uk") {
			$("#toolbar").find(".pulldown").find("ul").hide();
			this.currentKeyboard = AjaxViewer.KEYBOARD_TYPE_UK_ENGLISH;
                } else if(cmd == "keyboard_fr") {
                        $("#toolbar").find(".pulldown").find("ul").hide();
                        this.currentKeyboard = AjaxViewer.KEYBOARD_TYPE_FRENCH;
		} else if(cmd == "sendCtrlAltDel") {
			this.sendKeyboardEvent(AjaxViewer.KEY_DOWN, 0xffe9, 0);		// X11 Alt
			this.sendKeyboardEvent(AjaxViewer.KEY_DOWN, 0xffe3, 0);		// X11 Ctrl
			this.sendKeyboardEvent(AjaxViewer.KEY_DOWN, 0xffff, 0);		// X11 Del
			this.sendKeyboardEvent(AjaxViewer.KEY_UP, 0xffff, 0);
			this.sendKeyboardEvent(AjaxViewer.KEY_UP, 0xffe3, 0);
			this.sendKeyboardEvent(AjaxViewer.KEY_UP, 0xffe9, 0);
		} else if(cmd == "sendCtrlEsc") {
			this.sendKeyboardEvent(AjaxViewer.KEY_DOWN, 0xffe3, 0);		// X11 Ctrl
			this.sendKeyboardEvent(AjaxViewer.KEY_DOWN, 0xff1b, 0);		// X11 ESC
			this.sendKeyboardEvent(AjaxViewer.KEY_UP, 0xff1b, 0);
			this.sendKeyboardEvent(AjaxViewer.KEY_UP, 0xffe3, 0);
		} else if(cmd == "toggle_logwin") {
			if(!g_logger.isOpen()) {
				g_logger.enable(true);
				g_logger.open();
				g_logger.log(Logger.LEVEL_SYS, "Accept languages: " + acceptLanguages + ", current language: " + getCurrentLanguage());
			} else {
				g_logger.close();
			}
		}
	},

	sendKeyboardEvent: function(event, code, modifiers) {
		// back door to open logger window - CTRL-ATL-SHIFT+SPACE
		if(code == 32 &&
			(modifiers & AjaxViewer.SHIFT_KEY_MASK | AjaxViewer.CTRL_KEY_MASK | AjaxViewer.ALT_KEY_MASK) == (AjaxViewer.SHIFT_KEY_MASK | AjaxViewer.CTRL_KEY_MASK | AjaxViewer.ALT_KEY_MASK)) {

			if(!g_logger.isOpen()) {
				g_logger.enable(true);
				g_logger.open();
				g_logger.log(Logger.LEVEL_SYS, "Accept languages: " + acceptLanguages + ", current language: " + getCurrentLanguage());
			} else {
				g_logger.close();
			}
		}

		var len;
		g_logger.log(Logger.LEVEL_INFO, "Keyboard event: " + AjaxViewer.getEventName(event) + ", code: " + code + ", modifiers: " + modifiers + ', char: ' + String.fromCharCode(code));
		this.eventQueue.push({
			type: AjaxViewer.EVENT_QUEUE_KEYBOARD_EVENT,
			event: event,
			code: code,
			modifiers: modifiers
		});

		if(event != AjaxViewer.KEY_DOWN)
			this.checkEventQueue();
	},

	aggregateEvents: function() {
		var ajaxViewer = this;
		var aggratedQueue = [];

		var aggregating = false;
		var mouseX;
		var mouseY;
		$.each(ajaxViewer.eventQueue, function(index, item) {
			if(item.type != AjaxViewer.EVENT_QUEUE_MOUSE_EVENT) {
				aggratedQueue.push(item);
			} else {
				if(!aggregating) {
					if(item.event == AjaxViewer.MOUSE_MOVE) {
						aggregating = true;
						mouseX = item.x;
						mouseY = item.y;
					} else {
						aggratedQueue.push(item);
					}
				} else {
					if(item.event == AjaxViewer.MOUSE_MOVE) {
						// continue to aggregate mouse move event
						mouseX = item.x;
						mouseY = item.y;
					} else {
						aggratedQueue.push({
							type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT,
							event: AjaxViewer.MOUSE_MOVE,
							x: mouseX,
							y: mouseY,
							code: 0,
							modifiers: 0
						});
						aggregating = false;

						aggratedQueue.push(item);
					}
				}
			}
		});

		if(aggregating) {
			aggratedQueue.push({
				type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT,
				event: AjaxViewer.MOUSE_MOVE,
				x: mouseX,
				y: mouseY,
				code: 0,
				modifiers: 0
			});
		}

		this.eventQueue = aggratedQueue;
	},

	checkEventQueue: function() {
		var ajaxViewer = this;

		if(!this.sendingEventInProgress && this.eventQueue.length > 0) {
			var sb = new StringBuilder();
			sb.append(""+this.eventQueue.length).append("|");
			$.each(this.eventQueue, function() {
				var item = this;
				if(item.type == AjaxViewer.EVENT_QUEUE_MOUSE_EVENT) {
					sb.append(""+item.type).append("|");
					sb.append(""+item.event).append("|");
					sb.append(""+item.x).append("|");
					sb.append(""+item.y).append("|");
					sb.append(""+item.code).append("|");
					sb.append(""+item.modifiers).append("|");
				} else {
					sb.append(""+item.type).append("|");
					sb.append(""+item.event).append("|");
					sb.append(""+item.code).append("|");
					sb.append(""+item.modifiers).append("|");
				}
			});
			this.eventQueue.length = 0;

			var url = ajaxViewer.updateUrl + "&event=" + AjaxViewer.EVENT_BAG;

			g_logger.log(Logger.LEVEL_TRACE, "Posting client event " + sb.toString() + "...");

			ajaxViewer.sendingEventInProgress = true;
			window.onStatusNotify(AjaxViewer.STATUS_SENDING);
			$.post(url, {data: sb.toString()}, function(data, textStatus) {
				g_logger.log(Logger.LEVEL_TRACE, "Client event " + sb.toString() + " is posted");

				ajaxViewer.sendingEventInProgress = false;
				window.onStatusNotify(AjaxViewer.STATUS_SENT);

				ajaxViewer.checkUpdate();
			}, 'html');
		}
	},

	onAjaxError: function(event, XMLHttpRequest, ajaxOptions, thrownError) {
		if(window.onClientError != undefined && jQuery.isFunction(window.onClientError)) {
			window.onClientError();
		}
	},

	onWindowResize: function() {
		var offset = this.panel.offset();

		var row = $('tr:first', this.panel);
		var cell = $('td:first', row);
		var tile = this.getTile(cell, 'tile');

		var tileOffset = tile.offset();
		var deltaX = offset.left - tileOffset.left;
		var deltaY = offset.top - tileOffset.top;

		if(deltaX != 0 || deltaY != 0) {
			$(".canvas_tile").each(function() {
				var offsetFrom = $(this).offset();
				$(this).css('left', offsetFrom.left + deltaX).css('top', offsetFrom.top + deltaY);
			});
		}
	},

	deleteCanvas: function() {
		$('.canvas_tile', $(document.body)).each(function() {
			$(this).remove();
		});
	},

	generateCanvas: function(wrapperDivId, width, height, tileWidth, tileHeight) {
		var canvasParent = $('#' + wrapperDivId);
		canvasParent.width(width);
		canvasParent.height(height);

		if(window.onCanvasSizeChange != undefined && jQuery.isFunction(window.onCanvasSizeChange))
			window.onCanvasSizeChange(width, height);

		var tableDef = '<table cellpadding="0px" cellspacing="0px">\r\n';
		var i = 0;
		var j = 0;
		for(i = 0; i < Math.ceil((height + tileHeight - 1) / tileHeight); i++) {
			var rowHeight = Math.min(height - i*tileHeight, tileHeight);
			tableDef += '<tr style="height:' + rowHeight + 'px">\r\n';

			for(j = 0; j < Math.ceil((width + tileWidth - 1) / tileWidth); j++) {
				var colWidth = Math.min(width - j*tileWidth, tileWidth);
				tableDef += '<td width="' + colWidth + 'px"></td>\r\n';
			}
			tableDef += '</tr>\r\n';
		}
		tableDef += '</table>\r\n';

		return $(tableDef).appendTo(canvasParent);
	},

	getTile: function(cell, name) {
		var clonedDiv = cell.data(name);
		if(!clonedDiv) {
			var offset = cell.offset();
			var divDef = "<div class=\"canvas_tile\" style=\"z-index:1;position:absolute;overflow:hidden;width:" + cell.width() + "px;height:"
				+ cell.height() + "px;left:" + offset.left + "px;top:" + offset.top+"px\"></div>";

			clonedDiv = $(divDef).appendTo($(document.body));
			cell.data(name, clonedDiv);
		}

		return clonedDiv;
	},

	initCell: function(cell) {
		if(!cell.data("init")) {
			cell.data("init", true);

			cell.data("current", 0);
			this.getTile(cell, "tile2");
			this.getTile(cell, "tile");
		}
	},

	displayCell: function(cell, bg) {
		var div;
		var divPrev;
		if(!cell.data("current")) {
			cell.data("current", 1);

			divPrev = this.getTile(cell, "tile");
			div = this.getTile(cell, "tile2");
		} else {
			cell.data("current", 0);
			divPrev = this.getTile(cell, "tile2");
			div = this.getTile(cell, "tile");
		}

		var zIndex = parseInt(divPrev.css("z-index")) + 1;
		this.maxTileZIndex = Math.max(this.maxTileZIndex, zIndex);
		div.css("z-index", zIndex);
		div.css("background", bg);
	},

	updateTile: function() {
		if(this.dirty) {
			var ajaxViewer = this;
			var tileWidth = this.tileWidth;
			var tileHeight = this.tileHeight;
			var imgUrl = this.imgUrl;
			var panel = this.panel;

			if(this.fullImage) {
				$.each(this.tileMap, function() {
					var i = $(this)[0];
					var j = $(this)[1];
					var row = $("TR:eq("+i+")", panel);
					var cell = $("TD:eq("+j+")", row);
					var attr = "url(" + imgUrl + ") -"+j*tileWidth+"px -"+i*tileHeight + "px";

					ajaxViewer.initCell(cell);
					ajaxViewer.displayCell(cell, attr);
				});
			} else {
				$.each(this.tileMap, function(index) {
					var i = $(this)[0];
					var j = $(this)[1];
					var offset = index*tileWidth;
					var attr = "url(" + imgUrl + ") no-repeat -"+offset+"px 0px";
					var row = $("TR:eq("+i+")", panel);
					var cell = $("TD:eq("+j+")", row);

					ajaxViewer.initCell(cell);
					ajaxViewer.displayCell(cell, attr);
				});
			}

			this.dirty = false;
		}
	},

	heartbeat: function() {
		this.checkEventQueue();
		this.checkUpdate();
	},

	checkUpdate: function() {
		if(!this.isDirty())
			return;

		if(this.isImageLoaded()) {
			this.updateTile();
			var url = this.updateUrl;
			var ajaxViewer = this;

			window.onStatusNotify(AjaxViewer.STATUS_RECEIVING);
			$.getScript(url, function(data, textStatus) {
				if(/^<html>/.test(data)) {
					ajaxViewer.stop();
					$(document.body).html(data);
				} else {
					eval(data);
					ajaxViewer.setDirty(true);
					window.onStatusNotify(AjaxViewer.STATUS_RECEIVED);

					ajaxViewer.checkUpdate();
				}
			});
		}
	},

	ptInPanel: function(pageX, pageY) {
		var mainPanel = this.panel;

		var offset = mainPanel.offset();
		var x = pageX - offset.left;
		var y = pageY - offset.top;

		if(x < 0 || y < 0 || x > mainPanel.width() - 1 || y > mainPanel.height() - 1)
			return false;
		return true;
	},

	pageToPanel: function(pageX, pageY) {
		var mainPanel = this.panel;

		var offset = mainPanel.offset();
		var x = pageX - offset.left;
		var y = pageY - offset.top;

		if(x < 0)
			x = 0;
		if(x > mainPanel.width() - 1)
			x = mainPanel.width() - 1;

		if(y < 0)
			y = 0;
		if(y > mainPanel.height() - 1)
			y = mainPanel.height() - 1;

		return { x: Math.ceil(x), y: Math.ceil(y) };
	},

	installMouseHook: function() {
		var ajaxViewer = this;
		var target = $(document.body);

		target.mousemove(function(e) {
			if(!ajaxViewer.ptInPanel(e.pageX, e.pageY))
				return true;

			var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY);
			ajaxViewer.onMouseMove(pt.x, pt.y);

			e.stopPropagation();
			return false;
		});

		target.mousedown(function(e) {
			ajaxViewer.panel.parent().focus();

			if(!ajaxViewer.ptInPanel(e.pageX, e.pageY))
				return true;

			var modifiers = ajaxViewer.getKeyModifiers(e);
			var whichButton = e.button;

			var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY);
			ajaxViewer.onMouseDown(pt.x, pt.y, whichButton, modifiers);

			e.stopPropagation();
			return false;
		});

		target.mouseup(function(e) {
			if(!ajaxViewer.ptInPanel(e.pageX, e.pageY))
				return true;

			var modifiers = ajaxViewer.getKeyModifiers(e);
			var whichButton = e.button;

			var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY);

			ajaxViewer.onMouseUp(pt.x, pt.y, whichButton, modifiers);
			e.stopPropagation();
			return false;
		});

		target.bind('mousewheel DOMMouseScroll',function(e) {
			if(!ajaxViewer.ptInPanel(e.pageX, e.pageY))
				return true;

			var modifiers = ajaxViewer.getKeyModifiers(e);
			var sd = e.originalEvent.detail/3;

			var pt = ajaxViewer.pageToPanel(e.clientX, e.clientY);


			ajaxViewer.onMouseScroll(pt.x, pt.y, sd, modifiers);
			ajaxViewer.onMouseScroll(pt.x, pt.y, 0, modifiers);

			e.stopPropagation();
			return false;
		});

		// disable browser right-click context menu
		target.bind("contextmenu", function() { return false; });
	},

	uninstallMouseHook : function() {
		var target = $(document);
		target.unbind("mousemove");
		target.unbind("mousedown");
		target.unbind("mouseup");
		target.unbind("contextmenu");
	},

	requiresDefaultKeyProcess : function(e) {
		switch(e.which) {
		case 8 :		// backspace
		case 9 :		// TAB
		case 19 :		// PAUSE/BREAK
		case 20 :		// CAPSLOCK
		case 27 :		// ESCAPE
		case 16 :		// SHIFT key
		case 17 :		// CTRL key
		case 18 :		// ALT key
		case 33 :		// PGUP
		case 34 :		// PGDN
		case 35 :		// END
		case 36 :		// HOME
		case 37 :		// LEFT
		case 38 :		// UP
		case 39 :		// RIGHT
		case 40 :		// DOWN
		case 47 :		// FORWARD SLASH // Added to stop Firefox's quick search from opening
			return false;
		}

		if(this.getKeyModifiers(e) == AjaxViewer.SHIFT_KEY_MASK)
			return true;

		if(this.getKeyModifiers(e) != 0)
			return false;

		return true;
	},

	installKeyboardHook: function() {
		var ajaxViewer = this;
		var target = $(document);

		target.keypress(function(e) {
			ajaxViewer.onKeyPress(e.which, ajaxViewer.getKeyModifiers(e));

			e.stopPropagation();
			if(ajaxViewer.requiresDefaultKeyProcess(e))
				return true;

			e.preventDefault();
			return false;
		});

		target.keydown(function(e) {
			ajaxViewer.onKeyDown(e.which, ajaxViewer.getKeyModifiers(e));

			e.stopPropagation();
			if(ajaxViewer.requiresDefaultKeyProcess(e))
				return true;

			e.preventDefault();
			return false;
		});

		target.keyup(function(e) {
			ajaxViewer.onKeyUp(e.which, ajaxViewer.getKeyModifiers(e));

			e.stopPropagation();
			if(ajaxViewer.requiresDefaultKeyProcess(e))
				return true;

			e.preventDefault();
			return false;
		});
	},

	uninstallKeyboardHook : function() {
		var target = $(document);
		target.unbind("keypress");
		target.unbind("keydown");
		target.unbind("keyup");
	},

	onMouseMove: function(x, y) {
		this.sendMouseEvent(AjaxViewer.MOUSE_MOVE, x, y, 0, 0);
	},

	onMouseDown: function(x, y, whichButton, modifiers) {
		this.sendMouseEvent(AjaxViewer.MOUSE_DOWN, x, y, whichButton, modifiers);
	},

	onMouseUp: function(x, y, whichButton, modifiers) {
		this.sendMouseEvent(AjaxViewer.MOUSE_UP, x, y, whichButton, modifiers);

		var curTick = new Date().getTime();
		if(this.lastClickEvent.time && (curTick - this.lastClickEvent.time < 300)) {
			this.onMouseDblClick(this.lastClickEvent.x, this.lastClickEvent.y,
				this.lastClickEvent.button, this.lastClickEvent.modifiers);
		}

		this.lastClickEvent.x = x;
		this.lastClickEvent.y = y;
		this.lastClickEvent.button = whichButton;
		this.lastClickEvent.modifiers = modifiers;
		this.lastClickEvent.time = curTick;
	},

	onMouseDblClick: function(x, y, whichButton, modifiers) {
		this.sendMouseEvent(AjaxViewer.MOUSE_DBLCLK, x, y, whichButton, modifiers);
	},

	onMouseScroll: function(x, y, whichButton, modifiers) {
		this.sendMouseEvent(AjaxViewer.MOUSE_SCROLL, x, y, whichButton, modifiers);
	},


	onKeyPress: function(code, modifiers) {
		g_logger.log(Logger.LEVEL_WARN, "RAW KEYBOARD EVENT. KEY-PRESS: " + code + ", modifers: " + modifiers);

		this.dispatchKeyboardInput(AjaxViewer.KEY_PRESS, code, modifiers);
	},

	onKeyDown: function(code, modifiers) {
		g_logger.log(Logger.LEVEL_WARN, "RAW KEYBOARD EVENT. KEY-DOWN: " + code + ", modifers: " + modifiers);

		this.dispatchKeyboardInput(AjaxViewer.KEY_DOWN, code, modifiers);
	},

	onKeyUp: function(code, modifiers) {
		g_logger.log(Logger.LEVEL_WARN, "RAW KEYBOARD EVENT. KEY-UP: " + code + ", modifers: " + modifiers);

		this.dispatchKeyboardInput(AjaxViewer.KEY_UP, code, modifiers);
	},

	dispatchKeyboardInput : function(event, code, modifiers) {
		var keyboardMapper = ajaxViewer.getCurrentKeyboardMapper();
		keyboardMapper.inputFeed(event, code, modifiers, this.guestos, $.browser, $.browser.version);
		this.dispatchMappedKeyboardInput(keyboardMapper.getMappedInput());
	},

	dispatchMappedKeyboardInput : function(mappedInput) {
		for(var i = 0; i < mappedInput.length; i++) {
			switch(mappedInput[i].type) {
			case AjaxViewer.KEY_DOWN :
				this.sendKeyboardEvent(AjaxViewer.KEY_DOWN, mappedInput[i].code, mappedInput[i].modifiers);
				break;

			case AjaxViewer.KEY_UP :
				this.sendKeyboardEvent(AjaxViewer.KEY_UP, mappedInput[i].code, mappedInput[i].modifiers);
				break;

			case AjaxViewer.KEY_PRESS :
				this.sendKeyboardEvent(AjaxViewer.KEY_PRESS, mappedInput[i].code, mappedInput[i].modifiers);
				break;
			}
		}
	},

	getKeyModifiers: function(e) {
		var modifiers = 0;
		if(e.altKey)
			modifiers |= AjaxViewer.ALT_KEY_MASK;

		if(e.altLeft)
			modifiers |= AjaxViewer.LEFT_ALT_MASK;

		if(e.ctrlKey)
			modifiers |= AjaxViewer.CTRL_KEY_MASK;

		if(e.ctrlLeft)
			modifiers |=  AjaxViewer.LEFT_CTRL_MASK;

		if(e.shiftKey)
			modifiers |=  AjaxViewer.SHIFT_KEY_MASK;

		if(e.shiftLeft)
			modifiers |= AjaxViewer.LEFT_SHIFT_MASK;

		// Don't pass meta key modifier filter if control key is pressed.
		// For more details see https://github.com/apache/cloudstack/issues/3229
		if(e.metaKey && !e.ctrlKey)
			modifiers |= AjaxViewer.META_KEY_MASK;

		return modifiers;
	}
};
