function displayDojoMap(id, lati, longi)
{
	require(["dojo/ready", "dojox/geo/openlayers/Map", "dojox/geo/openlayers/Layer",
		 "dojox/geo/openlayers/WidgetFeature", "dijit/layout/ContentPane"], function(ready, Map,Layer, WidgetFeature, ContentPane){
			ready(function(){
				var map = new Map(id, {
					baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
					baseLayerUrl: "openlayers/proxy.jsp?r=mapnik&z=\${z}&x=\${x}&y=\${y}"
				});
				
				var ny = {
			      latitude : lati,
			      longitude : longi
			    };

				var ind= new ContentPane({
			    	href: 'images/house.html',
			    	style:'width:16px;height:16px;'
			    })
			    
				var descr = {
				      longitude : ny.longitude,
				      latitude : ny.latitude,
				      widget : ind,
				      width : 16,
				      height : 16
			    };
			    feature = new WidgetFeature(descr);
			
			    layer = new Layer();
			    layer.addFeature(feature);
			    map.addLayer(layer);			    
			    
			    // fit to New York with 0.1 degrees extent
			    map.fitTo({
			      position : [ ny.longitude, ny.latitude ],
			      extent : 0.0005
			    });
			});
		});			
			
		
}

function displayProgressBar(id, barvalue, width)
{
	require(["dojo/ready", "dijit/ProgressBar"], function(ready, ProgressBar){
		ready(function(){
			var bar = new ProgressBar({
				style:"width:100px",
				maximum:100,
				minimum:0,
				progress:barvalue
			},id);
			bar.startup();
				
		});
	});
}


function displayTooltip(id, p_href)
{
	require(["dojo/ready", "dojox/widget/DynamicTooltip"], function(ready, DynamicTooltip){
		ready(function(){
			var tt = new DynamicTooltip({
				label:'Info box',
				href: p_href,
				showDelay: 50,
				position: ['before','below','after'],
				connectId: [id]
			});
			bar.startup();
				
		});
	});
}


function displayTooltipContent(id, p_content)
{
	require(["dojo/domReady!", "dijit/Tooltip", "dojo/on", "dojo/dom", "dojo/mouse"], function(ready, Tooltip, on, dom, mouse){
		var node = dom.byId(id);
		Tooltip.show(p_content, node);
		on.once(node, mouse.leave, function(){
			Tooltip.hide(node);
		});
	});
}

function initMenuBox(){
	//console.debug('call: initMenuBox');
	var clickedItem=getCookie('fCurrentMenuboxItem');
	if (clickedItem && clickedItem!="null")
	{
		clearMenuBox();	
		require(["dojo/dom-class","dojo/dom"],
			function(domClass,dom) {
				
				if(dom.byId(clickedItem)) {
					domClass.add(dom.byId(clickedItem),'active');
					if(dom.byId(clickedItem).getAttribute('sub')) {
						if(dom.byId("menumore")) {
							dom.byId("menumore").innerHTML = '&#160;(' + dom.byId(clickedItem).textContent + ')';
							domClass.add(dom.byId("menumore").parentNode.parentNode,'active');
						}
					}
				}
			}
		);
	}
}

function resetMenuBox()
{
	setCookie('fCurrentMenuboxItem',null,null);
	//console.debug('call: resetMenuBox');
}


function menuBoxClick(e)
{
	require(["dojo/query","dojo/dom","dojo/dom-class"],
		function(query,dom,domClass) {
			query('.menuBox li').forEach(function(node,index,arr){
				domClass.remove(node,'active');
			});
			if(dom.byId("menumore")) {
				dom.byId("menumore").innerHTML = "";
			}
			
			if(e.parentNode.getAttribute('sub')) {
				if(dom.byId("menumore")) {
					dom.byId("menumore").innerHTML = '&#160;(' + e.textContent + ')';
					domClass.add(dom.byId("menumore").parentNode.parentNode,'active');
				}
			}
			domClass.add(e.parentNode,'active');
			setCookie('fCurrentMenuboxItem',e.parentNode.id,null);
		});
			
}

function menuBoxSet(id,tab) {
	require(["dojo/query","dojo/dom-class","dojo/dom"],
		function(query,domClass,dom) {
			
			query('.menuBox li').forEach(function(node,index,arr){
				if(node != undefined && dom.byId(node.id)) {
					domClass.remove(node,'active');
				}
			});
			if(dom.byId("menumore")) {
				dom.byId("menumore").innerHTML = "";
			}
			
			
			if(dom.byId(id)) {
				if(dom.byId(id).getAttribute('sub')) {
					if(dom.byId("menumore")) {
						dom.byId("menumore").innerHTML = '&#160;(' + dom.byId(id).textContent + ')';
						domClass.add(dom.byId("menumore").parentNode.parentNode,'active');
					}
				}
				domClass.add(dom.byId(id),'active');
			}
			if (tab!=null) {
				setNavBarActive(tab);
			}
		});
}

