/*
 * core javascript helper functions, contains:
 * Url.encode/decode
 * RPC (XMLHttpRequest...)
 * log(message...)
 * B.isIE/.isOpera/.isGecko/...
 * $('id'), getClassName(obj)
 * HashMap ... foreach, Array.prototype.foreach
 * @author jonas.
 */
$ = function(id) { return document.getElementById(id);};
$c = function(name) { return document.createElement(name);};
$t = function(txt) { return document.createTextNode(txt);};

if (!window["contextPath"]) { 
	window.contextPath = "";
	if (document.location.href.indexOf("/firstrater1/") > 0) window.contextPath = "/firstrater1";
}

// if (!document["body"]) document.body = document.getElementsByTagName("body").item(0);
var B={isIE:false,isOpera:false,isSafari:false,isKonquerer:false,isGecko:false};
checkB = function() {
 var UA = navigator.userAgent.toLowerCase();
 var vendor = navigator.vendor || "";
 if (vendor === "KDE") { B.isKonqueror = true;} 
 else if (window["opera"]) { B.isOpera = true;} 
 else if (document["all"]) { B.isIE = true; } 
 else if (vendor.indexOf("Apple Computer, Inc.") > -1) { B = isSafari = true; } 
 else if (UA.indexOf("gecko") != -1) { B.isGecko = true; }
};
checkB();

function getClassName(obj) {
	if (typeof obj != "object" || obj === null) return false;
	return /(\w+)\(/.exec(obj.constructor.toString())[1];
}

/* http request -- as on wikipedia */
function ajax(url, vars, callbackFunction) {
  r =  new XMLHttpRequest();
  var r2 = r;
  r.open("POST", url, true);
  r.setRequestHeader("Content-Type","application/x-javascript;"); 
  r.onreadystatechange = function() {
    if (r2.readyState == 4 && r2.status == 200) {
      if (r2.responseText) {
        callbackFunction(r2.responseText);
      }
    }
  };
  r.send(vars);
}

// function us used in ProjectTaskRender.
function trimString(sInString) {
  sInString = sInString.replace( /^\s+/g, "" );// strip leading
  return sInString.replace( /\s+$/g, "" );// strip trailing
}

/* check email. Just the xxx@yyy.zz part
   possibly add name with utf-8 chars to test. 
*/
function checkEmail(email){
	var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z]{2,4})+$/;
	if (filter.test(email)){
		return true;
	}else{
		return false;
	}
}
    
function log(title,html) {

	if (window["console"] && window["console"]["log"]) { // firebug
		window.console.log(title+":"+html);
		return;
	}

	var d = $c("div");
	d.className="console_entry";
	var txt = $t(title);
	d.appendChild(txt);
	
	if (html) {
	    var div2 = document.createElement("div");
	    div2.className="console_entry_body";
	    div2.innerHTML = ""+html;
	    d.appendChild(div2); 
	}
		
	var console = $("console");
	if (console == null) {
		console = document.createElement("div");
		console.id = "console";
		console.style.backgroundColor="yellow";
		console.style.border="1px solid black";
		console.style.zIndex="10000";
		document.body.appendChild(console);
	}
	              
	console.appendChild(d);
}

/*
* to open email dialog/url "mailto:" from link
*/
function onClickEmail(str1,str2){

	var form = $("123email");
	if(!form){
		form = document.createElement("form");
		form.setAttribute("id","123email");
		
		document.body.appendChild(form);
	}
	
	form.action = "mailto:"+str1 + '@' + str2;
	form.submit();
} 
    
/* URL encoding / decoding in UTF-8  */
var Url = {
	// public method for url encoding
	encode : function (string) {
		return escape(this._utf8_encode(string));
	},
	// public method for url decoding
	decode : function (string) {
		return this._utf8_decode(unescape(string));
	},
	ccode : function (i) {
		return String.fromCharCode(i);
	},
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += Url.ccode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += Url.ccode((c >> 6) | 192);
				utftext += Url.ccode((c & 63) | 128);
			}
			else {
				utftext += Url.ccode((c >> 12) | 224);
				utftext += Url.ccode(((c >> 6) & 63) | 128);
				utftext += Url.ccode((c & 63) | 128);
			}
		}
		return utftext;
	},
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += Url.ccode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += Url.ccode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += Url.ccode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}
		return string;
	}
 };  


if (!window["encodeURI"]) {
	window.encodeURI = Url.encode;
}



/**
 *   RPC-hantering
 *    /jonas 
 *    
 */ 
function RPC() {
  	  this.url = null;
      this.request = this.createXMLHttpRequest();
      this.ticket = -1;
      this.draw = function() { alert("RPC.draw() not implemented for "+this.request);};
      this.draw.obj = this;
}

