var VK_SPACE = 50, VK_BACK_SPACE = 51, VK_TAB = 52, VK_DELETE = 53, VK_ENTER = 54;
var VK_CAPS_LOCK = 55, VK_LEFT_SHIFT = 56, VK_RIGHT_SHIFT = 57, VK_ALTGR = 58;

function getEventPos (e, ctrl) {
   return { x: e.clientX - ctrl.clientX, y: e.clientY - ctrl.clientY };
}

function getElemPos (elem) {
   var pos = { x: 0, y: 0 };
   for (var parent = elem; parent; parent = parent.offsetParent) {
      pos.x += parent.offsetLeft;
      pos.y += parent.offsetTop;
   }
   return pos;
}

function TextRange (ctrl) {
   if (!ctrl.ownerDocument) return;
   this.ctrl = ctrl;
   if (document.selection) {
		this.ctrl.focus ()
		this.range = ctrl.ownerDocument.selection.createRange ();
		this.ctrl = this.range.parentElement ();
		this.insertText = rangeInsertText;
		this.deleteText = rangeDeleteText;
   } else {
		this.insertText = plainInsertText;
		this.deleteText = plainDeleteText;
   }
}

function rangeInsertText (text) {
	this.range.text = text;
	this.range.collapse (false);
	this.range.select ();
}

function rangeDeleteText (dir) {
   if (!this.range.text) {
      var savedRange = this.range.duplicate ();
      if (dir < 0)
         this.range.moveStart ("character", -1);
      else
         this.range.moveEnd ("character", 1);
      if (/<.*>/.test (this.range.htmlText)) {
         this.range = savedRange;
         return;
      }
   }
   this.range.text = "";
   this.range.collapse (false);
   this.range.select ();
}

function plainInsertText (text) {
	if(this.ctrl.selectionStart || this.ctrl.selectionStart == '0'){
		var startPos = this.ctrl.selectionStart;
		var endPos = this.ctrl.selectionEnd;
		this.ctrl.value = this.ctrl.value.substring(0, startPos) + text + this.ctrl.value.substring(endPos, this.ctrl.value.length);
		this.ctrl.focus();
		this.ctrl.selectionStart = startPos + text.length;
		this.ctrl.selectionEnd = startPos + text.length;
	}
	else{	
   		this.ctrl.value = this.ctrl.value + text;
   	}
}

function plainDeleteText (dir) {
	if (dir < 0 && this.ctrl.value.length){
		if(this.ctrl.selectionStart || this.ctrl.selectionStart == '0'){
			var startPos = this.ctrl.selectionStart;
			var endPos = this.ctrl.selectionEnd;
			this.ctrl.value = this.ctrl.value.substring(0, startPos - 1) + this.ctrl.value.substring(endPos, this.ctrl.value.length);
			this.ctrl.focus();
			this.ctrl.selectionStart = startPos - 1;
			this.ctrl.selectionEnd = startPos - 1;
		}			
		else{
   			this.ctrl.value = this.ctrl.value.substr (0, this.ctrl.value.length - 1);
   		}
	}
	else{
		if(this.ctrl.selectionStart || this.ctrl.selectionStart == '0'){
			var startPos = this.ctrl.selectionStart;
			var endPos = this.ctrl.selectionEnd;
			this.ctrl.value = this.ctrl.value.substring(0, startPos) + this.ctrl.value.substring(endPos, this.ctrl.value.length - 1);
			this.ctrl.focus();
			this.ctrl.selectionStart = startPos;
			this.ctrl.selectionEnd = startPos;
		}			
		else{
   			this.ctrl.value = this.ctrl.value.substr (0, this.ctrl.value.length - 1);
   		}	
	}
	
}