function clearMenuBox()
{
		require(["dojo/query","dojo/dom","dojo/dom-class"],
			function(query,dom,domClass) {
				query('.menuBox li').forEach(function(node,index,arr){
					domClass.remove(node,'active');
				});
				if(dom.byId("menumore")) {
					dom.byId("menumore").innerHTML = "";
				}
			});
				
}

function showInfo(e,id,link)
{
	require(["dojo/_base/xhr","dojo/dom-construct"],
		function(xhr,domConstruct){
			xhr.get({
				url:'jsp/proxy.jsp?url='+ escape(link),
				handleAs:'text',
				load: function(result){
					//console.debug(result);
					//console.debug(id);
					domConstruct.place('<div class="tooltipContent">' + result+'<img alt="" src="images/icons/pointer.png" /></div>',id,'replace');					
				}
			});
		});
}

function showTooltip(a,b){
}

function hideTooltip(){};


function showTabContainer(id)
{
	require(["dojo/ready", "dijit/layout/TabContainer", "dijit/layout/ContentPane","dojo/_base/array","dojo/dom"],
		function(ready, TabContainer, ContentPane,array,dom){
    		ready(function(){
    			var cNode=dom.byId(id);
				var maxHeight=0;
    			
    			array.forEach(dom.byId(id).childNodes,function(item){
					console.log("tab :" + item.id);
					if (maxHeight < item.clientHeight) {
						maxHeight = item.clientHeight;
					}
			        var cp1 = new ContentPane({
			             //class: "chytabs",
			             title: item.title
			             
			        },item.id);
//			        tc.addChild(cp1);
    				
    			});
    			
    			var tc = new TabContainer({
		            style: "height: " + (maxHeight + 80) +  "px; width: 100%;"
		        }, id);
		        
		        tc.startup();
   		    });
	});
}	

function setNavBarActive(id) {
	require(["dojo/query","dojo/dom-class"], function(query,domClass){
	  query(".nav .active").forEach(function(node){
	  				domClass.remove(node,"active");
	  			});
	  domClass.add(id,"active");
	});	
}

function togglecheckboxes(elementname, selectiontype) {
	require(["dojo/query!css3"], function(qccs3){
		var nl;
		switch(selectiontype) {
			case "endswith":
				nl = qccs3("input[name$=" + elementname+"]");
				break;
			case "startswith":
				nl = qccs3("input[name^=" + elementname+"]");
				break;
			default:
				nl = qccs3("input[name=" + elementname+"]");
		}
		nl.forEach(function(node){
	  		if(node.checked) { node.checked = false; } else { node.checked=true;}
		});
		
	});		
}

function checkall(elementname, selectiontype) {
	require(["dojo/query!css3"], function(qccs3){
		var nl;
		switch(selectiontype) {
			case "endswith":
				nl = qccs3("input[name$=" + elementname+"]");
				break;
			case "startswith":
				nl = qccs3("input[name^=" + elementname+"]");
				break;
			default:
				nl = qccs3("input[name=" + elementname+"]");
		}
		nl.forEach(function(node){
	  		node.checked = true;
		});
		
	});		
}

function uncheckall(elementname, selectiontype) {
	require(["dojo/query!css3"], function(qccs3){
		var nl;
		switch(selectiontype) {
			case "endswith":
				nl = qccs3("input[name$=" + elementname+"]");
				break;
			case "startswith":
				nl = qccs3("input[name^=" + elementname+"]");
				break;
			default:
				nl = qccs3("input[name=" + elementname+"]");
		}
		nl.forEach(function(node){
	  		node.checked = false;
		});
		
	});		
}

function toggleDisplay(id)
{
	require(["dojo/dom-class"], function(domClass){
		if (domClass.contains(id,"open"))
		{
			domClass.remove(id,"open");
		} else {
			domClass.add(id,"open");		
		}
	});	
	
}
function setComboxTarget(id,url)
{
	require(["dijit/registry"], function(reg){
		var obj=reg.byId(id);
		if (obj) {
			obj.store.target=parseStr(url,1);
			console.log("store changed",id,obj.store.target);
			obj.set("value",null);
		}
		
	});
}

function toggle(e,cssclass){
	require(["dojo/query","dojo/dom-style","dojo/dom-class"],function(query,style,domClass){
		domClass.toggle(e,cssclass);
	});
	
}

function togglerow2(e,cssclass,selectiontype){
	
	require(["dojo/query!css3","dojo/dom-class"], function(qccs3,domClass){
		var nl;
		switch(selectiontype) {
			case "endswith":
				nl = qccs3("*[id$=" + e+"]");
				break;
			case "startswith":
				nl = qccs3("*[id^=" + e+"]");
				break;
			default:
			
				nl = qccs3("*[id=" + e+"]");
		}
			
		nl.forEach(function(node){
			domClass.toggle(node.id, cssclass);
		});
		
	});	
	
}

