/* dashboard.js -- PVX Plus generic dashboard logic
 * (C) Copyright 2014, PVX Plus Technologies Ltd., Ontario, Canada
 *
 * All rights reserved worldwide.
 * Unauthorized use of this code is strictly prohibited.
 * http://www.pvxplus.com
 */

var bInit = false;
var dvInfo;

var nId = 1;	/* Sequence counter for div ids */
var oMain;		/* Page contents to link to */
var oDbg;
var oMvDiv;
var oMask;
var nMseX;
var nMseY;
var bAutoArrange = 0;
var bRestrict = false;
var isIOS = false;
var zIndex = 0;

function dashOnLoad()
{	if (!('localStorage' in window) || (window['localStorage'] == null))
	{	alert("Unsupported Browser");
		return;
	}

	if ((navigator.userAgent.indexOf('iPhone') != -1) || (navigator.userAgent.indexOf('iPad') != -1))
		isIOS = true;

	oMain = document.getElementById('id_main');
	oDbg = document.getElementById('id_dbg');
	
	dashLoadDivs();

	if (bRestrict) document.getElementById('id_url').readOnly = true;
	
	for (var i=0; i < dvInfo.length; i++) dashShowDiv(i);

	if (window.navigator.msPointerEnabled)
	{	i_AddEvent(window, 'MSPointerDown', dashMove, true);
	}
	else
	{	i_AddEvent(window, 'mousedown', dashMove, true);
		if ("ontouchstart" in document.documentElement)
			i_AddEvent(window, 'touchstart', dashMove, true);
	}

	setInterval(function ()
	{	var	oInfo;
		for (var i=0; i < dvInfo.length; i++)
		{	oInfo = dvInfo[i];
			oInfo.cycle++;
			
			if (oInfo.timer == 0) continue;

			if ((oInfo.timer * 6) <= oInfo.cycle)
			{	oInfo.oDiv.oFrm.src = oInfo.src;
				oInfo.cycle = 0;
			}
		}
	}, 10000);
}

function dashLoadDivs()
{	var		sUrl;
	dvInfo = new Array();
	
	for (var i = 1;;i++)
	{	sUrl = localStorage["dbrd_"+i+"_url"];
		if (!sUrl) break;

		dashNewDiv(sUrl, 
			localStorage["dbrd_"+i+"_ttl"], 
			localStorage["dbrd_"+i+"_top"],
			localStorage["dbrd_"+i+"_left"],
			localStorage["dbrd_"+i+"_wd"],
			localStorage["dbrd_"+i+"_hi"],
			localStorage["dbrd_"+i+"_color"],
			localStorage["dbrd_"+i+"_bgcolor"], 
			localStorage["dbrd_"+i+"_timer"],
			localStorage["dbrd_"+i+"_zindex"] );
	}
	
	bAutoArrange = false;
	if (localStorage["dbrd_autoArrange"] == 'true') bAutoArrange = true;

	bRestrict = false;
	
	var QueryString = parseQuery();
	var bDefault = true;
	
	if (typeof QueryString["json"] == 'undefined')
	{	sUrl = '/dashboard.json';
	}
	else
	{	sUrl = QueryString["json"];
		bDefault = false;
	}
		
	sUrl += '?rnd=' + Math.random();
	
	var xhr = new XMLHttpRequest();
    xhr.open('get', sUrl, false);

    xhr.onload = function()
    {	var status = xhr.status;
		if (status == 200) 
			LoadJSON(JSON.parse(xhr.response));
		else
		if ((status == 404) && (bDefault))
		{	bDefault = false;
				
			sUrl = "dashboard.json";
			xhr.open('get', sUrl, false);
			xhr.send();
		}
		else
			alert("Could not load defaults from:" + sUrl + " (status="+status + ")");
    }
    xhr.send();
    
    var oInfo;
    
	for (zIndex = 0; zIndex < dvInfo.length;)
	{	zIndex++;
		oInfo = null;
		
		for (i = 0; i < dvInfo.length; i++)
		{	if (dvInfo[i].zindex < zIndex) continue;
			if ((oInfo == null) || (oInfo.zindex > dvInfo[i].zindex)) oInfo = dvInfo[i];
		}
		oInfo.zindex = zIndex;
	}
	
	return;
}

