//globals
var doc;
var can_switch_view = true;
var docElement;

/* the location of the scripts  */
var ScriptLocation   = "";
var ViewInfoLocation = "";
var WebLiveLocation = "";

/* this actually starts up the needed external scripts */
function runscriptfromsrc(src) {
	document.write(unescape("%3Cscript src='" + src + "' type='text/javascript'%3E%3C/script%3E"));
}
function runscriptinline(fn) {
	document.write(unescape("%3Cscript type='text/javascript'%3E "+fn+" %3C/script%3E"));
}


// constructor
function magnaviewweblive(config) {
	this.ScriptLocation = ScriptLocation;

	runscriptfromsrc(this.ScriptLocation+'wz_jsgraphics.js');
	this.elements = new Object();
	this.viewinfo = new Object();
	this.events   = new Object();

	this.thisview  = 0;
	this.scriptuid = 0;

	this.settings = new Object();

	this.settings.overviewshowing     = true;
	this.settings.Loading             = (this.settings.ShowLoadingScreen || (this.settings.pagetype == 2));

	this.graphics = new Array();	

	this.curviewinfo = -1;
	this.prevviewinfo = -1;
	this.viewinfolist = new Array();

	this.mode = 2;

	this.oldcurnodes         = new Array();
	this.dynloadingnodes = false;
	this.lastx = -1;
	this.lasty = -1;

	window.mv_object = this;

	attachEventFunction(window, 'unload', function() { window.mv_object.unload(); } );

	if (config) // dynamic version
		runscriptfromsrc(this.createurl({'type':'settings', 'data':config}));
	else
		runscriptfromsrc(ViewInfoLocation+'settings.js');

	/*call initialisation.
	this method is used so all scripts are executed in correct order. The init
	function depends on the settings script loaded just before */
	//runscriptinline("window.mv_object.init()");

}

magnaviewweblive.prototype.setElement = function(name, eltid) {
	this.elements[name] = document.getElementById(eltid);
}	

magnaviewweblive.prototype.init = function() {

	/* initialise globals */
	doc = (this.mode==1) ? parent.document : document;
	docElement = (typeof doc.compatMode != "undefined" && doc.compatMode != "BackCompat")? "documentElement" : "body"

	/* initialise buttons */
	if (this.elements.overview) {
		this.settings.thumbnailsoverview = true;
		this.elements.overview.onclick = function() { 
			this.mvobj.selectoverview();
			hide(this.mvobj.elements.overview);
			show(this.mvobj.elements.curview);
		};
		this.elements.overview.mvobj = this;
		
		if(this.elements.curview) {
			this.elements.curview.mvobj = this;
			hide(this.elements.curview);
			this.elements.curview.onclick = function() {
				var toview = this.mvobj.prevviewinfo;
				if(toview==-1) { //initial
					if(this.mvobj.viewinfolist.length>1) { toview = 1; }
				}
				this.mvobj.selectview(toview);
				hide(this.mvobj.elements.curview);
				show(this.mvobj.elements.overview);
			}
		}
	}
	
	if (this.elements.nextview) {
		this.elements.nextview.onclick = function() { this.mvobj.nextview() };
		this.elements.nextview.mvobj = this;
	}
	if (this.elements.prevview) {
		this.elements.prevview.onclick = function() { this.mvobj.prevview() };
		this.elements.prevview.mvobj = this;
	}
	if (this.elements.moredetail) {
		this.elements.moredetail.onclick = function() { this.mvobj.moredetail() };
		this.elements.moredetail.mvobj = this;
	}
	if (this.elements.zoomout) {
		this.elements.zoomout.onclick = function() { this.mvobj.zoomout() };
		this.elements.zoomout.mvobj = this;
	}
	if (this.elements.lessdetail) {
		this.elements.lessdetail.onclick = function() { this.mvobj.lessdetail() };
		this.elements.lessdetail.mvobj = this;
	}

	if (this.elements.filter) {
		this.elements.filter.style.display = 'none';
	}

	if (this.elements.selectview)
		this.fillselector(this.elements.selectview);
	if (this.elements.thumbnails)
		this.fillthumbs(this.elements.thumbnails);

	/* Generate main view div html */
	if(this.elements.main) {
		viewareadiv = this.elements.main;
	} else {
		viewareadiv = false;
	}

	var drawdiv = document.createElement('div');
	this.elements.draw = drawdiv;
	drawdiv.className = 'draw';
	drawdiv.style.position = 'relative';
	drawdiv.style.width    = '100%';
	drawdiv.style.height   = '100%';

	var drawimage = document.createElement('img');
	this.elements.drawimage = drawimage;
	drawimage.border = 0;
	if (this.pagetype == 1) {
		drawimage.width = this.settings.TreemapWidth;
		drawimage.height = this.settings.TreemapHeight;
	}

	drawdiv.appendChild(drawimage);

	for (var i = 0; i < this.settings.allmaxdepth; ++i) {
		var drawarea = document.createElement('div');
		drawarea.id = 'adrawarea'+i;
		drawarea.style.position = 'absolute';
		drawarea.style.top      = '0';
		drawarea.style.bottom   = '0';
		drawarea.style.left     = '0';
		drawarea.style.right    = '0';
		drawdiv.appendChild(drawarea);
	}

	if(viewareadiv){
		viewareadiv.appendChild(drawdiv);
	}

	/* From HTML script */
	for (var i = 0; i < this.settings.allmaxdepth; ++i) {
		this.graphics[i] = new jsGraphics('adrawarea'+i);
	}

	this.settings.mv_width    = this.settings.TreemapWidth;
	this.settings.mv_height   = this.settings.TreemapHeight;
	this.settings.ASPMode     = 0;
	this.settings.NoRight     = 0;
	this.settings.NoHeader    = 0;

	/* From body.onload = initialize */
	this.init_buttons();
	this.settings.screenh = document.getElementsByTagName("body")[0].innerHeight;

	{this.init_mousemove();};
    	window.onresize=resizehandler;

	this.initposition('0');


	//load the overview or the first view
	// if i do this directly, the nodes request will return something not matching the image, no idea why...
	// possibly concurrency issues within the COM object? returning node info for a previously rendered view?
	// ( seems to be the node info for a 600x600 image )
	window.setTimeout('window.mv_object.selectview(0)', 1)
	//this.selectview(0);
}

magnaviewweblive.prototype.fillselector = function(selector) {
	selector.mvobj = this;
	selector.onchange = function() { this.mvobj.selectview(this.selectedIndex); };
	
	if (this.settings.thumbnailsoverview) {
		this.viewinfolist.unshift(new Array("overview"));
		var option = document.createElement('option');
		option.innerHTML = "Overview";
		selector.appendChild(option);
	}

	var groups = new Array();
	for (var i = 0; i < this.groupinfolist.length; ++i) {
		groups[i] = document.createElement('optgroup');
		groups[i].label = (i+1) + '. ' + this.groupinfolist[i];
		selector.appendChild(groups[i]);
	}

	for (var i = 0; i < this.viewinfolist.length; ++i)
	if (this.viewinfolist[i][0] == "group") {
		var option = document.createElement('option');
		option.innerHTML = (this.viewinfolist[i][1]+1) + '. Group Image';
		groups[this.viewinfolist[i][1]].appendChild(option);
	} else if (this.viewinfolist[i][0] == "view") {
		var option = document.createElement('option');
		option.innerHTML = (this.viewinfolist[i][3]+1) + '.' + (this.viewinfolist[i][4]+1) + '. ' +this.viewinfolist[i][1];
		groups[this.viewinfolist[i][3]].appendChild(option);
	}
}