RPC.queue = {};
RPC.ticketCount = 0;

/* writes and shows an error message. */
RPC.prototype.showErrorMessage = function(xmlresponse){
	var errorElementList = xmlresponse.getElementsByTagName("error");
	var errorMsg = "";
	//collect errorMessages.
	for(var j = 0 ; j < errorElementList.length ; j++){
		var node = errorElementList[j];
		// var errorName = node.getAttribute("name");
		var errorMessage = node.getAttribute("message");
		errorMsg += (errorMessage + "\n");
	}
	if (errorElementList.length == 0) {
		errorMsg += ("missing error tags in message" + "\n");
		log("RPC-error:",errorMsg+"\n"+xmlresponse);
	}
	alert(errorMsg);
};

//this method is using post instead of get, better when sending params.
RPC.prototype.load = function(command,queryString,targetObj) {
	
	this.ticket = RPC.ticketCount;
	RPC.ticketCount ++;
	RPC.queue[this.ticket] = this;
	
	this.target = targetObj;
	this.queryString = queryString;
	this.url = command; 
	var params = this.queryString;
	this.draw.obj = this;
    		 
	if (!this.request){
		alert("can't handle xml-rpc! debug command: " + command + ", queryString: " + queryString + ", targetObj: " + targetObj);
	} else {
		window.r = this.request;
		eval("window.r.onreadystatechange = function() { var rpc = RPC.queue["+this.ticket+"]; rpc.stateChange(); }; ");
		try{delete window["r"];}catch(error){}
		genericHandler = this; // local reference
		this.request.open("POST",this.url+"?tick="+this.ticket);
		//post headers
		this.request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		this.request.setRequestHeader("Content-length", params.length);
		this.request.setRequestHeader("Connection", "close");
		//send!
		this.request.send(params); 
	} 
};
/*
RPC.prototype.loadGet = function(command,queryString,targetObj) {
	
	this.ticket = RPC.ticketCount;
	RPC.ticketCount ++;
	RPC.queue[this.ticket] = this;
	
	this.target = targetObj;
	this.queryString = queryString;
	this.url = command; 
	var params = this.queryString;
	this.draw.obj = this;
    		 
	if (!this.request){
		alert("can't handle xml-rpc! debug command: " + command + ", queryString: " + queryString + ", targetObj: " + targetObj);
	} else {
		window.r = this.request;
		eval("window.r.onreadystatechange = function() { var rpc = RPC.queue["+this.ticket+"]; rpc.stateChange(); }; ");
		try{delete window["r"];}catch(error){}
		genericHandler = this; // local reference
		this.request.open("GET",this.url+"?tick="+this.ticket);
		//post headers
		//this.request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		//this.request.setRequestHeader("Content-length", params.length);
		//this.request.setRequestHeader("Connection", "close");
		//send!
		this.request.send(params); 
	} 
}*/

RPC.prototype.stateChange = function() {

	if (this.request && this.request.readyState == 4) { 
		var targetClass = (this.target)?getClassName(this.target):'no target';
		if (this.request.status != 200) {
			log('RPC Error ('+this.request.status+' '+ this.request.statusText+'), nurl:'+this.url+'?'+this.queryString+' target:'+targetClass, this.request.responseText); 
		} else {
			if (!B.isIE) {
				try {
					this.draw();
				} catch (error) {
					alert(targetClass+"->"+error.name+": "+error.message+"\nstack:\n"+error["stack"]);	
				}
			} else {
				this.draw();
			}	
	 	} 
	 	delete RPC.queue[this.ticket];
	 	this.request = null;
	 }
}

RPC.prototype.createXMLHttpRequest = function() {
	var r = null;
	if (typeof XMLHttpRequest != 'undefined') {
		r = new XMLHttpRequest();
	} else {
		try {
			r = new ActiveXObject('Msxml2.XMLHTTP')
		} catch(e) {
			try { 
				r = new ActiveXObject('Microsoft.XMLHTTP')
			} catch(e) { 
				r = null;
			}
		}
	}
	return r;
};
  
//builds a query string form fields on form.  	
RPC.prototype.loadForm = function(formName){
 	var form = $(formName);
  	var inputs = form.getElementsByTagName("input");
  	var selects = form.getElementsByTagName("select");
  	var queryString = "";
  	queryString = this.buildQueryFromInput(queryString,inputs);
  	queryString = this.buildQueryFromSelect(queryString,selects);
  	this.load(queryString);
};

/* used?
RPC.prototype.pop = function(form){
 	var str = "";
  	for(var i in form) if (form.hasOwnProperty(i)) {
  		str += i + " = " + form[i] + " | ";
  	}
  	alert(str);
};
*/
  
