String.prototype.reverse=function(){ return this.split("").reverse().join("") }

function Is() {
	agent = navigator.userAgent.toLowerCase();
	this.major = parseInt(navigator.appVersion);
	this.version = $.browser.version;
	
	this.win = ( (agent.indexOf("win")!=-1) || (agent.indexOf("16bit")!=-1) );
	this.mac = (agent.indexOf("mac")!=-1); 
	
	this.ie = ((agent.indexOf("msie") != -1)&& (agent.indexOf('opera')==-1));	
	this.ns = ((agent.indexOf('mozilla')!=-1) && (agent.indexOf('spoofer')==-1)
		&& (agent.indexOf('compatible') == -1) && (agent.indexOf('opera')==-1)
		&& (agent.indexOf('webtv')==-1));
	this.moz = (this.ns && (this.major >= 5) && (agent.indexOf('netscape')==-1));
	this.mozBased = (agent.indexOf('gecko')!=-1); 
	this.safari = (agent.indexOf("safari")!=-1);
	this.opera = (agent.indexOf("opera") != -1);
	this.chrome = (agent.indexOf("chrome") != -1);
		
	this.winie = (this.win && this.ie);
	this.macie = (this.mac && this.ie); 
}

var is = new Is(); 


Listener = function(src) {
	this.src = src;
	this.callStack = [];
};

Listener.instances = {};

Listener.getInstance = function(src, sEvent, oScope) {
    var bucket = Listener.instances[sEvent] || (Listener.instances[sEvent] = []);
    
    for(var i = bucket.length-1; i >= 0; i--)
        if(bucket[i].src == src)
            return bucket[i];
    
	// not found.
    var listener = new Listener(src);
    if(src[sEvent])
        listener.callStack[listener.callStack.length] = src[sEvent];
    
    src[sEvent] = Listener.fire(listener, oScope||src);
    return bucket[bucket.length] = listener;
};

Listener.fire = function(listener, src) {
    return function(e) {
        for(var i = listener.callStack.length - 1; i >= 0; i--) {
            src.__scopeFix = listener.callStack[i];
            src.__scopeFix(e);
        }
        src.__scopeFix = null;
    };
};

Listener.add = function(src, sEvent, fp, oScope) {
    var callStack = Listener.getInstance(src, sEvent, oScope).callStack;
    callStack[callStack.length] = fp;
};

Listener.cleanUp = function () {
    for(var type in Listener.instances) {
        var bucket = Listener.instances[type];
        var i = bucket.length-1;
        while(i >= 0)
            bucket[i--][type] = null;
    }
    if(window.CollectGarbage && i > 15)
        window.CollectGarbage();
};

function jsFramePosHelper(layerObj, frameObj) {
	frameObj.style.top = layerObj.style.top;
	frameObj.style.left = layerObj.style.left;
	frameObj.style.width = layerObj.offsetWidth;
	frameObj.style.height = layerObj.offsetHeight - 1;
	frameObj.style.zIndex = layerObj.style.zIndex - 1;		
}


var smartFooterLayerObj = null;
var smartFooterFrameObj = null;

function jsFooterInit() {
	smartFooterLayerObj = document.getElementById('bottomnavbar');
	if(is.winie) {
		smartFooterFrameObj = document.getElementById('bottomnavbarframe');
	}
	
	// firefox has a bug preventing the onscroll event to be fired when
	// scrolling with the mouse wheel
	window.setInterval('jsFooterTrack()', 300);
	
	Listener.add(window, 'onresize', jsFooterTrack);	
	Listener.add(window, 'onscroll', jsFooterTrack);
	
	jsFooterTrack();
	jsFooterShow();
}

function jsFooterShow() {
	if(smartFooterFrameObj != null) {
		smartFooterFrameObj.style.visibility = 'visible';
	}
	
	if(smartFooterLayerObj != null) {
		smartFooterLayerObj.style.visibility = 'visible';
	}
}

function jsFooterTrack() {
	if(smartFooterLayerObj != null) {	
		var footerHeight = smartFooterLayerObj.offsetHeight;
		var scrollOffset = document.documentElement.scrollTop;
		var clientHeight = document.documentElement.clientHeight;
		
		//This is a Workaround for the IE because he cannot measure the effective height of the Body
		var curtop = 0;
		var obj = document.getElementById('contentholder');
		if(obj.offsetParent){
			curtop = obj.offsetTop;
			while (obj = obj.offsetParent) {
				curtop += obj.offsetTop;
			}
		}
		var bodyHeight = curtop + document.getElementById('contentholder').offsetHeight;
		
		var topOffset = document.documentElement.clientHeight + document.documentElement.scrollTop - smartFooterLayerObj.offsetHeight;
		var bodyBottomFooterPos = document.documentElement.offsetHeight - smartFooterLayerObj.offsetHeight;

		if(clientHeight + scrollOffset > bodyHeight){
			smartFooterLayerObj.style.top = (bodyHeight - footerHeight) + 'px';
		}
		else{		
			smartFooterLayerObj.style.top = (clientHeight + scrollOffset - footerHeight) + 'px';		
		}	
		
		if(smartFooterFrameObj != null) {
			jsFramePosHelper(smartFooterLayerObj, smartFooterFrameObj);	
		}
	}
}

