//used to mark form dirty and warn user to save first.
var o2c=0;
o_info.guibusy = false;


function o_init() {
	try {
		// all init-on-new-page calls here
		o_getOpenWin().o_afterserver();	
	} catch(e) {}	
}

function o_getOpenWin() {
	var w = top;
	try {
		if (w.opener && w.opener.o_info) {
			w = w.opener;
		}
	} catch (e) {}
	return w;
}

o_info.linkbusy = false;

function o2cl() {
	//alert("busy:"+o_info.linkbusy);
	if (o_info.linkbusy) {
		return false;
	} else {
		if (window.olatonunload) olatonunload();
		var doreq = (o2c==0 || confirm(o_info.dirty_form));
		if (doreq) o_beforeserver();
		return doreq;
	}
}


function o_ajaxwins() {
	for (var key in o_info.wins) {
    	var curwin = o_info.wins[key];
    	if (curwin.closed) {
    		delete o_info.wins[key];
    		//todo: notify server that window has been closed
    	} 
    }
    window.setTimeout("o_ajaxwins()", 1280);
}

function o_beforeserver() {
	o_info.linkbusy = true;
	o_info.busyon = true;
	setTimeout("showAjaxBusy()",1000);
	setTimeout("o_afterserver()",1500);
}


function o_afterserver() {
	o_info.linkbusy = false;
	removeBusy();
	removeAjaxBusy();
}

function showerror(e) {
	var r = "";
    for (var p in e)
      r += p + ": " + e[p] + "\n";
    return "error detail:\n"+r;
}


function o_mainregister(winid, win) {
	o_info.wins[winid] = win;
}

function o_ainvoke(r) {
	// commands
	var cmdcnt = r["cmdcnt"];
	if (cmdcnt > 0) {
		var cs = r["cmds"];
		for (var i=0; i<cmdcnt; i++) {
			var acmd = cs[i];
			var co = acmd["cmd"];
			var cda = acmd["cda"];
			var wid = acmd["w"];
			var wi = o_info.wins[wid]; 
			var out;
			if (wi) {
				switch (co) {
					case 1: // specific command
						var f = cda["f"];
						var jso = cda["jso"];
						var cdata = cda["data"];
						var e1;
						try {
							eval("e1 = wi."+jso);
							if (e1) {
								eval("e1."+f+"(cdata)");
							} else {
								// if a component function was not found
								if (isdebug) alert ("function f = '"+f+"' not found");
							}
							
						} catch (e) {
							if (isdebug) alert("eval error: jso='"+jso+"', exception:"+e);
						}
						
						break;
					case 2:  // redraw components command
						var cnt = cda["cc"];
						var ca = cda["cps"];
						for (var j=0;  j<cnt; j++) {
							var c1 = ca[j];
							var ciid = c1["cid"]; // component id
							var hfrag = c1["hfrag"]; // html fragment of component
							var jsol = c1["jsol"]; // javascript on load
							var hdr = c1["hdr"]; // header
							var con = hfrag.stripScripts();
							var hdrco = hdr+"\n\n"+con;
							var inscripts = hfrag.extractScripts();
							var newc = wi.document.getElementById("o_c"+ciid);
							if (newc == null) {
								if (isdebug) alert("could not find comp with id: o_c"+ciid+",\nname: "+c1["cname"]+",\nlistener(s): "+c1["clisteners"]+",\n\nhtml:\n"+hfrag);
							} else {								
								newc.innerHTML = hdrco;	
								if (inscripts!= "") {
									try {
										inscripts.each(
											function(val) { 
												if (wi.ActiveXObject){ 
													wi.execScript(val);
												} else {
													//to reach global scope: timeout instead of wi.eval(val);
													wi.setTimeout(val,0);
												}
											} );
									} catch(e2) {
										if (isdebug) {
											var s = "";
											inscripts.each(function(val) { s+= "\n:::"+val;});
											alert("inscripts error:"+showerror(e2)+"\n\nfor: "+s);
										}
									}
								}
								if (jsol != "") {
									try {
										if (wi.ActiveXObject){ 
											wi.execScript(jsol);
										} else {
											wi.setTimeout(jsol,0);
										}
									} catch(e2) {
										if (isdebug) { 
											alert("jsol2 error:"+showerror(e2)+"\n\nwhile executing:::\n:::"+jsol+":::");
										}
									}
								}
								if (ishighlight) new Effect.Highlight(newc);
							}
						}
						break;
					case 3:  // createParentRedirectTo
						var rurl = cda["rurl"];
						wi.document.location.replace(rurl);
						break;
					case 6: // createPrepareClientCommand
						wi.o2c = 0;
						wi.o_afterserver();
						var om = wi.$("o_messages"); if (om) Element.hide(om);						
						break;
					case 4: // reload e.g. in case where a command could not be dispatched to the component
						if (isdebug) alert("now reloading win since not dispatched");
						wi.document.location.reload();
						break;
					default:
						if (isdebug) alert("unknown command "+co); 
						break;
				}		
			} else {
				// window closed
			}		
		}
	}
	o_afterserver();
}


