
function jsFr()
{
	this.domLoad = [];
	this.domLoaderSet = false;
	this.tagEvents = [];
	this.addEvent = addEvent;
	this.addTagEvent = addTagEvent;
	this.processTagEvents = processTagEvents;
	this.addDomLoadEvent = addDomLoadEvent;
	this.domLoaded = domLoaded;
	this.getElementsByClassName = getElementsByClassName;
	this.getEventTarget = getEventTarget;

	this.hasClass = hasClass;
	this.addClass = addClass;
	this.removeClass = removeClass;
	this.replaceClass = replaceClass;
	this.eventReturnFalse = eventReturnFalse;

	this.removeFromQueryString = removeFromQueryString;
	this.getFromQueryString = getFromQueryString;
	this.findPos = findPos;
	this.getStyle = getStyle;

	this.strip_tags = strip_tags;

	this.ajaxRequest = ajaxRequest;
}

function addEvent(elem, act, func) {
    if(typeof elem == 'string') {
        elem = document.getElementById(elem);
    }
    if(!elem) return false;

    if (act == 'domload' && elem == window) {
        this.addDomLoadEvent(func);
    }

    if(window.addEventListener) {
       elem.addEventListener(act, func, false);
    }
    else if(window.attachEvent) {
        elem.attachEvent('on'+act, func);
    }
    else return false;
    return true;
};

function addTagEvent(tagName, className, act, func)
{
	var tagEvent = new Array();
	tagEvent['tagName'] = tagName.toLowerCase();
	tagEvent['className'] = className;
	tagEvent['act'] = act;
	tagEvent['func'] = func;
	jsFr.tagEvents.push(tagEvent);
	if(jsFr.tagEvents.length<=1)
	{
		jsFr.addEvent(window, 'domload', jsFr.processTagEvents);
	}
}

function processTagEvents()
{
	var tagEvents = jsFr.tagEvents;
	for(var i=0; i<tagEvents.length; i++)
	{
		var elems = document.getElementsByTagName(tagEvents[i].tagName);
		for(var b=0; b<elems.length; b++)
		{	
			if(tagEvents[i].className == "" || elems[b].className.indexOf(tagEvents[i].className) >= 0)
			{
				jsFr.addEvent(elems[b], tagEvents[i].act, tagEvents[i].func);
			}
		}
    }
}

function addDomLoadEvent(func) {

    jsFr.domLoad.push(func);
    if (jsFr.domLoaderSet) {
        return false;
    }

	if (document.addEventListener) {
		document.addEventListener("DOMContentLoaded", jsFr.domLoaded, null);
    }
	if (/KHTML|WebKit/i.test(navigator.userAgent)) {
		var _timer = setInterval(function()	{
			if (/loaded|complete/.test(document.readyState)) {
				clearInterval(_timer);
				delete _timer;
				jsFr.domLoaded();
			}
		}, 25);
	}
   this.addEvent(window, 'load', jsFr.domLoaded);
   jsFr.domLoaderSet = true;
};

function domLoaded() {

    if (arguments.callee.done) return;
    arguments.callee.done = true;

    for (var i = 0;i < jsFr.domLoad.length;i++) {
        jsFr.domLoad[i]();
    }
};