RPC.prototype.buildQueryFromInput = function(queryString,inputs){  
	//read input text/hidden fields.
	for(var j = 0 ; j < inputs.length ; j++){
		var item = inputs.item(j);
  		if(item.type == "text"){
  			if(item.id == undefined) alert("DOM error: id on input tag not set.");
  			queryString += item.id + "=" + Url.encode(item.value) + "&"
  		} else if(item.type == "hidden"){
  			if(item.id == undefined) alert("DOM error: id on input tag not set.");
  			queryString += item.id + "=" + Url.encode(item.value) + "&"
  		}
	}
	return queryString;
};
  
RPC.prototype.buildQueryFromSelect = function(queryString,selects){
  	for(var i = 0; i < selects.length ; i++){
  		var item = selects.item(i);	
  		if(item.id == undefined) alert("DOM error: id on select tag is not set.");
  		queryString += item.id + "=" + Url.encode(item.options[item.selectedIndex].value) + "&"
  	}
  	return queryString;
};
  
/**
 * HashMap ============================================================
 */
function HashMap() {
 	this.oStruct = {};
}
HashMap.prototype.containsKey = function(sKey){
    return this.oStruct.hasOwnProperty(sKey);
};
HashMap.prototype.containsValue = function(sValue){
    for(var x in this.oStruct){
        if( this.oStruct[x] != undefined && (this.oStruct[x] == (sValue))){
            return true;
        }
    }
    return false;
};
HashMap.prototype.get = function(sKey){
	if (this.oStruct.hasOwnProperty(sKey)) return this.oStruct[sKey];
	return null;
};
HashMap.prototype.isEmpty = function(){
   	return (this.size() == 0);
};
HashMap.prototype.put = function(sKey,oObj){
    var oOldObj = this.get(sKey);
    this.oStruct[sKey] = oObj;
    return oOldObj;
};
HashMap.prototype.remove = function(sKey){
    if(!this.containsKey(sKey)) return null;    
    var oldObj = this.oStruct[sKey];
    delete this.oStruct[sKey];
    return oldObj;
};
/**
* executes function (key, [value]) for each entry in map / jonas
*/
HashMap.prototype.foreach = function(func) {
   for(var k in this.oStruct) {
   	   if (this.oStruct.hasOwnProperty(k)) func(k,this.oStruct[k]);
   }
};
HashMap.prototype.size = function(){
	var index = 0;
	for(var k in this.oStruct){
	    if (this.oStruct.hasOwnProperty(k)) index++;
	}
	return index;
};

HashMap.prototype.clear = function(){
 	this.oStruct = {};
};

/**
* foreach for Arrays... 
* note: causes eclipse error "the type Function could not be resolved" ??
* not used right now...
Array.prototype.foreach = function(f) {
   for(var i = 0; i < this.length; i++) {
       if (this[i]) f(i,this[i]);
   }
};

*/

/**
 * EventSource connected to listeners...
 */
function EventSource() {
	listeners = new Array();
}
EventSource.prototype.addListener = function(obj) {
	if (obj["notify"] == undefined) throw new Error("object missing notify function");
	listeners.push(obj);
};
EventSource.prototype.notifyAll = function(event) {
	for (i in listeners) {
		if (listeners.hasOwnProperty(i)) listeners[i].notify(event);
	}
};

/**
 * DOM Helper functions.
 * used ? 
 *
 */ 
function getNodeValueFromNodeList(list,name){
	for(var i = 0 ; i != list.length ; i++){
		if(list[i].tagName == name){
			return list[i].firstChild.nodeValue; 
		}
	}
	return "";
}  
  
function getNodeValue(domObject,name){
	var tagList = domObject.getElementsByTagName(name);
	if(tagList.length > 0){
		if(tagList.item(0).firstChild){
			return tagList.item(0).firstChild.nodeValue;
		}
	}
	return "not found: " + name;
}  
    

/**
* legacy for att visa/dolja div:ar
*/

/* show/hide div, pop-uperna*/

function setVisible(szDivID, iState) { // 1 visible, 0 hidden

    var obj = $(szDivID);
    obj.style.visibility = iState ? "visible" : "hidden";

}

/* get the mouse pos form event.*/
function getPosition(e) {
    e = e || window.event;
    var cursor = {x:0, y:0};
    if (e.pageX || e.pageY) {
        cursor.x = e.pageX;
        cursor.y = e.pageY;
    } else {
        var de = document.documentElement;
        var b = document.body;
        cursor.x = e.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
        cursor.y = e.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
    }
    return cursor;
}

/* show/hide div,   display not visability */
function setDisplay(szDivID, iState,x,y) {
    var obj = $(szDivID);
    obj.style.display = iState ? "block" : "none";
    if(x) obj.style.left = x; 
    if(y) obj.style.top = y;
}

