//shaker init Script

//namespace
var shaker = {};

//Namespace fuer widgets
shaker.widgets = {};

//DOM Erleichterungen
shaker.dom = {};

shaker.dom.checkEventModifier = function(evt, modifier) {
    evt = shaker.dom.getEvent(evt);

    var ret = true;
    
    if (!modifier) modifier = '';
    ret = (ret && ((modifier.search(/ALT/) == -1) ? !evt.altKey : evt.altKey));
    ret = (ret && ((modifier.search(/CTRL/) == -1) ? !evt.ctrlKey : evt.ctrlKey));
    ret = (ret && ((modifier.search(/SHIFT/) == -1) ? !evt.shiftKey : evt.shiftKey));

    button = shaker.dom.getMouseButton(evt);
    ret = (ret && ((modifier.search(/MB_LEFT/) == -1) ? button == null || (button != 'LEFT') : (button != null && button == 'LEFT')));
    ret = (ret && ((modifier.search(/MB_MIDDLE/) == -1) ? button == null || (button != 'MIDDLE') : (button != null && button == 'MIDDLE')));
    ret = (ret && ((modifier.search(/MB_RIGHT/) == -1) ? button == null || (button != 'RIGHT') : (button != null && button == 'RIGHT')));

    return ret;
};

shaker.dom.findPosX = function (obj) {
    var curleft = parseInt(obj.style.left);
    if (obj.offsetParent) {
        curleft = obj.offsetLeft;
        while (obj = obj.offsetParent) {
            curleft += obj.offsetLeft;
        }
    }
    return curleft;
};

shaker.dom.findPosY = function (obj) {
    var curtop = parseInt(obj.style.top);
    if (obj.offsetParent) {
        curtop = obj.offsetTop;
        while (obj = obj.offsetParent) {
            curtop += obj.offsetTop;
        }
    }
    return curtop;
};

shaker.dom.findViewPosX = function (obj) {
	var docPos = shaker.dom.findPosX(obj);
    var scrollLeft = shaker.dom.getScrollPos()['x'];
    while (obj = obj.parentNode) {
        if (obj.scrollLeft) {
        	scrollLeft += obj.scrollLeft;
        }
    }
    return (docPos - scrollLeft);
};

shaker.dom.findViewPosY = function (obj) {
	var docPos = shaker.dom.findPosY(obj);
    var scrollTop = shaker.dom.getScrollPos()['y'];
    while (obj = obj.parentNode) {
        if (obj.scrollTop) {
        	scrollTop += obj.scrollTop;
        }
    }
    return (docPos - scrollTop);
};


shaker.dom.findViewWidth = function (obj) {
    var curWidth = 0;
    if (obj.offsetParent) {
        curWidth = obj.offsetWidth;
        while (obj = obj.offsetParent) {
            curWidth = (obj.offsetWidth < curWidth ? obj.offsetWidth : curWidth);
        }
    }
    return curWidth;
};

shaker.dom.findViewHeight = function (obj) {
    var curHeight = 0;
    if (obj.offsetParent) {
        curHeight = obj.offsetHeight;
        while (obj = obj.offsetParent) {
            curHeight = (obj.offsetHeight < curHeight ? obj.offsetHeight : curHeight);
        }
    }
    return curHeight;
};


shaker.dom.getEvent = function(evt) {
	evt = (evt) ? evt : ((window.event) ? shaker.dom.fixEvent(window.event) : '');
	return evt;
};

shaker.dom.getEventTarget = function(evt) {
    var target = null;
    
    evt = shaker.dom.getEvent(evt);
    if (evt){
        target = (evt.target) ? evt.target : evt.srcElement;
        
        //KHTML target correction
    	if (target.nodeType==3) target = target.parentNode;
            
        //Gecko target correction for option tags
    	if (target.nodeName=='OPTION') target = target.parentNode;

	 	while (target && !target.id) target = target.parentNode;
    }
    return target;
};

shaker.dom.getEventType = function(evt, target) {
    var evt_type = '';
    
    evt = shaker.dom.getEvent(evt);
    if (evt){
        if (evt.type=='keydown'){
            if (target.returnpress==true && evt.keyCode==13) {
                evt_type = 'returnpress';
            } else {
                evt_type = evt.type;
            }
        } else if (evt.type=='mousedown' && (window.opera || navigator.vendor=='KDE')) {
            mouse_button = shaker.dom.getMouseButton();
            if (target.contextmenu==true && mouse_button=='LEFT' && evt.ctrlKey) {
                evt_type = 'contextmenu';
            } else {
                evt_type = evt.type;
            }
        } else {
            evt_type = evt.type;
        }
    }

    return evt_type;
};

