var wnVisualization =
{
	browser: '',
	boxes: new Array(),
	box_tag: 'span',
	box_class: 'wn_visualization',


	/*runs wnVisualization at the right time*/
	init: function()
	{
		oldFunc = window["onload"];
		window.onload = function(args)
		{
			wnVisualization.run();
			if (oldFunc!=undefined && oldFunc!=null)
			{
				return oldFunc(args);
			}

		}
	},

	run: function()
	{
		boxes = document.getElementsByTagName(this.box_tag);
		boxesCount = 0;
		for (i=0;i<boxes.length;i++)
		{
            box = boxes[i];
        	if (box.className==this.box_class)
        	{            	boxesCount++;
        	}
        }

		if (boxesCount>0)
		{
			this.determine_browser();			this.gatherBoxes();	    	this.createTopLayer();
	    	this.createControls();
    	}
	},


	gatherBoxes: function()
	{
		boxes = document.getElementsByTagName(this.box_tag);

		for (i=0;i<boxes.length;i++)
		{
            box = boxes[i];        	if (box.className==this.box_class)
        	{            	//START: float and width fix goes here
            	//walk through all direct children of element and apply the last defined float that was foubd
            	//the outer box width is 100% by default but later it is reduced to the combined width of children if it does not exceed 100%
            	//this is neede to prevent box from stretch to far if children are on the same line
            	children = box.childNodes;
            	lastFloat = '';
            	lastAlign = '';
            	lastMargin = new Array;
            	widthCombined = new Array;
            	realWidthCombined = new Array;
           		for (j=0;j<children.length;j++)
           		{            		child = children[j];
            		if (child.innerHTML!=undefined)
            		{
            			if (this.browser=='FF') float = window.getComputedStyle(child, null).cssFloat;
            			else float = child.currentStyle.styleFloat;            			if (float=='left' || float=='right')
            			{                        	lastFloat = float;
                        	//get margins that we'll use later for float margin fix
                        	if (this.browser=='FF') lastMargin = new Array(window.getComputedStyle(child, null).marginTop, window.getComputedStyle(child, null).marginRight, window.getComputedStyle(child, null).marginBottom, window.getComputedStyle(child, null).marginLeft);
                        	else lastMargin = new Array(child.currentStyle.marginTop, child.currentStyle.marginRight, child.currentStyle.marginBottom, child.currentStyle.marginLeft);
            			}

						//this is usefull for orange_blossom with its tables aligned in HTML
            			if (child.align=='center' || child.align=='left' || child.align=='right')
            			{            				lastAlign = child.align;
            			}

            			//we'll need this for width fix later
            			width = parseFloat(child.offsetWidth);
            			realWidthCombined.push(width);
                        if (this.browser=='FF')
                        {                        	widthCombined.push(window.getComputedStyle(child, null).width);
                        }
                        else
                        {
                        	widthCombined.push(child.currentStyle.width);
                        }
					}
           		}
           		//float fix
          		if (lastFloat=='left' || lastFloat=='right')
           		{                  	if (this.browser=='FF')
                  	{
	                  	box.style.cssFloat = lastFloat;
	                  	//margin fix for floated boxes
	                	if (parseFloat(lastMargin[0])!=0) box.style.marginTop = lastMargin[0];
	                	if (parseFloat(lastMargin[1])!=0) box.style.marginRight = lastMargin[1];
	                	if (parseFloat(lastMargin[2])!=0) box.style.marginBottom = lastMargin[2];
	                	if (parseFloat(lastMargin[3])!=0) box.style.marginLeft = lastMargin[3];
                  	}
                  	else
                  	{
	                  	box.style.styleFloat = lastFloat;
                  	}
         		}

                //width fix
                currentWidth = box.offsetWidth;
                sumWidth = 0;
                //sum up widths of children
                for(g=0;g<realWidthCombined.length;g++)
                {
                  	width = realWidthCombined[g];
                   	sumWidth += width;
                }
                if (wnVisualization.browser=='IE' && widthCombined.length==1 && widthCombined[0]=='auto') //IE specific fix: if one of the inner boxes has auto width, our outer box should have auto width too (this is used for webboxes)
                {                	box.style.width = 'auto';
                }
                else if (sumWidth<currentWidth) //if total children width does not exceed 100% use it instead
                {
                	if (lastAlign=='' && sumWidth>0) //otherwise we'll break orange_blossom
                	{
                   		box.style.width = sumWidth+'px';
                   	}
                }
            	//END: float and width fix ends here

				//CSS zoom is IE hasLayout trigger that lets us gather more accurate coordinates for floated elements
				box.style.zoom = '1';
            	coordinates = this.getElemCoordinates(box);
				box.style.zoom = 'normal';

            	newBox = new Array();
            	newBox['elementId'] = box.id;
            	newBox['elementTop'] = coordinates[0];
            	newBox['elementLeft'] = coordinates[1];
            	newBox['elementHeight'] = box.offsetHeight;
            	newBox['elementWidth'] = box.offsetWidth;
            	newBox['filename'] = box.title;

            	this.boxes.push(newBox);
       		}
		}
	},


	getElemCoordinates: function(obj)
	{    	curleft = curtop = 0;
    	if (obj.offsetParent) {
			do {
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
			} while (obj = obj.offsetParent);
         }

         return [curtop, curleft];
	},


	createTopLayer: function()
	{    	for (i=0;i<this.boxes.length;i++)
    	{
    		box = this.boxes[i];    		upperDiv = document.createElement('div');
    		upperDiv.visualization_filename = box['filename'];
    		upperDiv.id = box['elementId'];
    		upperDiv.style.position = 'absolute';
    		upperDiv.style.top = box['elementTop']+'px';
    		upperDiv.style.left = box['elementLeft']+'px';
    		/*this is supposed to be a fix for empty places (like main_include.html) but I comment this out as for now and will see if there is any better fix later
    		upper_div.style.height = (box['elementHeight']<25?'25':box['elementHeight']);
    		upper_div.style.width = (box['elementWidth']<150?'150':box['elementWidth']);*/
    		upperDiv.style.height = box['elementHeight']+'px';
    		upperDiv.style.width = box['elementWidth']+'px';
    		upperDiv.style.zIndex = '99';
    		upperDiv.style.border = '1px solid black';
    		upperDiv.style.display = 'none';
    		upperDiv.className = this.box_class;
    		upperDiv.onmouseover = function()
    								{
    									visualizationBoxMethods.mouseOver(this);
    								};
    		upperDiv.onmouseout = function()
    							   {
    									visualizationBoxMethods.mouseOut(this);
    							   };
    		//this is a temporary fix
    		//the boxes should be cleaned up for all browsers but if they are left for IE the overall thing becomes a little more accurate
    		//so untill some better solution is found, the following IF should not be removed
            if (this.browser=='FF') this.removeBox(box);
            else box.id = box.id+'_disabled';
    		document.body.appendChild(upperDiv);
    	}
	},


	removeBox: function(arr)
	{
		element = document.getElementById(arr['elementId']);
		txtNode = document.createTextNode("tmp_dummy_text_node");
		element.parentNode.insertBefore(txtNode, element);
		element.parentNode.innerHTML = element.parentNode.innerHTML.replace(/tmp_dummy_text_node/, element.innerHTML);
		element = document.getElementById(arr['elementId']);
		removedNode = element.parentNode.removeChild(element);
	},


	createControls: function()
	{
    	controlsImg = document.createElement('img');
    	controlsImg.src = 'images/icon_search.png';
  		controlsImg.style.zIndex = '100';
   		controlsImg.style.position = 'absolute';
   		controlsImg.style.top = '0';
  		controlsImg.style.left = '0';
   		controlsImg.style.margin = '3px';
    	controlsA = document.createElement('a');
    	controlsA.onmouseover = function()
    							{    								this.style.cursor='pointer';
    							};
    	controlsA.onmouseout = function()
    						   {    						   		this.style.cursor='default';
    						   };
    	controlsA.onclick = function()
    						{					    		wnVisualization.showUpperLayer(this);
					    	};
    	controlsA.appendChild(controlsImg);
    	document.body.appendChild(controlsA);
	},


	hideUpperLayer: function(calledBy)
	{
		boxes = document.getElementsByTagName("div");
		for (i=0;i<boxes.length;i++)
		{
            box = boxes[i];
        	if (box.className==this.box_class)
        	{
            	box.style.display = 'none';
        	}
		}
    	calledBy.onclick = function(){wnVisualization.showUpperLayer(this)};
	},


	showUpperLayer: function(calledBy)
	{
		boxes = document.getElementsByTagName("div");
		for (i=0;i<boxes.length;i++)
		{
            box = boxes[i];
        	if (box.className==this.box_class)
        	{
            	box.style.display = 'block';
        	}
		}
    	calledBy.onclick = function(){wnVisualization.hideUpperLayer(this)};
	},


	determine_browser: function()
	{    	if (window.getComputedStyle)
    	{    		this.browser = 'FF';
    	}
    	else
    	{        	this.browser = 'IE';
    	}
	}


};




