	//global vars
	var myEngine;
	var globalPushPageSettings;
	var disconnectEngine;
	
	//functions
	function pushPageSetting(
		domain,
		host,
		port
	) {
		this.domain = domain;
		this.host = host;
		this.port = port;
	}
	function pushTableSetting(
		tableName,
		group,
		schema,
		redColor,
		greenColor,
		flashTime,
		fadeTime,
		backC1Bid,
		backC2Bid,
		backC1Ask,
		backC2Ask,
		startSnapshot,
		clearOnDisconnect,
		pushTableUpdateItem,
		pushTableFormatValues
	) {
		this.tableName = tableName;
		this.group = group;
		this.schema = schema;
		this.redColor = redColor;
		this.greenColor = greenColor;
		this.flashTime = flashTime;
		this.fadeTime = fadeTime;
		this.backC1Bid = backC1Bid;
		this.backC2Bid = backC2Bid;
		this.backC1Ask = backC1Ask;
		this.backC2Ask = backC2Ask;
		this.startSnapshot = startSnapshot;
		this.clearOnDisconnect = clearOnDisconnect;
		this.pushTableUpdateItem = pushTableUpdateItem;
		this.pushTableFormatValues = pushTableFormatValues;
	}
	function pushScrollTableSetting(
		tableName,
		item,
		schema,
		maxRows,
		upwardScroll,
		flashColor,
		flashTime,
		fadeTime,
		backColor,
		startSnapshot,
		clearOnDisconnect,
		clearOnRemove,
		clearOnAdd,
		pushScrollTableUpdateItem,
		pushScrollTableFormatValues
	) {
		this.tableName = tableName;
		this.item = item;
		this.schema = schema;
		this.maxRows = maxRows;
		this.upwardScroll = upwardScroll;
		this.flashColor = flashColor;
		this.flashTime = flashTime;
		this.fadeTime = fadeTime;
		this.backColor = backColor;
		this.startSnapshot = startSnapshot;
		this.clearOnDisconnect = clearOnDisconnect;
		this.clearOnRemove = clearOnRemove;
		this.clearOnAdd = clearOnAdd;
		this.pushScrollTableUpdateItem = pushScrollTableUpdateItem;
		this.pushScrollTableFormatValues = pushScrollTableFormatValues;
	}
	function pushChartSetting (
		tableName,
		group,
		schema,
		startSnapshot,
		clearOnDisconnect,
		areaClass,
		areaWidth,
		areaHeight,
		areaTop,
		areaLeft
	) {
		this.tableName = tableName;
		this.group = group;
		this.schema = schema;
		this.startSnapshot = startSnapshot;
		this.clearOnDisconnect = clearOnDisconnect;
		this.areaClass = areaClass;
		this.areaWidth = areaWidth;
		this.areaHeight = areaHeight;
		this.areaTop = areaTop;
		this.areaLeft = areaLeft;
	}
	function pushTableUpdateItem(item, updateInfo) {
		if (updateInfo == null) {
			return;
		}
		var oldValue = parseFloat(updateInfo.getOldValue(1));
		var newValue = parseFloat(updateInfo.getNewValue(1));
		var isChanged = updateInfo.isValueChanged(1);
		if (oldValue == null) { //first update for this item
			updateInfo.addField(schema.length+1,greenColor,true);
			if (doFade) {
				updateInfo.addField(schema.length+2,false,true);
			}
		} else if (isChanged) {
			//at least second update
			if (oldValue > newValue) {
				updateInfo.addField(schema.length+1,redColor,true);
			} else {
				updateInfo.addField(schema.length+1,greenColor,true);
			}
			if (doFade) {
				updateInfo.addField(schema.length+2,true,true);
			}
		}
	}
	function pushTableFormatValues(item, itemUpdate) { //onChangingValues
		if (itemUpdate == null) {
			return;
		}
		if (doFade) {
			if (itemUpdate.getServerValue(schema.length+2) == true) {
				itemUpdate.setHotToColdTime(fadeTime);
			}
		}
		itemUpdate.setHotTime(flashTime);
		//choose the backgroundColor
		var backC = (item % 2 == 1) ? backC1 : backC2;
		itemUpdate.setRowAttribute(itemUpdate.getServerValue(schema.length+1),backC,"backgroundColor");
	}
	function pushSwitchMode() {
		if (myEngine.getStatus()== "STREAMING") {
			myEngine.changeStatus("DISCONNECTED");
		} else {
			myEngine.changeStatus("STREAMING");
		};
	}
	function pushSetMode() {
		try {
			var element = document.getElementById("pushEngineMode");
			mode = element.innerHTML;
		}
		catch (error) {
			return;
		}

		if (mode == null)
			return;

		if (mode == "On") {
			if (myEngine == null) {
				disconnectEngine = false;
				return;
			}
			myEngine.changeStatus("STREAMING");
		}
		
		if (mode == "Off") {
			if (myEngine == null) {
				disconnectEngine = true;
				return;
			}
			myEngine.changeStatus("DISCONNECTED");
		}
	}
	function pushGetNewChart(item,xStart,yStart) {
		chart = new ChartLine();
		chart.setPointClass("pushpo"+item);
		chart.setLineClass("pushpx"+item);
		chart.onpushYOverflow = pushYOverflow;
		
		xStart = new String(xStart);
		
		maxX = pushGetSeconds(xStart)+180; //-- Schrittweite der X-Achse (min - max, wobei min + 60 Sekunden = max ist)
		minX = pushGetSeconds(xStart);
		pushChart.positionXAxis(minX, maxX)
		
		yShift = Math.max(yStart * 0.001, 0.05);
		minY = Math.max(yStart - yShift, 0.00);
		maxY = yStart + yShift;

		chart.setYAxis(item,2,true); //bid
		chart.positionYAxis(minY,maxY);
		
		var lblFrmttr = {};
		lblFrmttr.formatValue = pushFormatYlbl;
		chart.setYLabels(6,"pushLabel pushLabelY",lblFrmttr); //--- Anzahl der Y-Achsenlabels
		
		return chart;
	}
	function pushOnChartUpdate(item, upOb) {
		if ((upOb == null) || (upOb.getNewValue(1) == null) || (upOb.getNewValue(2) == null))
			return;

		var sec = pushGetSeconds(upOb.getNewValue(1));
		var val = pushYPosition(upOb.getNewValue(2));

		upOb.addField(3, sec, true);
		if (upOb.getOldValue(1) == null) { //first update for this item
			if (!lines[item]) {
				lines[item] = pushGetNewChart(item, sec, val);
				pushChart.addLine(lines[item],"t"+item);
			}
		}
	}
	function pushGetSeconds(stringDate) {
		stringDate = new String(stringDate);
		i1 = stringDate.indexOf(':');
		i2= stringDate.lastIndexOf(':');
		return(stringDate.substring(0,i1)*3600+stringDate.substring(i1+1,i2)*60+stringDate.substring(i2+1,stringDate.length)*1);
	}
	function pushYPosition(yValue) {
		var y = new String(yValue);
		if (y.indexOf(",") > -1 ) {
			var y=y.replace(",",".");
		}
		return new Number(y);
	}
	function pushYOverflow(lastY, minY, maxY) {
		var _shift = (maxY - minY)/2;
		var newMax;
		var newMin;
		
		if (lastY > maxY) {
			newMax = maxY + _shift;
			if (lastY > newMax) {
				newMax = lastY;
			}
			newMin = minY;
			
		} else if (lastY < minY) {
			newMin = minY - _shift;
			if (lastY < newMin) {
				newMin = lastY;
			}
			newMax = maxY;
		} 
		
		for (var item in lines) {
			lines[item].positionYAxis(newMin,newMax);
		}
	}
	function pushFormatYlbl (val) {
		return pushFormatDecimal(val,2,true);
	}
	
	function pushFormatXlbl (val) {
		return pushFormatTime(pushGetTime(val));
	}
	
	function pushGetTime(secondsStr) {
		var hours = Math.floor(secondsStr/(60*60));
		var seconds = secondsStr - (hours * (60*60));
		var minutes = Math.floor(seconds/60);
		var seconds = Math.round(seconds - (minutes * 60));
		if (minutes.toString().length < 2) {
			minutes = ":0" + minutes; 
		} else {
			minutes = ":" + minutes; 
		}
		
		if (seconds.toString().length < 2) {
			seconds = ":0" + seconds; 
		} else {
			seconds = ":" + seconds; 
		}
		
		return hours +  minutes + seconds;
	}
	function pushFormatTime(val) {
		var a = new Number(val.substring(0,val.indexOf(":")));
		var b = val.substring(val.indexOf(":"),val.length);
		return a + b;
	}
	function pushFormatDecimalCulture(commaSeperator, thousandSeperator, value, maximumDecimals, minimumDecimals) {
		var mul = new String("1");
		var zero = new String("0");
		for (var i = maximumDecimals; i > 0; i--) {
			mul += zero;
		}
		value = Math.round(value * mul);
		value = value / mul;
		var strVal = new String(value);
		if (minimumDecimals <= 0) {
			return strVal;	
		}
		var nowDecimals = 0;
		var dot = strVal.indexOf(".");
		if (dot == -1) {
			strVal += commaSeperator;
		} else {
			nowDecimals = strVal.length - dot - 1;
			strVal = strVal.substr(0, dot) + commaSeperator + strVal.substr(dot + 1);
		}
		for (var i = nowDecimals; i < minimumDecimals; i++) {
			strVal = strVal + zero;
		}
		return strVal;
	}
	function pushFormatDecimal(value, decimals, keepZeros) {
		return pushFormatDecimalCulture(".", ",", value, decimals, (keepZeros ? decimals : 0));
	}

	function pushFormatThousandSeparatorCulture(commaSeperator, thousandSeperator, value) {
		var strVal = new String(value);

		var dot = strVal.indexOf(thousandSeperator);
		if (dot >= 0)
		  return strVal;

		var comma = strVal.indexOf(commaSeperator);
		if (commaSeperator == "") {
			comma = strVal.length;
		}
		var i = 0;
		for (i = comma-3; i > 0; i -= 3) {
			strVal = strVal.substr(0, i) + thousandSeperator + strVal.substr(i, strVal.length - i);
		}

		return strVal;
	}
	function pushFormatThousandSeparator(value) {
		return pushFormatThousandSeparatorCulture(".", ",", value);
	}
	
	function insertThousandSeparator(value, sep) {
		var strVal = new String(value);

		var dot = strVal.indexOf(sep);
		if (dot >= 0) return strVal;

		var i = 0;
		for (i = strVal.length-3; i > 0; i -= 3) {
			strVal = strVal.substr(0, i) + sep + strVal.substr(i, strVal.length - i);
		}

		return strVal;
	}
	
	function pushChartInit(oC) {
		lines = {};
		pushChart = new ChartTable(oC.group, oC.schema, "MERGE");
		pushChart.setSnapshotRequired(oC.startSnapshot);
		pushChart.setRequestedMaxFrequency(0.9);
		pushChart.setAreaClass(oC.areaClass);
		pushChart.setAreaWidth(oC.areaWidth);
		pushChart.setAreaHeight(oC.areaHeight);
		pushChart.setAreaTop(oC.areaTop);
		pushChart.setAreaLeft(oC.areaLeft);
		pushChart.onItemUpdate = pushOnChartUpdate;
		pushChart.setClearOnRemove(true);
		pushChart.setClearOnDisconnected(oC.clearOnDisconnect);
		pushChart.setClearOnAdd(false);
		//--- x
		pushChart.setXAxis(3,false); //aus item2 in pushOnChartUpdate
		var labelFormatter = {};
		labelFormatter.formatValue = pushFormatXlbl;
		pushChart.setXLabels(5,"pushLabel",labelFormatter); //Anzahl der X-Achsenlabels
		//---
		page.addTable(pushChart,oC.tableName);
	}
	function pushTableInit(o) {
		var pushTable = new OverwriteTable(o.group,o.schema,"MERGE");
		pushTable.setSnapshotRequired(o.startSnapshot);
		pushTable.setRequestedMaxFrequency(1);
		pushTable.setClearOnDisconnected(o.clearOnDisconnect);
		pushTable.setClearOnRemove(true); //default is false
		pushTable.onItemUpdate = o.pushTableUpdateItem;
		pushTable.onChangingValues = o.pushTableFormatValues;
		pushTable.setPushedHtmlEnabled(true); 
		page.addTable(pushTable,o.tableName);
	}
	function pushScrollTableInit(o) {
		var pushScrollTable = new DynaScrollTable(o.item,o.schema,"MERGE");
		pushScrollTable.setSnapshotRequired(o.startSnapshot); 
		pushScrollTable.setPushedHtmlEnabled(true); 
		pushScrollTable.setClearOnDisconnected(o.clearOnDisconnect); 
		pushScrollTable.setClearOnRemove(o.clearOnRemove); 
		pushScrollTable.setClearOnAdd(o.clearOnAdd); 
		pushScrollTable.setMaxDynaRows(o.maxRows); 
		pushScrollTable.setUpwardScroll(o.upwardScroll);
		pushScrollTable.onRowUpdate = o.pushScrollTableUpdateItem;
		pushScrollTable.onChangingValues = o.pushScrollTableFormatValues;
//		pushScrollTable.setClearOnRemove(true); //default is false
//		pushScrollTable.setClearOnAdd(true);
		page.addTable(pushScrollTable,o.tableName);
		return pushScrollTable;
	}
	function pushPageInit(o) {
		page = new PushPage();
		page.context.setDebugAlertsOnClientError(false);
		page.context.setRemoteAlertsOnClientError(false);
		page.context.setDomain(o.domain);
		page.onEngineCreation = pushStartEngine;
		page.onClientAlert = null;
		page.bind();
		page.createEngine("SHEngine", "/js/push/","SHARE_SESSION");
	}
	function pushStartEngine(eng) {
		myEngine = eng;
		eng.context.setDebugAlertsOnClientError(false);
		eng.context.setRemoteAlertsOnClientError(false);
		eng.policy.setIdleTimeout(30000);
		eng.policy.setPollingInterval(1000);
		eng.connection.setLSHost(globalPushPageSettings.host);
		eng.connection.setLSPort(globalPushPageSettings.port);
		eng.connection.setAdapterName("SmarthouseFeed");
		eng.onStatusChange = pushServerMessage;
		eng.onClientAlert = null;
		if (disconnectEngine) {
			eng.changeStatus("DISCONNECTED");
		}
		else {
			eng.changeStatus("STREAMING");
		}
	}
	
	function pushServerMessage() {
		defaultStatus = "Smarthouse Pushserver: " + myEngine.getStatus();
	};
	function pushSHErrorhandler(number,message) {
		switch (number){
			case 120: 
				alert('Es sind zu viele Browserfenster / Browsertabs mit einer Verbindung zum Smarthouse Pushserver geöffnet. Bitte schließen Sie min. eines dieser Fenster.\r\nToo many browser windows / browser tabs are connected to Smarthouse Pushserver - please consider to close some of them.');
				break;
		/*
			default :
				statement;
		*/
		}
	};

function getCurrentTimestamp()
{
		var current = new Date();
		var year = current.getFullYear();
		var month = current.getMonth() + 1;
		var day = current.getDate();
		var hours = current.getHours();
		var minutes = current.getMinutes();
		var seconds = current.getSeconds();

		if (month < 10) month = "0" + month;
		if (day < 10) day = "0" + day;
		if (hours < 10) hours = "0" + hours;
		if (minutes < 10) minutes = "0" + minutes;
		if (seconds < 10) seconds = "0" + seconds;

		return '' + year + month + day + hours + minutes + seconds;
}