function dashAddDiv(sUrl, sTtl, sWd, sHi)
{	if (sUrl == '') sUrl = "about:blank"
	dashNewDiv(sUrl, sTtl, 0, 0, sWd, sHi, null, null, 0, 0);
	dashShowDiv(dvInfo.length-1);
	dashSaveSettings();
}

function dashNewDiv(sUrl, sTtl, nTop, nLeft, nWd, nHi, sColor, sBgColor, nTimer, nIndex)
{	var sId = 'dash_' + (nId++);
	var nIndex = parseInt(nIndex, 10);
	var sSrc;
	
	if (!nTop) nTop = 0;
	if (!nLeft) nLeft = 0;
	if (!sColor) sColor = '';
	if (!sBgColor) sBgColor = '';
	if (!nTimer) nTimer = 0;
	if (!nIndex) nIndex = ++zIndex;
	
	sSrc = sUrl;
	if (sSrc.substr(0,3) == 'id=') sSrc = location.origin + '/services/service.pxp?' + sSrc.replace(/ /g,'&');
	
	if (zIndex < nIndex) zIndex = nIndex;
	dvInfo.push({ url: sUrl, ttl: sTtl, top: nTop, left: nLeft, wd: nWd, hi: nHi, id: sId, color: sColor, bgcolor: sBgColor, timer: nTimer, zindex: nIndex, src: sSrc });
}

function dashShowDiv(nIdx)
{	var oInfo = dvInfo[nIdx];
	var sHtml;
	var sColor = oInfo.color;
	var sBgColor = oInfo.bgcolor;
	var sScroll = "";
	
	if (oInfo.hi < 50) oInfo.hi = 50;
	if (oInfo.wd < 50) oInfo.wd = 50;
	
	oInfo.cycle = 0;
	oInfo.loadAOK = false;
	
	if (isIOS) sScroll = " scrolling='no'";
	 
	sHtml = "<iframe id='frm_"+oInfo.id+"'"+sScroll+" src='"+oInfo.src+"' />";
	sHtml = "<div class='vue'><div id='ttl_"+oInfo.id+"' class='ttl' style='color:" + sColor + 
		"; background-color:"+sBgColor+";'>" + 
		"<span id='txt_" + oInfo.id + "'>" + oInfo.ttl + "</span>" + 
		"<div class='ttlright'>" +	
		"<span onclick='editReload(this);'><img id='set_" + oInfo.id +"x' src='reload.png' title='Reload this widget' /></span>&nbsp;" +
		"<span onclick='editShow(this);'><img id='set_" + oInfo.id + "' src='gear.png' title='Widget settings' /></span>" +
		"</div></div>" +
		"<div id='rsz_" + oInfo.id + "' class='drag'><img src='drag.png' /></div>" +
		sHtml +  "</div>";

	var oDiv = document.createElement('div');;

	++nId;
	oDiv.id = oInfo.id;
	
	oDiv.className = 'box';
	oDiv.innerHTML = sHtml;

	oDiv.style.width = oInfo.wd + 'px';
	oDiv.style.height = oInfo.hi + 'px';

	if (bAutoArrange)
	{	oDiv.style.position='relative';
		oDiv.style.top = oDiv.style.left = '0px';
	}
	else
	{	oDiv.style.position='absolute';
		oDiv.style.top = oInfo.top + 'px';
		oDiv.style.left = oInfo.left + 'px';
	}
	oDiv.style.zIndex = oInfo.zindex;
	
	oDiv.oInfo = oInfo;
	oDiv.nIdx = nIdx;
	oInfo.oDiv = oDiv;
	
	oMain.appendChild(oDiv);
	
	oDiv.oFrm = document.getElementById('frm_' + oInfo.id);

	oDiv.oTtl = document.getElementById('ttl_' + oInfo.id)
	oDiv.oTtlHi = oDiv.oTtl.offsetHeight + 2;
	document.getElementById('rsz_' + oInfo.id).title = oInfo.wd + 'x' + oInfo.hi + ' @ '+oInfo.left + 'x' + oInfo.top;
	oDiv.oFrm.style.height = (oInfo.hi - oDiv.oTtlHi) + 'px';
	oDiv.oFrm.style.width = oDiv.oTtl.offsetWidth + 'px';
}

var sIcon = null;
var sHdr1 = null;
var sHdr2 = null;
var sHdr3 = null;
var sSubHdr = null;
var sCss = null;

