/* Fix ie6 background image caching
-------------------------------------------------------------------------*/
try {
  document.execCommand('BackgroundImageCache', false, true);
} catch(e) {}


/* Browser detection
-------------------------------------------------------------------------*/
Browser = {
	IE:		!!(window.attachEvent && !window.opera),
	Opera: 	!!window.opera,
	WebKit:	navigator.userAgent.indexOf('AppleWebKit/') > -1,
	Gecko:	navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
}


/* Shortcut functions
-------------------------------------------------------------------------*/
function $id(id) {
	return document.getElementById(id);
}

function $class(name,parent,tag) {
	var se = [];
	var parent = typeof(parent) != "undefined" ? parent : document;
	var tag = typeof(tag) != "undefined" ? tag : "*";
	var elements = $tag(tag,parent);
	for (var i=0;elements[i]!==undefined;i++) {
		if (Element.Class.contains(elements[i],name)) {
			se.push(elements[i]);
		}
	}
	return se;
}

function $tag(name,parent) {
	return (typeof(parent) != "undefined") ? parent.getElementsByTagName(name) : document.getElementsByTagName(name);
}

function $parent(tag,obj) {
	if (obj.parentNode) {
		while(obj = obj.parentNode) {
			if (tag == obj.nodeName.toLowerCase()) {
				return obj;
			}
		}
	}
	return obj;
}

function $parentByClass(name,obj) {
    if (obj.parentNode) {
		while(obj = obj.parentNode) {
			if (Element.Class.contains(obj,name)) {
				return obj;
			}
		}
	}
	return obj;
}

function $create(tag,text) {
	var element = document.createElement(tag);
	if (typeof(text) != "undefined") {
		element.appendChild(document.createTextNode(text));}
	return element;
}

function $firstChildByTagName(tag,element) {
	for (var i=0;element.childNodes[i]!==undefined;i++) {
		if (element.childNodes[i].nodeType == 1 && element.childNodes[i].nodeName.toLowerCase() == tag) {
			return element.childNodes[i];
		}
	}
	return null;
}


/* Element related 
-------------------------------------------------------------------------*/
Element = {
	remove:function(obj) {
		if(obj.parentNode) {			
			obj.parentNode.removeChild(obj);
		}
	},
	
	removeChildNodes:function(obj) {
		var cn = obj.childNodes;		
		for (var i=cn.length-1;i>=0;i--) {
			cn[i].parentNode.removeChild(cn[i]);
		}
	},
	
	Class:{
		add:function(obj,name) {
			if (!Element.Class.contains(obj,name)) {
				obj.className += " " + name; }
		},
		
		contains:function(obj,name) {
		    var regExp = new RegExp("(^|\\s)" + name + "(\\s|$)");
		    return regExp.test(obj.className);
		},
		
		remove:function(obj,name) {
			if (Element.Class.contains(obj,name)) {
				obj.className = obj.className.replace(name,"");
			}
		},
		
		swap:function(obj,original,replacement) {
		    Element.Class.remove(obj,original);
		    Element.Class.add(obj,replacement);
		}
	},
	
	// returns the absolute position of the element
	getPosition:function(obj) {
		var pos = {x:0,y:0};
		if (obj.offsetParent) {
			pos.x = obj.offsetLeft;
			pos.y = obj.offsetTop;
			while(obj = obj.offsetParent) {
				pos.x += obj.offsetLeft;
				pos.y += obj.offsetTop;
			}
		}
		return pos;
	},
	
	// returns the size of the element
	getSize:function(obj) {
	    return {width:obj.offsetWidth || 0,height:obj.offsetHeight || 0};
  	},
  	
  	// val is percentage
  	Opacity: {
  	    set:function(obj,val) {
  	        obj.style.opacity = val / 100;
	        obj.style.filter = "alpha(opacity=" + val + ")";
  	    },
  	    
  	    get:function(obj) {
  	        return obj.style.opacity * 100;
  	    },
  	    
  	    increase:function(obj,val) {
  	        var current = obj.style.opacity * 100;
  	        Element.Opacity.Set(obj,current + val);
  	    },
  	    
  	    decrease:function(obj,val) {
  	        if (!obj.style.opacity) {
  	            Element.Opacity.Set(obj,100);
  	        }
  	        var current = obj.style.opacity * 100;
  	        Element.Opacity.Set(obj,current - val);
  	    },
  	    
  	    isOpaque:function(obj) {
  	        return Element.Opacity.Get(obj) >= 100;
  	    },
  	    
  	    isTransparent:function(obj) {
  	        return Element.Opacity.Get(obj) <= 0;
  	    },
  	    
  	    clear:function(obj) {
  	        obj.style.opacity = "";
	        obj.style.filter = "";
  	    }
  	}
}



