// Written by Petter Ahlberg

/*  ============================================================================= 

    Version Info
    v 0.* First Version written some time in April 2007
    
    ----------------------------------------------------
    
    v 1.5 2007-05-25 (First numbered version, the ".5" part is completly made up)
    
        1.  added func. for "he.setAttr()" because IE (7> cannot change the "type" attribute once an element is added to the DOM tree)
    
    ----------------------------------------------------
    
    v 1.5.0.1 2007-05-30
        1. fixed some bugs in "he.setAttr()" for IE. It's still not perfect. But I'm getting there
    
    ----------------------------------------------------
    
    v 1.5.1.0 2007-06-04
    
        1. "he.addClass" now checks the exact className insted of the previous used "indexOf()"
        2. function "getKeys()" added
        3. "test.flush()" func. added
        4. xhr (XMLHttpRequest) added. The "post" thingy does'nt really work as it's supposed to.
        5. Fixed the (IE) bug in "he.setAttr()".
        
    ============================================================================= 
*/

// he == Html Element
var he = {
	ce : null, // Current Element
	te : null, // Target Element
	cbc : "", // Cross Browser Class
	cec : null, // Current Element Class
	tc : "", // Text Content
	et : null, // Event Target
	at : null, // All Tags
	pn : null, // ParentNode
	cea : null, // Current Element Attribute
	str : "",
	heInit : false,
	init : function(){
		if(navigator.appName.indexOf("Microsoft") != -1){
			// IE
			this.cbc = "className";
			this.tc = "text";
			this.et = "window.event.srcElement";
		}
		else{
			// Mozilla, Opera
			this.cbc = "class";
			this.tc = "textContent";
			this.et = "this";
		}
		this.heInit = true;
	},
	create : function(tagName,tagId){
		if(this.heInit == false){
			this.init();
		}
		var nElem = document.createElement(tagName);
			nElem.setAttribute("id",tagId);
		document.body.appendChild(nElem);
	},
	createSpecial : function(tagName,attrList,tagId){
		if(this.heInit == false){
			this.init();
		}
		var nElem = document.createElement(tagName);
			nElem.setAttribute("id",tagId);
			
		//
		// attrList: [["Attribute name","Attribute Value"],["Attribute name","Attribute Value"],["Attribute name","Attribute Value"]];
		//
		for(al=0;al<attrList.length;al++){
			if(attrList[al][0] == "class" || attrList[al][0] == "className"){
				alert("If you want to add a 'class' attribute to " + tagId + " use the 'he.addClass()' function");
				return false;
			}
			nElem.setAttribute(attrList[al][0],attrList[al][1]);
		}
		document.body.appendChild(nElem);
	},
	createTable : function(tHead,tFoot,tagId){
		if(!tagId || !tFoot || !tHead){
			alert("You must specify 'tHead' (true || false), 'tFoot' (true || false) & 'tagId'")
		}
		if(this.heInit == false){
			this.init();
		}
		
		this.createSpecial("table",[["cellpadding","0"],["cellspacing","0"]],tagId);
		
		if(tHead == true){
			this.create("thead",tagId+"THead");
			this.addTo(tagId,"last",tagId+"THead");
		}
		if(tFoot == true){
			this.create("tfoot",tagId+"TFoot");
			this.addTo(tagId,"last",tagId+"TFoot");
		}
		
		this.create("tbody",tagId+"TBody");
		this.addTo(tagId,"last",tagId+"TBody");
		
	},
	remove : function(tagId){
		this.get(tagId);
		alert("hjk");
		alert("this.ce = " + this.ce);
		this.getParent(this.ce.id);
		this.pn.removeChild(this.ce);
	},
	get : function(tagId){
		if(this.heInit == false){
			this.init();
		}
		if(tagId == "window" || tagId == window){
			this.ce = window;
		}
		else if(tagId == "document" || tagId == document){
			this.ce = document;
		}
		else if(tagId == "body" || tagId == document.body){
			this.ce = document.body;
		}
		else{
			this.ce = document.getElementById(tagId);
		}
	},
	getTarget : function(tagId){
		//
		// Same func. as "get". Used when you need to get two elements at the same time (ex: "this.addTo")
		//
		if(tagId == "window" || tagId == window){
			this.te = window;
		}
		else if(tagId == "document" || tagId == document){
			this.te = document;
		}
		else if(tagId == "body" || tagId == document.body){
			this.te = document.body;
		}
		else{
			this.te = document.getElementById(tagId);
		}
	},
	getParent : function(tagId){
		this.get(tagId);
		this.pn = this.ce.parentNode;
	},
	getAll : function(tagName){
		this.at = document.getElementsByTagName(tagName);
	},
	writeTo : function(str,action,tagId){
		// action = "all" || "add"
		if(!tagId){
		    alert("\"tagId\" is missing\nfunction: he.writeTo(str,action,tagId)\nfile: common.js");
		    return false;
		}
		this.get(tagId);
		
		if(action == "all"){
			// over writes all previous content in the target element.
			this.ce.innerHTML = str.toString();
			return;
		}
		else if(action == "add"){
			// Adds a string to the tagret element.
			this.ce.innerHTML += str.toString();
			return;
		}
		else{
			alert("ERROR!\nSomething is wrong somewhere.\nThere is a microscopic chance that someone will care at some point.\nBut that is not a promise")
		}
	},
	addTo : function(addTo,pos,tagId){
		//
		// Adds an element as a childNode to another element.
		// pos = "Position". valid values are: "first", "last" & any number
		//
		this.get(tagId);
		this.getTarget(addTo);
		
		if(this.ce && this.te){
			if(this.te.childNodes.length == 0 || pos == "last"){
				this.te.appendChild(this.ce)
			}
			else if(pos == "first" || parseInt(pos,10) <= 0){
				this.te.insertBefore(this.ce,this.te.firstChild);
			}
			else if(!isNaN(parseInt(pos,10))){
				this.te.insertBefore(this.ce,this.te.childNodes[parseInt(pos,10)]);
			}
		}
	},
	addClass : function(newClass,tagId){
		this.get(tagId);
		
		if(!this.ce.getAttribute(this.cbc)){
			this.ce.setAttribute(this.cbc,newClass);
		}
		else{
			this.getClass(tagId);
			var splitOldClass = he.cec.split(" ");
			if(splitOldClass.length == 1 && splitOldClass[0] != newClass){
				this.ce.setAttribute(this.cbc,this.ce.getAttribute(this.cbc) + " " + newClass);
			}
			else{
				var addClass = true;
				for(oc=0;oc<splitOldClass.length;oc++){
					if(splitOldClass[oc] == newClass){
						addClass = false;
						break;
					}
				}
				if(addClass == true){
					this.ce.setAttribute(this.cbc,this.ce.getAttribute(this.cbc) + " " + newClass);
				}
				//test.writeTo("addClass : he.cec = " + he.cec + ", newClass = " + newClass + " &amp; tagId = " + tagId + "<hr>","add");
			}
		}
	},
	removeClass : function(oldClass,tagId){
		this.get(tagId);
		this.getClass(tagId);
		if(oldClass == "all"){
			this.ce.removeAttribute(this.cbc);
			return;
		}
		if(this.cec == null || this.cec.toString().indexOf(oldClass) == -1){
			return;
		}
		else{
			var splitOldClass = this.cec.split(" ");
			if(splitOldClass.length == 1){
				this.ce.removeAttribute(this.cbc);
			}
			else{
				var printClass = new String();
				for(oc=0;oc<splitOldClass.length;oc++){
					if(splitOldClass[oc] != oldClass){
						if(printClass.length == 0){
							printClass = splitOldClass[oc];
						}
						else{
							printClass += " " + splitOldClass[oc];
						}
					}
				}
				this.ce.setAttribute(this.cbc,printClass);
			}
		}
	},
	replaceClass : function(newClass,oldClass,tagId){
		this.removeClass(oldClass,tagId);
		this.addClass(newClass,tagId);
	},
	getClass : function(tagId){
		this.get(tagId);
		if(this.ce){
		    this.cec = this.ce.getAttribute(this.cbc);
		}
		else{
		    this.cec = null;
		}
	},
	getAttr : function(attrName,tagId){
		this.get(tagId),
		this.cea = this.ce.getAttribute(attrName);
	},
	setAttr : function(attrName,attrVal,tagId){
		this.get(tagId);
		if(this.cbc == "className" && attrName == "type"){ // IE
		    var oldNode = this.ce.cloneNode(true);
		    
		    var newNode = document.createElement(oldNode.nodeName)
		        newNode.type = attrVal;
		    
		    for(at=0;at<oldNode.attributes.length;at++){
		        if(
		            (
		                oldNode.attributes[at].name.toLowerCase() != "type" && oldNode.attributes[at].name.toLowerCase() != "class" && 
		                oldNode.attributes[at].name.toLowerCase() != "height" && oldNode.attributes[at].name.toLowerCase() != "width"
		            )
		            && 
		            (oldNode.attributes[at].value != "null" && oldNode.attributes[at].value != "" && oldNode.attributes[at].value != "false")){
		            newNode.setAttribute(oldNode.attributes[at].name,oldNode.attributes[at].value);
		        }
		        else if(oldNode.attributes[at].name.toLowerCase() == "class"){
		            newNode.className = "\"" + oldNode.attributes[at].value + "\"";
		        }
		    }
	        
            this.getParent(tagId);
            for(cn=0;cn<this.pn.childNodes.length;cn++){
                if(this.pn.childNodes[cn].id == oldNode.id){
                    this.pn.removeChild(this.pn.childNodes[cn]);
                    break;
                }
            }
            
            this.pn.appendChild(newNode);
            
		    oldNode = null;
		    return;
		}
		
		if(attrName == "multiple"){
			// special... Develop or discard!
			this.ce.multiple = true;
		}
		else{
			this.ce.setAttribute(attrName,attrVal);
		}
	},
	removeAttr : function(attrName,tagId){
		this.get(tagId);
		this.ce.removeAttribute(attrName);
	},
	toStr : function(notAString){
		this.str = notAString.toString();
	},
	addEvent : function(evt,func,bubble,tagId){
		if(typeof tagId === "object"){
			he.ce = tagId;
		}
		else{
			this.get(tagId);
		}
		
		if(evt.indexOf("on") != -1){
			alert("Specify events without \"on[event]\"\nWrong: onmouseover\nRight: mouseover");
			return;
		}
		if(window.attachEvent){
			this.ce.attachEvent("on"+evt,func);	
		}
		else{		
			this.ce.addEventListener(evt,func,bubble);
		}
	},
	removeEvent : function(evt,func,bubble,tagId){
		this.get(tagId);
		if(window.detachEvent){
			this.ce.detachEvent("on"+evt,func);
		}
		else{		
			this.ce.removeEventListener(evt,func,bubble);
		}
	}
}