function LoadJSON(oJson)
{	var oDiv;
	var	i;
	
	if (oJson.title) document.title = oJson.title;
	
	if (oJson.options && (oJson.options.length > 0))
	{	var oOption;
		var oStd = document.getElementById('id_std');
		oStd.disabled = false;
		
		for (i = 0; i<oJson.options.length;)
		{	oDiv = oJson.options[i++];
			oStd.add( new Option(oDiv.ttl, oDiv.url, false, false));
		}
	}
	else
	{	document.getElementById('tr_std').style.display = 'none';
	}
	
	if (oJson.icon || oJson.header1 || oJson.header2 || oJson.header3 || oJson.subheader)
	{	oDiv = document.createElement('div');
		var		sHtml;
		
		oDiv.id = 'id_hdr';
		if (oJson.icon)
		{	sIcon = oJson.icon;
			sHtml = "<img class='icon' src='"+oJson.icon+"' title='"+document.title+"' />";
		}
		if (oJson.header1)
		{	sIcon = oJson.header1;
			sHtml += "<h1>"+oJson.header1+"</h1>";
		}
		if (oJson.header2)
		{	sHdr2 = oJson.header2;
			sHtml += "<h2>"+oJson.header2+"</h2>";
		}
		if (oJson.header3)
		{	sHdr3 = oJson.header3;
			sHtml += "<h3>"+oJson.header3+"</h3>";
		}
		if (oJson.subheader)
		{	sSubHdr = oJson.subheader;
			sHtml += "<div class='subheader'>"+oJson.subheader+"</div>";
		}
			
		oDiv.innerHTML = sHtml;
		document.body.insertBefore(oDiv, oMain);
	}
		
	if (oJson.css)
	{	var oCss = document.createElement("link");
		sCss = oJson.css;
		oCss.setAttribute("rel", "stylesheet");
		oCss.setAttribute("type", "text/css");
		oCss.setAttribute("href", oJson.css);
		document.getElementsByTagName("head")[0].appendChild(oCss);
	}
	
	if (oJson.restrict) bRestrict = true;

	if (dvInfo.length == 0)
	{	for (i = 0; i<oJson.div.length;)
		{	oDiv = oJson.div[i++];
			if (typeof(oDiv.color) == "undefined") oDiv.color = null;
			if (typeof(oDiv.bgcolor) == "undefined") oDiv.bgcolor = null;
			dashNewDiv(oDiv.url, oDiv.ttl, oDiv.top, oDiv.left, oDiv.wd, oDiv.hi, oDiv.color, oDiv.bgcolor, oDiv.timer, 0);
		}
		
		if (oJson.autoArrange) 
			bAutoArrange = true; 
		else
			bAutoArrange = false;
		
		dashSaveSettings();
	}
}

function dashSaveSettings()
{	var		oInfo;
	ClearStorage();

	for (var i = 0; i < dvInfo.length;)
	{	oInfo = dvInfo[i++];

		localStorage["dbrd_"+i+"_url"] = oInfo.url;
		localStorage["dbrd_"+i+"_ttl"] = oInfo.ttl;
		localStorage["dbrd_"+i+"_top"] = oInfo.top;
		localStorage["dbrd_"+i+"_left"] = oInfo.left;
		localStorage["dbrd_"+i+"_wd"] = oInfo.wd;
		localStorage["dbrd_"+i+"_hi"] = oInfo.hi;
		localStorage["dbrd_"+i+"_color"] = oInfo.color;
		localStorage["dbrd_"+i+"_bgcolor"] = oInfo.bgcolor;
		localStorage["dbrd_"+i+"_timer"] = oInfo.timer;
		localStorage["dbrd_"+i+"_zindex"] = oInfo.zindex;
	}
	
	localStorage["dbrd_autoArrange"] = (bAutoArrange ? 'true' : 'false');
	
	return;
}