var visualizationBoxMethods =
{
	templateNameBoxId: 'templateNameBoxId',


	mouseOver: function(obj)
	{
    	obj.style.borderWidth = '2px';
    	obj.style.borderColor = '#840586';
    	obj.style.backgroundColor = '#EAEAEA';
    	obj.style.opacity = '0.4';
    	obj.style.filter = 'alpha(opacity=40)';
    	obj.style.backgroundImage = "none";
    	visualizationBoxMethods.showTemplateNameBox(obj);
	},


	mouseOut: function(obj)
	{
    	obj.style.borderWidth = '1px';
    	obj.style.borderColor = '#000000';
    	obj.style.backgroundColor = 'transparent';
    	obj.style.backgroundImage = "url('images/background_visualization.gif')";
    	obj.style.opacity = '1.0';
    	obj.style.filter = 'alpha(opacity=100)';
    	visualizationBoxMethods.hideTemplateNameBox(obj);
	},


	createTemplateNameBox: function(obj)
	{
		nameDiv = document.createElement('div');
		nameDiv.id = visualizationBoxMethods.templateNameBoxId;
		nameDiv.style.display = 'none';
		nameDiv.style.zIndex = '99';
		nameDiv.style.position = 'absolute';
		nameDiv.style.width = 'auto';
		nameDiv.style.height = 'auto';
    	nameDiv.style.backgroundColor = '#840586';
    	nameDiv.style.color = '#FFFFFF';
		nameDiv.style.padding = '2px 2px 2px 2px';
		document.body.appendChild(nameDiv);
		return nameDiv;
	},


	showTemplateNameBox: function(obj)
	{
    	nameBox = document.getElementById(visualizationBoxMethods.templateNameBoxId);
    	if (nameBox==null)
    	{        	nameBox = visualizationBoxMethods.createTemplateNameBox();
    	}
    	nameBox.style.display = 'block';
    	nameBox.innerHTML = obj.visualization_filename;
    	boxTop = parseFloat(obj.style.top)-nameBox.offsetHeight;
    	boxLeft = parseFloat(obj.style.left);

    	if (boxTop<0) boxTop=0; //prevent moving out of the screen area
    	if (boxLeft<30 && boxTop<20) boxLeft=33; //prevent overflowing by controls image
    	nameBox.style.top = boxTop+'px';
    	nameBox.style.left = boxLeft+'px';
	},


	hideTemplateNameBox: function(obj)
	{
    	nameBox = document.getElementById(visualizationBoxMethods.templateNameBoxId);
    	if (nameBox==null)
    	{
        	nameBox = visualizationBoxMethods.createTemplateNameBox();
    	}
    	nameBox.style.display = 'none';
	}
};