function showBusy(captionText) {
	// Add an overlay div and on top of the div 
	// a layer that contains a busy message with a caption.
	// The reason why this is done dynamically is to not bloat the
	// HTML code and to prevent IE to render the page ugly due to 
	// CSS and background images bugs
	// (fg)
	// add overlay div at very top of page
	var root = document.getElementsByTagName("body")[0];
	var overlay = document.createElement("div");
	overlay.id="o_overlay";
	root.insertBefore(overlay, root.firstChild);
	// add busy layer, also on top
	var busy = document.createElement("div");
	busy.id="o_busy";
	// add busy caption	
	var caption = document.createElement("div");
	caption.id="o_busyCaption";
	caption.innerHTML=captionText;
	busy.appendChild(caption);
	root.insertBefore(busy, overlay);
	o_info.guibusy = true;
}

function removeBusy() {
	if (o_info.guibusy) {
		o_info.guibusy = false;
		// Removes the overlay div and the busy screen (untested)
		var root = document.getElementsByTagName("body")[0];
		root.removeChild(document.getElementById('o_busy'));
		root.removeChild(document.getElementById('o_overlay'));
	}
}

function showAjaxBusy() {
	if (o_info.busyon) {
		document.getElementById("o_ajax_busy").className = "o_ajax_busy";
	}
}

function removeAjaxBusy() {
	o_info.busyon = false;
	document.getElementById("o_ajax_busy").className = "";
}

// moved to package js - delete here if enabeld: guido
function toggleCheck(field, doCheck) {
	for (i = 0; i < field.length; i++) {
		field[i].checked = doCheck;
	}
}

function checkDom() {
	var cdom = false;
	if (document.hasChildNodes()) {
		cdom = document.hasChildNodes();
		// disable ie 5.2x for mac since buggy
		if (navigator.userAgent.indexOf("MSIE 5.2") != -1 ||
			navigator.userAgent.indexOf("MSIE 5.16") != -1 ){
			cdom = false;
		}
	}
	return cdom;
}

var dom = checkDom();
var htmlEditorEnabled = (dom && (browser.isIE55 || browser.isIE6up || browser.isGecko) && !browser.isSafari && !browser.isKonqueror);

function setFormDirty(formId) {
	// sets dirty form content flag to true and renders the submit button
	// of the form with given dom id as dirty.
	// (fg) 
	o2c=1;
	if (dom) {
		// fetch the form and the forms submit button is identified via the olat 
		// form submit name
		var myForm = document.getElementById(formId);
		//TODO:gs:a why not directly accessing the submit button by an id. name="olat_fosm" send additional parameter which is unused. Zendle-1363
		var mySubmit = myForm.olat_fosm_0;
		if(mySubmit == null){
			mySubmit = myForm.olat_fosm;
		}
		// set dirty css class
		if(mySubmit) mySubmit.className ="o_form_button_changes";
	}
}

function moveMessagesToContent() {
	// Hack to move error messages from the o_main div to the 
	// o_content div. Works only with dom browsers
	// (fg)
	if (dom) {
		var messages = document.getElementById("o_messages");
		var content = document.getElementById("o_content");
		var modalc = document.getElementById("o_modalcontent");
		if (modalc != null) content = modalc;
		if (content != null) {
			content.insertBefore(messages, content.firstChild);
		}
	}
}

// functions for tooltip layer
var _ie=(document.all)?1:0,_nn=(document.layers)?2:0,_w3=(document.getElementById)?3:0;

