// 	Version 21.08.2010 // มกราคม
//	slib.browser.XXX
//	this.date2code = function (str) {
//	this.isNumeric = function(numVal) {
//	this.disableTextSelection = function(elem) {
//	this.pad2 = function (number) { return (number < 10 ? '0' : '') + number + ''; } 
//	slib.loadjavafile = function (filename, callback){
//	slib.loadcssfile  = function (filename){
//	slib.removejscssfile = function (filename, filetype){
//	slib.getCookie = function ( cookieName ) {
//	slib.setCookie = function ( cookieName, cookieValue, lifeTime, path, domain, isSecure ) {
//	this.encodeForm = function (theForm, fields) {
//	this.decodeForm = function (cooki, setfield) {
//	slib.print_r = function(x, max, sep, l) {
//	slib.Debugger = function(w,h) {
//	slib.Debug = function (txt) {
//	slib.lightbox.
//	slib.toolbox.
//	function genLandmarkOptions (node, responseXML) {
//	function $() {
//  getElement = { Id: function(tag) , Class: function (searchClass,node,tag) }  
//  getDocumentSize.x()  getDocumentSize.y()
//  getUrl = { query: function(key) {    
//	Array.indexOf for IE
//	DOMReady.add ( function () {  alert (" DOM is ready ! 1") ; } ) ;
//	function addEvent( obj, type, fn ) {
//	function ajaxObject(url, callbackFunction) {
//	function insertAfter(newNode,oldNode){
//	function createLink(url,text,cssClass){
//	function removeNode(node){
//	function textElement(elementName,text){

/* ====================================== */

//var slanguage = new slang('th');
function slang (lng) {
	switch (lng) {
		case "th":	this.monthList = ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน','กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม']; ;
					this.weekDays  = ['อา','จ','อ','พ','พฤ','ศ','ส']; break
		case "de":	this.monthList = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember']; 
					this.weekDays  = ['So','Mo','Di','Mi','Do','Fr','Sa']; break
		case "en":
		default  :	this.monthList = ['January','February','March','April','May','June','July','August','September','October','November','December'];
					this.weekDays  = ['Su','Mo','Tu','We','Th','Fr','Sa'];
	}	
}