magnaviewweblive.prototype.fillthumbs = function(obj)
{
	//TODO: this function could be simplified!
	var lastgroup = -1;
	var ul = document.createElement('ul');
	for (var i = 0; i < this.viewinfolist.length; ++i) {
		if (this.viewinfolist[i][0] == "view") {
			if (lastgroup != this.viewinfolist[i][3]) {
				lastgroup = this.viewinfolist[i][3];
				var grouphdr = document.createElement('li');
				grouphdr.className = 'header';
				grouphdr.innerHTML = (this.viewinfolist[i][3]+1) + '. ' + this.groupinfolist[this.viewinfolist[i][3]];
				ul.appendChild(grouphdr);
			}

			var viewnum = this.viewinfolist[i][2];
			var li = document.createElement('li');
			var thumbdiv = document.createElement('div');
			var thumbimgdiv = document.createElement('div');

			var thumbimg = document.createElement('img');
			thumbimg.alt = this.viewinfolist[i][1];
			thumbimg.className = "thumbimg";
			if (this.settings.pagetype == 2) {
				thumbimg.src = this.createurl({'type':'thumbnails','view':viewnum,'th':78,'tw':115});
			} else {
				thumbimg.src = 'T_view_'+viewnum+'.png?r='+Math.round(Math.random()*999999);
			}
			thumbimg.mvobj = this;
			thumbimg.selnum = i;
			thumbimg.onclick = function() { this.mvobj.selectview(this.selnum); };

			thumbimgdiv.className = "thumb";
			thumbimgdiv.appendChild(thumbimg);
			thumbdiv.appendChild(thumbimgdiv);

			var thumbtxt = document.createElement('span');
			thumbtxt.innerHTML = (this.viewinfolist[i][3]+1) + '.' + (this.viewinfolist[i][4]+1) + '. ' + this.viewinfolist[i][1];		
			thumbdiv.appendChild(thumbtxt);

			li.appendChild(thumbdiv);
			ul.appendChild(li);
			
		} else if (this.viewinfolist[i][0] == "group") {
			lastgroup = this.viewinfolist[i][1];
			var grouphdr = document.createElement('li');
			grouphdr.className = 'header';
			grouphdr.innerHTML = (this.viewinfolist[i][1]+1) + '. ' + this.groupinfolist[this.viewinfolist[i][1]];
			ul.appendChild(grouphdr);

			var groupnum = this.viewinfolist[i][2];
			var li = document.createElement('li');
			var thumbdiv = document.createElement('div');
			var thumbimgdiv = document.createElement('div');
			
			var thumbimg = document.createElement('img');
			thumbimg.alt = this.viewinfolist[i][1];
			thumbimg.className = "thumb";
			if (this.settings.pagetype == 2) {
				thumbimg.src = this.createurl({'type':'groupthumbnail','group':groupnum,'th':78,'tw':115});
			} else {
				thumbimg.src = 'T_group_'+groupnum+'.png?r='+Math.round(Math.random()*999999);
			}
			thumbimg.mvobj = this;
			thumbimg.selnum = i;
			thumbimg.onclick = function() { this.mvobj.selectview(this.selnum); };

			thumbimgdiv.className = "thumb";
			thumbimgdiv.appendChild(thumbimg);
			thumbdiv.appendChild(thumbimgdiv);

			var thumbtxt = document.createElement('span');
			thumbtxt.innerHTML = (this.viewinfolist[i][1]+1) + '. Group Image';
			thumbdiv.appendChild(thumbtxt);

			li.appendChild(thumbdiv);
			ul.appendChild(li);
		}
	}
	obj.appendChild(ul);
}


magnaviewweblive.prototype.selectview = function(index) {
	function hasClass(ele,cls) {
		return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
	}
	function addClass(ele,cls) {
		if (ele && !hasClass(ele,cls)) ele.className += " "+cls;
	}
	function removeClass(ele,cls) {
		if (ele && hasClass(ele,cls)) {
			var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
			ele.className=ele.className.replace(reg,' ');
		}
	}

	if (index == -1) return;
	if (index >= this.viewinfolist.length) return;
	this.prevviewinfo = this.curviewinfo;
	this.curviewinfo = index;
	if (this.elements.selectview) {
		this.elements.selectview.selectedIndex = this.curviewinfo;
	}

	this.settings.overviewshowing = (this.viewinfolist[this.curviewinfo][0] == "overview");

	if (this.viewinfolist[this.curviewinfo][0] == "overview") {
		this.overview();
		addClass(this.elements.thumbnails, 'overview');
	} else if (this.viewinfolist[this.curviewinfo][0] == "view") {
		this.changeview(this.viewinfolist[this.curviewinfo][2]);
		removeClass(this.elements.thumbnails, 'overview');
	} else if (this.viewinfolist[this.curviewinfo][0] == "group") {
		this.changegroup(this.viewinfolist[this.curviewinfo][2]);
		removeClass(this.elements.thumbnails, 'overview');
	}

	if(typeof(this.changecallback)=='function') {
		this.changecallback();
	}
}

magnaviewweblive.prototype.initposition = function(_nr) {
//this function sets the correct offset for the treemap image
//needed for relative positioning
//This function also check which browser the user uses, and switches to SVG if needed
	//if firefox >= 1.5 or SeaMonkey >= 1.0, then addSVG and mode=1

	//TODO: check for IE7
	var agent = navigator.userAgent;
	var vers = "";
	//var doc = this.doc;
	doc.onmousemove = mousemove;
	if((agent.indexOf('Firefox') > 0) || (agent.indexOf('SeaMonkey') > 0) && (agent.indexOf('Gecko') > 0)){
		if(agent.indexOf('Firefox') > 0){
			var temp = agent.indexOf('Firefox')+8;
			for(var k = temp; k<agent.length; k++){
				vers = vers + agent.charAt(k);
			}
			vers = parseFloat(vers);
			if(vers>=1.5){
			//addSVG(_nr);
			//mode=1;
			}
		}else if(agent.indexOf('SeaMonkey') > 0){
			var temp = agent.indexOf('SeaMonkey')+10;
			for(var k = temp; k<agent.length; k++){
				vers = vers + agent.charAt(k);
			}
			vers = parseFloat(vers);
			if(vers>=1.0){
			//addSVG(_nr);
			//mode=1;
			}
		}
	}
	//if(mode==2 || mode==3){
		//IE: currentStyle
		//moz: getComputedStyle
	var drawarea = this.elements.draw;

	if (this.ASPMode==0)	{
		if(doc.defaultView){ //w3c DOM
			var drawstyle = doc.defaultView.getComputedStyle(drawarea, null);
			var divOffsetY = drawstyle.getPropertyValue('top').split('px');
			var divOffsetX = drawstyle.getPropertyValue('left').split('px');
		}
		else if (drawarea.currentStyle) { //IE
			var divOffsetY = drawarea.currentStyle.top.split('px');
			var divOffsetX = drawarea.currentStyle.left.split('px');
		}
		this.settings.TreemapTop  = parseInt(divOffsetY[0]) ;
		this.settings.TreemapLeft = parseInt(divOffsetX[0]) ;
	} else {
		this.settings.TreemapLeft = findPosX(drawarea);
		this.settings.TreemapTop  = findPosY(drawarea);
	}
	if (this.settings.pagetype == 2) {
		resizehandler();
	}
};

magnaviewweblive.prototype.init_buttons = function() {
/*	initialize the 'buttons' that are needed for the navigation. Enabling of
	certain elements is dependent on displaydepth, zoomdepth and viewnumber */
	setenabled(this.elements.lessdetail, this.viewinfo.depth != 1);
	setenabled(this.elements.moredetail, this.viewinfo.depth != (this.viewinfo.maximumdepth-this.viewinfo.zoomdepth));
	setenabled(this.elements.print     , (this.settings.mode==3 || this.settings.mode==2)&&!this.settings.thumbnailsoverview);
	setenabled(this.elements.zoomout   , this.viewinfo.zoomdepth > 0);

	setenabled(this.elements.prevview, this.curviewinfo>0);
	setenabled(this.elements.nextview, this.curviewinfo<this.viewinfolist.length-1);
	setenabled(this.elements.overview, this.settings.thumbnailsoverview);
};

magnaviewweblive.prototype.update_buttons = function() {
/*	this function updates the state of the 'buttons' of the navigation */
	var isview = this.viewinfolist[this.curviewinfo][0] == "view";
	setenabled(this.elements.lessdetail, isview && this.viewinfo.depth != 1);
	setenabled(this.elements.moredetail, isview && this.viewinfo.depth != (this.viewinfo.maximumdepth-this.viewinfo.zoomdepth));
	setenabled(this.elements.zoomout   , isview && this.viewinfo.zoomdepth > 0);

	if (this.settings.thumbnailsoverview){
		if(this.settings.overviewshowing) {
			disable(this.elements.print);
			if (this.elements.print) {
				this.elements.print.onclick = function() {};
			}
		} else {
			enable(this.elements.print);
			if (this.elements.print) {
				this.elements.print.onclick = function() {window.print()};
			}
		}
	}

	setenabled(this.elements.prevview, this.curviewinfo>0);
	setenabled(this.elements.nextview, this.curviewinfo<this.viewinfolist.length-1);
	if(this.settings.overviewshowing) {
		hide(this.elements.overview);
		show(this.elements.curview);
	} else {
		show(this.elements.overview);
		hide(this.elements.curview);
	}
};

magnaviewweblive.prototype.overview = function() {
//  this function hides the current view and shows the overview
	overviewshowing = true;
	
	this.update_buttons();

	this.hideloadingscreen();
}

magnaviewweblive.prototype.showloadingscreenforscript = function(js) {
	// be sure we make the loading div visible first
	this.showloadingscreen();
	// call the real function with 1ms delay, so the browser gets a chance
	// to rerender and actually show the loading div
	window.mvobj = this;
	window.setTimeout(js, 1)
};

magnaviewweblive.prototype.hideloadingscreen = function () {
	if (this.elements.loadingscreen) {
		this.elements.loadingscreen.style.display = 'none';
		this.elements.loadingscreen.style.visibility = 'hidden';
	}
}

magnaviewweblive.prototype.showloadingscreen = function() {
	if (this.elements.loadingscreen) {
		this.elements.loadingscreen.style.display = '';
		this.elements.loadingscreen.style.visibility = 'visible';
	}
};

magnaviewweblive.prototype.changeview = function(url) {
	//this.showloadingscreenforscript('window.mvobj.do_changeview('+url+')');
	//does't seem to be needed anymore? test in IE6/8 etc
	this.showloadingscreen();
	this.do_changeview(url);
}

magnaviewweblive.prototype.do_changeview = function(url) {
	this.thisview = url;
	this.disabledrawing();
	this.settings.displayoverlay = false;
	this.settings.overviewshowing = false;
	this.changeNodes(url,"","","",false);
	this.switchview(url);
}