function showrow(e,prefix,cssclass) {
	require(["dojo/query!css3","dojo/dom-class"], function(qccs3,domClass){
		var nl = qccs3("tr[id^=" + prefix+"]");
		var added = false;
		var lastidx = nl.length-1;
		nl.forEach(function(node,index){
			if(!added && domClass.contains(node, 'hidden')) {
				if(index < lastidx) {
					added = true;
				}
				domClass.remove(node.id, 'hidden');
			}
		});
		
		if(!added) {
			//Reached without return, disable button
			domClass.add(e, 'hidden');
		}
		
	});	
}

function displayEditor(e,v_disabled, val) {
	require([
		"dojo/ready",
		"dijit/Editor",
		"dijit/_editor/plugins/LinkDialog",
		"dijit/_editor/plugins/AlwaysShowToolbar",
		"dojox/editor/plugins/NormalizeStyle",
		"dojox/html/entities",
		"dojo/domReady!"
		],function(ready,Editor,LinkDialog,AlwaysShowToolbar){
			ready(function(){
					
				if (v_disabled) {
					var edt = new Editor({
						disabled : v_disabled,
						height: '250px'
						}, 'edt_'+e);
					edt.startup();
					edt.onChange=function(){
						//dojo.byId(e).value=dijit.byId('edt_'+e).get("value");
						dojo.byId(e).value=cleanHTML(dijit.byId('edt_'+e).get("value"));
					};
				}
				else {
					var edt = new Editor({
						disabled : v_disabled,
						height: '250px',
			        		extraPlugins:["createLink", "insertImage","normalizestyle",AlwaysShowToolbar]
						}, 'edt_'+e);
					edt.startup();
					edt.onChange=function(){
						dojo.byId(e).value=cleanHTML(dijit.byId('edt_'+e).get("value"));
					};
				}
				console.log('set value to ' + dojox.html.entities.decode(dojo.byId(e).value));
				edt.setValue(dojox.html.entities.decode(dojo.byId(e).value));
				//dojo.byId(e).value=cleanHTML(edt.get("value"));	
			});
	});
}