/* ====================================== */
var slib = new slibrary();
function slibrary() {
	this.lng = 'en';

//	convert YYYY-MM-DD <==> YYddd (used for shorten ID
	this.date2code = function (str) {
		if (str.length > 7) {	// YYYY-MM-DD => YYddd
//			var t = new Date(str);
			var t = new Date(parseInt(str.substr(0,4),10),parseInt(str.substr(5,2),10) -1,parseInt(str.substr(8,2),10));
            var t1 = new Date(t.getFullYear(), t.getMonth(), t.getDate()),
                t2 = new Date(t.getFullYear(), 0, 1);
            var d = Math.round((t1 - t2) / 864e5) + 1;
			var result = slib.pad2(t.getFullYear() - 2000) + d + '';
		} else {				// YYYY-MM-DD <= YYddd
			var t = new Date(2000 + parseInt(str.substr(0,2),10), 0, parseInt(str.substr(2,3),10));
			var result = t.getFullYear() + '-' + (t.getMonth() < 9 ? '0' : '') + (t.getMonth() + 1) + '-' + (t.getDate() < 10 ? '0' : '') + t.getDate(); 
		}		
		return result;
	}
	
	
	this.validEmail = function(email) {
//		if (email.match(/^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+\.)+[a-zA-Z0-9.-]{2,4}$/)) return true;	
		if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/.test(email.value)) return true;
		return false;
	}


	this.disableTextSelection = function(elem) {
		if (!elem) return false;
		elem.onselectstart = function() { return false; };
		elem.unselectable = "on";
		elem.style.MozUserSelect = "none";
		elem.style.cursor = "default";
	}


	this.disableClick = function(obj) {
		elem.oncontextmenu = function() { return false; };
		elem.onselectstart = function() { return false; };
		if (window.sidebar)
		{	elem.onmousedown = function() { return false; };
			elem.onclick = function() { return true; };
		}
	}


	this.enableClick = function(obj) {
		obj.onselectstart = function() { return true; };
		obj.oncontextmenu = function() { return true; };
	}


	this.getTableId = function(obj) {
		while (obj && !/table/i.test(obj.nodeName)){ obj = obj.parentNode; }
		return obj || null;
	}


	this.isNumeric = function(numVal) {
		//var RegExp = /^(-)?(\d*)(\.?)(\d*)$/;
		var RegExp = /^[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$/;
		var result = numVal.match(RegExp);
		return (result == null ? false : true);
	}

	this.roundNumber = function (rnum, rlength) { // Arguments: number to round, number of decimal places
		var newnumber = Math.round(rnum*Math.pow(10,rlength))/Math.pow(10,rlength);
		return newnumber;
	}

	this.pad2 = function (number) { return (number < 10 ? '0' : '') + +number + ''; } 

	this.oBrowserInfo = function() {
		var aVersion = navigator.appVersion;
		var uAgent = navigator.userAgent;
		this.opera = uAgent.indexOf("Opera") >= 0;
		this.safari = aVersion.indexOf("Safari") >= 0;
		this.khtml = (aVersion.indexOf("Konqueror") >= 0) || (aVersion.indexOf("Safari") >= 0);
		this.mozilla = (uAgent.indexOf("Gecko") >= 0) && (!this.khtml);
		this.ie = (document.all) && (!this.opera);
		if (!this.ie) { this.ie = false; }
		this.ie50 = this.ie && aVersion.indexOf("MSIE 5.0")>=0;
		this.ie55 = this.ie && aVersion.indexOf("MSIE 5.5")>=0;
		this.ie60 = this.ie && aVersion.indexOf("MSIE 6.0")>=0;
		this.ie70 = this.ie && aVersion.indexOf("MSIE 7.0")>=0;
	}
	var browser = {};
	this.browser = new this.oBrowserInfo();

	/*----------------------------------------------------------------------*/
	// install a javascript file at the end of the HEAD tag
	this.loadjavafile = function (filename, callback){
		var el = document.createElement('script');
		el.setAttribute("type","text/javascript");
		if (typeof callback == "undefined") callback = null;
		if (callback) {
			if (el.readyState) { // IE
				el.onreadystatechange= function () { 	
					if (el.readyState=="complete" || el.readyState=="loaded") { el.onreadystatechange = null; callback(); }
					};
			} else { // other
				el.onload = function () { callback(); };
			}	
		}	
		el.setAttribute("src", filename);
		if (typeof el != "undefined") document.getElementsByTagName("head")[0].appendChild(el);
	}


	/*----------------------------------------------------------------------*/
	// install a css stylesheet at the end of the HEAD tag
	this.loadcssfile = function (filename){
		var el=document.createElement("link")
		el.setAttribute("rel", "stylesheet")
		el.setAttribute("type", "text/css")
		el.setAttribute("href", filename)
		if (typeof el != "undefined") document.getElementsByTagName("head")[0].appendChild(el)
	}


	/*----------------------------------------------------------------------*/
	// remove a javascript or stylesheet from HEAD tag
	this.removejscssfile = function (filename, filetype){
		var targetfile = [];
		if (filename.indexOf("?") < 0) { targetfile[0] = filename; } else { targetfile = filename.split("\?"); } // ignore things after '?'
		var targetelement = (filetype=="js")? "script" : (filetype=="css")? "link" : "none";  //determine element type to create nodelist from
		var targetattr    = (filetype=="js")? "src"    : (filetype=="css")? "href" : "none";  //determine corresponding attribute to test for
		var allsuspects   = document.getElementsByTagName(targetelement);
		for (var fn,i=allsuspects.length; i>=0; i--) 				  //search backwards within nodelist for matching elements to remove
		     if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!=null) {   
			    fn = allsuspects[i].getAttribute(targetattr);
			if (fn.substr(0,targetfile[0].length) == targetfile[0])
			    allsuspects[i].parentNode.removeChild(allsuspects[i]) //remove element by calling parentNode.removeChild()
		}
	}


	/*----------------------------------------------------------------------*/
	this.cookie = function () {
		var cookieEnabled = (navigator.cookieEnabled) ? true : false
		//if not IE4+ nor NS6+
		if (typeof navigator.cookieEnabled=="undefined" && !cookieEnabled){ 
			document.cookie="test";
			cookieEnabled=(document.cookie.indexOf("test")!=-1)? true : false
			this.setCookie("test","","delete");
		}
		return cookieEnabled;
	}
	
	this.getCookie = function (cookieName) {
	/* retrieved in the format 	cookieName4=value; cookieName3=value; cookieName2=value; cookieName1=value 	only cookies for this domain and path will be retrieved */
		var cookieJar = document.cookie.split( "; " );
		for( var x = 0; x < cookieJar.length; x++ ) {
			var oneCookie = cookieJar[x].split( "=" );
			if( oneCookie[0] == escape( cookieName ) ) { return unescape( oneCookie[1] ); }
		}
		return null;
	}

	this.setCookie = function (cookieName, cookieValue, lifeTime, path, domain, isSecure) {
		if( !cookieName ) { return false; }
		if( lifeTime == "delete" ) { lifeTime = -10; } //this is in the past. Expires immediately.
		/* This next line sets the cookie but does not overwrite other cookies.
		syntax: cookieName=cookieValue[;expires=dataAsString[;path=pathAsString[;domain=domainAsString[;secure]]]]
		Because of the way that document.cookie behaves, writing this here is equivalent to writing
		document.cookie = whatIAmWritingNow + "; " + document.cookie; */
		document.cookie = escape( cookieName ) + "=" + escape( cookieValue ) +
			( lifeTime ? ";expires=" + ( new Date( ( new Date() ).getTime() + ( 1000 * lifeTime ) ) ).toGMTString() : "" ) +
			( path ? ";path=" + path : "") + ( domain ? ";domain=" + domain : "") + 
			( isSecure ? ";secure" : "");
		//check if the cookie has been set/deleted as required
		if( lifeTime < 0 ) { if( typeof( this.getCookie( cookieName ) ) == "string" ) { return false; } return true; }
		if( typeof( this.getCookie( cookieName ) ) == "string" ) { return true; } return false;
	}

	this.delCookie = function (cookieName) {
		this.setCookie(cookieName,"","delete");
	}	

	/*----------------------------------------------------------------------*/
	this.encodeForm = function (theForm, fields) {
//	if formname = null, fields contain a plain list of nodeID
//	if fields is null, all formfields are used.
//	cooki-format: id=field,id=field,id=field,...
		var fe = null;
		if (typeof fields == "undefined") fields = null;
		if (theForm &&  theForm.elements) fe = theForm.elements; // theForm is object,e.a. this
		if (theForm && !theForm.elements) fe = document.forms[theForm].elements; // theForm is string
		var cooki = '';
		if (fields) for (var i in fields) {		// with fieldname array
			var oE = fe ? fe[fields[i]] : getElement.Id(fields[i]);
			if (oE) cooki += ',' + getOneElement(oE);
			} // end for

		if (fe && !fields) for (var i=0; i < fe.length; i++) {	// all formfields
			cooki += ',' + getOneElement(fe[i]);
			} // end for
		console.log(cooki.slice(1));	
		return cooki.slice(1);
	
		function getOneElement(oE) {
			var field = '';
			if (!oE.type) return field;
			var oT = oE.type.toLowerCase();
			switch (oT) {
				case "text": case "hidden": 
				case "textarea": // replace % -> %p and , -> %c
					  try { field = oE.value.replace(/~/g,'~t').replace(/,/g,'~c').replace(/=/g,'~e'); } catch(e){;} 
					  break;
				case "checkbox": case "radio":
					  field = oE.checked ? '1' : ''; break;
				case "select-one": 
					  field = oE.selectedIndex; break;
				case "select-multiple": var oO = oE.options;
					  for (var i = 0, s = ''; oO[i]; i++ ) s += oO[i].selected ? '|'+i : '';
					  if (s.length) field = s.slice(1); break;
				// ignore: password, button, image, reset, submit, file
			}
			return oE.name + '=' + field;
		} // end func
	}


	this.decodeForm = function (cooki, setfield) {
//	cooki-format: id=field,id=field,id=field,...
//	sets fields and return 2-dim array
		if (!cooki) return false;
		if (typeof setfield == "undefined") setfield = true;
		var arr = new Array();
		var coo = cooki.split(',');
		for (var c=0; c<coo.length; c++) {
			arr[c] = coo[c].split('=');
			try { arr[c][1] = arr[c][1].replace(/~e/g,'=').replace(/~c/g,',').replace(/~t/g,'~'); } catch(e){;}  
			var oE = document.getElementsByName(arr[c][0])[0];
			if (oE && setfield) setOneElement(oE, arr[c][1]);
		}
		console.log(arr);
		return arr;

		function setOneElement(oE, val) {
			if (!oE.type) return false;
			var oT = oE.type.toLowerCase();
			switch (oT) {
				case "text": case "hidden": case "file": 
				case "textarea": 
					  oE.value = val; break;
				case "checkbox": case "radio":
					  oE.checked = val ? true : false; break;
				case "select-one": 
					  oE.selectedIndex = +val; break;
				case "select-multiple": 
					  var oO = oE.options;
					  var opt = val.split('|');
					  for (var i = 0, s = ''; oO[i]; i++ ) oO[i].selected = false;
					  if (val.length) for (var i=0; i<opt.length; i++) { 
					  oO[+opt[i]].selected = true;
					   }
					  break;
				// ignore: password, button, image, reset, submit
			}
			return true;
		} // end func
	}

	/*----------------------------------------------------------------------*/
	this.getMousePos = function (e) {
		var xRel=0,xPos=0,xMax=0;
		var yRel=0,yPos=0,yMax=0;
		var evt = window.event || e;
	   	if (!evt.target) evt.target = evt.srcElement;
		// relative to target element
		var xRel = evt.layerX? evt.layerX : evt.offsetX? evt.offsetX : 0; // +document.body.scrollLeft
		var yRel = evt.layerY? evt.layerY : evt.offsetY? evt.offsetY : 0; // +document.body.scrollTop
		// absolute to document
		if (evt.pageX || evt.pageY) { 						// NON-IE
			xPos = evt.pageX; 
			yPos = evt.pageY; 
	        xMax = window.innerWidth +window.pageXOffset;
	        yMax = window.innerHeight+window.pageYOffset;
		} else if (evt.clientX || evt.clientY) {			// for IE
			xPos = evt.clientX; + document.body.scrollLeft;
			yPos = evt.clientY; + document.body.scrollTop;
			if (document.documentElement) { xPos += document.documentElement.scrollLeft;
											yPos += document.documentElement.scrollTop; }
	        xMax = document.body.clientWidth +document.body.scrollLeft + document.documentElement.scrollLeft;
	        yMax = document.body.clientHeight+document.body.scrollTop  + document.documentElement.scrollTop;
		}
//		window.status = 'x='+xPos + ' y='+yPos + ' xrel='+xRel + ' yrel='+yRel;
//		alert([evt.pageY,evt.clientY,document.body.scrollTop,document.documentElement.scrollTop]);
		return {x:xPos, y:yPos, xRel:xRel, yRel:yRel, xMax:xMax, yMax:yMax, target:evt.target};
	}

	/*----------------------------------------------------------------------*/
	this.Debugger = function(w,h,mouse) {
		var divElm = document.createElement("div");
			divElm.setAttribute("name", "DEBUG_MESSAGE");
			divElm.setAttribute("id", "DEBUG_MESSAGE");
			divElm.style.width = w + 'px';
			divElm.style.height = h + 'px';
			divElm.style.right = '10px';
			divElm.style.top = '10px';
			divElm.style.position = 'absolute';
			divElm.style.borderStyle = 'solid';
			divElm.style.borderWidth = '2px';
			divElm.style.borderColor = 'black';
			divElm.style.backgroundColor = 'white';
			divElm.style.zIndex = '10000';
			divElm.style.overflow = 'auto';
			document.body.appendChild(divElm);
		if (!divElm) { return; }
		var tblElm =	'<table style="width:100%;height:100%;textalign:left;font-size:10px">' + 
						'<tr><th style="cursor:move;height:15px;background-color:black;color:white;" id="DEBUG_MESSAGE_HEADER">Debug Windows</th></tr>' + 
						'<tr><td style="width=100%;height=100%" valign=top id="DEBUG_MESSAGE_CONTAINER"></td></tr>' +
						'</table>';
		divElm.innerHTML = tblElm;
		if (mouse) {
			if (document.layers) { document.captureEvents(Event.MOUSEMOVE); document.onmousemove = this.DebugMouse; // Netscape
			} else if (document.all) { document.onmousemove = this.DebugMouse; // Internet Explorer
			} else if (document.getElementById) { document.onmousemove = this.DebugMouse; // Netcsape 6
			}
		}
	}

	this.Debug = function (txt) {
		if(typeof obj == "object") txt = slib.print_r(txt);
		var p = document.getElementById("DEBUG_MESSAGE_CONTAINER");
		if (p) p.innerHTML = p.innerHTML + txt + "<br>";
		return p;
	}

	this.DebugMouse = function(e) {
//		alert(e);
//		document.onmousemove = null;
		var m = slib.getMousePos(e);
		var s = "Mouse: x=" + m.x + ", y=" + m.y + ",<br> xMax=" + m.xMax + ", yMax=" + m.yMax + ",<br> xRel=" + m.xRel + ", yRel=" + m.yRel;
		var p = document.getElementById("DEBUG_MESSAGE_HEADER");
		if (p) p.innerHTML = s;
		window.status = s;
//		setTimeout( function() { document.onmousemove = slib.DebugMouse; }, 100);
	}

	this.var_dump = function (obj) {
	   if(typeof obj == "object") {
	      return "Type: "+typeof(obj)+((obj.constructor) ? "\nConstructor: "+obj.constructor : "")+"\nValue: " + obj;
	   } else {
	      return "Type: "+typeof(obj)+"\nValue: "+obj;
	   }
	}

	this.print_r = function(x, max, sep, l) {
		l = l || 0;
		max = max || 10;
		sep = sep || ' ';
		if (l > max) { return "[WARNING: Too much recursion]\n"; }
		var i,r = '',t = typeof x,tab = '';
		if (x === null) { r += "(null)\n"; } else if (t == 'object') {
			l++; for (i = 0; i < l; i++) { tab += sep; }
			if (x && x.length) { t = 'array'; }
			r += '(' + t + ") :\n";
			for (i in x) { try { r += tab + '[' + i + '] : ' + this.print_r(x[i], max, sep, (l + 1)); } catch(e) { return "[ERROR: " + e + "]\n"; } }
		} else {
			if (t == 'string') { if (x == '') {	x = '(empty)'; } }
			r += '(' +  t + ') ' + x + "\n";
		}
		return r;
	};

	/*----------------------------------------------------------------------*/
	this.lightbox = {
		oTag : "overlayPAGE",
		bTag : "overlayBOX",
		cssDiv : "position:absolute;top:  0;bottom:0%;left:0 ;right:0%;z-index: 999;background-color:white;opacity:.70;filter:alpha(opacity=70);-moz-opacity:0.7;",
		cssBox : "position:absolute;top:30%;bottom:0%;left:0%;right:0%;z-index:1000;font-family:Arial;font-size:14px;color:black;border-color:gray;border-style:solid;border-width:3px;background-color:white; ",
		// set addition styles for overlay and popup if (typeof Div != "undefined") 
		css: function (Div,Box) {	
			 if (typeof Div == "undefined") Div = '';	
			 if (typeof Box == "undefined") Box = '';	
			 this.cssDivStyle = Div;	
			 this.cssBoxStyle = Box;	
		},		

		// set size of popup or 50%-auto if 0		
		size: function (width,height) {
			 if (typeof width  == "undefined") width  = 300;
			 if (typeof height == "undefined") height = 80;
			 this.BoxSize = {}
			 this.BoxSize.width  = width;
			 this.BoxSize.height = height;
		},
		
		open: function (content,boxOnly){
			if (typeof boxOnly  == "undefined") boxOnly = false;
			if (typeof this.cssBoxStyle == "undefined") this.cssBoxStyle = '';
			if (typeof this.BoxSize== "undefined") this.BoxSize = {width:300,height:80};
			if (!getElement.Id(this.oTag)) {
				var overlay	= document.createElement('div');
				overlay.setAttribute("id", this.oTag);
				overlay.style.cssText = this.cssDiv; // + ';background-color:#333333; ';
				if (typeof this.cssDivStyle != "undefined") overlay.style.cssText += this.cssDivStyle;
//				overlay.style.height = '3000px'; // Change to dynamic!!
				overlay.style.height = getDocumentSize.height() + 'px';
				overlay.style.width = getDocumentSize.width() + 'px';
				overlay.style.top = getDocumentSize.scrollHeight() + 'px';
				if (!boxOnly) document.body.appendChild(overlay);
			}	
			if (!getElement.Id(this.bTag)) {
				var box = document.createElement('div');
				box.setAttribute("id", this.bTag);

				box.className= "overlayBOX";
				box.style.cssText = this.cssBox;// + ';background-color:white; text-align:left; ';
				box.style.cssText += this.cssBoxStyle;
				document.body.appendChild(box);
			}	
//			var tableBegin = '<table style="width:100%;height:100%;"><tr><td style="width=100%;height=100%" valign="middle" align="center">';
//			var tableEnd = '</td></tr></table>';
//			if (box && typeof(content) === "string") box.innerHTML = tableBegin + content+ tableEnd;
			if (box && typeof(content) === "string") box.innerHTML = content;
			if (box) box.onclick = function() { slib.lightbox.close(); };
			var x = (getDocumentSize.width()  - this.BoxSize.width ) / 2;
			var y = (getDocumentSize.height() - this.BoxSize.height) / 2;
			box.style.width  = this.BoxSize.width  + 'px';
			box.style.height = this.BoxSize.height + 'px';
			box.style.left = Math.round(x) + 'px';
			box.style.top = getDocumentSize.scrollHeight() + Math.round(y) + 'px';
		},

		close: function(){
			this.init();
		},
		
		init: function(){
			this.cssDivStyle = '';
			this.cssBoxStyle = '';	
			this.cssBoxSize  = '';
			var node = getElement.Id(this.bTag);
	      	if (node) node.parentNode.removeChild(node);
			var node = getElement.Id(this.oTag);
	      	if (node) node.parentNode.removeChild(node);
		}
		
	} 	// end of lightbox


	/*----------------------------------------------------------------------*/
	this.toolboxTimer = null; // timeout object for toolbox
	this.toolbox = {
		bTag   : "slibToolbox",
		cssOvl : "position:absolute; z-index:899; ",
		cssBox : "position:absolute; left:10px; top:10px; z-index:888; ",
		cssBox2: "font-family:Arial; font-size:12px; color:#FF0000; padding:3px; \
				  border:2px solid; border-color:#C0C0C0 #999999 #999999 #C0C0C0; background-color:#D0D0D0; ",
		mouse: function (e) {
			var evt = window.event || e;
			var xPos=0,yPos=0;
			if (evt.pageX || evt.pageY) { 						// NON-IE
				xPos = evt.pageX; 
				yPos = evt.pageY; 
			} else if (evt.clientX || evt.clientY) {			// for IE
				xPos = evt.clientX; + document.body.scrollLeft;
				yPos = evt.clientY; + document.body.scrollTop;
				if (document.documentElement) { xPos += document.documentElement.scrollLeft;
												yPos += document.documentElement.scrollTop; }
			}
			return {left:xPos, top:yPos};
		} ,
		open: function (node, className, useEvent){
			if (!node) return null;
			clearTimeout(slib.toolboxTimer); // stop time if mouse move back to trigger element
			this.timeout = 1000; // default 1 sec
			this.offset = {left:25,top:1}
			this.position = (typeof useEvent == "undefined") ? getElement.pos(node) : this.mouse(useEvent); 
//			console.log(this.position);
			if (typeof className == "undefined") className = null;
			if (getElement.Id(this.bTag)) { if (this.thenode == node) return this.thebox; this.close(); }
			var box = document.createElement('div');
			box.setAttribute("id", this.bTag);
			box.style.cssText = this.cssBox;
			if (className) { box.className= className; } else { box.style.cssText += this.cssBox2; }
			box.style.left = (this.position.left + this.offset.left) + 'px';
			box.style.top  = (this.position.top  + this.offset.top ) + 'px';
			box.style.display = 'block';
			document.body.appendChild(box);
			this.thebox  = box;	
			this.thenode = node;	
			node.onmouseout = function() { slib.toolboxTimer = setTimeout( function() { slib.toolbox.close(); }, slib.toolbox.timeout); }
			box.onmouseout  = function() { slib.toolboxTimer = setTimeout( function() { slib.toolbox.close();  }, slib.toolbox.timeout); }
			box.onmouseover = function() { clearTimeout(slib.toolboxTimer); } // stop time if mouseover the toolbox
			return box;
		} ,
		pos: function(x,y){
			this.offset.left = x; 
			this.offset.top  = y;
			this.thebox.style.left = (this.position.left + this.offset.left) + 'px';
			this.thebox.style.top  = (this.position.top  + this.offset.top ) + 'px';
			return this.thenode;
		} ,
		html: function(html){
			if (!this.thebox) return false;
			this.thebox.innerHTML = html;
			slib.toolbox.relocate(this.thebox);
			return this.thebox;
		} ,
		img: function(src, oTxt){
			if (!this.thebox) return false;
			if (getElement.Id(this.bTag+ 'img')) return this.thebox;
			if (typeof oTxt == "undefined") oTxt = null;
			if (oTxt) 
			{	var	oSpan = document.createElement('span');
				oSpan.setAttribute("id", this.bTag + 'span' );
				oSpan.style.cssText = this.cssOvl;
				oSpan.innerHTML = oTxt;
				this.thebox.appendChild(oSpan);
			}
			var	oImg = document.createElement('img');
			oImg.onload = function() { var that=this, wait=this.offsetHeight ? 0:50; // IE cache bug
						setTimeout(function() {slib.toolbox.relocate(that)}, wait); return;	 }		
			oImg.setAttribute('src', src);
			oImg.setAttribute("id", this.bTag + 'img' );
			this.thebox.appendChild(oImg);
			return this.thebox;
		} ,
		close: function(){
			if (this.thenode) this.thenode.onmouseout = function(){}
			if (this.thebox ) this.thebox.onmouseout  = function(){}
//			if (that) that.onmouseout = function(){}
			var box = getElement.Id(this.bTag);
			if (box) box.style.display = 'none';
	      	if (box) box.parentNode.removeChild(box);
	      	this.thebox = null;
	      	return false;
		} ,
		relocate: function(obj) { 
			var box = slib.toolbox.thebox; if (!box) return false;
			var pos =  slib.toolbox.position; //getElement.pos(box);
			var posY = pos.top - getDocumentSize.scrollHeight() + obj.offsetHeight;
			if (posY > getDocumentSize.height()) slib.toolbox.thebox.style.top  = (pos.top   - obj.offsetHeight) + 'px';   
			var posX = pos.left - getDocumentSize.scrollWidth() + obj.offsetWidth;
			if (posX > getDocumentSize.width()) slib.toolbox.thebox.style.left  = (pos.left  - obj.offsetWidth - this.offset.left)  + 'px';   
			return true; 
		}
	} 	// end of toolbox


}; // end of slib