magnaviewweblive.prototype.changegroup = function(group) {
	this.showloadingscreen();
	this.thisview = -1;

	this.disabledrawing();
	this.settings.displayoverlay = false;

	var thumbsOverview = this.elements.thumbnails;
	if (thumbsOverview) {
		thumbsOverview.className = "sidebar";
	}

	this.settings.overviewshowing = false;

	if (can_switch_view) {
		var drawtag = this.elements.drawimage
		if (this.settings.pagetype == 2) {
			this.calcImageSize();
			var ImageArea = this.createurl({'type':'groupimage','group':group});
		} else {
			var ImageArea = 'group_'+group+'.png?r='+Math.round(Math.random()*999999);
		}
		drawtag.src = ImageArea;
	}

	if (this.elements.legend)
		this.elements.legend.innerHTML = '';
	if (this.elements.nodeinfo)
		this.givenodeinfo(-1);
	if (this.elements.filter)
		this.elements.filter.innerHTML = '';
	if (this.elements.comment)
		this.elements.comment.innerHTML = '';

	this.update_buttons();
	this.hideloadingscreen();
	if(this.elements.totalview) 
		this.elements.totalview.style.visibility = "visible";

}

magnaviewweblive.prototype.disabledrawing = function() {
	if (this.mode==2) {
		//if (oldcurnodes[0] == -1) {HideLinesJS()}
		this.HideLinesJS();
	}else if(this.mode==3){
		this.HideLinesVML();
	} else if(move=="1"){
		move="0";
	}
};

magnaviewweblive.prototype.HideLinesJS = function () {
	var olddepth = this.viewinfo.depth;
	for(var j=0; j<olddepth; j++) {
		if (this.graphics[j]) {
			this.graphics[j].clear();
		}
		this.oldcurnodes[j] = -1;
		if(this.settings.GenerateNodeinfo && this.elements.nodeinfo){
			//clear the nodeinfo
			var nodeinfofield = this.elements.nodeinfo;
			this.givenodeinfo(-1);
		}
		//'hack' for IE, to resolve the >100% problem
		if (!(self.innerHeight) && this.graphics[j]) {
			this.graphics[j].setStroke(0);
			this.graphics[j].drawLine(0,0,0,0);
			this.graphics[j].paint();
		}
	}
};

magnaviewweblive.prototype.switchview = function(url) {
//this function changes the image area
	if (can_switch_view) {
		var drawtag = this.elements.drawimage
		if (this.settings.pagetype == 2) {
			this.calcImageSize();
			var ImageArea = this.createurl({'type':'image','view':url});
		} else {
			var ImageArea = 'view_'+url+'.png?r='+Math.round(Math.random()*999999);
		}
		drawtag.src = ImageArea;
		drawtag.style.display = 'block';
	}
}

magnaviewweblive.prototype.calcImageSize = function() {
	if(this.elements.main) {
		var neww = this.elements.main.clientWidth;
		var newh = this.elements.main.clientHeight;
	}

	if ((neww > 0) && (newh > 0) && ((neww!=mvobj.settings.mv_width) || (newh!=mvobj.settings.mv_height)) ){
			this.settings.mv_width  = neww;
			this.settings.mv_height = newh;
			return true;
	}
	return false

}

magnaviewweblive.prototype.changeNodes = function(number, attribute, value, hide, listbox) {
// removes the old nodes file out the source and replaces it by the current files
	var el = document.getElementById("js_variables");
	if (el)
		el.parentNode.removeChild(el);
	var script   = document.createElement('script');
	script.type  = 'text/javascript';
	script.id    = 'js_variables';
	script.defer = true;
	if (this.settings.pagetype ==1) {
		script.src = 'nodes_'+number+'.js';
	} else {
		// note: hide parameter is always '', so we ignore it...
		script.src = this.createurl({
			'type':'nodes',
			'view':number,
			'attribute':attribute,
			'Listbox': (listbox ? value : ''),
			'value': (!listbox ? value : '')
		});
	}
	document.getElementsByTagName("head")[0].appendChild(script);
};

magnaviewweblive.prototype.ShowView = function(){
	if (!this.settings.overviewshowing && this.elements.totalview) {
		this.elements.totalview.style.visibility = "visible";
	}
}

function resizehandler() {
	var resizeTimeout = 0;

	function doResize(mvobj) {
		if (mvobj.calcImageSize()) {
			//if IE7 and in iframe do not showloadingscreen, as this will cause the browser to fire many resize events
			if (!(window.XMLHttpRequest) || (top.location == self.location)) {
				mvobj.showloadingscreen();
			}
			mvobj.selectview(mvobj.curviewinfo);
		} 
	}

	var mvobj = window.mv_object;

	//IE fires the onresize event continiously, Firefox only after user is ready.
	//force IE to update the screen only once!

	if (mvobj.settings.pagetype ==2){
		if (self.innerHeight)	{ //not IE
			doResize(mvobj);
		} else {
			if (resizeTimeout!=0) {
				window.clearTimeout(resizeTimeout);
			}
			resizeTimeout = window.setTimeout(function(){
				resizeTimeout = 0;
				doResize(mvobj);
			},200);
		}
	}
		mvobj.settings.TreemapTop  = findPosY(mvobj.elements.draw);
		mvobj.settings.TreemapLeft = findPosX(mvobj.elements.draw);
};

magnaviewweblive.prototype.nextview = function() {
	if(this.curviewinfo<this.viewinfolist.length-1){
		this.selectview(this.curviewinfo+1);
	}
};

magnaviewweblive.prototype.prevview = function() {
 if(this.curviewinfo>0 && !this.settings.overviewshowing){
		this.selectview(this.curviewinfo-1);
	}
};

magnaviewweblive.prototype.selectoverview = function() {
	if (!this.settings.thumbnailsoverview) return;
	this.selectview(0); // overview always at 0 if it exists
}

magnaviewweblive.prototype.lessdetail = function() {
	if (this.viewinfo.depth >= 2) {
		var ImageArea = this.createurl({'type':'image','detail':'less'});
		this.viewinfo.depth--;
		this.update_buttons();
		this.elements.drawimage.src = ImageArea;
	}
}

magnaviewweblive.prototype.moredetail = function() {
	if (this.viewinfo.depth < (this.viewinfo.maximumdepth-this.viewinfo.zoomdepth)) {
		var ImageArea = this.createurl({'type':'image','detail':'more'});
		this.viewinfo.depth++;
		this.update_buttons();
		this.elements.drawimage.src = ImageArea;
	}
}

magnaviewweblive.prototype.init_mousemove = function() {
	//initialilze handling of mousemove event
	if(doc.layers) doc.captureEvents(Event.MOUSEMOVE);
	for(var i=0;i<this.oldcurnodes.length;i++) this.oldcurnodes[i] = -1
	//if (HandleClicks=="1"){
		//initialize right mouseclick (*add the context menu to the right mouseclick)
		//TODO: better handling of contextmenu
		//document.getElementById("draw").oncontextmenu = ItemSelMenu;
	//}
	//HandleClicks++
	this.elements.draw.ondblclick = handle_events;
	this.elements.draw.object = this;
	doc.mousemove = mousemove;
};

function handle_events(evt) {
	// pass event to associated object
	this.object.handle_events(evt);
}

function mousemove(evt) {
/*	For performance reasons the eventhandler is temporarily unhooked, so the
	number of calls is limited. */

	doc.onmousemove = null;

	window.mv_object.mousemove(evt);

	//setup the mousemove eventhandler again
	doc.onmousemove = mousemove;
}

magnaviewweblive.prototype.mousemove = function(e) {
/*	this function handles the mousemove event.
	The mousecoordinates are determined and then another function is calles that
	will display the overlay based on the coordinates relative to the treemap */

	// get mouseposition
	var X = e? e.clientX : window.event.clientX;
	var Y = e? e.clientY : window.event.clientY;
	
	X += document[docElement].scrollLeft;
	Y += document[docElement].scrollTop;
	
	if( (X <  this.settings.TreemapLeft) ||  
		(X > (this.settings.TreemapLeft + this.settings.mv_width)) ||
		(Y <  this.settings.TreemapTop) ||
		(Y > (this.settings.TreemapTop  + this.settings.mv_height))    ) {
		return;
	}
	
	//X -= 5;//correct for shadows
	//Y -= 3;//correct for shadows

	//display the treemap overlay for the coordinates relative to the treemap
	//if(move=="1")
	if (this.settings.displayoverlay) {
		this.displaytreemapoverlay(X-this.settings.TreemapLeft,Y-this.settings.TreemapTop,e);
	}
};

magnaviewweblive.prototype.handle_events = function(e) {
//	this function handles click and double click
	var eventtype = e? e.type : window.event.type;
	
	clickX    =  e? e.clientX : window.event.clientX
	clickY    =  e? e.clientY : window.event.clientY;
	
	clickX += document[docElement].scrollLeft;
	clickY += document[docElement].scrollTop;
	
	clickX -= this.settings.TreemapLeft;
	clickY -= this.settings.TreemapTop;

	// todo: properly distinguish single and double clicks
	switch (eventtype) {
		case "click": 
			break;
		case "dblclick":
			if (this.events.ondoubleclick) this.events.ondoubleclick(clickX, clickY);
			break;
		default:
	}

	return;
	if(this.mode==1){
		clickX=PosX;
		clickY=PosY;
	}else if (this.mode == 2 || this.mode==3){
		//save the mouseposition for the clickevent
		var eventtype = evt? evt.type : window.event.type;
		clickX    =  evt? evt.pageX : window.event.x;
		clickY    =  evt? evt.pageY : window.event.y;
	}
	if(eventtype == 'dblclick') {
		//doDoubleClick(clickX, clickY);
		PopUp_activity(clickX-TreemapLeft,clickY-TreemapTop);
	}
	/*
	if(clickcounter == 0){
		clickcounter=1;
		tfClick = dclick.getTime();
		savTO = setTimeout("mouseclick(clickX, clickY)", dcTime);
	}
	else if(clickcounter == 1){
		clickcounter=0;
		tsClick = dclick.getTime();
		if (tsClick-tfClick < dcTime){
			clearTimeout(savTO);
			savTO=null;
			setTimeout("doDoubleClick(clickX, clickY)", dcTime);
		}
		tfClick=0;
		tsClick=0;
	}
	*/
};