shaker.dom.getStyle = function(el,styleProp) {
    var x = document.getElementById(el);
    if (x.currentStyle)
        var y = x.currentStyle[styleProp];
    else if (window.getComputedStyle)
        var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
    return y;
}

shaker.dom.getStyle = function(el,styleProp) {
    var x = document.getElementById(el);
    if (x.currentStyle)
        var y = x.currentStyle[styleProp];
    else if (window.getComputedStyle)
        var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
    return y;
}

shaker.dom.getMousePos = function(evt) {
    evt = shaker.dom.getEvent(evt);
    var ret = new Array();
    ret.x = 0;
    ret.y = 0;
    
    if (evt.pageX || evt.pageY) {
		ret.x = evt.pageX;
		ret.y = evt.pageY;
    } else if (evt.clientX || evt.clientY) {
		ret.x = evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
		ret.y = evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
    }
    
    return ret;
};

shaker.dom.getMouseButton = function(evt) {
    evt = shaker.dom.getEvent(evt);

    button = null;
    if (typeof(evt.button) != 'undefined') {
	    if (typeof(evt.which) == 'undefined') {
	    	/* IE case */
	    	button = (evt.button == 1 || evt.type == "click" || evt.type == "dblclick") ? "LEFT" : ((evt.button == 4) ? "MIDDLE" : ((evt.button == 2 || evt.type == "contextmenu") ? "RIGHT" : null));
	    } else {
	   		/* All others */
	   		button = (evt.which < 2) ? "LEFT" : ((evt.which == 2) ? "MIDDLE" : "RIGHT");
	    }
	}
	return button;
};

shaker.dom.getScrollPos = function() {
    var ret = new Array();
    ret.x = 0;
    ret.y = 0;
	if (self.pageYOffset) // all except Explorer
	{
		ret.x = self.pageXOffset;
		ret.y = self.pageYOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop)
		// Explorer 6 Strict
	{
		ret.x = document.documentElement.scrollLeft;
		ret.y = document.documentElement.scrollTop;
	}
	else if (document.body) // all other Explorers
	{
		ret.x = document.body.scrollLeft;
		ret.y = document.body.scrollTop;
	}
    
    return ret;
};

shaker.dom.fixEvent = function(evt) {
    evt.preventDefault = function() {
		this.returnValue = false;	
    };
    evt.stopPropagation = function() {
		this.cancelBubble = true;
    };
    return evt;
};

shaker.dom.include = function(script_filename) {
    var script = document.createElement('script');
    script.setAttribute('language', 'javascript');
    script.setAttribute('type', 'text/javascript');
    script.setAttribute('src', script_filename);
    document.getElementsByTagName('head')[0].appendChild(script);
};

shaker.dom.replace = function(id, outerHTML) {
	var elem = document.getElementById(id);
	
	if (!elem) {
		elem = shaker.dom.searchComment(id);
	}	

	try {
		var outerElem = document.createElement(elem.parentNode.nodeName);
		outerElem.innerHTML = outerHTML;
	    elem.parentNode.insertBefore(outerElem.firstChild, elem);
	    elem.parentNode.removeChild(elem);
	    outerElem.innerHTML = '';
	} catch(e) {
		// Workaround for IE
		var tn = elem.nodeName;
		if(tn=='#comment' || tn=='THEAD' || tn=='TFOOT' || tn=='TBODY' || tn=='TR' || tn=='TD') {
			var tempDiv = document.createElement("div");
			tempDiv.innerHTML = '<table>' + outerHTML + '</table>';
		    elem.parentNode.insertBefore(tempDiv.firstChild.firstChild, elem);
		    elem.parentNode.removeChild(elem);
			tempDiv.innerHTML = '';
		}
		else throw e;	
	}
	
	if (shaker.effects.active & shaker.effects.list.domReplaceFade) {
		shaker.effects.fadeOpacity(id, 0, 100, 250, {});
		shaker.effects.restoreCSSOpacity(document.getElementById(id));		
	}

};

shaker.dom.searchComment = function(value, node) {
	if (!node) {
		node = document.getElementsByTagName('BODY')[0];
	}
	var comment = null;

	for (var i = 0; i < node.childNodes.length; i++) {
		if (node.childNodes[i].nodeType == 8 && node.childNodes[i].nodeValue == value) {
			comment = node.childNodes[i];
		} else {
			comment = shaker.dom.searchComment(value, node.childNodes[i]);
		}
		if (comment != null) {
			break;
		}
	}
	
	return comment;
};

shaker.dom.hide = function(id) {
	if (shaker.effects.active & shaker.effects.list.domHideFade) {
		shaker.effects.fadeOpacity(id, 100, 0, 250, {
			'done': function() {
				document.getElementById(id).styleDisplay = document.getElementById(id).style.display;
				document.getElementById(id).style.display = 'none';
			}
		});
	} else {
		document.getElementById(id).styleDisplay = document.getElementById(id).style.display;
		document.getElementById(id).style.display = 'none';
	}	
};