/*----------------------------------------------------------------------*/
function genLandmarkOptions (node, responseXML) {
	var col = new Array('#FFFFDD','#DDFFDD','#FFDDDD','#DDFFFF','#FFFFFF');
	var master 		= responseXML.getElementsByTagName('landmarks')[0]; 
	var landmarks 	= responseXML.getElementsByTagName('landmark');	  	
	var groups 		= responseXML.getElementsByTagName('groupLandmark');
	var i,j,name,area,o = 0;
	var sel = (typeof node == "string") ? getElement.Id(node) : node; // tag or node allow
	if (!sel) return false;
	for( i= 0 ; sel && i < groups.length ; i++ ) {
		labelgroup = groups[i].attributes.getNamedItem('label') ;
		name = labelgroup.value ;
		option = document.createElement('optgroup');
		option.label = name ;
		option.style.backgroundColor = col[o]  ;
		try      { sel.appendChild(option , null); }
		catch(e) { sel.appendChild(option ); } // IE
		//----------------------------------------------//
		lands  = groups[i].getElementsByTagName("landmark") ;
		for(j=0;j< lands.length;j++ ) {
			name = lands[j].firstChild.nodeValue;
			area = lands[j].attributes.getNamedItem('area').value ;
			option2 = document.createElement('option');
			option2.text 	= name ;
			option2.value 	= area ;	 
			option2.style.backgroundColor = col[o]  ;
			try      { sel.add(option2 , null); }
			catch(e) { sel.add(option2 ); } // IE
			} // end for(j)
			//----------------------------------------------//
		o = (o + 1) % 4;
		} // end for(i)  		
	return true;
}