function dashMove(e)
{	if (window.event) e = window.event;

	if (oMvDiv)
	{	if (e.type != oMvDiv.EventType) return i_IgnEvent(e);
	}
	
	oMvPos = -1;
	dashMoveEnd(e);
	
	var oDiv = (e.target ? e.target : e.srcElement);
	var	bResize = false;
	while (oDiv)
	{	if (oDiv.id)
		{	if (oDiv.id.substr(0,5) == 'dash_') break;
			if (oDiv.id.substr(0,4) == 'rsz_') bResize = true;
			if (oDiv.id.substr(0,4) == 'set_') return;
			
			if (oDiv.id == 'id_mnu') return;
		}
		oDiv = oDiv.parentNode;
	}

	if (!oDiv) return;

	var nIdx;
	for (nIdx = 0; nIdx < dvInfo.length;nIdx++)
	{	if (dvInfo[nIdx].id == oDiv.id) break;
	}
	if (nIdx == dvInfo.length) return;
	
	var oBox = document.createElement('div');
	oBox.className = 'box';

	oBox.style.height = (2 + oDiv.offsetHeight) + "px";
	oBox.setAttribute('data-mv', "1");
	
	oDiv.appendChild(oBox);
	oMvDiv = oBox;
	oMvDiv.EventType = e.type;
	
	getMseXY(e);
	
	oDiv.bResize = bResize;
	oDiv.style.zIndex = oDiv.oInfo.zindex = ++zIndex;
	
	oDiv.nIdx = nIdx;
	oDiv.nDownX = nMseX;
	oDiv.nDownY = nMseY;
	
	oDiv.nOrigHi = oDiv.offsetHeight;
	oDiv.nOrigWd = oDiv.offsetWidth;

	var	rcMain = oMain.getBoundingClientRect();
	var rcDiv = oDiv.getBoundingClientRect();
	oDiv.nOrigTop = rcDiv.top - rcMain.top;
	oDiv.nOrigLeft = rcDiv.left - rcMain.left;
	
	if (oMvDiv.EventType == 'pointerdown')
	{	i_AddEvent(window, 'MSPointerMove', dashMoveShow, true);
		i_AddEvent(window, 'MSPointerUp', dashMoveEnd, true);
	}
	else	
	if (oMvDiv.EventType == 'mousedown')
	{	i_AddEvent(window, 'mousemove', dashMoveShow, true);
		i_AddEvent(window, 'mouseup', dashMoveEnd, true);
	}
	else
	{	i_AddEvent(window, 'touchmove', dashMoveShow, true);
		i_AddEvent(window, 'touchend', dashMoveEnd, true);
	}	

	oMask = document.createElement('div');
	oMask.className = 'msk';
	oMask.style.zIndex = zIndex;
	
	document.body.appendChild(oMask);
	
	return i_IgnEvent(e);
}

function dashMoveShow(e)
{	if (window.event) e = window.event;
	if (!oMvDiv) return;
	
	getMseXY(e);

	var oDiv = oMvDiv.parentNode;
	var nDiffX = nMseX - oDiv.nDownX;
	var nDiffY = nMseY - oDiv.nDownY;
	
	if (oDiv.bResize)
	{	var nNewHi = Math.max(50, 10 * Math.floor((oDiv.nOrigHi + nDiffY + 5) / 10));
		var nNewWd = Math.max(50, 10 * Math.floor((oDiv.nOrigWd + nDiffX + 5) / 10));
		
		if (oDiv.offsetHeight != nNewHi)
		{	oMvDiv.style.height = (nNewHi + 2) + 'px';
			oDiv.style.height = nNewHi + 'px';
			oDiv.oFrm.style.height = (nNewHi - oDiv.oTtlHi) + 'px';	 
		}
		if (oDiv.offsetWidth != nNewWd)
		{	oMvDiv.style.width = oDiv.style.width = nNewWd + 'px';
			oDiv.oFrm.style.width = oDiv.oTtl.offsetWidth + 'px';
		}
		return i_IgnEvent(e);
	} 
		
	var oInfo = oDiv.oInfo;

	/* See still in initial move logic and if so, 
	** did it move more than 10 px away from original location */

	if (oDiv.style.position != 'absolute')
	{	if (((nDiffX * nDiffX) + (nDiffY * nDiffY)) < 100)
		{	oDiv.style.left = nDiffX + 'px';
			oDiv.style.top = nDiffY + 'px';
			return i_IgnEvent(e);
		}
	}
	
	oInfo.left = 10 * Math.floor((oDiv.nOrigLeft + nDiffX + 5) / 10);
	oInfo.top =  10 * Math.floor((oDiv.nOrigTop + nDiffY + 5) / 10);
	
	oDiv.style.position = 'absolute';
	oDiv.style.left = oInfo.left + 'px';
	oDiv.style.top = oInfo.top + 'px';

	return i_IgnEvent(e);
}