shaker.dom.show = function(id) {
	if (shaker.effects.active & shaker.effects.list.domShowFade) {
		shaker.effects.fadeOpacity(id, 0, 100, 250, {
			'done': function() {
				if (!document.getElementById(id).styleDisplay) document.getElementById(id).styleDisplay = 'block';
				document.getElementById(id).style.display = document.getElementById(id).styleDisplay;
			}
		});
	} else {
		if (!document.getElementById(id).styleDisplay) document.getElementById(id).styleDisplay = 'block';
		document.getElementById(id).style.display = document.getElementById(id).styleDisplay;
	}
};



//Javascript Effects

shaker.effects = {};
shaker.effects.active = 0;
shaker.effects.list = {
	'domReplaceFade': 1,
	'domHideFade': 2,
	'domShowFade': 4,
	'domPulse': 8
};

//change the opacity for different browsers By Id
shaker.effects.changeOpacity = function(opacity, id) {
    shaker.effects.elemChangeOpacity(opacity, document.getElementById(id));
};

//change the opacity for different browsers for Elem
shaker.effects.elemChangeOpacity = function(opacity, elem) {
    var object = elem.style;
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "alpha(opacity=" + opacity + ")"; 
};

shaker.effects.fadeOpacity = function(id, opacStart, opacEnd, millisec, options) {
//speed for each frame
    var speed = Math.round(millisec / 100);
    var timer = 0;

    //determine the direction for the blending, if start and end are the same nothing happens
    if(opacStart > opacEnd) {
        for(i = opacStart; i >= opacEnd; i--) {
            setTimeout("shaker.effects.changeOpacity(" + i + ",'" + id + "')",(timer * speed));
            timer++;
        }
    } else if(opacStart < opacEnd) {
        for(i = opacStart; i <= opacEnd; i++)
            {
            setTimeout("shaker.effects.changeOpacity(" + i + ",'" + id + "')",(timer * speed));
            timer++;
        }
    }
    if (typeof(options.done) == 'function') {
    	setTimeout(options.done,(timer * speed));
    };
};

shaker.effects.restoreCSSOpacity = function (elem) {
    var object = elem.style;
    object.opacity = null;
    object.MozOpacity = null;
    object.KhtmlOpacity = null;
    object.filter = null 
};		





// Allgemeine funktionen
shaker.debug = false;

shaker.addVML = function () {
    if (!document.namespaces) return;

    for(var i =0; i< document.namespaces.length; i++)
    {
        if (document.namespaces(i).name=='v' ) return;
    }
    document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');
}; 

shaker.init = function(windowname, activeEffects) {
    window.scrollTo(document.forms[0].shaker_page_posx.value, document.forms[0].shaker_page_posy.value);
    window.name = windowname;
    for (i=0; i<activeEffects.length; i++) {
    	shaker.effects.active = shaker.effects.active | shaker.effects.list[activeEffects[i]];
    }
    shaker.registerLocalEvent(document, 'keydown', shaker.showDebugConsole); 
    shaker.registerLocalEvent(document, 'click', shaker.inhibitMiddleClick); 
};

shaker.inhibitMiddleClick = function(evt, evt_widget) {
    evt = shaker.dom.getEvent(evt);

	if (shaker.dom.checkEventModifier(evt, "MB_MIDDLE") || shaker.dom.checkEventModifier(evt, "CTRL|MB_LEFT") || shaker.dom.checkEventModifier(evt, "CTRL|MB_MIDDLE")) {
		shaker.stopBubble(evt);
	}
};

shaker.showDebugConsole = function(evt, evt_widget) {
	evt = shaker.dom.getEvent(evt);
    
    if (shaker.dom.checkEventModifier(evt, "CTRL|SHIFT") && evt.keyCode == 68 /* CTRL+SHIFT+D */) {
		var debugCon = shaker.buildDebugConsole();
		debugCon.style.display = (debugCon.style.display == 'none' ? 'block' : 'none');
        evt.preventDefault();
	}
};

shaker.buildDebugConsole = function() {

	if (document.getElementById('shaker_debug')) {
		var debugDIV = document.getElementById('shaker_debug');
	} else {
		var debugDIV = document.createElement('div');
		debugDIV.setAttribute('id', 'shaker_debug');
		debugDIV.style.position = 'absolute';
		debugDIV.style.left = 0;
		debugDIV.style.bottom = 0;
		debugDIV.style.width = '100%';
		debugDIV.style.height = '200px';
		debugDIV.style.overflow = 'auto';
		debugDIV.style.color = '#0f0';
		debugDIV.style.backgroundColor = '#000';
		debugDIV.style.textAlign = 'left';
		debugDIV.style.zIndex = '95';
		debugDIV.style.display = 'none';
		document.getElementsByTagName('body')[0].appendChild(debugDIV);

		debugDIV.ondblclick = function(evt) {
			evt = shaker.dom.getEvent(evt);
	        debugDIV.style.display = 'none';
	        shaker.stopBubble(evt);
	   	};
		debugDIV.oncontextmenu = function(evt) {
			evt = shaker.dom.getEvent(evt);
	        debugDIV.innerHTML = '';
			shaker.stopBubble(evt);
	   	};
	}

	return debugDIV;
};