function cleanHTML(content) {
	
	var res = content;
	
	
	res = res.replace(/(<meta\s*[^>]*\s*>)|(<\s*link\s* href="file:[^>]*\s*>)|(<\/?\s*\w+:[^>]*\s*>)/gi, "");
	res = res.replace(/(?:<style([^>]*)>([\s\S]*?)<\/style>|<link\s+(?=[^>]*rel=['"]?stylesheet)([^>]*?href=(['"])([^>]*?)\4[^>\/]*)\/?>)/gi, "");
	res = res.replace(/(class="Mso[^"]*")|(<!--(.|\s){1,}?-->)/gi, "");
	res = res.replace(/(<p[^>]*>\s*(\&nbsp;|\u00A0)*\s*<\/p[^>]*>)|(<p[^>]*>\s*<font[^>]*>\s*(\&nbsp;|\u00A0)*\s*<\/\s*font\s*>\s<\/p[^>]*>)/ig, "");
	res = res.replace(/(style="[^"]*mso-[^;][^"]*")|(style="margin:\s*[^;"]*;")/gi, "");
	res = res.replace(/(<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>)|(<\s*script\b([^<>]|\s)*>?)|(<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>)/ig, "");
	res = res.replace("v:shapes", "vshapes");
	
	
	return res;	
}


function displayHighCharts(container, definition, dataurl) {
	var graph = null;
	var graphData = null;
	var stock = true;
	require(
		[ "dojo/json","dojo/request/xhr", "dojo/promise/all", "dojo/Deferred", "dojo/_base/lang","hc/js/highstock","dojo/domReady!" ],
		function(JSON,xhr,all,Deffered,lang) {
			var promiseGraphDefinition = xhr(definition, {handleAs : "json"});
			var promiseGraphData = xhr(dataurl, {handleAs : "json"});

/*			graph.series = graphData.series;
			if (graph.chart == undefined) {
				graph.chart = {};
				graph.chart.type = 'line';
			}*/
			
			// Merge data and graph definition
			console.log("before extend");
			all([promiseGraphDefinition, promiseGraphData]).then(function(results){
				graph = results[0];
				graphData = results[1];
				
				console.log("graph", graph);
				console.log("graphData", graphData);
				if (graph.stock != undefined && graph.stock.enabled != undefined) {
					stock = graph.stock.enabled;
				}
		          	
	          	//graph.xAxis = lang.mixin(graph.xAxis, graphData.xAxis);
	          	//graph = lang.mixin(graph, graphData);
	          	deepMixin(graph, graphData);
	          	//graph.series = graphData.series; PART of DEEP MIXIN
	          	
	          	// enabling JavaScript for formatting
				for (var i = 0; i < graph.yAxis.length; i++) {
					if((graph.yAxis[i].labels != undefined) && (graph.yAxis[i].labels.formatterCode != undefined)) {
						graph.yAxis[i].labels.formatter = eval('(' + graph.yAxis[i].labels.formatterCode + ')');
					}
					if((graph.yAxis[i].stackLabels != undefined) && (graph.yAxis[i].stackLabels.formatterCode != undefined)) {
						console.log ('eval .stackLabels.formatterCode' + graph.yAxis[i].stackLabels.formatterCode);
						graph.yAxis[i].stackLabels.formatter = eval('(' + graph.yAxis[i].stackLabels.formatterCode + ')');
					}
					if(	(graph.plotOptions != undefined) && 
						(graph.plotOptions.column != undefined) && 
						(graph.plotOptions.column.dataLabels != undefined) && 
						(graph.plotOptions.column.dataLabels.formatterCode != undefined)) {
							console.log ('eval .raph.plotOptions.column.dataLabels.formatter ' + graph.plotOptions.column.dataLabels.formatterCode);
						graph.plotOptions.column.dataLabels.formatter = eval('(' + graph.plotOptions.column.dataLabels.formatterCode + ')');
					}
					if(	(graph.plotOptions != undefined) && 
						(graph.plotOptions.bar != undefined) && 
						(graph.plotOptions.bar.dataLabels != undefined) && 
						(graph.plotOptions.bar.dataLabels.formatterCode != undefined)) {
							console.log ('eval .raph.plotOptions.bar.dataLabels.formatter ' + graph.plotOptions.bar.dataLabels.formatterCode);
						graph.plotOptions.bar.dataLabels.formatter = eval('(' + graph.plotOptions.bar.dataLabels.formatterCode + ')');
					}
				}
				
				for(var j = 0; j < graph.series.length; j++){
					if(typeof graph.series[j].data == 'string'){
						graph.series[j].data = eval(graph.series[j].data);
					}
				}
			
	          	console.log("graph after merge", graph);
				
				graph.chart.renderTo = container;
				
				console.log('Final graph as', graph, stock);
				
				var jsonstr = JSON.stringify(graph);
				
				console.log('json string ', JSON.stringify(JSON.parse(jsonstr)));
				if(stock) {
					new Highcharts.StockChart(graph);
				}
				else {
					new Highcharts.Chart(graph);
				}
			});
	});
}

function deepMixin(destination, source) {
    for (var prop in source) {
        if (source.hasOwnProperty(prop)) {
       		if (destination.hasOwnProperty(prop)) {
       			// both have the same property
	        	if(typeof source[prop] === 'object') {
	        		// multiple values to copy
	        		deepMixin(destination[prop], source[prop]);
	        	} else {
	            	destination[prop] = source[prop];
	        	}
       		} else {
       			destination[prop] = source[prop];
       		}
        }
    }
}

//generate array with tendline values for highchart
function highchartRegressionData(data){
		console.log("calculating regression data ");
		console.log(data);
		var yData = Array();
		var stopTrim = false;
		//trim empty data from end from data for trendline
		for(var i = data.length-1; i>=0; i--){
			if(stopTrim || data[i]!='0'){
				yData[i] = data[i];
				stopTrim = true;
			}
		}
		var xData = Array();
		for(var i = 0; i<yData.length; i++){
			xData[i] = i+1;
		}
		//calc trendline
		var leastSquaresCoeff = leastSquares(xData, yData);
		
		//generate array with trendline data for all x values
		var returnData=Array();
		for(var i = 1; i < data.length+1; i++){
			returnData[i-1] = leastSquaresCoeff[0] * i + leastSquaresCoeff[1];
		}		
		return returnData;
}
//trendline formula
function leastSquares(xSeries, ySeries) {
		var reduceSumFunc = function(prev, cur) { return prev + cur; };
		
		var xBar = xSeries.reduce(reduceSumFunc) * 1.0 / xSeries.length;
		var yBar = ySeries.reduce(reduceSumFunc) * 1.0 / ySeries.length;

		var ssXX = xSeries.map(function(d) { return Math.pow(d - xBar, 2); })
			.reduce(reduceSumFunc);
		
		var ssYY = ySeries.map(function(d) { return Math.pow(d - yBar, 2); })
			.reduce(reduceSumFunc);
			
		var ssXY = xSeries.map(function(d, i) { return (d - xBar) * (ySeries[i] - yBar); })
			.reduce(reduceSumFunc);
			
		var slope = ssXY / ssXX;
		var intercept = yBar - (xBar * slope);
		var rSquare = Math.pow(ssXY, 2) / (ssXX * ssYY);
		
		return [slope, intercept, rSquare];
}