function showtip(e,n) { var x,y,ex,ey,dw,lw,z; 
if(_nn){
	z=document.layers[n];
	ex=e.pageX;
	ey=e.pageY;
if(document.width){
	dw=document.width;
}else if(window.innerWidth){
	dw=window.innerWidth;
}
else {
	dw=800;
}
if(z.clip.width) {
	lw=z.clip.width;
}else{
	lw=400;
} 
if(ex+lw>dw){
	x=ex-lw-12;if(x<0){x=0;}
}
else {
	x=ex+8;
} 
y=ey+12;

z.clip.width=lw;

z.left=parseInt(x);
z.top=parseInt(y);
z.visibility="show";
}
else if(_w3) {z=document.getElementById(n);if(e.pageX){ex=e.pageX;ey=e.pageY;} else {ex=e.clientX;ey=e.clientY;}

if(document.width){dw=document.width;}
else if(document.body.offsetWidth){dw=document.body.offsetWidth;}
else if(window.innerWidth){dw=window.innerWidth;}else {dw=800;}
if(z.style.width){lw=z.style.width;}else if(document.all){var _w=document.all[n];lw=_w.offsetWidth;}
if(!lw){lw=100;}if(ex+lw>dw){x=ex-lw-12;if(x<0){x=0;}} else {x=ex+8;}y=ey+12;
if(document.body.scrollTop){y+=document.body.scrollTop;}

//z.getAttributeNode("style").setAttribute("left", parseInt(x));

z.style.left=parseInt(x);
z.style.top=parseInt(y);
z.style.visibility="visible";
//alert("x"+x+","+z.style.left);
}

else if(_ie){z=document.all[n]; ex=e.clientX;ey=e.clientY;dw=document.body.offsetWidth;
lw=z.offsetWidth; if(!lw) {lw=100;}if(ex+lw>dw){x=ex-lw-12;if(x<0){x=0;}} else {x=ex+8;}
y=ey+12; if(document.body.scrollTop){y+=document.body.scrollTop;}

z.style.pixelLeft=parseInt(x);
z.style.pixelTop=parseInt(y);
z.style.visibility="visible";}}

function hidetip(n){if(_nn){document.layers[n].visibility="hide";}
else if(_w3){document.getElementById(n).style.visibility="hidden";}
else if(_ie){document.all[n].style.visibility="hidden";}
}


//Pop-up window for context-sensitive help
function contextHelpWindow(URI) {
helpWindow = window.open(URI, "HelpWindow", "height=400, width=600, left=0, top=0, location=no, menubar=no, resizable=yes, scrollbars=yes, toolbar=no");
helpWindow.focus();
}

var activeNode;
function o_debugHighlight(enabled, currentNode) {
	// highlight div in debuging mode
	// enabled: true: do highlight: false: do not
	// currentNode: the node to be highlighted
	// (fg)
	if (currentNode != activeNode) {
		o_debugHighlight(false, activeNode);
		activeNode = currentNode;
	}
	if (currentNode == null) return;
	if (currentNode.style == null) return;
	if (enabled) {
		currentNode.style.border='1px solid gold';
		currentNode.style.background='#FCFCB8';
	} else {
		currentNode.style.border='1px dotted black';
		currentNode.style.background='';
	}
}

function openMovieViewer(vieweraddress, maddress, mname, displayname, displayduration, width, height) {
	// function to start movie viewer (see radeox macro s)
	// (fg)
	// height+60 (some browsers need this space) + 20 (to show playButton tag)
	// width+40 (some browsers need this space)
	var args = 'width=' + (parseInt(width)+40) + ',height=' + (parseInt(height)+80) + ',resizable=yes,scrollbars=yes';
	//IE does not like (crashed) writing out header data with javascript loaded again, so wo load a static file, pass the vars and write out the code there
	var viewer =  window.open("../../raw/movie/popup.html?vieweraddress="+encodeURIComponent(vieweraddress)+"&maddress="+encodeURIComponent(maddress)+"&mname="+encodeURIComponent(mname)+"&displayname="+encodeURIComponent(displayname)+"&displayduration="+encodeURIComponent(displayduration)+"&width="+width+"&height="+height+"", mname, args);
}

function o_playButtonTag(name, start, end, displayname, displayduration) {
	// function called by timemarker quicktime movie to create a forum
	// movie play button
	// (fg) 

 	var buttonElement = document.getElementById("o_movieButtonTag");
	if (buttonElement != null) {
		var tag = "{movieButton:name=" + name + "|start=" + start + "|end=" + end + "|displayduration=" + displayduration + "}" + displayname + "{movieButton}";
		buttonElement.value = tag;
	}
}