/*----------------------------------------------------------------------*/
// new Ajax object, concurrency enabled. Proxy support for GET.
// ProxyDestination domain/path is not supported due to security reason. Hardcode it in the proxy.
function ajaxObject(url, callbackFunction, proxyUrl, proxyType) {
	if (typeof proxyUrl  == "undefined") proxyUrl  = null;
	if (typeof proxyType == "undefined") proxyType = 'htm';
	var that=this;      
	this.updating = false;
	this.abort = function() 
	{	if (that.updating) 
		{	that.updating=false;
			that.AJAX.abort();
			that.AJAX=null;
		}
	}
	this.update = function(passData,postMethod) 
	{ 	if (that.updating) { return false; }
		that.AJAX = this.GetXmlHttpObject();                          
		if (that.AJAX==null) { return false; } else 
		{	that.AJAX.onreadystatechange = function() 
			{  	if (that.AJAX.readyState==4 || that.AJAX.readyState=="complete") 
				{	that.updating=false;                
					if (that.AJAX.status == 200) { that.callback(that.AJAX.responseText, that.AJAX.responseXML, that.AJAX.status); }
											else { that.onError (that.AJAX.status, that.AJAX.statusText); }
					that.AJAX=null;                                         
				}                                                      
			}                                                        
			that.updating = new Date();                              
			if (/post/i.test(postMethod)) 
			{	var uri=urlCall+'?'+that.updating.getTime();
				that.AJAX.open("POST", uri, true);
				that.AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
				that.AJAX.setRequestHeader("Content-Length", passData.length);
				that.AJAX.send(passData);
			} else {
				var uri = urlCall+'?'+passData;
				if (proxyUrl) uri = proxyUrl+ '?p' + proxyType+ '=' + uri;
				if (that.cache==0) uri = uri + '&timestamp='+(that.updating.getTime()); 
				that.AJAX.open("GET", uri, true);                             
				that.AJAX.send(null);                                         
			}              
			return true;                                             
    	}                                                                           
  	}
	var urlCall = url;    
	this.onError = function () { };
	this.callback = callbackFunction || function () { };
	this.dataset = null; // can be used to pass external variables in an array
	this.cache = 0;

	this.GetXmlHttpObject = function() {
		 var crossxhr = false;
		 if (window.XMLHttpRequest) {         // Firefox, Opera 8.0+, Safari
		    crossxhr = new XMLHttpRequest();
		    if (crossxhr.overrideMimeType) { crossxhr.overrideMimeType('text/xml'); }
		 } else if (window.ActiveXObject) {   // Internet Explorer 
		  try { crossxhr = new ActiveXObject('Msxml2.XMLHTTP');  } catch(e) {
		  try { crossxhr = new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { crossxhr = false;  } } 
		 }
		 return crossxhr;
	}
}
// example origional ajax:                     aj_hotellist.php?  p=test&region=chumphon
// pxy1.php? phtm=http://www.sawadee.com/R24n/ aj_hotellist.php?  p=test&region=chumphon		[ proxy = pxy1.php      | path=http://www.sawade.com/R24n/ ]


/*----------------------------------------------------------------------*/
// install a dummy function console.log() if no firebug installed
if (typeof console === "undefined") { 
    console = { log: function() { } }; 
}


if (typeof multiClassName === "undefined") { 
    multiClassName = { 
    	test: function(obj,strClass) {
				if (obj.className)
				{	var arrList = obj.className.split(' ');
					var strClassUpper = strClass.toUpperCase();
					for (var i = 0; i < arrList.length; i++)
						if ( arrList[i].toUpperCase() == strClassUpper ) return true;
				}
				return false;
		} ,
    	add: function(obj,strClass) {
				if (obj.className)
				{	var arrList = obj.className.split(' ');
			        var strClassUpper = strClass.toUpperCase();
			        for (var i = 0; i < arrList.length; i++)
			        	if (arrList[i].toUpperCase() == strClassUpper) { arrList.splice(i, 1); i--; }
			        arrList[arrList.length] = strClass;
			        obj.className = arrList.join(' ');
				} else { obj.className = strClass; }
				return obj.className;
		} ,
    	remove: function(obj,strClass) {
			 	if (obj.className)
				{	var arrList = obj.className.split(' ');
			      	var strClassUpper = strClass.toUpperCase();
			      	for ( var i = 0; i < arrList.length; i++ )
			        	if (arrList[i].toUpperCase() == strClassUpper) { arrList.splice(i, 1); i--; }
			      	obj.className = arrList.join(' ');
				}
				return obj.className;
		} 
	}; 
}


if (typeof getDocumentSize === "undefined") { 
	getDocumentSize = { maxWidth: function () {
						if (window.innerWidth) { return window.innerWidth; }
						   else if (document.body) { return document.body.offsetWidth;	}
						      else if (document.documentElement) { return document.documentElement.offsetWidth;	}
					    } ,
					    maxHeight: function () {
						if (window.innerHeight) { return window.innerHeight; }
						   else if (document.body) { return document.body.offsetHeight;  }
							  else if (document.documentElement) { return document.documentElement.offsetHeight; }
					    } ,
						scrollWidth: function () {
						if (window.pageXOffset) { return window.pageXOffset; }
						   else if (document.documentElement) { return document.documentElement.scrollLeft; }
							  else if (document.body) { return document.body.scrollLeft; }
						} ,
						scrollHeight: function () {
							if (window.pageYOffset) { return window.pageYOffset; }
							   else if (document.documentElement) { return document.documentElement.scrollTop; }
								  else if (document.body) { return document.body.scrollTop; }
						} ,
						width: function () {
							if( typeof( window.innerWidth ) == 'number' ) return window.innerWidth;//Non-IE
							if( document.documentElement && ( document.documentElement.clientWidth  ) ) return document.documentElement.clientWidth;//IE 6+ in 'standards compliant mode'
							if( document.body && ( document.body.clientWidth  ) )   return document.body.clientWidth;//IE 4 compatible
						    return false;
						} ,
						height: function () {
							if( typeof( window.innerHeight) == 'number' ) return window.innerHeight;//Non-IE
							if( document.documentElement && (  document.documentElement.clientHeight ) ) return document.documentElement.clientHeight; //IE 6+ in 'standards compliant mode'
							if( document.body && (  document.body.clientHeight ) ) return document.body.clientHeight;//IE 4 compatible
	    					return false;
						}
					 }; 
}


// DOM helpers
if (typeof getElement === "undefined") { 
    getElement = { Id: function(tag) {     
    					if( document.layers ) { return document.layers[tag]; } //Netscape layers
					    if( document.getElementById ) { return document.getElementById(tag); } //DOM; IE5, NS6, Mozilla, Opera
					    if( document.all ) { return document.all[tag]; } //Proprietary DOM; IE4
					    if( document[tag] ) { return document[tag]; } //Netscape alternative
					    return false;
					} ,   
					Class: function (searchClass,node,tag) {	// get gelements by class name
						var classElements = new Array();
						if ( node == null ) node = document;
						if ( tag  == null ) tag = '*';
						var els = node.getElementsByTagName(tag);
						var elsLen = els.length;
						var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');
						for (i = 0, j = 0; i < elsLen; i++) {
							if ( pattern.test(els[i].className) ) { classElements[j] = els[i]; j++; }
						}
						return classElements;
					} ,	
					Table: function(obj) {	// find parent TABLE.id of object inside a table
						while (obj && !/table/i.test(obj.nodeName)){ obj = obj.parentNode; }
						return obj || null;
					} ,
					Tr: function(obj) {	// find parent TR.id of object inside a table
						while (obj && !/tr/i.test(obj.nodeName)){ obj = obj.parentNode; }
						return obj || null;
					} ,
					posX: function(obj) { // find position of object
						var curleft = 0;
						if (obj.offsetParent) while(1) 
					    {	curleft += obj.offsetLeft;
					        if (!obj.offsetParent) break;
							obj = obj.offsetParent;
						} else if(obj.x) curleft += obj.x;
					    return curleft;
					} ,
					posY: function(obj) { // find position of object
						var curtop = 0;
						if (obj.offsetParent) while(1)
						{	curtop += obj.offsetTop;
							if (!obj.offsetParent) break;
							obj = obj.offsetParent;
						} else if(obj.y) curtop += obj.y;
						return curtop;
					} ,
					posOffset: function(element) { // cumulativeOffset
					    var t = 0, l = 0;
					    do {
					      t += element.offsetTop  || 0;
					      l += element.offsetLeft || 0;
					      element = element.offsetParent;
					    } while (element);
						return getElement.store(l,t);
					} ,
					posScroll: function(element) { // cumulativeScrollOffset
					    var t = 0, l = 0;
					    do {
					      t += element.scrollTop  || 0;
					      l += element.scrollLeft || 0;
					      element = element.parentNode;
					    } while (element);
						return getElement.store(l,t);
					} ,
					pos: function(element) { // posOffset - posScroll + dsoc
						var o = getElement.posOffset(element);
						var s = getElement.posScroll(element);
					    var t = o.top  - s.top  + getDocumentSize.scrollHeight();
					    var l = o.left + s.left - getDocumentSize.scrollWidth();
//					    console.log(['pos',l,t]);
						return getElement.store(l,t);
					} ,
					store: function (l,t) { 
						var result = [l, t];
						result.left = l;
						result.top = t;
						return result; 
					}
			     }; 
}
if (typeof getID === "undefined") { // keep compatible to old function
	getID = function(tag) { return getElement.Id(tag); }
}


if (typeof getUrl === "undefined") { 
    getUrl = { query: function(key) {    
					if (typeof key == "undefined") key = null;
					var arrQueryString = window.location.href.split("?");
					var returnString = "";
					if (arrQueryString.length-1 > 0) 
					{	var queryString = arrQueryString[1];
						var arrPairString = queryString.split("&");
						for (var i=0;i<arrPairString.length;i++) 
						{	arrPiece = arrPairString[i].split("=");
							if (key && key == arrPiece[0]) return arrPiece[1];
						}
					} // end if
					return key ? null : queryString;
				} ,
				scriptNameFull: function () {
					var curUrl = window.location.href;
					return curUrl.substring(curUrl.lastIndexOf("/")+1);
				} ,
				scriptNameOnly: function() {
					var curUrl = window.location.href;
					curUrl = curUrl.substring(curUrl.lastIndexOf("/")+1);
					return curUrl.substring(0, curUrl.lastIndexOf("?"));
				} ,
				domain: function () {
					return document.domain ? document.domain : window.location.hostname;
				}
		     }; 
}
     

if (!Function.prototype.chainEvent) { 
	Function.prototype.chainEvent = function(args) {   
	    args.push(this);   
	    return function() { for(var i = 0; i < args.length; i++) { args[i](); } }
	}; 
}		
//window.addLoad = function(fn) {   
//    window.onload = typeof(window.onload) != 'function' ? fn : window.onload.chainEvent([fn]);   
//   };  
   
   
// Prototype extensions
if (!String.prototype.trim) { 
	String.prototype.trim = function(){ return (this.replace(/^\s\s*/, '').replace(/\s\s*$/, '')); }
}		


// Extension for IE Browser
if (!Array.prototype.indexOf) { 
	Array.prototype.indexOf = function (obj, fromIndex) { 
	    if (fromIndex == null) { fromIndex = 0; } else if (fromIndex < 0) { 
	        fromIndex = Math.max(0, this.length + fromIndex); 
	    } 
	    for (var i = fromIndex, j = this.length; i < j; i++) { if (this[i] === obj) return i; } 
	    return -1; 
	}; 
} 


if (!Array.prototype.find) { 
	Array.prototype.find = function(searchStr,idx) {  
		if (typeof idx == "undefined") idx=null;
		var returnArray = false;  
		for (var i=0; i<this.length; i++) {    
			var element = (idx === null) ? this[i] : this[i][idx];
			if (typeof(searchStr) == 'function') {      
				if (searchStr.test(element)) {        
					if (!returnArray) { returnArray = [] }        
					returnArray.push(i);      
				}    
			} else {      
			  if (element===searchStr) {        
				if (!returnArray) { returnArray = [] }        
				returnArray.push(i);      
			  }    
			}  
		}  
		return returnArray;
	};
}


if (!insertAfter) {
var insertAfter = function(newNode,oldNode) {
    oldNode.nextSibling
      ? oldNode.parentNode.insertBefore(newNode, oldNode.nextSibling)
      : oldNode.parentNode.appendChild(newNode);
	return oldNode.parentNode;
	};
}


if (!createLink) {
	var createLink = function(url,text,cssClass) {
	    var link =  document.createElement('a');
	    if (typeof url  === 'string') { link.setAttribute('href', url); }
	    if (typeof text === 'string') { link.appendChild(document.createTextNode(text)); }
	    if (typeof cssClass === 'string') { link.className = cssClass; }
	    return link;
	};
}


if (!removeNode) {
	var removeNode = function(node){
	    if (node) node.parentNode.removeChild(node);
	};
}


if (!textElement) {
	var textElement = function(elementName,text){
	    if (typeof text === 'string')
		{	var txtElement = document.createElement(elementName);
			var txtNode = document.createTextNode(text);
			txtElement.appendChild(txtNode);
	    }
		return txtElement;
	};
}



/*----------------------------------------------------------------------*/
function $() {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
//		elements[elements.length] = element;
	}
	return elements;
}