magnaviewweblive.prototype.zoomin = function(X,Y) {
	var ImageArea = this.createurl({'type':'image','mode':'zoomin','x':X,'y':Y,'z':this.viewinfo.zoomdepth});
	this.elements.drawimage.src = ImageArea;

	this.changeNodes(this.thisview,"","","",false);
}

magnaviewweblive.prototype.zoomout = function() {
	var ImageArea = this.createurl({'type':'image','mode':'zoomout','z':this.viewinfo.zoomdepth});
	this.elements.drawimage.src = ImageArea;

	this.changeNodes(this.thisview,"","","",false);
}

magnaviewweblive.prototype.loadDynamicNodes = function(X, Y, curnode, j) {
	if (mvobj.dynloadingnodes) return;
	var script   = document.createElement('script');
	script.type  = 'text/javascript';
	script.id = this.scriptuid++;
	script.src = this.createurl({'type':'nodesxy','x':X,'y':Y,'curnode':curnode,'cleanscript':script.id});
	mvobj.dynloadingnodes = true;
	document.getElementsByTagName("head")[0].appendChild(script);
}

magnaviewweblive.prototype.displaytreemapoverlay = function(X,Y, evt) {
/*	this function will display the correct overlay rectangles and node
	information based on the (x,y) coordinate */

	var mv_width = this.settings.mv_width;
	var mv_height = this.settings.mv_height;
	var depth = this.viewinfo.depth;
	var graphics = this.graphics;
	var mode = this.mode;
	var topnodes = this.viewinfo.topnodes;
	var nodes = this.viewinfo.nodes;
	this.lastx = X;
	this.lasty = Y;

	var found = false;
	var updatelevel = 0;
	var curnode = -2;
	var counter = 0;
	var curchild;
	var tmppoint = new TPoint(X,Y);
	var tmprect  = new TRect;

	//retrieve the updatelevel
	updatelevel = this.updatefrom(X,Y);
	
	//if the updatelevel is equal to the depth, then nothing has to be updated */
	if (updatelevel==depth) return true;
	
	curnode = 0; // node 0 is the root node
	for(j=0; j<depth; j++) {
		if(mode==1){
			if(svgDocument!=null){
				if ((svgDocument.getElementById(j)) == null){
					makePolyline(evt, j, "0,0");
				}
			}
		}else if(mode==3){
			if ((doc.getElementById(j)) == null){
				makeVMLPolyline(j, "0 0");
			}
		}
		nrChildnodes = nodes[curnode][2].length;
		found = false;
		var i = nrChildnodes;
		if (i>0 && tmppoint.x>=nodes[curnode][8] && tmppoint.x<=nodes[curnode][8]+nodes[curnode][10] &&
			tmppoint.y>=nodes[curnode][9] && tmppoint.y<=nodes[curnode][9]+nodes[curnode][11] ) {
			var hasnullchild = false;
			do {
				curchild = nodes[curnode][2][i-1];
				if(curchild==null){curchild=this.oldcurnodes[i];}
				if (nodes[curchild] != null) {
					tmprect = this.getParentRect(curchild);
					if(counter == 0){
						tmppoint = this.CoordinateTransformUp(tmppoint.x, tmppoint.y, j, tmprect, curchild);
						counter  = 1;
					}
					if (tmppoint.x <= mv_width && tmppoint.y <=mv_height){
						if (tmppoint.x>=nodes[curchild][3] && tmppoint.x<=nodes[curchild][3]+nodes[curchild][5] &&
							tmppoint.y>=nodes[curchild][4] && tmppoint.y<=nodes[curchild][4]+nodes[curchild][6] ) {
								//if(this.oldcurnodes[j]!=curchild){
									if(mode==2){graphics[j].clear();}
									this.drawnode(curchild, j);
									this.oldcurnodes[j] = curchild;
								//}
								found = true;
								curnode = curchild;
								i=1;
						}
					}
				} else
					hasnullchild = true;
			}
			while (--i); //do (...) while(--i) loop for increase of speed
			if (!found && hasnullchild) {
				// Initiate dynamic loading if not doing so already;
				for(; j<depth; j++) {
					if(mode==2){graphics[j].clear();}
				}
				this.loadDynamicNodes(X, Y, curnode);
				return true;
			}
		} else {
			for(; j<depth; j++) {
				if(mode==2){graphics[j].clear();}
			}
			return;
		}
		counter=0;
	}

	//display the node information of the current node pointed at
	this.givenodeinfo(curnode);
	 if((curchild-1) == curnode){
		if(mode == 1){
			this.HideLines();
		} else if(mode == 2){
			this.HideLinesJS();
		}else if(mode==3){
			this.HideLinesVML();
		}
	}
	return true;
};

magnaviewweblive.prototype.updatefrom = function(X,Y) {
//this function tells, based on the current mousecoordinates which level
//(and the levels below) has to be updated
	var tmppoint2 = new TPoint;
	var tmprect2  = new TRect(this.settings.RootMarginLeft,this.settings.RootMarginTop,this.settings.mv_width+this.settings.RootMarginRight,this.settings.mv_height+this.settings.RootMarginBottom);
	if((this.oldcurnodes[0])==null) {this.oldcurnodes[0]=-1;}
	for(i=0; i<this.viewinfo.depth; i++) {
		if(i>0){
			tmprect2 = this.getParentRect(this.oldcurnodes[i]);
		}
		tmppoint2 = this.CoordinateTransformUp(X, Y, i, tmprect2, this.oldcurnodes[i]);
		if (!(this.oldcurnodes[i]>-1 &&
			tmppoint2.x>=this.viewinfo.nodes[this.oldcurnodes[i]][3] && tmppoint2.x<=(this.viewinfo.nodes[this.oldcurnodes[i]][3]+this.viewinfo.nodes[this.oldcurnodes[i]][5]) &&
			tmppoint2.y>=this.viewinfo.nodes[this.oldcurnodes[i]][4] && tmppoint2.y<=(this.viewinfo.nodes[this.oldcurnodes[i]][4]+this.viewinfo.nodes[this.oldcurnodes[i]][6]) )) {
			return i;
		}
	}
	return this.viewinfo.depth;
};

magnaviewweblive.prototype.CoordinateTransform = function(x, y, level, r, id) {
/*	this function will apply a coordinatetransformation, from rectangle to x */
	var transformedpoint = new TPoint;
	switch((this.viewinfo.leveltransformations[level+this.viewinfo.zoomdepth])) {
		case 2: //PolarXtoR
			transformedpoint = TreemapXY2PolarMapXYRectXtoR(x,y,r);
			break;
		case 3: //PolarYtoR
			transformedpoint = TreemapXY2PolarMapXYRectXtoR(y,x, new TRect(r.top,r.left,r.bottom,r.right));
			var temp = transformedpoint.x;
			transformedpoint.x = transformedpoint.y;
			transformedpoint.y = temp;
			break;
		case 4: //PyramidTop
			transformedpoint = PyramidTopTransform(x,y,r);
			break;
		case 5: //PyramidLeft
			transformedpoint = PyramidTopTransform(y,x,new TRect(r.top,r.left,r.bottom,r.right));
			var temp = transformedpoint.x;
			transformedpoint.x = transformedpoint.y;
			transformedpoint.y = temp;
			break;
		case 6: //PyramidRight
			transformedpoint = PyramidTopTransform(y,x,new TRect(r.top,r.left,r.bottom,r.right));
			var temp = transformedpoint.x;
			transformedpoint.x = transformedpoint.y;
			transformedpoint.y = temp;
			transformedpoint.x = r.right-(transformedpoint.x-r.left);
			break;
		case 7: //PyramidBottom
			transformedpoint   = PyramidTopTransform(x,y,r);
			transformedpoint.y = r.bottom-(transformedpoint.y-r.top);
			break;
		case 8: //mirror X
			transformedpoint.x = (r.right) - (x - r.left);
			transformedpoint.y = y;
			break;
		case 9: //mirror Y
			transformedpoint.x = x;
			transformedpoint.y = (r.bottom)-(y-r.top);
			break;
		default:
			transformedpoint.x = x;
			transformedpoint.y = y;
	}
	if (this.viewinfo.nodes[id][1] != 0) {
		par_id = this.viewinfo.nodes[id][1];
		par_rect = this.getParentRect(par_id);
		transformedpoint = this.CoordinateTransform(transformedpoint.x, transformedpoint.y, level-1, par_rect, par_id);
	}
	return transformedpoint;
};