function writeMovieViewerCode(doc, vieweraddress, maddress, mname, displayname, displayduration, width, height) {
	// function to write movie viewer to given html document. 
	// Used by radeox macro and openMovieViewer function
	// (fg)

	// title
	if(displayname == "null" || displayname == null) displayname = "";
	if(displayduration == "null" || displayduration == null) displayduration = "";
	if (displayname != "" || displayduration != "") {
		doc.write("<span class='o_movietitle'>");
		if (displayname != "") {
			doc.write(displayname);
			if (displayduration != "") {
				doc.write(": ");
			}
		}
		if (displayduration != "") {
			doc.write(displayduration);
		}
		doc.write("</span><br><br>");
	}
	// movie object
	doc.write("<object classid=\"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B\"  width=\"" + width + "\" height=\"" + height + "\" codebase=\"http://www.apple.com/qtactivex/qtplugin.cab\">");
	doc.write("<param name=\"SRC\" value=\"" + vieweraddress + "\">");
	doc.write("<param name=\"CONTROLLER\" value=\"TRUE\">");
	doc.write("<param name=\"AUTOPLAY\" value=\"FALSE\">");
	doc.write("<param name=\"MOVIENAME\" value=\"" + mname + "\">");
	doc.write("<param name=\"CACHE\" value=\"FALSE\">");
	doc.write("<param name=\"MovieQTList\" value=\"<movieinfo><address>" + maddress + "</address><displayname>" + displayname + "</displayname></movieinfo>\">");
	doc.write("<embed");
	doc.write(" src=\"" + vieweraddress + "\"");
	doc.write(" width=\"" + width + "\" height=\"" + height + "\"");
	doc.write(" controller=\"TRUE\"");
	doc.write(" autoplay=\"FALSE\"");
	doc.write(" moviename=\"" + mname + "\"");
	doc.write(" cache=\"FALSE\"");
	doc.write(" MovieQTList=\"<movieinfo><address>" + maddress + "</address><displayname>" + displayname + "</displayname></movieinfo>\"");
	doc.write(" type=\"video/quicktime\"");
	doc.write(" pluginspage=\"http://www.apple.com/quicktime/download/\">");
	doc.write("</embed>");
	doc.write("</object>");
	doc.write("<br><input type=\"text\" size=\"40\" id=\"o_movieButtonTag\" style=\"font: x-small sans-serif; padding-top: 5px; width: " + width + "px;\">");
}


function o_hideDiv(divId) {
	// helper function: remove element from screen using css
	// (fg)
	var divElem = document.getElementById(divId);
	if (divElem != null) {
		divElem.style.display = "none";
	}
}

function o_showDiv(divId) {
	// helper function: show element on screen using css
	// (fg)
	var divElem = document.getElementById(divId);
	if (divElem != null) {
		divElem.style.display = "block";
	}
}
xMenuEnabled = false;
function o_xMenu(showMenu){
	// showMenu: true: show the menu layer
	//           false: hide the menu layer and show the opener instead
	// (fg)
	if (!xMenuEnabled && showMenu) {
		o_hideDiv("o_xmenuopener");
		o_showDiv("o_xmenucontent");
		xMenuEnabled = true;
	} else if (xMenuEnabled && !showMenu) {
		o_hideDiv("o_xmenucontent");
		o_showDiv("o_xmenuopener");
		xMenuEnabled = false;
	}
}

xToolsEnabled = false;
function o_xTools(showTools){
	// showTools: true: show the tools layer
	//           false: hide the tools layer and show the opener instead
	// (fg)
	if (!xToolsEnabled && showTools) {
		o_hideDiv("o_xtoolsopener");
		o_showDiv("o_xtoolscontent");
		xToolsEnabled = true;
	} else if (xToolsEnabled && !showTools) {
		o_hideDiv("o_xtoolscontent");
		o_showDiv("o_xtoolsopener");
		xToolsEnabled = false;
	}
}

function o_openPopUp(url, windowname, width, height, menubar) {
	// generic window popup function
	attributes = "height=" + height + ", width=" + width + ", resizable=yes, scrollbars=yes, left=100, top=100, ";
	if (menubar) {
		attributes += "location=yes, menubar=yes, status=yes, toolbar=yes";
	} else {
		attributes += "location=no, menubar=no, status=no, toolbar=no";
	}
	var win = window.open(url, windowname, attributes);
	win.focus();
}

function o_openClose(iconId, divId, openCss, closeCss) {
	var div = document.getElementById(divId);
	if (div != null) {
		if (div.style != null && div.style.display == "none") {
			var icon = document.getElementById(iconId);
			if (icon != null) {
				icon.className = openCss;
				// make div visible
				o_showDiv(divId);
			}
		} else {
			// change opener icon
			var icon = document.getElementById(iconId);
			if (icon != null) {
				icon.className = closeCss;
				// make div invisible
				o_hideDiv(divId);
			}
		}
	
	}
}