function toggleDisplay(szDivID) {
    var o = $(szDivID);
    var state = o.style.display;
    o.style.display = (state && state=="block") ? "none" : "block";
}

// place object just under element
function placeBox(element, szDivID) {

    var o = $(szDivID);
	o.style.left = (element.offsetLeft+40)+"px";
	
	var y = 0;
	var el = element;
	while(el.parentNode != o.parentNode) {
	    y=y+el.offsetTop;
	    el = el.parentNode;
	    if (!el) break;
	}
	o.style.top = (y + element.offsetHeight)+"px";   
}

// function img(id,imgsrc) { $(id).src = imgName; }

/* pa kryssikonerna*/
function swpBtn(button,imgName,contextPath) {
    alert("dont use swpBtn! Try i.e $(id).src = contextPath+'/images/'+src instead!");
}

function addHighlighting(el,hiColor,lowColor) {
   if (el.addEventListener) { // W3C
      el.addEventListener('mouseover',function () { this.style.backgroundColor = hiColor},false);
      el.addEventListener('mouseout',function () { this.style.backgroundColor = lowColor},false);
   } else { // IE (no this...)
      el.attachEvent('onmouseover',function () { el.style.backgroundColor = hiColor})
      el.attachEvent('onmouseout',function () { el.style.backgroundColor = lowColor})
   }
}

/**
* set highlighting on form objects.
* use: window.onload=fixLayout;
* /jonas
*/
function fixLayout() {    
    var i,n;
	var list = document.getElementsByTagName("input");
	for (i = 0; i < list.length; i++) {
		n = list.item(i);
		if (n.getAttribute("type") == "submit") {
			//addHighlighting(n,"#e7f1f3","#e0e0e0");
		} else if (n.getAttribute("type") == "button") {
			//addHighlighting(n,"#e7f1f3","white");
		} else {
			addHighlighting(n,"#f8f7e6","white");
		}
	}
	// removed som IE until IE7 focus-lost-bug fixed. 
	if (!B.isIE) {
		list = document.getElementsByTagName("select");
		for (i = 0; i < list.length; i++) {
			n = list.item(i);
			addHighlighting(n,"#f8f7e6","white");
		}
	}
	list = document.getElementsByTagName("textarea");
	for (i = 0; i < list.length; i++) {
		n = list.item(i);
		addHighlighting(n,"#f8f7e6","white");
	}
}

/* DOM operation to find if we are under parent */
function hasParent(node,parent) {
 while(parent != node.parentNode) {
  node = node.parentNode;
  if (!node || node.nodeName=="BODY") return false;
 }	
 return true;
}

function dropDownOpen(divId) {
 $(divId).onmouseout = dropDownCloseEvent;
 setDisplay(divId,1);
}

function dropDownClose(divId) { setDisplay(divId,0); }

function dropDownCloseEvent(event) {
 event = (event) ? event : window.event;
 var target = (event.target) ? event.target : event.srcElement;
 var rTarget = (event.relatedTarget) ? event.relatedTarget : event.toElement;
 if (!hasParent(rTarget,target)) dropDownClose(target.id);
}

function createErrorBox() {

    // html copied from error_popup.jsp
    var html = 	'<div id="errorbox_cont"> felmeddelande ... </div><div class="logknapp_pos"><div class="knapp_wrapper"><div class="kw_left_trans"></div><div class="kw_center_trans"><a href="javascript:setVisible(\"errorbox\",0);">st�ng</a></div><div class="kw_right_trans"></div></div></div>';
	var d = $c("div");
	d.id = "errorbox";
	d.style.width="393px";
	d.style.height="137px"; // ??
	d.style.backgroundImage="url(../images/alertbox.png)";
    d.innerHTML = html;
    // document.getElementsByTagName("body").item(0).appendChild(div);
    document.body.appendChild(d);
}
 
/**
*  show a tooltip ... 
*  used ? 
*/

openTip = function(text) {
	
	var node = $("tooltip");
	var body = document.body;
	
	if (!node) { // create div if not available
		node = document.createElement("div"); 
		node.id="tooltip";
		node.display="none";
		node.style.zIndex="100";
		node.style.position="absolute";	
		node.style.backgroundColor="#f0e084";
		body.appendChild(node);
	
		window.onmousemove= function(evt) { 
		   if (!evt) evt = window.event;
		   var tip=$("tooltip");
		   if (tip.style.display=="block") { 
		     tip.left=evt.clientX+"px"; tip.top=evt.clientY+"px";
		   }
		}	
	}
	
	while(node.childNodes.length > 0) 
		node.removeChild(node.childNodes[0]);

	node.appendChild(document.createTextNode(text));	
	node.style.display="block";		
	node.style.left="0px";
	node.style.top="0px";
}

closeTip = function() {
	var node = $("tooltip");
	node.style.display="none";
}

  