magnaviewweblive.prototype.CoordinateTransformUp = function(x, y, level, r, id) {
/*	this function will apply a coordinatetransformation, from x back to rectangle */
	var transformedpoint = new TPoint;
	switch(this.viewinfo.leveltransformations[level+this.viewinfo.zoomdepth]) {
		case 2: //PolarXtoR
			transformedpoint = PolarMapXY2TreemapXYrelRextXtoR(x,y,r);
			break;
		case 3: //PolarYtoR
			transformedpoint = PolarMapXY2TreemapXYrelRextXtoR(y,x,new TRect(r.top,r.left,r.bottom,r.right));
			var temp = transformedpoint.x;
			transformedpoint.x = transformedpoint.y;
			transformedpoint.y = temp;
			break;
		case 4: //PyramidTop
			transformedpoint = PyramidTopTransformUp(x,y,r);
			break;
		case 5: //PyramidLeft
			transformedpoint = PyramidTopTransformUp(y,x,new TRect(r.top,r.left,r.bottom,r.right));
			var temp = transformedpoint.x;
			transformedpoint.x = transformedpoint.y;
			transformedpoint.y = temp;
			break;
		case 6: //PyramidRight
			transformedpoint = PyramidTopTransformUp(y,r.right-(x-r.left),new TRect(r.top,r.left,r.bottom,r.right));
			var temp = transformedpoint.x;
			transformedpoint.x = transformedpoint.y;
			transformedpoint.y = temp;
			break;
		case 7: //PyramidBottom
			transformedpoint = PyramidTopTransformUp(x,r.bottom-(y-r.top),r);
			break;
		case 8: //mirror X
			transformedpoint.x = (r.right) - (x - r.left);
			transformedpoint.y = y;
			break;
		case 9: //mirror Y
			transformedpoint.x = x;
			transformedpoint.y = (r.bottom)-(y-r.top);
			break;
		default:
			transformedpoint.x = x;
			transformedpoint.y = y;
	}
	return transformedpoint;
};

magnaviewweblive.prototype.getParentRect = function(id) {
/* this function returns the parent rectangle (Trect) of node 'id' */
	if(this.viewinfo.nodes[id]!=null){
		if (this.viewinfo.nodes[id][1] == 0) {
			var rect_left   = this.viewinfo.RootMarginLeft;
			var rect_top    = this.viewinfo.RootMarginTop;
			var rect_right  = this.settings.mv_width+this.viewinfo.RootMarginRight;
			var rect_bottom = this.settings.mv_height+this.viewinfo.RootMarginBottom;
		} else {
			var rect_left   = this.viewinfo.nodes[this.viewinfo.nodes[id][1]][8];
			var rect_top    = this.viewinfo.nodes[this.viewinfo.nodes[id][1]][9];
			var rect_right  = rect_left + this.viewinfo.nodes[this.viewinfo.nodes[id][1]][10];
			var rect_bottom = rect_top  + this.viewinfo.nodes[this.viewinfo.nodes[id][1]][11];
		}
		pr_rect = new TRect(rect_left, rect_top, rect_right, rect_bottom);
	}else{
		pr_rect = new TRect(0,0,this.settings.mv_width,this.settings.mv_height);
	}
	return pr_rect;
};

magnaviewweblive.prototype.givenodeinfo = function(node) {
/*	display the node information of the current node in the correct place. This
	function assumes a nodeinfo div */
	var n_info = "";
	var nodeinfofield = this.elements.nodeinfo;
	if(this.settings.GenerateNodeinfo && nodeinfofield){
		var isnodelevel = (node >= 0) && !this.viewinfo.nodes[node][9]; // no children means node level
		if (isnodelevel) {
			var varnum = this.viewinfo.nodes[node][8];
			if (this.variables[varnum]) {
				var varinfo = this.variables[varnum].split('\x00');
				for (i=0; i<this.viewinfo.var_ids.length ;i++ ) {
					n_info += "<div class='nodeinforow'>";
					n_info += "<div class='nodeinfoattr'>";
					n_info += this.viewinfo.var_names[i];
					n_info += "</div>";
					n_info += "<div class='nodeinfovalue'>";
					n_info += varinfo[this.viewinfo.var_ids[i]]+"</b><br />";
					n_info += "</div>";
					n_info += "</div>";
				}
			} else {
				// variable info not known yet, request it
				var script   = document.createElement('script');
				script.type  = 'text/javascript';
				script.id = this.scriptuid++;
				script.src = this.createurl({'type':'variables','start':varnum,'stop':varnum+1,'other':'false','node':node,'cleanscript':script.id});
				document.getElementsByTagName("head")[0].appendChild(script);
				return;
			}
		} else  {
			if(this.viewinfo && this.viewinfo.var_ids){
				for (i=0; i<this.viewinfo.var_ids.length ;i++ ) {
					n_info += "<div class='nodeinforow'>";
					n_info += "<div class='nodeinfoattr'>";
					n_info += this.viewinfo.var_names[i];
					n_info += "</div>";
					n_info += "<div class='nodeinfovalue'></div>";
					n_info += "</div>";
				}
			}
		}
		if(this.mode==1){
			if(nodeinfo!=null)
				nodeinfo.innerHTML = n_info;
		}
		else if(this.mode==2 || this.mode==3){
			nodeinfofield.innerHTML = n_info;
		}
	}
};

magnaviewweblive.prototype.drawnode = function(id, level) {
/*	this function draws the node, i.e. the lines of the node and the label */
	//determine the depth of the node. A node should only be drawn if the level is correct. TODO: this should be a property of nodes array
	var l = 0;
	tmpid = id;
	while (this.viewinfo.nodes[tmpid][1] != 0) {
		tmpid = this.viewinfo.nodes[tmpid][1];
		l++;
	}
	if(l==level) {
		this.drawNodeLines(id,level);
		this.drawNodeLabel(id,level);
		this.drawNodeIcon(id,level);
		if(this.mode == 2){
			if (this.graphics[level]) this.graphics[level].paint();
		}
	}
};



magnaviewweblive.prototype.DrawLine = function(p1, p2, level, parent_rect, id){
	/*Draw a line between the points p1 and p2 using given transformation function.
		Stops when the line to draw and it's actual transformation have a maximum
		distance of MaxDist. i.e. low values of MaxDist => nicer line*/
	var mode = this.mode;

	var newp1 = new TPoint(0,0);
	var newp2 = new TPoint(0,0);
	var c     = new TPoint(0,0);
	if(mode==3){
		var MaxDist = 0.7;
	}else{
		var MaxDist = 0.2;
	}
	var midp1p2;
	var d;
	if(mode==1 || mode==3){
		var _temps = "";
	}else if(mode==2){
		var _arrx		= new Array();
		var _arry		= new Array();
		var _arr		= new Array();
		var temparray	= new Array();
	}
	midp1p2 = Midpoint(p1,p2);
	newp1	= this.CoordinateTransform(p1.x, p1.y, level, parent_rect, id);
	newp2	= this.CoordinateTransform(p2.x, p2.y, level, parent_rect, id);
	c		= this.CoordinateTransform(midp1p2.x, midp1p2.y, level, parent_rect, id);
	d		= Midpoint(newp1, newp2);
	if(PointDist(d,c) <= (MaxDist*MaxDist)){
		if(mode==1){
			_temps = _temps + newp1.x + "," + newp1.y + " ";
			_temps = _temps + newp2.x + "," + newp2.y + " ";
		}else if(mode==2){
			_arrx[_arrx.length] = Math.round(newp1.x);
			_arry[_arry.length] = Math.round(newp1.y);
			_arrx[_arrx.length] = Math.round(newp2.x);
			_arry[_arry.length] = Math.round(newp2.y);
		}else if(mode==3){
			_temps = _temps + Math.round(newp1.x) + "," + Math.round(newp1.y) + " ";
			_temps = _temps + Math.round(newp2.x) + "," + Math.round(newp2.y) + " ";
		}
	} else{
		if(mode==1){
			_temps = _temps + this.DrawLine(p1, midp1p2, level, parent_rect, id);
			_temps = _temps + c.x + "," + c.y + " ";
			_temps = _temps + this.DrawLine(midp1p2, p2, level, parent_rect, id);
		}else if(mode==2){
			temparray = this.DrawLine(p1, midp1p2, level, parent_rect, id);
			for(var k=0; k<temparray[0].length;k++){
				_arrx[_arrx.length] = temparray[0][k];
				_arry[_arry.length] = temparray[1][k];
			}
			_arrx[_arrx.length] = c.x;
			_arry[_arry.length] = c.y;
			temparray = this.DrawLine(midp1p2, p2, level, parent_rect, id);
			for(var k=0; k<temparray[0].length;k++){
				_arrx[_arrx.length] = temparray[0][k];
				_arry[_arry.length] = temparray[1][k];
			}
		}else if(mode==3){
			_temps = _temps + this.DrawLine(p1, midp1p2, level, parent_rect, id);
			_temps = _temps + Math.round(c.x) + "," + Math.round(c.y) + " ";
			_temps = _temps + this.DrawLine(midp1p2, p2, level, parent_rect, id);
		}
	}
	if(mode==1 || mode==3){
		return _temps;
	}else if(mode==2){
		_arr[0] = _arrx;
		_arr[1] = _arry;
		return _arr;
	}
};