o_addEventListener = function (obj, name, handler) {
	// Generic add event listener method that works both
	// with IE and other browsers. Make sure you remove
	// listeners that you add, latest when unloading a page!
	// (IE has memory leaks, added events are not removed 
	// just by the fact that you load another page!)
	// (fg)
	if (obj.addEventListener)
		obj.addEventListener(name, handler, false);
	else
		obj.attachEvent("on" + name, handler);
}
o_removeEventListener = function (obj, name, handler) {
	// Generic remove event listener method that works both
	// with IE and other browsers.
	// (fg)
	if (obj.removeEventListener)
		obj.removeEventListener(name, handler, false);
	else
		obj.detachEvent("on" + name, handler);
}


function O_DynObject (wrapperId, dynamicId) {
	// Object for showing a dynamic child element contained in a wrapper
	// element using a rollover effect. As soon as you leave the rollover 
	// area, the element will be removed from the visible screen.
	// IN: wrapperID: DOM tree ID of the wrapper element
	// IN: dynamicID: DOM tree ID of the dynamic child element.
	// (fg)
	this.wrapperId = wrapperId;
	this.dynamicId = dynamicId;
	this.isVisible = false; // current state is "not visible"
}
O_DynObject.prototype.o_isInWrapper = function(node) {
	// Internal helper method: recursive check if given node
	// is a child of the wrapper element
	// IN: node: the node that should be testd
	// OUT: true: node is a child; false: node is not a child
	// (fg)
	if (node == null || node.id == null)
		return false;
	if (node.id == this.wrapperId) 
		return true;
	else {
		if (node.parentNode != null) 
			return this.o_isInWrapper(node.parentNode);
		else 
			return false;
	}
}
O_DynObject.prototype.o_showDynObject = function () {
	// Makes the dynamic object visible and starts event capturing.
	// Will remove event capturing when leaving the dynamic object
	// and hide it from the visible screen.
	// (fg)
	if (this.isVisible) return; // do not attach listener twice
	// mark object as visible so listener gets attached ony once
	this.isVisible = true; 
	document.getElementById(this.dynamicId).style.display = "block";		
	// dynamic callback method as anonymous function, refering 
	// to itself for the remove listener code.
	var my = this;
	var listener = function(e) {
		// get node which fired event
		var target = e["target"];
		// fix IE event handling
		if (target == null) target = e["srcElement"];
		var isInWrapper = my.o_isInWrapper(target);	
		if (!isInWrapper) {
			o_removeEventListener(document, 'mousemove',listener);
			document.getElementById(my.dynamicId).style.display = "none";	
			my.isVisible = false; // mark as not visible	
		}
	};
	o_addEventListener(document, 'mousemove', listener);
}


function gotonode(nodeid) {
	// get the "Zendlemain" window
	var w = top;
	try {
		if (w.opener && w.opener.o_info) {
		  w = w.opener;
		}
	} catch (e) {}
	
	w.focus();
	var str = w.location.href;
	var pos = str.search(/\/auth\//);
	var strnew = str.substring(0, pos+6);
	if (w.o_info && w.o_info.course_id) {
		var alu = strnew + "repo/go?rid="+w.o_info.course_id+"&par="+nodeid;
		w.location.replace(alu);
	}
}

function o_openUriInMainWindow(uri) {
	// get the "Zendlemain" window
	var w = top;
	try {
		if (w.opener && w.opener.o_info) {
		  w = w.opener;
		}
	} catch (e) {}
	
	w.focus();
	w.location.replace(uri);
}

o_getDisplayableInnerContentHeight = function () {
	// calculate the height of the inner content area that can be used for 
	// displaying content without using scrollbars. Uses the o_info.o_topBottomLayoutWaste
	// variable set in the main layout to know how much space is used by header and footer.
	// Depends on prototype library!
	// (fg)
	if (!dom) return 0;
	// rule is: window height - o_topBottomLayoutWaster
	var windowHeight = 0;
	if (window.innerHeight) 
		windowHeight = window.innerHeight - 18;
   	else if (document.documentElement && document.documentElement.clientHeight) 
    		windowHeight = document.documentElement.clientHeight;
   	else if (document.body && document.body.clientHeight) 
    		windowHeight = document.body.clientHeight;
    var messagesHeight = Element.getHeight("o_messages"); // using prototype
    return (windowHeight - o_info.o_topBottomLayoutWaste - messagesHeight);
}
  
function o_adjustIframeHeight(iframeId) {
	// adjust the given iframe to use as much height as possible
	// (fg)
	if (!dom) return;
	var theIframe = document.getElementById(iframeId);
	if (theIframe) {
		var contentHeight = o_getDisplayableInnerContentHeight();
		if (contentHeight > 0) 
			theIframe.style.height = contentHeight + "px";
		else 
			// could not calculate content height, use fallback
			theIframe.style.height = "600px";
	}
}