function dashMoveEnd(e)
{	if (window.event) e = window.event;
	if (!oMvDiv) return;

	getMseXY(e);
	var oDiv = oMvDiv.parentNode;
	var oInfo = dvInfo[oDiv.nIdx];

	if (oDiv.bResize)
	{	if ((oInfo.wd != oDiv.offsetWidth) || (oInfo.hi != oDiv.offsetHeight))
		{	oInfo.wd = oDiv.offsetWidth;
			oInfo.hi = oDiv.offsetHeight;
			
			dashSaveSettings();
		}
	}
	else
	{	/* If it moved enough we need to re-insert it into the list */
		
		if (oDiv.style.position == 'absolute')
		{	var nIdx;
			var oDivOver;
			var rcDivOver;
			
			dvInfo.splice(oDiv.nIdx, 1);	/* Remove from array */
			
			for (nIdx=0; nIdx < dvInfo.length;nIdx++)
			{	oDivOver = document.getElementById(dvInfo[nIdx].id);
				if (!oDivOver) continue;		/* Should not happen not it does */

				rcDivOver = oDivOver.getBoundingClientRect();
				
				if (nMseY < rcDivOver.top) break;
				if (nMseY > rcDivOver.bottom) continue;
							
				if (nMseX < rcDivOver.left) break;
				if (nMseX > rcDivOver.right) continue;
				break;
			}
			
			if (nIdx >= dvInfo.length)
			{	dvInfo.push(oInfo);
				oMain.appendChild(oDiv);
			}
			else
			{	dvInfo.splice(nIdx,0,oInfo);
				oMain.insertBefore(oDiv, oDivOver);
			}
			
			/* Rebuild nIdx values */
			
			for (nIdx=0; nIdx < dvInfo.length;nIdx++) dvInfo[nIdx].oDiv.nIdx = nIdx;
			
			if (bAutoArrange) divAuto(oInfo);
			dashSaveSettings();
		}
	}

	document.getElementById('rsz_' + oInfo.id).title = oInfo.wd + 'x' + oInfo.hi + ' @ '+oInfo.left + 'x' + oInfo.top;

	if (oMvDiv.EventType == 'pointerdown')
	{	i_RmvEvent(window, 'MSPointerMove', dashMoveShow, true);
		i_RmvEvent(window, 'MSPointerUp', dashMoveEnd, true);
	}
	else	
	if (oMvDiv.EventType == 'mousedown')
	{	i_RmvEvent(window, 'mousemove', dashMoveShow, true);
		i_RmvEvent(window, 'mouseup', dashMoveEnd, true);
	}
	else
	{	i_RmvEvent(window, 'touchmove', dashMoveShow, true);
		i_RmvEvent(window, 'touchend', dashMoveEnd, true);
	}	

	oMask.parentNode.removeChild(oMask);
	oMask = null;
	
	oDiv.removeChild(oMvDiv);
	oMvDiv = null;
	
	return i_IgnEvent(e);
}

function editShow(oDiv)
{	var oEdit = document.getElementById('id_mnu');
	if (!oEdit) return;

	if (oEdit.style.display != 'none')
	{	editHide();
		return;
	}
	
	while (oDiv)
	{	if ((oDiv.id) && (oDiv.id.substr(0,5) == 'dash_'))break;
		oDiv = oDiv.parentNode;
	}
	
	if (!oDiv) return;
	
	oDiv.style.zIndex = oDiv.oInfo.zindex = ++zIndex;
	var oDrop =	document.getElementById('id_std');

	oDiv.appendChild(oEdit);
	oEdit.style.display = 'block';

	if (oDiv.offsetWidth < oEdit.offsetWidth)
		oEdit.style.right = (oDiv.offsetWidth - oEdit.offsetWidth) + 'px';
	else
		oEdit.style.right = '0px';

	var oFld = document.getElementById('id_url');
	
	oFld.value = oDiv.oInfo.url;
	
	setSelect(oDrop, "Custom");
	
	if (oFld.value && (oFld.value != ''))
	{	setSelect(oDrop, oFld.value);
		if (oDrop.value != oFld.value) 	setSelect(oDrop, "Custom");
	}
	
	oFld = document.getElementById('id_ttl');
	oFld.value = oDiv.oInfo.ttl;

	oFld = document.getElementById('id_timer');
	oFld.value = oDiv.oInfo.timer;

	oFld = document.getElementById('id_color');
	setSelect(oFld, oDiv.oInfo.color);

	oFld = document.getElementById('id_bgcolor');
	setSelect(oFld,oDiv.oInfo.bgcolor);

	return;
}