/*----------------------------------------------------------------------*/
function addEvent( obj, type, fn ) {
	if (obj.addEventListener) {
		obj.addEventListener( type, fn, false );
		EventCache.add(obj, type, fn);
	}
	else if (obj.attachEvent) {
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
		EventCache.add(obj, type, fn);
	}
	else {
		obj["on"+type] = obj["e"+type+fn];
	}
}

var EventCache = function(){
	var listEvents = [];
	return {
		listEvents : listEvents,
		add : function(node, sEventName, fHandler){
			listEvents.push(arguments);
		},
		flush : function(){
			var i, item;
			for(i = listEvents.length - 1; i >= 0; i = i - 1){
				item = listEvents[i];
				if(item[0].removeEventListener){
					item[0].removeEventListener(item[1], item[2], item[3]);
				};
				if(item[1].substring(0, 2) != "on"){
					item[1] = "on" + item[1];
				};
				if(item[0].detachEvent){
					item[0].detachEvent(item[1], item[2]);
				};
				item[0][item[1]] = null;
			};
		return false;
		}
	};
}();
addEvent(window,'unload',EventCache.flush);


function clearEvent(e){
	var evt=window.event || e;
	if (evt.preventDefault) evt.preventDefault();
	return false;
}

/*----------------------------------------------------------------------*/
// adds an window.onload event (chaining)
function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	}
	else {
		window.onload = function() {
			oldonload();
			func();
		}
	}
}