/*
	Developed by Robert Nyman, http://www.robertnyman.com
	Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/
var getElementsByClassName = function (className, tag, elm){
	if (document.getElementsByClassName) {
		getElementsByClassName = function (className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className),
				nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
				returnElements = [],
				current;
			for(var i=0, il=elements.length; i<il; i+=1){
				current = elements[i];
				if(!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	else if (document.evaluate) {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = "",
				xhtmlNamespace = "http://www.w3.org/1999/xhtml",
				namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
				returnElements = [],
				elements,
				node;
			for(var j=0, jl=classes.length; j<jl; j+=1){
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			}
			try	{
				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			}
			catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			}
			while ((node = elements.iterateNext())) {
				returnElements.push(node);
			}
			return returnElements;
		};
	}
	else {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = [],
				elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
				current,
				returnElements = [],
				match;
			for(var k=0, kl=classes.length; k<kl; k+=1){
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for(var l=0, ll=elements.length; l<ll; l+=1){
				current = elements[l];
				match = false;
				for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};

function getEventTarget(e)
{
	if(window.event)
	{
		e=window.event;
	}
	if(e.srcElement) // mozilla
	{
		target=e.srcElement;
	}else if(e.target) // IE
	{
		target=e.target;
	}
	return target;
}

function hasClass(elem , Class_Name) {
	var regExp = new RegExp("(^|\\s)" + Class_Name + "(\\s|$)");
    return regExp.test(elem.className);
}

function addClass(elem,Class_Name) {
	if (!jsFr.hasClass(elem,Class_Name)) elem.className += " " + Class_Name;
}

function removeClass(elem,Class_Name) {
	if (jsFr.hasClass(elem,Class_Name)) {
		var reg = new RegExp("(^|\\s)" + Class_Name + "(\\s|$)", "g");
		elem.className=elem.className.replace(reg,' ');
	}
}

function replaceClass(elem,toReplace,newClass)
{
	jsFr.removeClass(elem,toReplace);
	jsFr.addClass(elem,newClass);
}
function eventReturnFalse(e)
{
	e.returnValue = false;
	if (e.preventDefault) {
		e.preventDefault( );
	} else if (e.cancelBubble) {
		e.cancelBubble = true;
	} else if (e.stopPropagation){
		e.stopPropagation();
	} else {
		return false;
	}
}

function getFromQueryString(item)
{
	var queryString;
	if(arguments.length > 1)
	{
		queryString = arguments[1];
	}else{
		queryString = window.location.search.substring(1);
	}

	var value = "";
	var items = queryString.split("&");
	for (var i=0;i<items.length;i++) {
		var pair = items[i].split("=");
	    if(pair[0] == item)
	    {
	    	value = pair[1];
	    }
	}
	return value;
}

function removeFromQueryString(remove)
{
	var queryString;
	if(arguments.length > 1)
	{
		queryString = arguments[1];
	}else{
		queryString = window.location.search.substring(1);
	}
	var newQueryString = new Array();

	var items = queryString.split("&");
	for (var i=0;i<items.length;i++) {
		var pair = items[i].split("=");
	    if(pair[0] != remove)
	    {
	    	newQueryString[newQueryString.length] = items[i];
	    }
	}
	return newQueryString.join('&');
}

function getStyle(el,styleProp)
{
	if (el.currentStyle)
		var y = el.currentStyle[styleProp];
	else if (window.getComputedStyle)
		var y = document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
	return y;
}

function findPos(obj, type)
{
	type = typeof(type) != "undefined" ? type : "absolute";
	var parent= obj.parentNode;
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
		if(type == "relative")
		{
			//search for relative positioned parent
			while(parent != "undefined" && parent.nodeType == 1)
			{
				var position = this.getStyle(parent,"position");
				if(position == "relative" || position == "absolute")
				{
					parentPos = findPos(parent);
					curleft-= parentPos[0];
					curtop-= parentPos[1];
					break;
				}
				parent = parent.parentNode;
			}
		}
	}
	return [curleft,curtop];
}


function strip_tags(str, allowed_tags) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Luke Godfrey
    // +      input by: Pul
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Onno Marsman
    // +      input by: Alex
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Marc Palau
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Eric Nagel
    // +      input by: Bobby Drake
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i><b>');
    // *     returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
    // *     example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
    // *     returns 2: '<p>Kevin van Zonneveld</p>'
    // *     example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
    // *     returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
    // *     example 4: strip_tags('1 < 5 5 > 1');
    // *     returns 4: '1 < 5 5 > 1'

    var key = '', allowed = false;
    var matches = [];
    var allowed_array = [];
    var allowed_tag = '';
    var i = 0;
    var k = '';
    var html = '';

    var replacer = function(search, replace, str) {
        return str.split(search).join(replace);
    };

    // Build allowes tags associative array
    if (allowed_tags) {
        allowed_array = allowed_tags.match(/([a-zA-Z]+)/gi);
    }

    str += '';

    // Match tags
    matches = str.match(/(<\/?[\S][^>]*>)/gi);

    // Go through all HTML tags
    for (key in matches) {
        if (isNaN(key)) {
            // IE7 Hack
            continue;
        }

        // Save HTML tag
        html = matches[key].toString();

        // Is tag not in allowed list? Remove from str!
        allowed = false;

        // Go through all allowed tags
        for (k in allowed_array) {
            // Init
            allowed_tag = allowed_array[k];
            i = -1;

            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+'>');}
            if (i != 0) { i = html.toLowerCase().indexOf('<'+allowed_tag+' ');}
            if (i != 0) { i = html.toLowerCase().indexOf('</'+allowed_tag)   ;}

            // Determine
            if (i == 0) {
                allowed = true;
                break;
            }
        }

        if (!allowed) {
            str = replacer(html, "", str); // Custom replace. No regexing
        }
    }

    return str;
}

function ajaxRequest(url, onReadyStateFunction, async)
{
	async = typeof(async) != "undefined" ? async : true;

	var xmlHttp;
	try
	{  // Firefox, Opera 8.0+, Safari
		xmlHttp=new XMLHttpRequest();
	}
	catch (e)
	{
		try// Internet Explorer
		{
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e)
		{
			try
			{
				xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch (e)
			{	//ajax not available
				return false;
			}
		}
	}
	xmlHttp.onreadystatechange=function()
	{
		if(xmlHttp.readyState==4)
		{
			onReadyStateFunction(xmlHttp.responseText);
		}
	}
	xmlHttp.open("GET",url,async);
	xmlHttp.send(null);
}


jsFr = new jsFr();