function jsFooterHide() {
	if(smartFooterLayerObj != null) {
		smartFooterLayerObj.style.visibility = 'hidden';			
	}
	if(smartFooterFrameObj != null) {		
		smartFooterFrameObj.style.visibility = 'hidden';
	}
}

var smartContentObj = null;
var smartFadeoutObj = null;

function jsFadeOutInit() {
	smartContentObj = document.getElementById('content');
	smartFadeoutObj = document.getElementById('fadeout');
	
	jsFadeOutTrack();	

	Listener.add(window, 'onresize', jsFadeOutTrack);
	Listener.add(window, 'onscroll', jsFadeOutTrack);
}

function jsFadeOutShow() {
	jsFadeOutTrack();
	
	if(smartFadeoutObj != null) {		
		smartFadeoutObj.style.visibility = 'visible';
	}
}

function jsFadeOutTrack() {
	if((smartFadeoutObj != null) && is.winie && (is.version < 7)) {
		$(smartFadeoutObj).css({'top':$(window).scrollTop() + 'px'});	
		$(smartFadeoutObj).height($(window).height());
	}	
}

function jsFadeOutHide() {
	if(smartFadeoutObj != null) {
		smartFadeoutObj.style.visibility = 'hidden';
	}
}


var smartInfoMsgLayerObj = null;
var smartInfoMsgFrameObj = null;

function jsInfoMsgInit() {
	if(is.winie) {
		smartInfoMsgFrameObj = document.getElementById('infomsgframe');
	}
	smartFadeoutObj = document.getElementById('fadeout');	

	Listener.add(window, 'onresize', jsInfoMsgTrack);
	Listener.add(window, 'onscroll', jsInfoMsgTrack);
}

function jsInfoMsgShow(id) {
	smartInfoMsgLayerObj = document.getElementById(id);
	
	jsInfoMsgTrack();
	
	if(smartInfoMsgFrameObj != null) {
		smartInfoMsgFrameObj.style.visibility = 'visible';
	}
	if(smartInfoMsgLayerObj != null) {
		jsFadeOutShow();
		smartInfoMsgLayerObj.style.visibility = 'visible';
	}	
}

function jsInfoMsgTrack() {
	if(smartInfoMsgLayerObj != null) {		
	
		var clientHeight = $(window).height();
		var infoHeight = $(smartInfoMsgLayerObj).height();
		$(smartInfoMsgLayerObj).css({'top':$(window).scrollTop() + ((clientHeight - infoHeight)/2) + 'px'});
		
		var clientWidth = $(window).width();
		var infoWidth = $(smartInfoMsgLayerObj).width();
		$(smartInfoMsgLayerObj).css({'left':$(window).scrollLeft() + ((clientWidth - infoWidth)/2) + 'px'});
		
		if(smartInfoMsgFrameObj != null) {
			jsFramePosHelper(smartInfoMsgLayerObj, smartInfoMsgFrameObj);
		}	
	}
}

function jsInfoMsgHide(id) {
	if(smartInfoMsgLayerObj != null) {
		smartInfoMsgLayerObj.style.visibility = 'hidden';
		smartInfoMsgLayerObj = null;
	}
	if(smartInfoMsgFrameObj != null) {
		smartInfoMsgFrameObj.style.visibility = 'hidden';
	}
	jsFadeOutHide();	
}


function jsLibInit() {
	if(is.winie && (is.version < 7)) {
		jsFooterInit();		
	}
    
    jsFadeOutInit();
	jsInfoMsgInit();
	jsToolTipInit();
}

function jsShowFirstExistingImg(imgObj, srcList, index) {
	if(imgObj == null) return;

	if(index == srcList.length) {
		imgObj.onerror = null;
		return;
	}
	
	imgObj.onerror = function(evt) { jsShowFirstExistingImg(imgObj, srcList, index + 1); }
	imgObj.src = srcList[index];	
}	

var smartToolTipLayerObj = null;

function jsToolTipInit() {
	Listener.add(document, 'onmousemove', jsUpdateToolTip);
}

function jsUpdateToolTip(e) {
	if(smartToolTipLayerObj != null) {
        x = (document.all) ? window.event.x + document.documentElement.scrollLeft : e.pageX;
        y = (document.all) ? window.event.y + document.documentElement.scrollTop  : e.pageY;
        smartToolTipLayerObj.style.left = (x + 20) + "px";
        smartToolTipLayerObj.style.top = (y + 20) + "px";
    }
}

function jsToolTipShow(id) {
   	smartToolTipLayerObj = document.getElementById(id);
   	if(smartToolTipLayerObj != null) {
		smartToolTipLayerObj.style.visibility = 'visible';
	}
}

function jsToolTipHide() {
    if(smartToolTipLayerObj != null) {
		smartToolTipLayerObj.style.visibility = 'hidden';
        smartToolTipLayerObj = null;
	}
}