shaker.buildUIBlocker = function() {

    if (document.getElementById('shaker_ui_blocker')) {
        var uiBlockerDIV = document.getElementById('shaker_ui_blocker');
    } else {
        var uiBlockerDIV = document.createElement('div');
        uiBlockerDIV.setAttribute('id', 'shaker_ui_blocker');
        uiBlockerDIV.style.position = 'absolute';
        uiBlockerDIV.style.top = 0;
        uiBlockerDIV.style.left = 0;
        uiBlockerDIV.style.width = '100%';
        uiBlockerDIV.style.height = '100%';
        uiBlockerDIV.style.overflow = 'hidden';
        uiBlockerDIV.style.background = '#fff';
        uiBlockerDIV.style.zIndex = '1000';
        uiBlockerDIV.style.display = 'block';

        document.getElementsByTagName('body')[0].appendChild(uiBlockerDIV);
        
        shaker.effects.elemChangeOpacity(50, uiBlockerDIV);
    }

    return uiBlockerDIV;
};

shaker.removeUIBlocker = function() {
    if (document.getElementById('shaker_ui_blocker')) {
        document.getElementsByTagName('body')[0].removeChild(document.getElementById('shaker_ui_blocker'));
    }
};

shaker.debuglog = function(text, type) {
	if (typeof(console) != 'undefined') {
		if (type=='error') {
			console.error(text);
		} else if (type=='ajax') {
			/* do nothing because it will be logged separately in Firebug */
		} else {
			console.info(text);
		}
	} else {
		if (typeof(text) == 'string') {
            text = text.replace(/&/g, '&amp;');
    		text = text.replace(/</g, '&lt;');
    		text = text.replace(/>/g, '&gt;');
    		text = text.replace("\n", "<br />\n");
        }

		if (type=='error') {
			style = 'color: #f00';
		} else if (type=='ajax') {
			style = 'color: #fff';
		} else {
			style = 'color: #0f0';
		}
		shaker.buildDebugConsole().innerHTML += '<p style="' + style + '">' + text + '</p><hr />'; 
	}
};


// Event Funktionen
shaker.onloadHandler = Array();
shaker.onloadStarted = false;
shaker.onDOMHandler = Array();
shaker.onDOMStarted = false;
shaker.eventQueue = Array();
shaker.eventExecutionBlocked = false;
shaker.UIBlocked = false;

shaker.registerOnloadHandler = function(handler) {
	if (typeof(handler) == 'function') {
		if (shaker.onloadStarted) {
			handler();
		} else {
			shaker.onloadHandler.push(handler);
		}
	}
};

shaker.registerOnDOMHandler = function(handler) {
	if (typeof(handler) == 'function') {
		if (shaker.onDOMStarted) {
			handler();
		} else {
			shaker.onDOMHandler.push(handler);
		}
	}
};

shaker.stopBubble = function(evt) {
    evt = shaker.dom.getEvent(evt);
    evt.preventDefault(); 
    evt.stopPropagation(); 
};