/*----------------------------------------------------------------------*/
// DOMReady.add ( function () {  alert (" DOM is ready ! 1") ; } ) ;
var DOMReady = (function () {
	var fns = [],
		isReady = false,
		getFunc = function ( fn ) {
			if ( fn.constructor == String ) return function () { eval( fn ); };
			return fn;
		},
		ready = function () {
			if (isReady) return; // only fire once
			isReady = true;
			// call all registered functions
			for ( var x = 0; x < fns.length; x++ ) fns[x]();	// call function
		};

	/**
	 * Add code or function to execute when the DOM is ready
	 * @param fn [function | string]
	 * @return [DOMReady] for chaining
	 */
	this.add = function ( fn ) {
		fn = getFunc( fn );

		// call imediately when DOM is already ready
		if ( isReady ) {
			fn();
		} else {
			// add to the list
			fns[fns.length] = fn;
		}

		// return this for chaining
		return this;
	};

	// For all browsers except IE
	if ( window.addEventListener )
		document.addEventListener( 'DOMContentLoaded', function(){ ready(); }, false );

	// For IE
	(function(){
		if ( ! document.uniqueID && document.expando ) return; // check IE's proprietary DOM members
		// you can create any tagName, even customTag like <document :ready />
		var tempNode = document.createElement('document:ready');
		try { tempNode.doScroll('left'); // see if it throws errors until after ondocumentready
			} catch ( err ) { setTimeout(arguments.callee, 50); return; }
		// no errors, fire
		ready();
	})();

	return this;
})();

   
//function obj2(v2) {
//o2=new obj2(22);
//x2 = o2.fn2(222);
//obj2.prototype.a2 = function (b) { return (this.var2 + b); }
//return {width: element.offsetWidth, height: element.offsetHeight};
//http://cross-browser.com/x/examples/property_viewer.html

