	//-- global vars
	var myEngine;
	//-- functions
	function pushPageSetting(
		domain,
		host,
		port,
		enginePath,
		startMode,
		heuristicSlowing,
		pollingInterval,
		idleTimeout,
		engineName
	) {
		this.domain = domain;
		this.host = host;
		this.port = port;
		this.enginePath = ((typeof(enginePath) === 'undefined') ? "/js/push/" : enginePath);
		this.startMode = ((typeof(startMode) === 'undefined') ? "STREAMING" : startMode.toUpperCase());
		this.heuristicSlowing = ((typeof(heuristicSlowing) === 'undefined') ? true : heuristicSlowing);
		this.pollingInterval = ((typeof(pollingInterval) === 'undefined') ? 1000 : pollingInterval);
		this.idleTimeout = ((typeof(idleTimeout) === 'undefined') ? 30000 : idleTimeout);
		this.engineName = ((typeof(engineName) === 'undefined') ? "SHEngine" : engineName);
	}
	function pushTableSetting(
		tableName,
		group,
		schema,
		redColor,
		greenColor,
		flashTime,
		fadeTime,
		backC1,
		backC2,
		startSnapshot,
		clearOnDisconnect,
		pushTableUpdateItem,
		pushTableFormatValues,
		dataAdapter
	) {
		this.tableName = tableName;
		this.group = group;
		this.schema = schema;
		this.redColor = redColor;
		this.greenColor = greenColor;
		this.flashTime = flashTime;
		this.fadeTime = fadeTime;
		this.backC1 = backC1;
		this.backC2 = backC2;
		this.startSnapshot = startSnapshot;
		this.clearOnDisconnect = clearOnDisconnect;
		this.pushTableUpdateItem = pushTableUpdateItem;
		this.pushTableFormatValues = pushTableFormatValues;
		this.dataAdapter = ((typeof(dataAdapter) === 'undefined') ? null : dataAdapter);
	}
	function pushGetNewChart(item,xStart,yRef) {
		chart = new ChartLine();
		chart.setPointClass("pushpo"+item);
		chart.setLineClass("pushpx"+item);
		chart.onpushYOverflow = pushYOverflow;
		
		xStart = new String(xStart);
		yRef = new String(yRef).replace(",",".");
		
		maxX = pushGetSeconds(xStart)+180; //-- Schrittweite der X-Achse (min - max, wobei min + 60 Sekunden = max ist)
		minX = pushGetSeconds(xStart);
		pushChart.positionXAxis(minX, maxX)
		
		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) {
			return;
		}
		var sec = pushGetSeconds(upOb.getNewValue(1));
		var prc = pushYPosition(upOb.getNewValue(2));
		if (upOb.getOldValue(1) == null) { //first update for this item
			if (!lines[item]) {
				//pbase[item] = prc;
				lines[item] = pushGetNewChart(item,sec,100);
				pushChart.addLine(lines[item],"t"+item);
			}
		}
		upOb.addField(4,sec,true);
	}
	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 pushFormatDecimal(value, decimals, keepZero) {
		var mul = new String("1");
		var zero = new String("0");
		for (var i = decimals; i > 0; i--) {
			mul += zero;
		}
		value = Math.round(value * mul);
		value = value / mul;
		var strVal = new String(value);
		if (!keepZero) {
			return strVal;	
		}
		var nowDecimals = 0;
		var dot = strVal.indexOf(".");
		if (dot == -1) {
			strVal += ".";
		} else {
			nowDecimals = strVal.length - dot - 1;
		}
		for (var i = nowDecimals; i < decimals; i++) {
			strVal = strVal + zero;
		}
		return strVal;
	}
	function pushChartInit() {
		lines = {};
		pushChart = new ChartTable(group, schemaChart, "MERGE");
		pushChart.setSnapshotRequired(startSnapshot);
		pushChart.setRequestedMaxFrequency(0.9);
		pushChart.setAreaClass("chartstyle");
		pushChart.setAreaWidth(AreaWidth);
		pushChart.setAreaHeight(AreaHeight);
		pushChart.setAreaLeft(AreaLeft);
		pushChart.onItemUpdate = pushOnChartUpdate;
		pushChart.setClearOnRemove(true);
		pushChart.setClearOnDisconnected(clearOnDisconnect);
		pushChart.setClearOnAdd(false);
		//--- X-Achse definieren
		pushChart.setXAxis(4,false); //aus item2 in pushOnChartUpdate
		var labelFormatter = {};
		labelFormatter.formatValue = pushFormatXlbl;
		pushChart.setXLabels(5,"pushLabel",labelFormatter); //Anzahl der X-Achsenlabels
		page.addTable(pushChart,"pushchart");
	}
	function pushTableInit(tableSetup) {
		var pushTable = new OverwriteTable(tableSetup.group,tableSetup.schema,"MERGE");
		pushTable.setSnapshotRequired(tableSetup.startSnapshot);
		pushTable.setRequestedMaxFrequency(1);
		pushTable.setClearOnDisconnected(tableSetup.clearOnDisconnect);
		pushTable.setClearOnRemove(true); //default is false
		pushTable.onItemUpdate = tableSetup.pushTableUpdateItem;
		pushTable.onChangingValues = tableSetup.pushTableFormatValues;
		if (tableSetup.dataAdapter) {
			pushTable.setDataAdapter(tableSetup.dataAdapter);
		}
		page.addTable(pushTable,tableSetup.tableName);
	}
	function pushScrollTableInit(scrollTableSetup) {
		var pushTable = new ScrollTable(scrollTableSetup.group,scrollTableSetup.schema,"MERGE");
		pushTable.setSnapshotRequired(scrollTableSetup.startSnapshot);
		pushTable.setRequestedMaxFrequency(1);
		pushTable.setClearOnDisconnected(scrollTableSetup.clearOnDisconnect);
		pushTable.setClearOnRemove(true); //default is false
		pushTable.onRowUpdate = scrollTableSetup.pushTableUpdateItem;
		pushTable.onChangingValues = scrollTableSetup.pushTableFormatValues;
		pushTable.setLastVisibleRow(8);
		pushTable.setUpwardScroll(false);
		page.addTable(pushTable,scrollTableSetup.tableName);
	}
	function pushPageInit(pageSetup) {
		page = new PushPage();
		page.onClientAlert = null;	// suppress all client alert popups
		page.context.setDebugAlertsOnClientError(false);
		page.context.setRemoteAlertsOnClientError(true);
		page.context.setDomain(pageSetup.domain);
		page.onEngineCreation = function(eng) {
			myEngine = eng;
			eng.onClientAlert = null;	// suppress all client alert popups
			eng.context.setDebugAlertsOnClientError(false);
			eng.context.setRemoteAlertsOnClientError(true);
			eng.policy.setIdleTimeout(pageSetup.idleTimeout);
			eng.policy.setPollingInterval(pageSetup.pollingInterval);
			eng.connection.setLSHost(pageSetup.host);
			eng.connection.setLSPort(pageSetup.port);
			eng.connection.setAdapterName("SmarthouseFeed");
			eng.onStatusChange = function (newStatus) {
				defaultStatus = "Smarthouse QuoteStream: " + newStatus;
			};
			eng.changeStatus(pageSetup.startMode);
		};
		page.bind();
		page.createEngine(pageSetup.engineName, pageSetup.enginePath, "SHARE_SESSION");
	}

	function pushSwitchMode() {
		if (myEngine.getStatus() != "DISCONNECTED") {
			myEngine.changeStatus("DISCONNECTED");
		} else {
			myEngine.changeStatus("STREAMING");
		};
	}
	function pushSetMode(mode) {
		var desiredMode = mode.toUpperCase();
		if (myEngine.getStatus() != desiredMode) {
			switch (desiredMode) {
				case "STREAMING":
					// fallthrough
				case "POLLING":
					// fallthrough
				case "DISCONNECTED":
					myEngine.changeStatus(desiredMode);
					break;
			}
		}
	}
