updateProgress();

function Utils() {
 
	this.getXmlDocument = getXmlDocument;
	this.createXmlDocument = createXmlDocument;
	this.PositionSort = PositionSort;
	this.showCursor = showCursor;
	this.attachContents = attachContents;
	this.attachEvents = attachEvents;
	this.createMediaHTML = createMediaHTML;
	this.createButton = createButton;
	this.createCheckbox = createCheckbox;
	this.createDrawObject = createDrawObject;
	this.convertImageTags = convertImageTags;
	this.convertLinks = convertLinks;
	this.convertBodyStyle = convertBodyStyle;
	this.createValidIcon = createValidIcon;
	this.getI18nValue = getI18nValue;
	this.trimString = trimString;
	this.include = include;
	this.preloadFile = preloadFile;
	this.getFileLoader = getFileLoader;
	this.drawHotspotBorders = drawHotspotBorders;
	this.ellipseToPoints = ellipseToPoints;
	this.getRandomElements = getRandomElements;
		
	this.getMediaType = getMediaType;
	
	//var i18nXParser = new XParser(i18nXmlDocument);
	var xParser = null;//new XParser();
	
	var i18nValues = new Array();


	function ellipseToPoints(left, top, width, height, resolution) {
	    var points = new Array();
		var a, b, x, y;
	    a = width / 2;
	    b = height / 2;
	    var delta = 2 * Math.PI / resolution;
	    for (var t = 0; t <= (2 * Math.PI); t += delta) {
	        x = a * Math.cos(t);
	        y = b * Math.sin(t);
	        points.push(Math.round(x + left + width / 2));
			points.push(Math.round(y + top + height / 2));
	    }
	    return points;
	}
	
	function drawHotspotBorders(content) {
		var html = "";
		drawHotspots(content);
		html = document.getElementById("drawarea").innerHTML;
		return html;
	}
	
	function drawHotspots(content) {
		var myGraphics = new jsGraphics("drawarea");
		var hotspots = content.hotspots;
		
		for (var n = 0; n < hotspots.length; n++) {
			drawHotspot(hotspots[n], myGraphics, 0, "white");
			drawHotspot(hotspots[n], myGraphics, 1, "black");
		}
		myGraphics.paint();
	}

	function drawHotspot(hotspot, myGraphics, offset, color) {
		var xCoords = new Array();
		var yCoords = new Array();
		var coords = hotspot.coords;
		var shape = hotspot.shape;
		var coordsArray = coords.split(",");
		
		myGraphics.setColor(color); 
		myGraphics.setStroke(Stroke.DOTTED); 
		  	
		if (shape == "rect") {
			var x = parseInt(coordsArray[0]);
			var y = parseInt(coordsArray[1]);
			var width = parseInt(coordsArray[2]) - x;
			var height = parseInt(coordsArray[3]) - y;
			myGraphics.drawRect(x + offset, y + offset, width, height);
		}
		else if (shape == "poly") {
			for (var i = 0; i < coordsArray.length; i++) {
				var x = coordsArray[i];
				i++;
				var y = coordsArray[i];
				xCoords[xCoords.length] = x * 1 + offset;
				yCoords[yCoords.length] = y * 1 + offset;
			}
			xCoords[xCoords.length] = xCoords[0];
			yCoords[yCoords.length] = yCoords[0];
				
			myGraphics.drawPolyline(xCoords, yCoords);
	  	}
	  	else if (shape == "circle") {
	  		var x = parseInt(coordsArray[0]);
			var y = parseInt(coordsArray[1]);
			var width = parseInt(coordsArray[2]) - x;
			var height = parseInt(coordsArray[3]) - y;
			
			myGraphics.drawEllipse(x + offset, y + offset, width, height);
	  	}
	
	}
	
	// create HTML-Code for different media-types
	function createMediaHTML(content) {
	    var html = new StringBuffer();
	    var id = content.id;
	    var type = content.type;
	    var width = content.width;
	    var height = content.height;
	    var filename = content.value;
	    
		
	    
	    // IMAGES
	    if (type == "image") {
	        var usemap = "";
	        
	        // handle hotspots
	        var hotspots = content.hotspots;
	        if (hotspots.length > 0) {
				usemap = "usemap=\"#" + content.id + "\"";    
	            html.append("<map name=\"");
	            html.append(content.id);
	            html.append("\">\n");
	            for (var i = 0; i < hotspots.length; i++) {
                    var myEvent = hotspots[i].event;
                    
                    var onmousedownAction = "";
                    var onmouseoverAction = "";
                    var onmouseoutAction = "";
                    
                    if (myEvent == "Rollover") {
                    	onmouseoverAction = "onmouseover=\"utils.showCursor(document.getElementById('media_" + id + "'), 'pointer');engine.showHotspotContent(event,'" + hotspots[i].href + "')\"";
    	            	onmouseoutAction = "onmouseout=\"utils.showCursor(document.getElementById('media_" + id + "'), 'default');engine.hideHotspotContent(event,'" + hotspots[i].href + "')\"";
    	            }
    	            else {
    	            	onmouseoverAction = "onmouseover=\"utils.showCursor(document.getElementById('media_" + id + "'), 'pointer')\"";
    	            	onmouseoutAction = "onmouseout=\"utils.showCursor(document.getElementById('media_" + id + "'), 'default')\"";
    	            }
    	            
    	            var target = hotspots[i].target;
    	            var type = hotspots[i].type;
    	            
    	            if (type == "glossar") type = "glossary";
    	            
    	            if (type == "step" && myEvent != "Rollover") {
    	                onmousedownAction = "onmousedown=\"javascript:engine.jumpToStep('" + hotspots[i].href + "')\"";
    	            }
    	            if (type == "www") {
    	                onmousedownAction = "onmousedown=\"javascript:engine.openURL('" + hotspots[i].href + "')\"";
    	            }
    	            if (type == "glossary" || type == "faq" || type == "help") {
    	                onmousedownAction = "onmousedown=\"javascript:engine.openListpage('" + type + "','" + hotspots[i].href + "',false)\"";
    	            }
    	           	
	                html.append("<area shape=\"");
	                html.append(hotspots[i].shape);
	                html.append("\" coords=\"");
	                html.append(hotspots[i].coords);
	                html.append("\"  href=\"#\" ");
	                html.append(onmousedownAction);
	                html.append(" ");
	                html.append(onmouseoverAction);
	                html.append(" ");
	                html.append(onmouseoutAction);
	                html.append(">\n");
	            }
	            html.append("</map>\n");
	        }
	        
	        html.append("<img id=\"media_");
	        html.append(id);
	        html.append("\" src=\"");
	        html.append(filename);
	        html.append("\" ");
	        html.append(usemap);
	        html.append(" width=\"");
	        html.append(width);
	        html.append("\" height=\"");
	        html.append(height);
	        html.append("\" border=\"0\" onmousemove=\"return false;\" onmousedown=\"return false;\" onmouseover=\"return false;\">");
	    }
	    
	    // FLASHMOVIES
	    if (type == "flash") {
	        html.append("<object id=\"media_");
	        html.append(id);
	        html.append("\" classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0' width='");
	        html.append(width);
	        html.append("' height='");
	        html.append(height);
	        html.append("'>");
            html.append("<param name=movie value='");
            html.append(filename);
            html.append("'/><param name=quality value=high/>");
            html.append("<embed src='");
            html.append(filename);
            html.append("' width='");
            html.append(width);
            html.append("' height='");
            html.append(height);
            html.append("' quality=high name='flashmovie' TYPE='application/x-shockwave-flash' PLUGINSPAGE='http://www.macromedia.com/go/getflashplayer'>");
            html.append("</object>");
	    }
	    
	    // VIDEOS
	    if (type == "video") {
	        html.append("<embed id=\"media_");
	        html.append(id);
	        html.append("\" controller=\"false\" ShowControls=0 ShowStatusBar=0 controls=\"false\" width=\"");
	        html.append(width);
	        html.append("\" height=\"");
	        html.append(height);
	        html.append("\" src=\"");
	        html.append(filename);
	        html.append("\"></embed>");
	    }
	    
	    // AUDIOS
	    if (type == "audio") {
	        //html = "<embed id=\"media_" + id + "\" autostart=\"false\" hidden=\"true\" src=\"" + filename + "\"></embed>";
	    }
	    return html.toString();
	}
	
	function createCheckbox(content) {
	    var html = new StringBuffer();
	    var id = content.id;
	    var icon = "";
	    var width = content.width;
	    var height = content.height;
	    html.append("<img id=\"media_");
	    html.append(id);
	    html.append("\" border=\"0\" ");
	    //html.append(icon);
	    html.append("\>");
	    //html.append(content.value);
	    //alert(html.toString());
	    return html.toString();
	}
	
	function createDrawObject(content) {
	    var color = content.color;
	    var drawtype = content.drawtype;
	    var html = color.getHexValue();
	    return html;
	}
	
	function createButton(content) {
	    var html = new StringBuffer();
	    var id = content.id;
	    var icon = "";
	    var width = content.width;
	    var height = content.height;
		var tooltip = content.tooltip;
		
	    var mousehandler = "";
	    html.append("<div style=\"position:absolute;top:0px;left:0px;width:");
	    html.append(width);
	    html.append(";height:");
	    html.append(height);
	    html.append(";\"><img id=\"media_");
	    html.append(id);
	    html.append("\" src=\"img/");
	    html.append(icon);
	    html.append("\" width=\"");
	    html.append(width);
	    html.append("\" height=\"");
	    html.append(height);
	    html.append("\" ");
	    html.append(mousehandler);
	    html.append(" alt=\"");
	    html.append(tooltip);
	    html.append("\"></div>");
	    html.append("<div style=\"position:absolute;top:0px;left:0px;width:");
	    html.append(width);
	    html.append(";height:");
	    html.append(height);
	    html.append(";\" class=\"buttonCaption\">");
	    html.append(content.caption);
	    html.append("</div>");
	    
	    return html.toString();
	}
	
	function getStringValueBetween(text, start, end) {
		var a = text.indexOf(start);
		if (a == -1) return "";
		var b = text.indexOf(end);
		if (b == -1) return "";
		var value = text.substring(a + start.length, b);
		return value;
	
	}
	
	function convertBodyStyle(text) {
		if (text == "<body></body>") {
			text = "<body>&nbsp;</body>";
		}
		if (text.indexOf("text-align:right") != -1) {
			text = text.replace("text-align:right", ";text-align:right;width:100%");
		}
		if (text.indexOf("text-align:center") != -1) {
			text = text.replace("text-align:center", ";text-align:center;width:100%");
		}
		
		return text;
		
	}
	
	function convertLinks(text) {
    	if (text == null) return text;
    	var newText = "";
    	for (var i = 0; i < text.length; i++) {
    		var a = text.indexOf("<a", i);
    		if (a == -1) break;
    		var b = text.indexOf(">", a) + 1;
    		var tag = text.substring(a, b);
    		var c = tag.indexOf("href=\"") + 6;
    		var d = tag.indexOf("\"", c);
    		var href = tag.substring(c, d);
    		var e = tag.indexOf("type=\"") + 6;
    		var f = tag.indexOf("\"", e);
    		var type = tag.substring(e, f);
    		var g = tag.indexOf("target=\"") + 8;
    		var h = tag.indexOf("\"", g + 1);
    		var target = tag.substring(g, h);
    		
    		// resolve step-links
    		if (type == "step") {
    			if (target != "_blank") {
    				href = "javascript:engine.jumpToStep('" + href + "')";
    			}
    			else {
    				href = "javascript:engine.showHotspotContent(event,'" + href + "', true)";
    			}
    		}
    		// resolve glossary-links
    		else if (type == "glossary") {
    			href = "javascript:engine.openGlossary('" + href + "')";
    		}
    		// resolve help-links
    		else if (type == "help") {
    			href = "javascript:engine.openHelp('" + href + "')";
    		}
    		// resolve faq-links
    		else if (type == "faq") {
    			href = "javascript:engine.openFAQ('" + href + "')";
    		}
    		// resolve www-links
    		else if (type == "www") {
    			if (href.indexOf("javascript:") == -1) {
	    			if (href.indexOf("http://") == -1 && href.indexOf("file://") == -1 && href.indexOf("mailto://") == -1 && href.indexOf("ftp://") == -1) {
	    				href = "http://" + href;
	    			}
	    			href = "javascript:engine.openURL('" + href + "')";
    			}
    		}
    		// resolve document-links
    		else if (type == "document") {
    			href = href.replace(/L:/, "Media/Local/");
				href = href.replace(/G:/, "Media/Global/");
    			//href = "javascript:engine.openDocument('" + href + "')";
    			
    		}
    		
    		// remove target-attribute if exists (not in document-links to enable "save as")
    		var z1 = tag.indexOf("target=");
    		if (z1 != -1 && type != "document") {
    			tag = tag.substring(0, z1) + tag.substring(tag.indexOf("\"", z1 + 8) + 1);
    		}
    		// create the new link
    		tag = "<a href=\"" + href + tag.substring(d);
    		newText += text.substring(i, a) + tag;
    		
    		i = b - 1;
    	}
    	newText += text.substring(i);
    	
    	return newText;
    }

	function convertImageTags(value) {
		if (value == null) return value;
		value = value.replace(/src="L:/, "src=\"Media/Local/");
		value = value.replace(/src="G:/, "src=\"Media/Global/");
		return value;
	}

	
	function getMediaType(filename) {
	    var type = null;
	    var extension = (filename.substring(filename.lastIndexOf(".") + 1)).toLowerCase();
	    if (extension == "jpg" || extension == "jpeg" || extension == "gif" || extension == "png") {
	        type = "image";
	    }
	    if (extension == "swf") {
	        type = "flash";
	    }
	    if (extension == "mpg" || extension == "mpeg" || extension == "avi" || extension == "mov" || extension == "wmv") {
	        type = "video";
	    }
	    if (extension == "mp3" || extension == "wav") {
	        type = "audio";
	    } 
	    return type;
	}
	
	function getI18nValue(code) {
		//code = code.toLowerCase();
		var value = i18nValues[code];
		if (value == null) {
			if (!xParser) {
				xParser = new XParser(i18nXmlDocument);
			}
			var rootNode = i18nXmlDocument.getElementsByTagName("i18n")[0];
		    var result = xParser.evaluateNodeValue("//entry[@code=\"" + code + "\"]", rootNode);
		    
			if (result == null || result == "") {
				value = "[not yet translated: " + code + "]";
			}
			else {
				value = result;
				i18nValues[code] = value;
			}
		}
		return value;
	}
	
	function getXmlDocument(filename, async) {
		var xmlDocument = null;
		var ie = document.all;
		
		if (!ie) {
	    	xmlDocument = document.implementation.createDocument('', 'dummy-root', null);
			xmlDocument.async = async;
	  	}
	  	else {
	    	xmlDocument = new ActiveXObject('Microsoft.XMLDOM');
	    	xmlDocument.setProperty("SelectionLanguage", "XPath");
	  		xmlDocument.async = async;
		}
		try {
		    xmlDocument.load(filename);
		}
		catch (e) {
		    //alert("not found: " + filename);
		}
		return xmlDocument;
	}
	
	function createXmlDocument(xml) {
		var xmlDocument = null;
		var ie = document.all;
		
		if (!ie) {
	    	xmlDocument = document.implementation.createDocument('', 'dummy-root', null);
	  	}
	  	else {
	    	xmlDocument = new ActiveXObject('Microsoft.XMLDOM');
		}
		xmlDocument.async = false;
		try {
		    xmlDocument.loadXML(xml);
		}
		catch (e) {
		    //alert("not found: " + filename);
		}
		return xmlDocument;
	}
	
	function preloadFile(filename, async) {
		var loader = null;
		var ie = document.all;
		
		if (!ie) {
	    	loader = document.implementation.createDocument('', 'dummy-root', null);
		}
	  	else {
	    	loader = new ActiveXObject('Microsoft.XMLDOM');
		}
		loader.async = async;
		try {
			loader.load(filename);
		}
		catch (e) {
		    alert("not found: " + filename);
		}
	}
	
	function include(filename) {
		var myDocument = getXmlDocument(filename);
		var html = myDocument.responseText;
		return html;
	}
	
	function getFileLoader(async) {
		var loader = null;
		var ie = document.all;
		if (!ie) {
	    	loader = document.implementation.createDocument('', 'dummy-root', null);
		}
	  	else {
	    	loader = new ActiveXObject('Microsoft.XMLDOM');
		}
		loader.async = async;
		return loader;
	}

	
	function PositionSort(a, b) {
		return a.position - b.position;
	}
	
	function showCursor(obj, type) {
		if (obj && obj.style) {
			obj.style.cursor = type;
		}
	}
	
	// defaults for missing icons
	function createValidIcon(result, state, type) {
        var resultString = result + "";
        if (resultString.charAt(resultString.length - 1) == "/") {
            if (type == "checkbox") {
                if (state == "default") {
                    return "img/checkbox_unselected.gif";
                }
                else if (state == "active") {
                    return "img/checkbox_selected.gif";
                }
                else {
                    return "img/checkbox_unselected.gif";
                }
            }
        }
        else {
            return resultString;
        }
     }
     
     	/*
	this function creates Content-objects from the step-xml and
	attaches them to a step or another content.
	object can be a step or a content; if object is a content, the function is
	called recursively
	*/
	function attachContents(object, contentNodes, xParser) {
	    var feedbackRangeIndex = 0;
	    
	    for (var i = 0; i < contentNodes.length; i++) {
		    //xpathContext.expressionContextNode = contentNodes[i];
			var content = null;
			var id = contentNodes[i].getAttribute("id");
		    if (id == null) {
	            id = engine.getNextId();
	        }
	        var type = contentNodes[i].getAttribute("type");
			
			var value = "";
			var valueNode = contentNodes[i].getElementsByTagName("value")[0];
			if (valueNode && valueNode.firstChild) {
				var i18nAttr = valueNode.getAttribute("i18n");
				value = valueNode.firstChild.nodeValue;
				if (i18nAttr && i18nAttr == "true") {
					value = getI18nValue(value);
				}
			}
			
			var width = "0";
			var height = "0";
			var left = "0";
			var top = "0";
			var overflow = "";
			var title = "";
			
			if (contentNodes[i].getElementsByTagName("style").length > 0) {
				width = contentNodes[i].getElementsByTagName("style")[0].getAttribute("width");
				height = contentNodes[i].getElementsByTagName("style")[0].getAttribute("height");
				left = contentNodes[i].getElementsByTagName("style")[0].getAttribute("x");
				top = contentNodes[i].getElementsByTagName("style")[0].getAttribute("y");
				overflow = contentNodes[i].getElementsByTagName("style")[0].getAttribute("overflow");
				title = contentNodes[i].getElementsByTagName("style")[0].getAttribute("title");
				if (title) {
					title = getI18nValue(title);
				}
				//alert("[" + height + "]");
				if (width == "max") width = -1;
				if (height == "max") height = -1;
				
			}
			
			var draggable = contentNodes[i].getAttribute("draggable");
			var visible = contentNodes[i].getAttribute("visible");
			var triggered = contentNodes[i].getAttribute("triggered");
			
			var isDraggable = false;
			var isVisible = false;
			var isTriggered = false;
			
			draggable == "true" ? isDraggable = true : isDraggable = false;
			visible == "true" || !visible ? isVisible = true : isVisible = false;
			triggered == "true" ? isTriggered = true : isTriggered = false;
			
			var overflow = "hidden";
			var overflowAttr = contentNodes[i].getAttribute("overflow");
			if (overflowAttr) overflow = overflowAttr;
				
			if (type == "container") {
			    content = new Container(id, top, left, width, height, isDraggable, isVisible, isTriggered);
			}
			else if (type == "audio" || type == "image" || type == "flash" || type == "video" || type == "document") {
				value = utils.trimString(value);
				var audiotext = "";
				
				if (type == "audio") {
					var audiotextNode = contentNodes[i].getElementsByTagName("audiotext")[0];
					if (audiotextNode != null && audiotextNode.firstChild != null) {
						audiotext = contentNodes[i].getElementsByTagName("audiotext")[0].firstChild.nodeValue;
					}
				}
				
				content = new Media(id, top, left, width, height, isDraggable, isVisible, isTriggered, value, audiotext, type);
				if (type == "image") {
					var showHotspotBorders = contentNodes[i].getAttribute("showBorder");
					var hotspotNodes = contentNodes[i].getElementsByTagName("hotspot");
					content.setHotspotBordersVisible(showHotspotBorders == "true");
					for (var ii = 0; ii < hotspotNodes.length; ii++) {
				            var shape = hotspotNodes[ii].getAttribute("shape");
				            var event = hotspotNodes[ii].getAttribute("event");
				            var target = hotspotNodes[ii].getAttribute("target");
				            var type = hotspotNodes[ii].getAttribute("type");
				            var href = hotspotNodes[ii].getAttribute("href");
				            var coords = hotspotNodes[ii].getAttribute("coords");
				            var hotspot = new Hotspot(shape, event, target, type, href, coords);
				            
				            content.addHotspot(hotspot);
				        }
				    
				}
				
				
			}
			else if (type == "label" || type == "popuplabel") {
			    content = new Text(id, top, left, width, height, isDraggable, isVisible, isTriggered, value, overflow);
				content.overflow = overflow;
				if (type == "popuplabel") {
					content.popup = true;
				}
			}
			else if (type == "text") {
				
				if (value.indexOf(constants.GAPMARKER) != -1) {
				    content = new GapText(id, top, left, width, height, isDraggable, isVisible, isTriggered, value);
			    }
			    else {
				    content = new Text(id, top, left, width, height, isDraggable, isVisible, isTriggered, value);
			    }
			    content.overflow = overflow;
			}
			
			else if (type == "drawobject") {
			    var drawtype = xParser.evaluateNodeValue("drawtype", contentNodes[i]); 
	            var red = xParser.evaluateNodeValue("color/red", contentNodes[i]); 
	            var green = xParser.evaluateNodeValue("color/green", contentNodes[i]); 
	            var blue = xParser.evaluateNodeValue("color/blue", contentNodes[i]); 
	            var alpha = xParser.evaluateNodeValue("color/alpha", contentNodes[i]); 
	            
	            var color = new Color(red, green, blue, alpha);
			
				content = new DrawObject(id, top, left, width, height, isDraggable, isVisible, isTriggered, drawtype, color);
			    
			}
			
			else if (type == "button" || type == "togglebutton" || type == "checkbox") {
				// default-icon
				var defaultIcon = xParser.evaluateNodeValue("icon[@type='default']", contentNodes[i]); 
	            if (!defaultIcon || defaultIcon == "") {
	            	defaultIcon = utils.createValidIcon(defaultIcon, "default", type);
	            }
	            
	            // active-icon
	            var activeIcon = xParser.evaluateNodeValue("icon[@type='active']", contentNodes[i]); 
	            if (!activeIcon || activeIcon == "") {
	            	activeIcon = utils.createValidIcon(activeIcon, "active", type);
	            }
	            
				if (type == "button" || type == "togglebutton") {
					// rollover-icon
					var rolloverIcon = xParser.evaluateNodeValue("icon[@type='rollover']", contentNodes[i]); 
		            if (!rolloverIcon || rolloverIcon == "") {
		            	rolloverIcon = utils.createValidIcon(rolloverIcon, "rollover", type);
		            }
					
					// disabled-icon
					var disabledIcon = xParser.evaluateNodeValue("icon[@type='disabled']", contentNodes[i]); 
		            if (!disabledIcon || disabledIcon == "") {
		            	disabledIcon = utils.createValidIcon(disabledIcon, "disabled", type);
		            }
					
				    // highlighted-icon
		            var highlightedIcon = xParser.evaluateNodeValue("icon[@type='highlighted']", contentNodes[i]); 
		            if (!highlightedIcon || highlightedIcon == "") {
		            	highlightedIcon = utils.createValidIcon(highlightedIcon, "highlighted", type);
		            }
		            
		            // tooltip
		            var tooltip = xParser.evaluateNodeValue("tooltip", contentNodes[i]);
		            if (tooltip != "") {
		            	tooltip = utils.getI18nValue(tooltip);
		            }
		        	
		            // caption
		            var caption = "";
					var captionNode = contentNodes[i].getElementsByTagName("caption")[0];
					if (captionNode && captionNode.firstChild) {
						caption = captionNode.firstChild.nodeValue;
					}		            
		            
		            if (type == "button") {
		            	content = new ActionButton(id, top, left, width, height, isDraggable, isVisible, isTriggered, defaultIcon, activeIcon, rolloverIcon, disabledIcon, highlightedIcon, tooltip, caption);
					}
					else {
						content = new ToggleButton(id, top, left, width, height, isDraggable, isVisible, isTriggered, defaultIcon, activeIcon, rolloverIcon, disabledIcon, highlightedIcon, tooltip, caption);
					}
				}
				else {
					content = new Checkbox(id, top, left, width, height, isDraggable, isVisible, isTriggered, defaultIcon, activeIcon, value);
				}
			}
			else if (type == "answer") {
				var isSource = false;
				var points = 0;
				var correct = false;
				var isSourceElement = contentNodes[i].getElementsByTagName("isSource")[0];
				if (isSourceElement && isSourceElement.firstChild) {
				    var source = isSourceElement.firstChild.nodeValue;
				    source == "true" ? isSource = true : isSource = false;
				}
				
				var dropTargetId = null;
				var dropTargetElement = contentNodes[i].getElementsByTagName("target-id")[0];
				if (dropTargetElement && dropTargetElement.firstChild) {
				    dropTargetId = dropTargetElement.firstChild.nodeValue;
				}
				
			    points = contentNodes[i].getElementsByTagName("points")[0].firstChild.nodeValue;
			    var correctS = contentNodes[i].getElementsByTagName("correct")[0].firstChild.nodeValue;
			    correctS == "true" ? correct = true : correct = false; 
			    
				content = new Answer(id, top, left, width, height, isDraggable, isVisible, isTriggered, value, isSource, dropTargetId, correct, points);
			
			}
						
			else if (type == "feedbackrange") {
		        var min = contentNodes[i].getAttribute("min");
                var max = contentNodes[i].getAttribute("max");
                content = new FeedbackRange("range_" + feedbackRangeIndex, top, left, width, height, isDraggable, isVisible, isTriggered, min, max);
				
				feedbackRangeIndex++;
				
		    }
			
			else if (type == "feedback") {
		        content = new Feedback(id, top, left, width, height, isDraggable, isVisible, isTriggered);
			}
		    else if (type == "timer") {
		        var value = contentNodes[i].getAttribute("value");
		        var triggered = contentNodes[i].getAttribute("triggered") == "true" ? true : false;
		        content = new Timer(id, value, triggered);
			}
		    
		    else if (type == "protocol") {
		        var viewtype = contentNodes[i].getAttribute("viewtype");
                content = new Protocol(id, top, left, width, height, isDraggable, isVisible, isTriggered, viewtype);
			}
			
			else if (type == "list") {
		        content = new Content(id, top, left, width, height, isDraggable, isVisible, isTriggered);
		        content.overflow = "auto";
			}
						
			else if (type == "menu") {
		        content = new Content(id, top, left, width, height, isDraggable, isVisible, isTriggered);
			}
			
			//if (!content) alert("content-type " + type + " is invalid");
			
			if (content) {
				content.title = title;
				attachComponent(contentNodes[i], content, xParser);
	            attachEvents(contentNodes[i], content, xParser);
	            attachProperties(contentNodes[i], content, xParser);
	            var innerContentNodes = xParser.evaluate("content", contentNodes[i]);
	            attachContents(content, innerContentNodes, xParser);
	        
	            var context = contentNodes[i].getAttribute("context");
				if (context && context != "") {
					content.context = context;
				}
				
	            object.addContent(content);
	            mousecontroller.registerContent(content);
            }
		}
		return object;
	}
	
	function attachComponent(contentNode, content, xParser) {
		var component = null;
		var componentNodes = xParser.evaluate("component", contentNode);
        if (componentNodes.length == 0) return;
        
        var id = componentNodes[0].getAttribute("id");
        var type = componentNodes[0].getAttribute("type");
        if (type == "tree") {
        	component = new Tree(id);
        	
        }
        else if (type == "menubar") {
        	component = new MenuBar(id);
        }
        
        content.setComponent(component);
        
        attachProperties(componentNodes[0], component, xParser);
        
	}
	
	function attachProperties(contentNode, component, xParser) {
		var properties = new Array();
		var propertiesNodes = xParser.evaluate("property", contentNode);
        if (propertiesNodes.length == 0) return;
        
        for (var i = 0; i < propertiesNodes.length; i++) {
        	var name = propertiesNodes[i].getAttribute("name");
        	var value = propertiesNodes[i].getAttribute("value");
        	properties[name] = value;
        }
        component.setProperties(properties);
        
	}
		
	
	
	
	function attachEvents(contentNode, content, xParser) {
		var eventNodes = xParser.evaluate("event", contentNode);
        
        for (var i = 0; i < eventNodes.length; i++) {
            var type = eventNodes[i].getAttribute("type");
            var action = eventNodes[i].getAttribute("action");
            var stepId = eventNodes[i].getAttribute("step");
            var objectId = eventNodes[i].getAttribute("object");
            var varname = eventNodes[i].getAttribute("varname");
            var varvalue = eventNodes[i].getAttribute("varvalue");
            
            // ATTENTION! HACK!
            if (type == "On_Press") type = "On_Release";
            if (type == "On_Click") type = "On_Release";
            
            //alert(type + " " + action + " " + objectId);
            var event = new Event(type, action, stepId, objectId, varname, varvalue);
            content.addEvent(event);
        
        }
        
	}
	
	
		 
	// function for the missing trim() in the javascript-String-object
	function trimString(string) {
		for (var i = 0; i < string.length; i++) {
			if (string.charAt(i) != " ") {
				string = string.substring(i);
				break;
			}
		}
		for (var i = string.length - 1; i >= 0; i--) {
			if (string.charAt(i) != " ") {
				string = string.substring(0, i + 1);
				break;
			}
		}
		return string;
	}
	
	// this function selects n elements of an Array randomly and returns them as new Array
	function getRandomElements(z, numElementsToSelect) {
		var allElementsSize = z.length;
		var myElementsSize = numElementsToSelect;
		var myElements = new Array();
		var myVector = new Vector(z);
		var k = 0;
		while (myElements.length < myElementsSize) {
			var vectorSize = myVector.size();
			var index = Math.round(Math.random() * (vectorSize - 1));
			var myElement = myVector.get(index);
			myElements[k] = myElement;
			myVector.remove(index);
			k++;
		}
		return myElements;
	}

}