magnaviewweblive.prototype.drawNodeLines = function(id, level) {
/*	this function will draw the lines of node 'id' on level  'level' */

	var overlay = this.viewinfo.overlay;
	var graphics = this.graphics;
	var nodes = this.viewinfo.nodes;
	var mode = this.mode;
	var depth = this.viewinfo.depth;

	if (overlay.level[level]){
		if (overlay.level[level].Rectangle) {
			for (i=0;i<overlay.level[level].Rectangle.length ;i++ ) {
				var Rectangle = overlay.level[level].Rectangle[i];
				var temps = "";
				var temp2;
				var p1 = new TPoint(0,0);
				var p2 = new TPoint(0,0);
				var visible = true;
				if(mode==2){
					graphics[level].setStroke(Rectangle.width);
					graphics[level].setColor(Rectangle.color);
					var temparray = new Array();
					var drawingx  = new Array();
					var drawingy  = new Array();
				}
				var left    = nodes[id][3]; //  + 3 ; //correct for shadows
				var top     = nodes[id][4]; //  + 1 ; //correct for shadows
				var right   = left + nodes[id][5] ; //left + width
				var bottom  = top  + nodes[id][6] ; //top + height
				parent_rect = this.getParentRect(id);
				if(nodes[id][2].length==0){
					visible = false;
				}
				if(level+1==depth){
					visible = true;
				}
				if(nodes[id][0]==0){
					visible = false;
				}
				if(visible){
					p1.x = left  ;
					p1.y = top   ;
					p2.x = right ;
					p2.y = top   ;
					if(mode==1 || mode==3){
						temp2 = this.DrawLine(p1, p2, level, parent_rect, id);
						temps = temps + temp2;
					} else if(mode==2){
						temparray = this.DrawLine(p1, p2, level, parent_rect, id);
						for(var k=0; k<temparray[0].length;k++){
							drawingx[drawingx.length] = temparray[0][k];
							drawingy[drawingy.length] = temparray[1][k];
						}
					}

					p1.x = right;
					p1.y = top;
					p2.x = right;
					p2.y = bottom;
					if(mode==1 || mode==3){
						temp2 = this.DrawLine(p1, p2, level, parent_rect, id);
						temps = temps + temp2;
					} else if(mode==2){
						temparray = this.DrawLine(p1, p2, level, parent_rect, id);
						for(var k=0; k<temparray[0].length;k++){
							drawingx[drawingx.length] = temparray[0][k];
							drawingy[drawingy.length] = temparray[1][k];
						}
					}

					p1.x = right;
					p1.y = bottom;
					p2.x = left;
					p2.y = bottom;
					if(mode==1 || mode==3){
						temp2 = this.DrawLine(p1, p2, level, parent_rect, id);
						temps = temps + temp2;
					} else if(mode==2){
						temparray = this.DrawLine(p1, p2, level, parent_rect, id);
						for(var k=0; k<temparray[0].length;k++){
							drawingx[drawingx.length] = temparray[0][k];
							drawingy[drawingy.length] = temparray[1][k];
						}
					}

					p1.x = left;
					p1.y = bottom;
					p2.x = left;
					p2.y = top;
					if(mode==1 || mode==3){
						temp2 = this.DrawLine(p1, p2, level, parent_rect, id);
						temps = temps + temp2;
					} else if(mode==2){
						temparray = this.DrawLine(p1, p2, level, parent_rect, id);
						for(var k=0; k<temparray[0].length;k++){
							drawingx[drawingx.length] = temparray[0][k];
							drawingy[drawingy.length] = temparray[1][k];
						}
					}
				}

				if(mode==1){
					changeAttribute(level,"stroke-width",mouseoverlaysettings[level][1]);
					changeAttribute(level,"stroke",mouseoverlaysettings[level][2]);
					changeAttribute(level,"points", temps);
				}else if(mode==2){
					graphics[level].drawPolyline(drawingx, drawingy);
				}else if(mode==3){
					changeVMLAttribute(level,"strokecolor",mouseoverlaysettings[level][2]);
					changeVMLAttribute(level,"strokeweight",mouseoverlaysettings[level][1]);
					changeVMLAttribute(level,"points",temps);
				}
			}//for
		}//if
		}
};


magnaviewweblive.prototype.drawNodeLabel = function(id, level) {
/*	this function draws the label of node 'id' on level 'level' */
//There is no text alignment on the right side, because there was no way to determine the width of the string
//so all the "right" settings are using the "left" coordinates.

	var overlay = this.viewinfo.overlay;
	var graphics = this.graphics;
	var nodes = this.viewinfo.nodes;
	var mode = this.mode;
	var depth = this.viewinfo.depth;
	var mv_width = this.settings.mv_width;
	var mv_height = this.settings.mv_height;

	var tmppoint3 = new TPoint(0,0);
	var tmprect3  = new TRect(0,0,mv_width,mv_height);
	var text_x, text_y, marge;
	var paintlabelx = false;
	var	paintlabely = false;
	if (overlay.level[level]) {
		if (overlay.level[level].Label) {
			for (i=0;i<overlay.level[level].Label.length ;i++ ) {
				var Label = overlay.level[level].Label[i]; //for loop for each level
				if(mode==2){
						graphics[level].drawString(" ",0, 0);
				} else if(mode==1){
						changeText(0, 0, " ", "text_b" + level, 'black', Label.font, Label.fontsize);
						changeText(0, 0, " ", "text_w" + level, Label.color, Label.font, Label.fontsize);
				} else if(mode==3){
						changeVMLText(-10, -10, " ", "text_b" + level, 'black', Label.font, Label.fontsize);
						changeVMLText(-10, -10, " ", "text_w" + level, Label.color, Label.font, Label.fontsize);
				}
				if (level<=depth) { //changed from depth-1 to depth since overlays weren't displayed
					text_w = nodes[id][5] - 2*Label.margin;
					marge  = Label.margin;
					labeltext = '';
					labelwidth = 0;
					labelfontheight = 0;
					if (nodes[id][7] && nodes[id][7][0] && nodes[id][7][0][i]) {
						labeltext = nodes[id][7][0][i][0];
						labelwidth = nodes[id][7][0][i][1];
						labelfontheight = nodes[id][7][0][i][2];
						text_x = nodes[id][7][0][i][3]; //+ 3;//correct for shadow
						text_y = nodes[id][7][0][i][4]; //+ 1;//correct for shadow
					}

					if (Label.displayshadow) {
						if(mode == 1){
							changeText(text_x+1,text_y+1, labeltext, "text_b" + level, 'black', Label.font, Label.fontsize);
						}else if (mode == 2){
							graphics[level].setFont(Label.font,(labelfontheight+1)+"px",Label.fontstyle);
							graphics[level].setColor('black');
							graphics[level].drawString(labeltext,text_x+1, text_y+1);
						}else if (mode==3){
							changeVMLText(text_x+1,text_y+1, labeltext, "text_b"+level, 'black', Label.font, label.fontsize);
						}
					}
					if(mode==1){
						changeText(text_x, text_y, labeltext, "text_w" + level, Label.color, Label.font, Label.fontsize);
					}else if(mode == 2){
						graphics[level].setFont(Label.font,(labelfontheight+1)+"px",Label.fontstyle);
						graphics[level].setColor(Label.color);
						graphics[level].drawString(labeltext,text_x, text_y);
					}else if(mode==3){
						changeVMLText(text_x, text_y, labeltext, "text_w" + level, Label.color, Label.font, label.fontsize);
					}
				}
			} //for
		}
	}
};