/* Page related
-------------------------------------------------------------------------*/
WebPage = {
    getSize:function() {
        var size = {height:0,width:0};
        
        if (window.innerHeight) {
  		    size.height = window.innerHeight;
  		    size.width = window.innerWidth;
  	    }
  	    else if (document.documentElement) {
  		    size.height = document.documentElement.clientHeight;
  		    size.width = document.documentElement.clientWidth;
  	    }
  	    else if (document.body) {
  		    size.height = document.body.clientHeight;
  		    size.width = document.body.clientWidth;
  	    }
      	
        return size;
    },
    
    getScrollSize:function() {
        var size = {height:0,width:0};
                
        if (window.innerHeight && window.scrollMaxY) {
		    size.height = window.innerHeight + window.scrollMaxY;
		    size.width = window.innerWidth + window.scrollMaxX;
	    } else if (document.body.scrollHeight > document.body.offsetHeight) {
		    size.height = document.body.scrollHeight;
		    size.width = document.body.scrollWidth;
	    } else {
		    size.height = document.body.offsetHeight;
		    size.width = document.body.offsetWidth;
  	    }
        
        return size;
    },
    
    getScrollPosition:function() {
        var position = {x:0,y:0};
        
        if( typeof( window.pageYOffset ) == 'number' ) {
            position.y = window.pageYOffset;
            position.x = window.pageXOffset;
        } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
            position.y = document.body.scrollTop;
            position.x = document.body.scrollLeft;
        } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
            position.y = document.documentElement.scrollTop;
            position.x = document.documentElement.scrollLeft;
        }
        return position;
    }
}


/* Event related
-------------------------------------------------------------------------*/
var $OBSERVERS = [];

Event = {
	// returns the correct event
	get:function(e) {
		return e || window.event;
	},
	
	// stop the event propagation from event e
	stop:function(e) {
		var e = Event.get(e);
			e.cancelBubble = true;
		if (e.preventDefault) {e.preventDefault();}
		if (e.stopPropagation) {e.stopPropagation();}
	},
	
	// returns the element that fired the event e
	getElement:function(e) {
		var e = Event.get(e);
		var obj = !e.target ? e.srcElement : e.target;		
		return obj;
	},
	
	// returns the event target for mouseout
	getTarget:function(e) {
		var e = Event.get(e);
		var obj;
		if (e.type == "mouseout") {
			if (!e.relatedTarget) {
				if (!e.toElement) {
					return null;
				} else {
					obj = e.toElement;
				}
			} else {
				obj = e.relatedTarget;
			}
		}
		while (obj.nodeType != 1) obj = obj.parentNode;
		return obj;
	},
	
	// attaches an event listener to an element obj
	observe:function(obj,name,func,capture) {
		if (obj == window && name == "load") {
			this._onContent(func);
			return true;
		}
		
		var capture = typeof(capture) == "undefined" ? false : capture;
		var success = false;
		
		if (obj.addEventListener) {
			obj.addEventListener(name,func,capture); 
			success = true;
		}
		else if (obj.attachEvent) {
			obj.attachEvent("on" + name,func); 
			success = true;
		}
		
		if (success) {
			// add object to observers array
			if (!$OBSERVERS[obj]) {
				$OBSERVERS[obj] = [];
			}
			// add event to observers arr
			$OBSERVERS[obj].push({Name:name,Function:func,Capture:capture});			
			return true;
		}
		return false;
	},
	
	// removes an event listener from element obj and removes it from the observer list
	remove:function(obj,name,func,capture) {
		if (typeof(name)=="undefined" && typeof(func) == "undefined" && typeof(capture) == "undefined") {
			Event.removeBoundTo(obj);
		}
		else {
			Event._removeFromObject(obj,name,func,capture);
			Event._removeFromList(obj,name,func,capture);
		}
	},
	
	// removes all event listeners
	removeAll:function() {
		for (var obj in $OBSERVERS) {
			this.removeBoundTo(obj);
		}
	},
	
	// removes all event listeners bound to the supplied element
	removeBoundTo:function(obj) {
		if ($OBSERVERS[obj]) {
		    for (var i=$OBSERVERS[obj].length-1;i>=0;i--) {
			    var e = $OBSERVERS[obj][i];
			    this._removeFromObject(obj,e.Name,e.Function,e.Capture);
		    }
    		
		    delete $OBSERVERS[obj];
		}
	},

	// removes the event from the object
	_removeFromObject:function(obj,name,func,capture) {
		var capture = typeof(capture)=="undefined" ? false : capture;
		if (obj.removeEventListener) {
			obj.removeEventListener(name,func,capture); 
			return true; 
		}
		if (obj.detachEvent) {
			return (obj.detachEvent("on" + name,func));
		}
		return false;
	},
	
	// removes an event from the event list
	_removeFromList:function(obj,name,func,capture) {
	    if ($OBSERVERS[obj]) {
		    var capture = typeof(capture)=="undefined" ? false : capture;		
		    for (var i=0;$OBSERVERS[obj][i]!==undefined;i++) {
			    var e = $OBSERVERS[obj][i];
			    if (e.Name == name && e.Function == func && e.Capture == capture) {
				    $OBSERVERS[obj].splice(i,1);
			    }
		    }
		    if ($OBSERVERS[obj].length==0) { 
			    delete $OBSERVERS[obj];
		    }
		}
	},
	
	// takes care of the window onload problem, see http://webreflection.blogspot.com/2006/11/my-domcontentloaded-final-solution.html
	_onContent:function(func) {
		var a,b=navigator.userAgent,d=document,w=window,
		c="__onContent__",e="addEventListener",o="opera",r="readyState",
		s="<scr".concat("ipt defer src='//:' on",r,"change='if(this.",r,"==\"complete\"){this.parentNode.removeChild(this);",c,"()}'></scr","ipt>");
		w[c]=(function(o){return function(){w[c]=function(){};for(a=arguments.callee;!a.done;a.done=1)func(o?o():o)}})(w[c]);
		if(d[e])d[e]("DOMContentLoaded",w[c],false);
		if(/WebKit|Khtml/i.test(b)||(w[o]&&parseInt(w[o].version())<9))
		(function(){/loaded|complete/.test(d[r])?w[c]():setTimeout(arguments.callee,1)})();
		else if(/MSIE/i.test(b))d.write(s);
	}
}