var kbd = {
	KEYS : [
	{ key: 0, c: 14, src: "btn", x: 1, y: 3, width: 322, height: 25 },
	{ key: VK_BACK_SPACE, c: 1, src: "bs", x: 324, y: 3, width: 24, height: 25, text: "<-" },
	{ key: VK_TAB, c: 1, src: "tab", x: 1, y: 28, width: 35, height: 25, text: "Tab" },
	{ key: 14, c: 12, src: "btn", x: 38, y: 28, width: 276, height: 25 },
	{ key: VK_DELETE, c: 1, src: "del", x: 313, y: 28, width: 35, height: 25, text: "Del" },
	{ key: VK_CAPS_LOCK, c: 1, src: "caps", x: 1, y: 53, width: 47, height: 25, text: "Caps" },
	{ key: 26, c: 11, src: "btn", x: 50, y: 53, width: 253, height: 25 },
	{ key: VK_ENTER, c: 1, src: "enter", x: 303, y: 53, width: 46, height: 25, text: "Enter" },
	{ key: VK_LEFT_SHIFT, c: 1, src: "lshift", x: 1, y: 78, width: 58, height: 25, text: "Shift" },
	{ key: 38, c: 10, src: "btn", x: 60, y: 78, width: 230, height: 25 },
	{ key: VK_RIGHT_SHIFT, c: 1, src: "rshift", x: 290, y: 78, width: 58, height: 25, text: "Shift" },
	{ key: VK_SPACE, c: 1, src: "space", x: 106, y: 103, width: 142, height: 25 }
	],	
	LAYOUTS : [
	{ id: "lt", name: "Lithuanian",
		normal: "`\u0105\u010d\u0119\u0117\u012f\u0161\u0173\u016b()-\u017e\\qwertyuiop[]asdfghjkl;' zxcvbnm,./",
		shift: "~\u0104\u010c\u0118\u0116\u012e\u0160\u0172\u016a\u201e\u201c_\u017d|QWERTYUIOP{}ASDFGHJKL:\" ZXCVBNM<>?",
		caps: "`\u0104\u010c\u0118\u0116\u012e\u0160\u0172\u016a\u201e\u201c-\u017d\\QWERTYUIOP[]ASDFGHJKL;' ZXCVBNM,./",
		altgr: " 1234567890 =   \u20ac         " },
	{ id: "en", name: "English",
		normal: "`1234567890-=\\qwertyuiop[]asdfghjkl;'\\zxcvbnm,./",
		shift: "~!@#$%^&*()_+|QWERTYUIOP{}ASDFGHJKL:\"\\ZXCVBNM<>?",
		caps: "`1234567890-=\\QWERTYUIOP[]ASDFGHJKL;'\\ZXCVBNM,./" },
	{ id: "fr", name: "French",
		normal: "\xb2&\xe9\"'(-\xe8_\xe7\xe0)=*azertyuiop\u2503$qsdfghjklm\xf9 wxcvbn,;:!",
		normal3: "\xb2&\xe9\"'(-\xe8_\xe7\xe0)=*\xe2z\xearty\xfb\xee\xf4p\u2503$qsdf\u011dhjklm\xf9 wxcvbn,;:!",
		shift: " 1234567890\xb0+\xb5AZERTYUIOP\u2503\xa3QSDFGHJKLM% WXCVBN?./\xa7",
		shift3:  " 1234567890\xb0+\xb5\xc2Z\xcaRTY\xdb\xce\xd4P\u2503\xa3QSDF\u011cHJKLM% WXCVBN?./\xa7",
		caps:  "\xb21234567890\xb0+\xb5AZERTYUIOP\u2503\xa3QSDFGHJKLM% WXCVBN?./\xa7" ,
		caps3: "\xb21234567890\xb0+\xb5\xc2Z\xcaRTY\xdb\xce\xd4P\u2503\xa3QSDF\u011cHJKLM% WXCVBN?./\xa7"}
  	],
	keyFind : function (x, y) {
		var keyID = -1;
		for (var i = 0; i < this.KEYS.length; ++i) {
			var key = this.KEYS [i];
			if (x >= key.x && x < key.x + key.width &&
				y >= key.y && y < key.y + key.height) {
				keyID = key.key;
				if (key.c > 1)
					keyID += Math.floor ((x - key.x) * key.c / key.width);
				var keyInfo = { id: keyID, src: key.src, x: key.x, y: key.y,
								width: key.width, height: key.height, text: key.text };
				keyInfo.width /= key.c;
				keyInfo.x += (keyID - key.key) * keyInfo.width;
				keyInfo.src =  keyInfo.src + ".gif";
				return keyInfo;
			}
		}
		return null;
	},
	attach : function () {
		this.elem = document.getElementById ("div_kbd");
		this.elem.onmousedown=this.onclick;
		this.elem.onmouseup=this.onclick;
		this.elem.onfocus=this.onfocus;
		
		this.l = document.getElementById ("layout");
		this.ls = document.getElementById ("layouts");
		this.ls.onchange = function () { kbd.layoutSet (kbd.ls.value) }
		var pos = getElemPos (this.elem);
		this.elem.clientX = pos.x; this.elem.clientY = pos.y;
		this.imgBtn = this.keyimgCreate (null);
		this.imgLShift = this.keyimgCreate (null);
		this.imgRShift = this.keyimgCreate (null);
		this.imgCaps = this.keyimgCreate (null);
		this.shift = false
		this.caps = false	
		this.deadState = 0

		var options = this.ls.options;
				
		this.layoutSet ("lt")
		for (var i = 0; i != this.LAYOUTS.length; ++i) {
			options [i] = new Option;
			options [i].value = this.LAYOUTS [i].id;
			options [i].text  = this.LAYOUTS [i].name;
			options [i].selected = (this.lang == this.LAYOUTS [i].id)
		}
		// sita reikia perstatyti i realu elementa
//		this.target = window.opener.document.getElementById ("elTranslationControl_elWord")

	},
	detach : function () {
	},
	shiftSet : function (f) {
		var t = this
		t.shift = f;
		t.keyimgSet (t.imgLShift, t.KEYS[8], t.shift)
		t.keyimgSet (t.imgRShift, t.KEYS[10], t.shift)
		t.layoutUpdate ()
	},
	keyProcess : function (key,down) {
		if (!key) return
		var t = this
		switch (key.id) {
		case VK_LEFT_SHIFT:
		case VK_RIGHT_SHIFT:
			if (down) {
				t.shiftSet (!t.shift)
			}
			break;
		case VK_CAPS_LOCK:
			if (down) {
				t.caps = !t.caps;
				t.keyimgSet (t.imgCaps, t.KEYS[5], t.caps)
				t.layoutUpdate ()
			}
			break;
		default:
			t.keyimgSet (t.imgBtn, key, down)
			if (down) {
				var k = t.layout[t.state].charAt (key.id)
				if (k.charCodeAt(0) > 0x2500) {
					this.deadState = (this.deadState == (k.charCodeAt(0) - 0x2500)) ? this.deadState = 0 : k.charCodeAt(0) - 0x2500
				} else {
					var r = new TextRange (t.target)
					switch (key.id) {
					case VK_BACK_SPACE:
						r.deleteText (-1); break;
					case VK_DELETE:
						r.deleteText ( 1); break;
					case VK_SPACE:
						r.insertText (" "); break;
					case VK_ENTER:
						r.insertText ("\n"); break;
					default:
						r.insertText (k); break;
					}
					this.deadState = 0
				}
				t.layoutUpdate ()
			}
			if (down && t.shift && !this.deadState) t.shiftSet (false)
			break;
		}
		if (!down) t.target.focus ()
	},
	onclick : function (e) {
		if (!e) e = event;
		var t = kbd
		var pos = getEventPos (e, kbd.elem);
		t.keyProcess (t.keyFind (pos.x, pos.y), (e.type == "mousedown")||(e.type == "keydown"))
	},
	layoutUpdate : function () {
		this.state = "normal"
		if (this.caps && !this.shift) this.state = "caps"
		else if (this.caps ^ this.shift) this.state = "shift"
		if (this.deadState) this.state += this.deadState
		this.l.src=this.lang+"/"+this.state + ".gif"
	},
	layoutSet : function (l) {
		this.lang = l;
		for (var i = 0; i != this.LAYOUTS.length; ++i) {
			if (this.LAYOUTS [i].id == l) this.layout = this.LAYOUTS [i]
		}
		this.layoutUpdate ()
	},
	keyimgCreate : function (keyInfo) {
		var key = document.createElement ("IMG");
		key.style.position = "absolute";
		key.style.display = "none";
		keyInfo && this.setKey (key, keyInfo);
		this.elem.appendChild (key);
		return key;
	},
	keyimgSet : function (key, keyInfo, show) {
		key.src        = keyInfo.src;
		key.src        = "btn.gif"
		key.style.left = keyInfo.x;
		key.style.top  = keyInfo.y;
		key.width      = keyInfo.width;
		key.height     = keyInfo.height;
		(show) ? key.style.display = "block" : key.style.display = "none";
	},
	onfocus : function (e) {
/*		if (!e) e = event
		if (e.fromElement) alert ("From: "+e.fromElement)
*/
	}
};