magnaviewweblive.prototype.drawNodeIcon = function(id, level) {
/*	this function draws the label of node 'id' on level 'level' */
//There is no text alignment on the right side, because there was no way to determine the width of the string
//so all the "right" settings are using the "left" coordinates.

	var overlay = this.viewinfo.overlay;
	var graphics = this.graphics;
	var nodes = this.viewinfo.nodes;
	var mode = this.mode;
	var depth = this.viewinfo.depth;
	var mv_width = this.settings.mv_width;
	var mv_height = this.settings.mv_height;

	if (overlay.level[level]) {
		if (overlay.level[level].Icon) {
			for (i=0;i<overlay.level[level].Icon.length ;i++ ) {
				if (level<=depth) { //changed from depth-1 to depth since overlays weren't displayed
					var Icon = overlay.level[level].Icon[i]; //for loop for each level

					// icon_[wh] : dimensions of the icon to draw
					// icon_url  : url of the icon to draw
					var icon_idx = nodes[id][7][1][i];
					if (icon_idx >= 0) {
						var icon_url = this.createurl({'type':'overlayicon','level':Icon.level,'overlay':Icon.index,'index':icon_idx});
						var icon_w   = this.iconinfo[icon_idx][0];
						var icon_h   = this.iconinfo[icon_idx][1];
						icon_ar = icon_w / icon_h; // icon aspect ratio

						// calculate the area in which to place the icon, and remember of it was a margin
						var area_l, area_r, area_t, area_b; // left, right, top, bottom
						var is_x_margin = false;
						var is_y_margin = false;

						// calculate horizontal bounds (x)
						switch (Icon.positionx) { 
							case "Auto":
							case "Left":
							case "Center":
							case "Right": {
								area_l = nodes[id][3];
								area_r = nodes[id][3] + nodes[id][5];
								break;
							}
							case "Left of Visualization":
							case "Center of Visualization":
							case "Right of Visualization":{
								area_l = 0;
								area_r = mv_width;
								break;
							}
							case "Left of left margin":
							case "Center of left margin":
							case "Right of left margin":{
								area_l = nodes[id][3];
								area_r = nodes[id][8];
								is_x_margin = true;
								break;
							}
							case "Left of right margin":
							case "Center of right margin":
							case "Right of right margin":{
								area_l = nodes[id][8] + nodes[id][10];
								area_r = nodes[id][3] + nodes[id][5];
								is_x_margin = true;
								break;
							}
						}

						// calculate vertical bounds (y)
						switch (Icon.positiony) { 
							case "Auto":
							case "Top":
							case "Center":
							case "Bottom": {
								area_t = nodes[id][4];
								area_b = nodes[id][4] + nodes[id][6];
								break;
							}
							case "Top of Visualization":
							case "Center of Visualization":
							case "Bottom of Visualization":{
								area_t = 0;
								area_b = mv_height;
								break;
							}
							case "Top of top margin":
							case "Center of top margin":
							case "Bottom of top margin":{
								area_t = nodes[id][4];
								area_b = nodes[id][9];
								is_y_margin = true;
								break;
							}
							case "Top of bottom margin":
							case "Center of bottom margin":
							case "Bottom of bottom margin":{
								area_t = nodes[id][9] + nodes[id][11];
								area_b = nodes[id][4] + nodes[id][6];
								is_y_margin = true;
								break;
							}
						}

						// calculate margins
						var margin_w = parseFloat(Icon.hormarginvalue);
						if ((margin_w > 0) && (Icon.hormarginmethod == 'relative to tile')) margin_w *= (area_r - area_l);

						var margin_h = parseFloat(Icon.vertmarginvalue);
						if ((margin_h > 0) && (Icon.vertmarginmethod == 'relative to tile')) margin_h *= (area_b - area_t);

						area_l += margin_w;
						area_r -= margin_w;
						area_t += margin_h;
						area_b -= margin_h;

						// img_[xywh] : dimensions of the rectangle where the icon will be drawn
						var img_x, img_y;
						var img_w = Icon.sizevalue;
						var img_h = Icon.sizevalue;
						// calculate target rectangle size
						if (Icon.sizemethod = 'relative to tile') {
							img_w *= (Icon.sizeisofwholenode == "1") ? nodes[id][5] : (is_x_margin ? (area_r - area_l) : nodes[id][10]);
							img_h *= (Icon.sizeisofwholenode == "1") ? nodes[id][6] : (is_y_margin ? (area_b - area_t) : nodes[id][11]);
						} else {
							img_w = img_h * icon_ar;
						}

						if (Icon.limitsize == "1") {
							if (img_w > icon_w) img_w = icon_w;
							if (img_h > icon_h) img_h = icon_h;
						}

						if (Icon.sizemethod = 'relative to tile' && Icon.keepaspectratio == "1") {
							var img_ar = img_w / img_h;
							if (icon_ar < img_ar) {
								img_w = img_h * icon_ar;
							} else {
								img_h = img_w / icon_ar;
							}
						}

						// calculate horizontal position of target rectangle (x)
						switch (Icon.positionx) { 
							case "Auto":
							case "Center":
							case "Center of Visualization":
							case "Center of left margin":
							case "Center of right margin":{
								img_x = (area_l + area_r - img_w) / 2;
								break;
							}
							case "Left":
							case "Left of Visualization":
							case "Left of left margin":
							case "Left of right margin":{
								img_x = area_l;
								break;
							}
							case "Right":
							case "Right of Visualization":
							case "Right of left margin":
							case "Right of right margin":{
								img_x = area_r - img_w;
								break;
							}
						}

						// calculate vertical position of target rectangle (y)
						switch (Icon.positiony) {
							case "Auto":
							case "Center":
							case "Center of Visualization":
							case "Center of top margin":
							case "Center of bottom margin":{
								img_y = (area_t + area_b - img_h) / 2;
								break;
							}
							case "Top":
							case "Top of Visualization":
							case "Top of top margin":
							case "Top of bottom margin":{
								img_y = area_t;
								break;
							}
							case "Bottom":
							case "Bottom of Visualization":
							case "Bottom of top margin":
							case "Bottom of bottom margin":{
								img_y = area_b - img_h;
								break;
							}
						}

						// draw image
						this.drawPNGImage(graphics[level], icon_url, img_x, img_y, img_w, img_h);
					}
				}
			} //for
		}
	}
};

magnaviewweblive.prototype.drawPNGImage = function(gfx, imgSrc, x, y, w, h) {
	if (!/MSIE (5\.5|6)/.test(navigator.userAgent) || typeof filters == 'unknown') {
		// not IE, just draw it normally
		gfx.drawImage(imgSrc, x, y, w, h);
	} else {
		//use pngfix
		var pngfixurl = ScriptLocation + 'pngfix/' + 'iepngfix.htc';
		
		gfx.htm += '<div style="position:absolute;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'width:' +  w + ';'+
			'height:' + h + ';">'+
			'<img style="display:none;behavior:url(' + pngfixurl + ');" src="' + imgSrc + '" width="' + w + '" height="' + h + '">'+
			'<\/div>';
	}

}

magnaviewweblive.prototype.ChangeFilter = function() {
// this function changes the HTML filter code
	var filtertag = this.elements.filter
	if (filtertag) {
		if (this.viewinfo.filterString != "") {
			filtertag.style.display = "block";
			filtertag.innerHTML = this.viewinfo.filterString;
		} else {
			filtertag.style.display = "none";
		}
	}
}

magnaviewweblive.prototype.pdfdownload = function() {
	window.open(this.createurl({'type':'pdf','table':'false','allviews':'true'}));
}

magnaviewweblive.prototype.createurl = function(urlobj) {
	var x = this.ScriptLocation + 'weblive.asp?';

	//add all parameters specified in call
	for (var i in urlobj) {
		x += (i + "=" + urlobj[i] + "&");
	}

	//add default parameters
	if (this.settings.SessionID)
		x += "ID="+this.settings.SessionID;
	if (this.settings.mv_height && this.settings.mv_height > 0)
		x += "&h="+this.settings.mv_height;
	if (this.settings.mv_width && this.settings.mv_width > 0)
		x += "&w="+this.settings.mv_width;

	//add content-type
	var contenttype = {
						'image'         : 'image/png',
						'nodes'         : 'application/x-javascript',
						'nodesxy'       : 'application/x-javascript',
						'variables'     : 'application/x-javascript',
						'settings'      : 'application/x-javascript',
						'thumbnails'    : 'image/png',
						'groupimage'    : 'image/png',
						'groupthumbnail': 'image/png',
						'pdf'           : 'application/pdf',
						'logoff'        : 'text/html',
						'icons'         : 'image/JPEG',
						'overlayicon' :   'image/JPEG'
	}
	if (urlobj["type"]) {
		x += "&content-type="+contenttype[urlobj["type"]];
	}


	if(!(urlobj["view"])) { //only add view parameter if not existing
		x += "&view="+this.thisview;
	}
	x += "&r="+ ((urlobj["type"] == 'overlayicon') ? 0 : Math.round(Math.random()*999999));
	return x;
}

function checkboxClick(name){
// this function is changing a checkbox filter
	var checkbox = doc.getElementById(name);
	if (checkbox.checked){
		filter(name,true);
	} else {
		filter(name,false);
	}
}

function editboxfilter(obj) {
	window.mv_object.filter(obj.id, 'x' + obj.value);
}

function filter(attribute, value) {
	window.mv_object.filter(attribute, value);
}

magnaviewweblive.prototype.filter = function(attribute, value) {
//  this function changes the image and nodes file after calling a filter expression
	if (can_switch_view){
		var drawtag   = this.elements.drawimage;
		//@//var ImageArea = 'image.asp?view='+thisview+'&id='+SessionID+'&attribute='+attribute+'&value='+value+'&h='+mv_height+'&w='+mv_width+"&r="+Math.round(Math.random()*999999)
		var ImageArea = this.createurl({'type':'image','attribute':attribute,'value':value});
		drawtag.src   = ImageArea;
		this.changeNodes(this.thisview, attribute, value,"", false);

		this.showloadingscreen();
	}
}


//TODO: call object method directly
function FilterListBox(name, bool) {
	window.mv_object.FilterListBox(doc.getElementById(name), bool);
}

magnaviewweblive.prototype.FilterListBox = function(Listbox, checkbox){
	var name=Listbox.id;

// gets a new image and nodes file after a listbox control is changed
	var truevalues	= new Array();
	if (checkbox){
		for (var i = 0 ;i<Listbox.childNodes.length ;i++ ){
				if (Listbox.childNodes[i].checked){
				truevalues[truevalues.length] = Math.round(i/3);
				}
		}
	}else{
		for (var i = 0 ;i<Listbox.childNodes.length ;i++ ){
			if (Listbox.childNodes[i].selected){
				truevalues[truevalues.length] = i;
			}
		}
	}

	if (truevalues == ''){
		truevalues = 'false';
	}

	var drawtag   = this.elements.drawimage
	//@//var ImageArea ='image.asp?view='+thisview+'&id='+SessionID+'&h='+mv_height+'&w='+mv_width+'&attribute='+name+'&Listbox='+truevalues+"&r="+Math.round(Math.random()*999999);
	var ImageArea = this.createurl({'type':'image','attribute':name,'Listbox':truevalues});
	drawtag.src = ImageArea;
	this.changeNodes(this.thisview,name,truevalues,"",true);
	this.showloadingscreen();
}