shaker.executeEvent = function(event_widget, target_widget, eventType) {
    if (event_widget != null && event_widget.id) {
    	document.forms[0].shaker_event_widget.value = event_widget.id;
    } else if (event_widget == 'page') {
    	document.forms[0].shaker_event_widget.value = 'page';
    } else {
    	document.forms[0].shaker_event_widget.value = '';
    }
	if (target_widget != null && target_widget.id) {
    	document.forms[0].shaker_target_widget.value = target_widget.id;
    } else {
    	document.forms[0].shaker_target_widget.value = '';
    }
    document.forms[0].shaker_event.value        = eventType;
    document.forms[0].shaker_page_posy.value    = ((window.pageYOffset) ?  window.pageYOffset : ( (document.body.scrollTop) ? document.body.scrollTop : (document.documentElement.scrollTop) ? document.documentElement.scrollTop : 0 ) );
    document.forms[0].shaker_page_posx.value    = ((window.pageXOffset) ?  window.pageXOffset : ( (document.body.scrollLeft) ? document.body.scrollLeft : (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : 0 ) );
    document.forms[0].submit();
};
        
shaker.eventHandler = function(evt, event_widget, modifier) {
    evt = shaker.dom.getEvent(evt);
    var eventType = shaker.dom.getEventType(evt, event_widget);

    if (!modifier) modifier = '';
    
    if (eventType == 'contextmenu' || (eventType == 'returnpress' || event_widget.returnpress != true)
        && (!(window.opera || navigator.vendor=='KDE') || ((window.opera || navigator.vendor=='KDE') && (eventType == 'contextmenu' ||  event_widget.contextmenu != true)))
        && shaker.dom.checkEventModifier(evt, modifier)) {

        if (eventType != 'keypress' && eventType != 'keyup' && eventType != 'keydown') evt.preventDefault();
	    
	    shaker.queueEvent(event_widget, shaker.dom.getEventTarget(evt), eventType + (modifier != '' ? '|' : '') + modifier);
    }
};

shaker.captureEvent = function(evt, event_widget, eventType) {
    for (i=0; i<event_widget.events[eventType].length; i++) {
	   event_widget.events[eventType][i](evt, event_widget);
	}
};

shaker.queueEvent = function(event_widget, event_target, eventType, modifier) {
    shaker.eventQueue.push(function() { shaker.executeEvent(event_widget, event_target, eventType); });

    shaker.processEventQueue();
};


shaker.registerLocalEvent = function(id, eventType, callback) {
	var element = (typeof(id) == 'object' ? id : document.getElementById(id));

	if (typeof(element.events) == 'undefined') element.events = new Array();
	if (typeof(element.events[eventType]) == 'undefined') element.events[eventType] = new Array();
	if (typeof(element["on"+eventType]) == 'undefined' || element["on"+eventType] == null) {
		eval("element[\"on"+eventType+"\"] = function (evt) { shaker.captureEvent(evt, this, \"" + eventType + "\", true); }");
	}

	element.events[eventType].unshift(callback);
}; 

shaker.registerEvent = function(id, eventType, modifier) {
	var element = document.getElementById(id);
	if (eventType == 'returnpress') {
		element.returnpress = true;
		eventType = 'keydown';
	}

    if (eventType == 'contextmenu' && (window.opera || navigator.vendor=='KDE')) {
        element.contextmenu = true;
        eventType = 'mousedown';
    }

	if (typeof(element.events) == 'undefined') element.events = new Array();
	if (typeof(element.events[eventType]) == 'undefined') element.events[eventType] = new Array();
	if (typeof(element["on"+eventType]) == 'undefined' || element["on"+eventType] == null) {
		eval("element.on"+eventType+" = function (evt) { shaker.captureEvent(evt, element, eventType); };");
	}

	eval("element.events."+eventType+".push(function (evt, event_widget) { shaker.eventHandler(evt, event_widget, \"" + modifier + "\"); })");

}; 

shaker.processEventQueue = function() {
    if (!this.semaphore) this.semaphore = false;
    if (this.semaphore == true) return;
    this.semaphore = true;
    
    if (this.timeoutHandler) window.clearTimeout(this.timeoutHandler);
    
    if (shaker.eventQueue.length > 0 && shaker.eventExecutionBlocked == false) {
        if (shaker.UIBlocked == true) {
            window.setTimeout(shaker.buildUIBlocker, 10);
        }
        shaker.eventQueue.shift()();
    }
    
    if (shaker.eventQueue.length > 0) {
        this.timeoutHandler = window.setTimeout(shaker.processEventQueue, 10);
    } else {
        if (shaker.UIBlocked == true && shaker.eventExecutionBlocked == false) {
            shaker.UIBlocked = false;
            shaker.removeUIBlocker();
        }
    }

    this.semaphore = false;
}

// onLoad / onDOMReady Events
shaker.registerOnloadHandler(window.onload);
window.onload = function() {
	shaker.onloadStarted = true;
	for (var i=0; i<shaker.onloadHandler.length; ++i) {
	    try {
			shaker.onloadHandler[i]();
		} catch(e) {}
	}
};

window.onDOMReady = function() {
	shaker.onDOMStarted = true;
	for (var i=0; i<shaker.onDOMHandler.length; ++i) {
	    try {
			shaker.onDOMHandler[i]();
		} catch(e) {}
	}
};


if (navigator.userAgent.indexOf('MSIE') != -1 && navigator.userAgent.indexOf('Mac') == -1) {
	document.write("<script id=__ie_onload defer src='" + (location.protocol == "https:" ? "https://javascript:void(0)" : "javascript:void(0)") + "'><\/script>");
	document.getElementById("__ie_onload").onreadystatechange = function() {
		if (this.readyState == "complete") { window.onDOMReady(); }
	};
} else if (document.readyState && !window.opera) {
	shaker.DOMReadyTimer = window.setInterval(function() {
		if (document.readyState == 'loaded' || document.readyState == 'complete') {
			window.clearInterval(shaker.DOMReadyTimer);
			window.onDOMReady();
		};
	}, 10);
} else if (document.addEventListener) {
	document.addEventListener("DOMContentLoaded", window.onDOMReady, false);
} else { 
	shaker.registerOnloadHandler(window.onDOMReady);
}
	

//Ajax
shaker.ajax = {};

shaker.ajax.url = '';
shaker.ajax.keepaliveUrl = '';
shaker.ajax.keepaliveInterval = '';
shaker.ajax.mouseX = 0;
shaker.ajax.mouseY = 0;
shaker.ajax.loaderCnt = 0;


shaker.ajax.init = function(url, loaderUrl, keepaliveUrl, keepaliveInterval) {
		shaker.ajax.url = url;
		
		img = document.createElement('img');
		img.id = 'AJAXLoader';
		img.src = loaderUrl;
		img.style.position = 'absolute';
		img.style.display = 'none';
		img.style.zIndex = '1001';
		document.getElementsByTagName('body')[0].appendChild(img);
		
		if (keepaliveUrl != '' && keepaliveInterval != '') {
			shaker.ajax.keepaliveUrl = keepaliveUrl;
			shaker.ajax.keepaliveInterval = keepaliveInterval * 1000;
			window.setTimeout('shaker.ajax.keepalive()', shaker.ajax.keepaliveInterval);
		}
};

shaker.ajax.keepalive = function() {
	if (shaker.ajax.keepaliveUrl != '') {
		var http = shaker.ajax.getXMLHttpRequestObject();
	
		http.open('GET', shaker.ajax.keepaliveUrl, true);
		http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		http.onreadystatechange = function() {
		    if (http.readyState == 4) {
				if (http.status == 200) {
					window.setTimeout('shaker.ajax.keepalive()', shaker.ajax.keepaliveInterval);
					try {
					    eval(http.responseText);
                        if (shaker.debug == true) shaker.debuglog(http.responseText, 'ajax');
					} catch(e) {
					    shaker.debuglog("\n" + "AJAX JavaScript Error:\n" + e + "\n" + http.responseText, 'error');
					}
				} else {
					alert('AJAX error: Could not establish keepalive connection');	
			    }
			}
	    };
	    
	    http.send('');
	}
};

shaker.ajax.showLoader = function() {
	shaker.ajax.loaderCnt++;
	if (shaker.ajax.loaderCnt==1) {
		shaker.ajax.setLoader(shaker.ajax.mouseX, shaker.ajax.mouseY);
		document.onmousemove = function (evt) {
			var mousepos = shaker.dom.getMousePos(evt); 
			shaker.ajax.setLoader(mousepos.x, mousepos.y);
		};
	}
};

shaker.ajax.hideLoader = function() {
	if (shaker.ajax.loaderCnt>0) shaker.ajax.loaderCnt--;
	if (shaker.ajax.loaderCnt==0) {
		document.getElementById('AJAXLoader').style.display = 'none';
		document.onmousemove = null;
	}
};

shaker.ajax.setLoader = function(x, y) {
	if (x>0 && y>0) {
		img = document.getElementById('AJAXLoader');
		img.style.left = (x + 20) + 'px';
		img.style.top = (y + 20) + 'px';
		img.style.display = 'block';
	}
};


shaker.ajax.getXMLHttpRequestObject = function() {
    if (!window.XMLHttpRequest) {
    	if (!window.createRequest) {
    		window.XMLHttpRequest = function() { return new ActiveXObject('Microsoft.XMLHTTP') };
    	} else {
    		window.XMLHttpRequest = window.createRequest;
    	}
    }

    try {
        xmlhttp = new XMLHttpRequest();
    } catch (e) {
        xmlhttp = false;
    }

	return xmlhttp;
};

shaker.ajax.executeEvent = function(event_widget, target_widget, eventType) {

	if (shaker.ajax.url != '') {
		var http = shaker.ajax.getXMLHttpRequestObject();
	    
        shaker.eventExecutionBlocked = true;
                
        //http.open('POST', shaker.ajax.url, async);
        http.open('POST', shaker.ajax.url, true);
		http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		http.onreadystatechange = function() {
		    if (http.readyState == 4) {
			    shaker.ajax.hideLoader();
                shaker.eventExecutionBlocked = false;
                shaker.processEventQueue();
                                
                if (http.status == 200) {
					try {
					    eval(http.responseText);
                        if (shaker.debug == true) shaker.debuglog(http.responseText, 'ajax');
					} catch(e) {
                        var errormsg = '';
                        if (typeof(e) == 'Error') {
                            errormsg = e.description;
                        } else {
                            errormsg = e;
                        }
                        shaker.debuglog("\n" + "AJAX JavaScript Error:\n" + errormsg + "\n" + http.responseText);
					}
			    } else {
					alert('AJAX error');
			    }
			}
	    };

	    if (event_widget != null && event_widget.id) {
	    	document.forms[0].shaker_event_widget.value = event_widget.id;
	    } else if (event_widget == 'page') {
	    	document.forms[0].shaker_event_widget.value = 'page';
	    } else {
	    	document.forms[0].shaker_event_widget.value = '';
	    }
	    if (target_widget != null && target_widget.id) {
	    	document.forms[0].shaker_target_widget.value = target_widget.id;
	    } else {
	    	document.forms[0].shaker_target_widget.value = '';
	    }
	    document.forms[0].shaker_event.value = eventType;

/*
	   	shaker.debuglog('event_widget '+document.forms[0].shaker_event_widget.value);
	   	shaker.debuglog('target_widget '+document.forms[0].shaker_target_widget.value);
	   	shaker.debuglog('event '+document.forms[0].shaker_event.value);
*/

	    shaker.ajax.showLoader();
	    http.send(shaker.ajax.getQueryString());
	}

};

shaker.ajax.getSelectedOptions = function(select) {
    var options = select.options;
    var option = null;
    var qs = "";
    var tempString = "";

    for(var x = 0; x < options.length; x++) {
        tempString = "";
        option = options[x];

        if(option.selected) {
            tempString = select.name + "=" + encodeURIComponent(option.value);
        }

        if(tempString != "") {
            if(qs == "") {
                qs = tempString;
            }
            else {
                qs = qs + "&" + tempString;
            }
        }
    }
    return qs;
};

shaker.ajax.getQueryString = function() {
    var elements = document.forms[0].elements;
    var node = null;
    var qs = "";
    var name = "";

    var tempString = "";
    for(var i = 0; i < elements.length; i++) {
        tempString = "";
        node = elements[i];
        name = node.getAttribute("name");

        //use id if name is null
        if (!name) {
        	name = node.getAttribute("id");
        }

        if(node.tagName.toLowerCase() == "input") {
            if(node.type.toLowerCase() == "radio" || node.type.toLowerCase() == "checkbox") {
                if(node.checked) {
                    tempString = name + "=" + node.value;
                }
            }

            if(node.type.toLowerCase() == "text" || node.type.toLowerCase() == "hidden" || node.type.toLowerCase() == "password") {
                tempString = name + "=" + encodeURIComponent(node.value);
            }
        }
        else if(node.tagName.toLowerCase() == "select") {
            tempString = shaker.ajax.getSelectedOptions(node);
        }

        else if(node.tagName.toLowerCase() == "textarea") {
            tempString = name + "=" + encodeURIComponent(node.value);
        }

        if(tempString != "") {
            if(qs == "") {
                qs = tempString;
            }
            else {
                qs = qs + "&" + tempString;
            }
        }

    }
    return qs;
};

shaker.ajax.eventHandler = function(evt, event_widget, modifier, async) {
    
    evt = shaker.dom.getEvent(evt);
    var eventType = shaker.dom.getEventType(evt, event_widget);
    var event_target = shaker.dom.getEventTarget(evt);

    if (!modifier) modifier = '';

    if (eventType == 'contextmenu' || (eventType == 'returnpress' || event_widget.returnpress != true)
        && (!(window.opera || navigator.vendor=='KDE') || ((window.opera || navigator.vendor=='KDE') && (eventType == 'contextmenu' ||  event_widget.contextmenu != true)))
        && shaker.dom.checkEventModifier(evt, modifier)) {
	    
        var mousepos = shaker.dom.getMousePos(evt);
        shaker.ajax.mouseX = mousepos.x;
        shaker.ajax.mouseY = mousepos.y;

        if (eventType != 'keypress' && eventType != 'keyup' && eventType != 'keydown') evt.preventDefault();

        window.setTimeout(function() { shaker.ajax.queueEvent(event_widget, event_target, eventType + (modifier != '' ? '|' : '') + modifier, async); }, 0);
    }
};

shaker.ajax.registerEvent = function(id, eventType, modifier, async) {

	var element = document.getElementById(id);
	if (eventType == 'returnpress') {
		element.returnpress = true;
		eventType = 'keydown';
	}
    
    if (eventType == 'contextmenu' && (window.opera || navigator.vendor=='KDE')) {
        element.contextmenu = true;
        eventType = 'mousedown';
    }

	if (typeof(element.events) == 'undefined') element.events = new Array();
	if (typeof(element.events[eventType]) == 'undefined') element.events[eventType] = new Array();
	if (typeof(element["on"+eventType]) == 'undefined' || element["on"+eventType] == null || async == false) {
        eval("element.on"+eventType+" = function (evt) { shaker.captureEvent(evt, element, eventType); };");
	}
	eval("element.events."+eventType+".push(function (evt, event_widget) { shaker.ajax.eventHandler(evt, event_widget, \"" + modifier + "\", async); })");
};

shaker.ajax.queueEvent = function(event_widget, event_target, eventType, async) {
    if (async == false) {
        shaker.UIBlocked = true;
    }

    shaker.eventQueue.push(function() { shaker.ajax.executeEvent(event_widget, event_target, eventType, async); });

    shaker.processEventQueue();
};

shaker.ajax.alert = function(message) {
	window.alert(message);
};

shaker.ajax.confirm = function(message, event) {
	if (window.confirm(message)) {
		event += '-ok';
	} else {
		event += '-cancel';
	}
	shaker.ajax.executeEvent('page', null, event, true);
};


// Drag 'n' drop
shaker.dom.dragndrop = {};

shaker.dom.dragndrop.startMouseX = null;
shaker.dom.dragndrop.startMouseY = null;
shaker.dom.dragndrop.startElementX = null;
shaker.dom.dragndrop.startElementY = null;
shaker.dom.dragndrop.lastElement = null;
shaker.dom.dragndrop.element = null;
shaker.dom.dragndrop.elementPositionArray = new Array();

shaker.dom.dragndrop.addElement = function (id, dragndropAreaId) {
    var element = document.getElementById(id);
    var dragndropArea = document.getElementById(dragndropAreaId);

	var XPos = shaker.dom.findViewPosX(element);
    var YPos = shaker.dom.findViewPosY(element);


    element.style.display = 'block';
    element.style.position = 'absolute';
	element.style.left = XPos + 'px';
    element.style.top = YPos + 'px';
	element.style.margin = '0';

    if (dragndropArea != null) {
        dragndropArea.style.position = 'relative';
        dragndropArea.style.cursor = 'move';
        dragndropArea.onmousedown = shaker.dom.dragndrop.start;
        dragndropArea.dragndropElement = element;
    } else if (element != null) {
        element.style.cursor = 'move';
        element.onmousedown = shaker.dom.dragndrop.start;
        element.dragndropElement = element;
    } else {
        alert('shaker.dom.dragndrop: Could not add Element with id "' + id + '"');
    }
};

shaker.dom.dragndrop.move = function (evt) {
    evt = shaker.dom.getEvent(evt);
    var mousepos = shaker.dom.getMousePos(evt);

    shaker.dom.dragndrop.element.dragndropElement.style.left = (shaker.dom.dragndrop.startElementX + (mousepos.x - shaker.dom.dragndrop.startMouseX)) + 'px';
    shaker.dom.dragndrop.element.dragndropElement.style.top = (shaker.dom.dragndrop.startElementY + (mousepos.y - shaker.dom.dragndrop.startMouseY)) + 'px';

    return false;
};

shaker.dom.dragndrop.start = function (evt) {
    evt = shaker.dom.getEvent(evt);
    shaker.dom.dragndrop.element = shaker.dom.getEventTarget(evt);
    var mousepos = shaker.dom.getMousePos(evt);

    shaker.dom.dragndrop.startMouseX = mousepos.x;
    shaker.dom.dragndrop.startMouseY = mousepos.y;
    shaker.dom.dragndrop.startElementX = shaker.dom.findPosX(shaker.dom.dragndrop.element.dragndropElement);
    shaker.dom.dragndrop.startElementY = shaker.dom.findPosY(shaker.dom.dragndrop.element.dragndropElement);
    document.onmousemove = shaker.dom.dragndrop.move;
    document.onmouseup = shaker.dom.dragndrop.stop;

    if (shaker.dom.dragndrop.lastElement != null) {
        shaker.dom.dragndrop.lastElement.style.zIndex -= 100;
        shaker.dom.dragndrop.lastElement.dragndropElement.style.zIndex -= 100;
    }
    shaker.dom.dragndrop.lastElement = shaker.dom.dragndrop.element;
    shaker.dom.dragndrop.element.style.zIndex += 100;
    shaker.dom.dragndrop.element.dragndropElement.style.zIndex += 100;

    return false;
};

shaker.dom.dragndrop.stop = function (evt) {
	var XPos = shaker.dom.findPosX(shaker.dom.dragndrop.element.dragndropElement);
    var YPos = shaker.dom.findPosY(shaker.dom.dragndrop.element.dragndropElement);
    
    document.onmousemove = null;
    document.onmouseup = null;
    shaker.dom.dragndrop.element = null;
    shaker.dom.dragndrop.startMouseX = null;
    shaker.dom.dragndrop.startMouseY = null;
    shaker.dom.dragndrop.startElementX = null;
    shaker.dom.dragndrop.startElementY = null;

    return false;
};