function editChange(oSelect)
{	if (oSelect.selectedIndex > 0) 
	{	document.getElementById('id_url').value = oSelect.value;
		document.getElementById('id_ttl').value = oSelect.options[oSelect.selectedIndex].text;
	}
	return;
}

function editDrop(oBtn)
{	var oDiv = oBtn.parentNode;
	
	while (oDiv)
	{	if ((oDiv.id) && (oDiv.id.substr(0,5) == 'dash_')) break;
		oDiv = oDiv.parentNode;
	}

	editHide();		/* Remove edit div from div we are dropping */
	
	dvInfo.splice(oDiv.nIdx, 1);
	oDiv.parentNode.removeChild(oDiv);
	
	for (var nIdx=0; nIdx < dvInfo.length;nIdx++) dvInfo[nIdx].oDiv.nIdx = nIdx;
	
	dashSaveSettings();
	return;
}

function editSave(oBtn)
{	var oDiv = oBtn.parentNode;

	while (oDiv)
	{	if ((oDiv.id) && (oDiv.id.substr(0,5) == 'dash_'))break;
		oDiv = oDiv.parentNode;
	}

	var oTtl = document.getElementById('ttl_' +oDiv.oInfo.id );
	var oFrm = document.getElementById('frm_' + oDiv.oInfo.id);
	
	var oVal = document.getElementById('id_url').value;
	if (oDiv.oInfo.url != oVal)
	{	if ((oVal.substr(0,4) != 'http') && (oVal.substr(0,1) != '/') && (oVal.substr(0,1) != '.') && (oVal.substr(0,3) != 'id='))
			oVal = 'http://' + oVal;
		
		oDiv.oInfo.url = oVal;
		oDiv.oInfo.cycle = 0;
		oDiv.oInfo.loadAOK = false;
		
		if (oVal.substr(0,3) == 'id=') oVal = location.origin + '/services/service.pxp?' + oVal.replace(/ /g,'&');
		oFrm.src = oDiv.oInfo.src = oVal;
	}

	oVal = document.getElementById('id_ttl').value;
	if (oDiv.oInfo.ttl != oVal) document.getElementById('txt_' +oDiv.oInfo.id ).innerHTML = oDiv.oInfo.ttl = oVal;
	
	oVal = document.getElementById('id_timer').value;
	oDiv.oInfo.timer = oVal;

	oVal = document.getElementById('id_color').value;
	if (oDiv.oInfo.color != oVal) oTtl.style.color = oDiv.oInfo.color = oVal;

	oVal = document.getElementById('id_bgcolor').value;
	if (oDiv.oInfo.bgcolor != oVal) oTtl.style.backgroundColor = oDiv.oInfo.bgcolor = oVal;

	editHide();
	dashSaveSettings();
}

function editReload(oBtn)
{	var oDiv = oBtn.parentNode;

	while (oDiv)
	{	if ((oDiv.id) && (oDiv.id.substr(0,5) == 'dash_'))break;
		oDiv = oDiv.parentNode;
	}
	
	editHide();
	if (oDiv.oFrm)
	{	oDiv.oFrm.src = oDiv.oInfo.src;
		oDiv.oInfo.cycle = 0;
	}
}
	
function editHide()
{	var oEdit = document.getElementById('id_mnu');
	if (!oEdit) return;

	if (oEdit.style.display != 'none')
	{	oEdit.style.display = 'none';
		document.body.appendChild(oEdit);
	}

	return;
}
	
function i_AddEvent(oObj, sEvent, fCode, fBubble)
{	if (oObj.addEventListener)
	{	oObj.addEventListener(sEvent, fCode, fBubble);
	}
	else
	{	if (oObj == window) oObj = document;
		oObj.attachEvent('on'+sEvent, fCode);
	}
return;
	if (!("ontouchstart" in document.documentElement)) return;
	if (sEvent == 'mousedown') 
		i_AddEvent(oObj, 'touchstart', fCode, fBubble);
	else
	if (sEvent == 'mousemove') 
		i_AddEvent(oObj, 'touchmove', fCode, fBubble);
	else
	if (sEvent == 'mouseup') 
		i_AddEvent(oObj, 'touchend', fCode, fBubble);
		 
}