/* Mouse related
-------------------------------------------------------------------------*/
Mouse = {
	getPosition:function(e) {
		var e = Event.get(e);
		var pos = {x:0,y:0};
		
		if (e.pageX || e.pageY)	{
			pos.x = e.pageX;
			pos.y = e.pageY;
		}
		else if (e.clientX || e.clientY) {
			pos.x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
			pos.y = e.clientY + document.body.scrollTop	+ document.documentElement.scrollTop;
		}
		return pos;
	}
}


/* Bind function from prototype library
-------------------------------------------------------------------------*/
Function.prototype.bind = function(obj) {
	var m = this;
	f = function() {
		return m.apply(obj, arguments);
	};
	return f;
}



/* Upgrade XMLHttpRequest
-------------------------------------------------------------------------*/
if (!window.XMLHttpRequest) {
    window.XMLHttpRequest = function() {
        var types = [
            "Microsoft.XMLHTTP",
            "MSXML2.XMLHTTP.5.0",
            "MSXML2.XMLHTTP.4.0",
            "MSXML2.XMLHTTP.3.0",
            "MSXML2.XMLHTTP"
        ];

        for (var i=0;types[i]!==undefined;i++) {
            try {
                return new ActiveXObject(types[i]);
            }
            catch(e) {}
        }

        return undefined;
    }
}



/* String extensions
-------------------------------------------------------------------------*/
String.prototype.trim = function() {
   return this.replace(/^\s+|\s+$/g,"");
}

String.prototype.ltrim = function() {
   return this.replace(/^\s+/g,"");
}

String.prototype.rtrim = function() {
   return this.replace(/\s+$/g,"");
}



/* Date extensions
-------------------------------------------------------------------------*/
Date.prototype.getFirstDay = function() {
	var day = new Date(this.getFullYear(),this.getMonth(),1);
	var dayNr = day.getDay();	
	return (dayNr == 0 ? 7 : dayNr);
}

Date.prototype.getTotalDays = function() {
	var month = this.getMonth();
	var year = this.getFullYear();
	return month<6 ? (month==1 ? (this.isLeapYear() ? 29 : 28) : (month%2==0?31:30)) : (month%2==0 ? 30 : 31);
}

Date.prototype.isLeapYear = function() {
	return ((this.getFullYear() %4 == 0) || (this.getFullYear() %400==0 && this.getFullYear() %100==0));
}

Date.prototype.format = function() {
    return (this.getDate() + "-" + (this.getMonth()+1) + "-" + this.getFullYear());
}

Date.prototype.matches = function(day,month,year) {
    day = Number(day);
    month = Number(month);
    year = Number(year);

    return (this.getDate() == day && this.getMonth() == month && this.getFullYear() == year);
}

Date.prototype.getFromString = function(str) {
    var deviders = ["-","/"," ",".",","];
    
    var dateParts = [];
    for (var i=0;deviders[i]!==undefined;i++) {
        var dateParts = str.split(deviders[i]);
        if (dateParts.length==3) {
            break;
        }
    }
    
    // check if the correct parts are found
    if (dateParts.length==3) {
        var part1 = parseInt(dateParts[0]);
        var part2 = parseInt(dateParts[1]);
        var part3 = parseInt(dateParts[2]);
        
        var day = part1;
        var month = part2 - 1;
        
        // if part 2 is bigger then 12 the format could be mm/dd/yyyy
        if (part2>12) {
            day = part2;
            month = part1 - 1;
        }
        
        var year = (part3<2000 && dateParts[2].length <= 2) ? part3 += 2000 : part3;
        
        return new Date(year,month,day);
    }
    else {
        return new Date();
    }
}



/* Cookie related
-------------------------------------------------------------------------*/
Cookie = {
    set:function(name,value,expires) {
        if (typeof(expires) == "undefined") {
            var theDate = new Date();
            var oneYearLater = new Date( theDate.getTime() + 31536000000 );
            var expires = oneYearLater.toGMTString();
        }
        document.cookie = name + "=" + value + ";expires=" + expires;
    },
    
    get:function(name) {
        var parts = document.cookie.split("; ");
        for (var i=0;parts[i]!==undefined;i++) {
            var cookieArr = parts[i].split("=");
            if (cookieArr[0] == name) {
                return cookieArr[1];
            }
        }
        return null;
    }
}

