/*
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.prototype = {

	setKeyboardType : function(keyboardType) {
		this.keyboardType = keyboardType;
		if(keyboardType == KeyboardMapper.KEYBOARD_TYPE_COOKED || keyboardType == KeyboardMapper.KEYBOARD_TYPE_UK) {
			// 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;
		}
	},
	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) {
				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 {
				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) {
			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});
				}
			}
		}
	},
	
	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;
		}
		
		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, 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.dirty = true;
	this.width = width;
	this.height = height;
	this.tileWidth = tileWidth;
	this.tileHeight = tileHeight;
	this.maxTileZIndex = 1;
	
	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;

// 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.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_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();

		$(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);

		// 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;
				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;
				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 == "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;
		});
		
		// 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
			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);
	},
	
	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;
		
		if(e.metaKey)
			modifiers |= AjaxViewer.META_KEY_MASK;
		
		return modifiers;
	}
};