function i_RmvEvent(oObj, sEvent, fCode, fBubble)
{	if (oObj.addEventListener)
	{	oObj.removeEventListener(sEvent, fCode, fBubble);
	}
	else
	{	if (oObj == window) oObj = document;
		oObj.detachEvent('on'+sEvent, fCode);
	}

	return;
	
	if (!("ontouchstart" in document.documentElement)) return;
	if (sEvent == 'mousedown') 
		i_RmvEvent(oObj, 'touchstart', fCode, fBubble);
	else
	if (sEvent == 'mousemove') 
		i_RmvEvent(oObj, 'touchmove', fCode, fBubble);
	else
	if (sEvent == 'mouseup') 
		i_RmvEvent(oObj, 'touchend', fCode, fBubble);

}

function i_IgnEvent(e)
{	if (e.stopPropagation) e.stopPropagation();
	if (e.preventDefault) e.preventDefault();
	e.cancelBubble = true;
    e.cancel = true;
	e.returnValue = false;
	return false;
}

function PropDump(objectname, object) 
{	var wNew = window.open('','','height=600,width=800,toolbar=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,location=no');
	var sVal;
	
	wNew.document.writeln('<html><body>');

	wNew.document.writeln("<table border=1 bgcolor=wheat><tr>");
	wNew.document.writeln("<td style='font-size: 18pt; font-weight: bold' colspan=2 align=center>");
	wNew.document.writeln("Properties of the <code>"+objectname+"</code> object</td></tr>");

	for (prop in object)
	{	if ((prop == 'innerHTML') || (prop == 'outerHTML'))
			sVal = "..suppressed..";
		else
			sVal =  object[prop];

		wNew.document.writeln("<tr><th>"+prop+"</th><td>" +  sVal +"</td></tr>");
	}

	wNew.document.writeln("</table><p>");
	wNew.document.writeln('</body></html>');
	wNew.document.close();
	return;
}

function getMseXY(e)
{	if (e.changedTouches && (e.changedTouches.length > 0))
	{	nMseX = e.changedTouches[0].pageX;
		nMseY = e.changedTouches[0].pageY;
	}
	else
	if (e.pageX)
	{	nMseX = e.pageX
		nMseY = e.pageY
	}  
	else
	if (e.clientX)
	{	nMseX = e.clientX;
		nMseY = e.clientY;
		if (window.event) 
		{	nMseX += document.body.scrollLeft; 
			nMseY += document.body.scrollTop;
		}
	}
}

function setSelect(oSel, sVal)
{	for (var i = 0; i < oSel.options.length; i++)
	{	if (sVal == oSel.options[i].value)
		{	oSel.selectedIndex = i;
			oSel.value = sVal;
			oSel.options[i].selected = true;
		}
		else
		{	oSel.options[i].selected = false;
		}
	}
}

function optShow(e)
{	if (window.event) e = window.event;
	if (e.ctrlKey && e.shiftKey)
	{	ShowJSON();
		return;
	}
	
	var oOpts = document.getElementById('id_opts');
	if (!oOpts) return;
	
	if (oOpts.style.display == 'block')
	{	oOpts.style.display = 'none';
	}
	else
	{	oOpts.style.display = 'block';
		var oAuto =	document.getElementById('id_auto');
		if (bAutoArrange) 
			oAuto.checked = true;
		else
			oAuto.checked = false;
			
		oOpts.style.display = 'block';
	}
	return;
}	

function optDone()
{	document.getElementById('id_opts').style.display = 'none';

	var nAuto = document.getElementById('id_auto').checked;
	var bAuto;
	
	if (nAuto)
		bAuto = true;
	else
		bAuto = false;
		
	if (bAuto == bAutoArrange) return;
	
	var oInfo;
	var nIdx;
	var	rcMain = oMain.getBoundingClientRect();
	var rcDiv;
	
	for (nIdx = 0; nIdx < dvInfo.length;)
	{	oInfo = dvInfo[nIdx++];	
		rcDiv = oInfo.oDiv.getBoundingClientRect();
		oInfo.top = (rcDiv.top - rcMain.top);
		oInfo.left = (rcDiv.left - rcMain.left);
	}	
	
	for (nIdx = 0; nIdx < dvInfo.length;)
	{	oInfo = dvInfo[nIdx++];	
		if (nAuto)
			divAuto(oInfo);
		else
			divFloat(oInfo);
	}

	bAutoArrange = bAuto;
	dashSaveSettings();
	return;
}