var xhr = { // XMLHttpRequest
	cxu : null, // Current XML URL
	ps : null, // Parameters
	ftr : null, // Funciton To Run
	gp : "get", // Get/Post
	hr : false, // Http Request
	ua : null,
	lr : null, // Last Request
	xd : null, // Xml Document
	ct : 0, // count times
	responseXML : null,
	req : function(xmlurl,parameters,functionToRun,getPost){
		
		this.hr = false;
		if(window.XMLHttpRequest){ // Mozilla, Safari,...
			this.hr = new XMLHttpRequest();
			if(this.hr.overrideMimeType) {this.hr.overrideMimeType('text/xml');}
		} 
		else if(window.ActiveXObject) { // IE
			try{this.hr = new ActiveXObject("Msxml2.XMLHTTP");} 
			catch (e){
				try{this.hr = new ActiveXObject("Microsoft.XMLHTTP");} 
				catch (e){}
			}
		}
		if (!this.hr) {
			alert('Cannot create XMLHTTP instance');
			return false;
		}
		
		var doclocser = document.location.search;
		
		if(!this.ua){
			var dlsSplit = doclocser.split("&");
			for(q=0;q<dlsSplit.length;q++){
				if(dlsSplit[q].split("=")[0] == "ua"){
					this.ua = dlsSplit[q].split("=")[1];	
				}	
			}
		}
		
		if(this.ua){
			if(parameters){
				parameters += "&ua=" + this.ua;
			}
			else{
				parameters += "?ua=" + this.ua;
			}
		}
		
		this.ftr = functionToRun; this.cxu = xmlurl; this.ps = parameters; this.gp = getPost;

		if(!getPost || getPost == "get"){
			this.hr.onreadystatechange = function(){xhr.checkHttpRec(xmlurl);};
			this.hr.open('GET', xmlurl + this.ps, true); 
			this.hr.setRequestHeader('Referer', this.lr); 
			this.hr.send(null);
		}
		else if(getPost == "post"){
			this.hr.onreadystatechange = function(){xhr.checkHttpRec(xmlurl);};
			this.hr.open('POST', xmlurl, true); 
			this.hr.setRequestHeader('Referer', this.lr);
			this.hr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 
			this.hr.send(this.ps);
		}
		
		if(xmlurl.toString().indexOf("get_data.php") != -1){
			this.lr = xmlurl + parameters;
		}
	},
	checkHttpRec : function(xmlurl){
		if(xmlurl.toString().indexOf("dummy.php") != -1){
			return true;	
		}
		
		if(this.hr.readyState == 4){
			if(this.hr.status == 200 || this.hr.status == 304){
				this.xd = this.hr.responseXML;
				
				if(this.ftr == ""){
					return true;	
				}
				
				if(this.gp == "get"){
					eval(this.ftr+"('" + this.ps + "')");
					return true;
				}
				else if(this.gp == "post"){
					eval(this.ftr+"('" + this.ps + "')");
					return true;
				}
			}
			if(this.hr.status == 500){
				if(this.ct > 20){
					test.writeTo("<b style=\"color:#000\">Code 500</b> in 'xhr' (XmlHttpRequest) in common.js","all");
					this.ct = 0;
					return false;
				}
				this.ct += 1;
				if(this.gp == "get" || this.gp == "post"){
					this.req(this.cxu,this.ps,this.ftr,this.gp);
					return true;
				}
			}
		} 
	}
}

var test = {
	create : function(){
		he.create("div","testDiv");
	},
	writeTo : function(str,action){
		he.get("testDiv");
		if(!he.ce){
			this.create();
		}
		he.writeTo(str,action,"testDiv");
	},
	flush : function(){
		he.get("testDiv");
		if(he.ce){
			he.ce.innerHTML = "";
		}
	}
}

var code = {
	writeTo : function(codeStr){
		var oldCodeStr = codeStr.toString();
		var newCodeStr = new String();
		for(cs=0;cs<oldCodeStr.length;cs++){
			if(oldCodeStr.charAt(cs) == "<"){
				newCodeStr += "&lt;";
			}
			else if(oldCodeStr.charAt(cs) == ">"){
				newCodeStr += "&gt;";
			}
			else{
				newCodeStr += oldCodeStr.charAt(cs);
			}
		}
		test.writeTo(newCodeStr,"all");
	}
}

function getKeys(obj){
	//MH rock n Roll!
	var keyArr = [];
	for(key in obj){
		keyArr.push([key,obj[key]]);
	}
	return keyArr;
}

window.onerror = function(err){
	try{
		alert(err);
	}
	catch(err){
		alert(err);
	}
	return false;
}