function itemselect(name, what) {
	var items = doc.getElementById(name);
	var total = items.childNodes.length;
	var value;

	if (what == "all") value = true;
	else if (what == "none") value = false;
	else if (what == "toggle") {
		var count = 0;
		for (var i = 0 ;i<total ;i++ ){
			count += items.childNodes[i].selected 
		}
		value = !(Boolean(Math.round(count/total)));
	}
	else return;

	for (var i = 0 ;i<total ;i++ ){
		items.childNodes[i].selected = value
	}

	window.mv_object.FilterListBox(items, false);
}

magnaviewweblive.prototype.initcalender = function() {
	if (this.elements.calender) {
		this.elements.calender.style.display = 'none';
		return;
	}
	var divtable = document.createElement('div');
	divtable.position = 'absolute'

	var caltable = document.createElement('table');
	caltable.className = 'ds_box';
	caltable.cellpadding = 0;
	caltable.cellscpacing = 0;
	caltable.id = 'ds_conclass';
	caltable.style.display = 'none';
	caltable.style.position = 'absolute';

	var caltr = document.createElement('tr');
	var caltd = document.createElement('td');
	caltd.id = 'ds_calclass';

	caltr.appendChild(caltd);
	caltable.appendChild(caltr);

	//this is needed for IE, it won't render dynamically generated tables otherwise
	if (caltable.outerHTML)
		divtable.innerHTML = caltable.outerHTML;
	else
		divtable.appendChild(caltable);

	document.body.appendChild(divtable);

	var script = document.createElement('script');
	script.src = this.ScriptLocation+'dateselect.js';
	script.type  = 'text/javascript';
	document.getElementsByTagName("head")[0].appendChild(script);
	this.elements.calender = caltable;
}

magnaviewweblive.prototype.unload = function() {
	if (this.settings.pagetype != 2) return;
	var xmlhttp = init_xmlhttp();
	if (xmlhttp) {
		xmlhttp.open("GET",this.createurl({'type':'logoff'}));
		xmlhttp.send(null);
	}
};

magnaviewweblive.prototype.changeLegend = function() {
	var legend_doc = mvobj.elements.legend;  
	if (legend_doc !=null && legend_doc != null){
		legend_doc.innerHTML = legend_content;
	}
	if(typeof(changeLegendCallBack)=='function') {
		changeLegendCallBack();
	}
}

magnaviewweblive.prototype.changeComment = function() {
	var comment_doc = mvobj.elements.comment; 
	if (comment_doc != null && comment_doc != null){
		comment_doc.innerHTML = comment_content;
	}
	if(typeof(changeCommentCallBack)=='function') {
		changeCommentCallBack();
	}
}

function findPosX(obj){
	var curleft = 0;
	if (obj.offsetParent){
		while (obj.offsetParent){
			curleft += obj.offsetLeft;
			obj = obj.offsetParent;
		}
	} else if (obj.x){
		curleft += obj.x;
	}
	return curleft;
};

function findPosY(obj){
	var curtop = 0;
	if (obj.offsetParent){
		while (obj.offsetParent){
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	} else if (obj.y){
		curtop += obj.y;
	}
	return curtop;
};

function disable(obj) {
/*	this function disables an element referenced by with 'id', i.e.
	the opacity is decreased */
	if (obj){
		if (doc.all) { //Explorer
			obj.style.filter = "alpha(opacity=30)";
		}
		obj.style.opacity = "0.3";
	}
};

function enable(obj) {
/*	this function disables an element referenced by with 'id', i.e.
	the opacity is increased */
	if (obj){
		if (doc.all) { //Explorer
			obj.style.filter = "alpha(opacity=100)";
		}
		obj.style.opacity = "1";
	}
};

function setenabled(obj, state) {
	if(obj) {
		if (state)
			enable(obj);
		else
			disable(obj);
	}
}

function show(obj) {
	if(obj && obj.style) obj.style.display='';
}
function hide(obj) {
	if(obj && obj.style) obj.style.display='none';
}

function TPoint(x,y) {
/*	this function creates a TPoint object */
	this.x = x;
	this.y = y;
};

function TRect(left, top, right, bottom) {
/*	this function creates a TRect object */
	this.left   = left;
	this.top    = top;
	this.right  = right;
	this.bottom = bottom;
};

function PyramidTopTransformUp(x,y,r){
	var f, cx, cy;
	var t = new TPoint;
	t.x   = (r.left + r.right)/2;
	t.y   = y;
	if(r.top==r.bottom){
		return t;
	}
	if(r.top==y){
		t.x = x;
		return t;
	}
	cx  = (r.right-r.left)/2;
	cy  = (r.bottom-r.top)/2;
	f   = cy * 2 / (y-r.top);
	t.x = f * (x-r.left-cx) + cx + r.left;
	t.y = (y-r.top)/(cy*2);
	t.y = t.y * t.y;
	t.y = t.y * cy * 2 + r.top;
	t.y = Math.min(y, t.y);
	return t;
};

function PyramidTopTransform(x,y,r){
	var t = new TPoint;
	var f, cx, cy;
	t.x = (r.left + r.right)/2;
	t.y = y;
	if(r.top==r.bottom){
		return t;
	}
	if(r.top==y){
		return t;
	}
	cx = (r.right-r.left)/2;
	cy = (r.bottom-r.top)/2;
	if(y<r.top){
		t.y = 0 - (Math.sqrt(-2*cy*(y-r.top)) + r.top);
	} else {
		t.y = Math.sqrt(2*cy*(y-r.top))+r.top;
	}
	f   = cy*2/(t.y-r.top);
	t.x = cx + (x-cx-r.left)/f+r.left;
	return t;
};

function PolarMapXY2TreemapXYrelXtoR(x,y,tx,ty,cx,cy,lx,ly){
	var a, r, mi, ma;
	var temp = new TPoint;
	if(x==0 && y<0) {x=1;}
	r = Math.sqrt(Math.pow(y,2)+Math.pow(x,2));
	if(x==0){
		if(y>0){
			a = Math.PI;
		}else{
			a = 2*Math.PI;
		}
	}else{
		if(x>0){
			a = Math.atan(y/x) + Math.PI/2;
		}else{
			a = Math.atan(y/x) + Math.PI/2 + Math.PI;
		}
	}
	if(lx<ly){
		mi = lx;
		ma=lx;
	}else{
		mi = ly;
		ma = lx;
	}
	if(x==0 && y<0){
		r  = Math.pow(r/mi,2)*ma;
		ty = 0-ly;
		tx = r*2-lx;
	}else{
		if(mi==0){mi=1;}
		r  = Math.pow(r/mi,2)*ma;
		ty = (cy)*a/Math.PI-ly;
		tx = r*2-lx;
	}
	temp.x = tx;
	temp.y = ty;
	return temp;
};


function TreemapXY2PolarMapXYRectXtoR(x,y,r){
	var cx,cy,mi,ma;
	var t = new TPoint;
	cx = (r.right - r.left)/2;
	cy = (r.bottom - r.top)/2;
	x  = x - r.left;
	y  = y - r.top;
	if (cx<cy) {
		mi = cx;
		ma = cx;
	} else {
		mi = cy;
		ma = cx;
	}
	if (ma == 0) ma = 1;
	cy==0 ? a = 0 : a=(y/(2*cy))*(2*Math.PI);
	ma==0 ? radius = 0 : radius=Math.sqrt(Math.abs(x/2)/ma)*mi;
	x   = radius*Math.sin(a);
	y   = radius*Math.cos(a);
	t.x = r.left + x + cx;
	t.y = r.top - y + cy;
	return t;
};


function PolarMapXY2TreemapXYrelRextXtoR(x,y,r){
	var cx,cy,inx,iny;
	var inv = new TPoint;
	var t = new TPoint;
	inv.x = x;
	inv.y = y;
	cx  = (r.right-r.left)/2;
	cy  = (r.bottom-r.top)/2;
	x   = x-r.left-cx;
	y   = y-r.top-cy;
	inv = PolarMapXY2TreemapXYrelXtoR(x,y,inv.x,inv.y,cx,cy,cx,cy);
	t.x = inv.x+cx+r.left;
	t.y = inv.y+cy+r.top;
	return t;
};

function Midpoint(a, b){
	var tmppoint = new TPoint;
	tmppoint.x = (a.x + b.x) / 2;
	tmppoint.y = (a.y + b.y) / 2;
	return tmppoint;
};

function PointDist(a, b){
	return Math.pow(b.x - a.x,2) + Math.pow(b.y - a.y,2);
};

function init_xmlhttp() {
/*	this function will setup xmlhttprequest.  */
	if (typeof window.XMLHttpRequest != 'undefined') { //w3c
		return new XMLHttpRequest();
	} else if (typeof window.ActiveXObject != 'undefined') { //IE
		return new ActiveXObject("Msxml2.XMLHTTP");
	} else return false;
};

function attachEventFunction(obj, evType, fn) {
	if (obj.addEventListener) {
		obj.addEventListener(evType, fn, false);
		return true;
	} else if (obj.attachEvent) {
		var r = obj.attachEvent("on"+evType, fn);
		return r;
	} else {
		return false;
	}
}