function optReset()
{	if (confirm("Are you sure you wish to reset to default?"))
	{	ClearStorage();
		location.reload(true);		/* Force to reload from server */
	}
	return;
}

function ClearStorage()
{	for (var oItem in localStorage)
	{	if (oItem.substr(0,5) == "dbrd_") localStorage.removeItem(oItem);
	}
}

function divAuto(oInfo)
{	var oDiv = oInfo.oDiv;
	if (oDiv.style.position != 'absolute') return;
	
	oDiv.style.position = 'relative';
	oDiv.style.top = oDiv.style.left = '0px';
	return;
}

function divFloat(oInfo)
{	var oDiv = oInfo.oDiv;

	if (oDiv.style.position == 'absolute') return;

	oDiv.style.top = oInfo.top + 'px';
	oDiv.style.left = oInfo.left + 'px';
	oDiv.style.position = 'absolute';
	
	return;
}

function parseQuery()
{	var qstr = window.location.search.substr(1);
	var query = {};
	if (qstr == '') return query;
	var a = qstr.split('&');
	for (var i in a)
	{	var b = a[i].split('=');
		if (!b[1]) b[1] = true;
		query[decodeURIComponent(b[0])] = decodeURIComponent(b[1]);
	}
	return query;
}

function ShowJSON()
{	var	sJson;
	var oInfo;
	sJson = '{\n' + 
			' "title":"'+document.title+'",\n' +
			' "autoArrange":' + (bAutoArrange ? 'true' : 'false') + ',\n' +
			' "restrict":' + (bRestrict ? 'true' : 'false') + ',\n';

	if (sIcon) sJson += ' "icon":"' + sIcon + '",\n';
	if (sHdr1) sJson += ' "header1":"' + sHdr1 + '",\n';
	if (sHdr2) sJson += ' "header2":"' + sHdr2 + '",\n';
	if (sHdr3) sJson += ' "header3":"' + sHdr3 + '",\n';
	if (sSubHdr) sJson += ' "subheader":"' + sSubHdr + '",\n';
	if (sCss) sJson += ' "css":"' + sCss + '",\n';

	sJson += ' "div":[\n';
	
	for (var i=0; i < dvInfo.length;) 
	{	oInfo = dvInfo[i++];
		sJson += '  { "ttl":"'	+ oInfo.ttl + '",\n' +
				 '    "url":"'	+ oInfo.url + '",\n' +
				 '    "timer":'	+ oInfo.timer + ',\n' +
				 '    "color":"' + oInfo.color + '",\n' +
				 '    "bgcolor":"' + oInfo.bgcolor + '",\n' +
				 '    "top":'	+ oInfo.top + ',\n' +
				 '    "left":'	+ oInfo.left + ',\n' +
				 '    "hi":'	+ oInfo.hi + ',\n' +
				 '    "wd":'	+ oInfo.wd + '\n' +
				 '  }' + (i < dvInfo.length ? ',' : '') + '\n';
	}
	sJson += ' ]';

	var oOption;
	var oStd = document.getElementById('id_std');

	if (!oStd.disabled)
	{	sJson += ',\n "options":[\n';
		
		for (var i = 1; i < oStd.options.length; )
		{	oOption = oStd.options[i++];
			sJson += '  { "ttl":"'	+ oOption.text + '",\n' +
					 '    "url":"'	+ oOption.value + '"\n' +
					 '  }' + (i < oStd.options.length ? ',' : '') + '\n';
		}
		sJson += ' ]';
	}
	
	sJson += '\n}\n';

	var wNew = window.open('','','height=600,width=800,toolbar=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,location=no');
	wNew.document.write('<html><body><pre>');
	wNew.document.write(toHTML(sJson));
	wNew.document.write('</pre></body></html>');
	wNew.document.close();
}		
	
function toHTML(sText)
{	var sHtml = sText.replace(/&/g, '&amp;');
	sHtml = sHtml.replace(/</g, '&lt;');
	sHtml = sHtml.replace(/>/g, '&gt;');
	sHtml = sHtml.replace(/ /g, '&nbsp;');
	return sHtml;
}
	
	
/*
var iframe = document.createElement("iframe");
iframe.src = "simpleinner.htm";

if (iframe.attachEvent){
    iframe.attachEvent("onload", function(){
        alert("Local iframe is now loaded.");
    });
} else {
    iframe.onload = function(){
        alert("Local iframe is now loaded.");
    };
}

document.body.appendChild(iframe);
*/