/**
 *  This class drawing option graph 
 *  @param bool isPlatform - if set true, then we are in "stand alone platform mode" (Big graph)
 *  @param bool isRescase - enables rescale x axis when new rate is recieved
 *  @param string feedId - selector that contains reference to elements that going to recieve current feed
 *  @param bool showPosition - determines if we need to show positions that related to the option on the graph 
 *  @param object option - option that belongs to the graph 
 */
var globalGraphs = [];
function Graph(container, feedId, isPlatform, isRescale, showPositions, option){
	    
		//public properties
		this.assetId  		= option.assetId.id || 0; //default values nuseccery when calld from child class
		this.optionId 		= option.id || 0;
		this.currRate 		= null;
		this.feedId   		= feedId || null;
		this.showPositions  = showPositions;
		this.isRescale = isRescale;
		/*
		 * if set to true, then zooming in progress
		 * and no
		 */
		this.zoomMode = false;
		/** bmo zone range in ms - xaxis**/
		this.startBMO = null;
		this.endBMO	  = null;
		this.bmoTextPlotted = false;
		
		this.noTradingTextPlotted = false;
		/** set true hen mouse over the graph **/
		this.mouseOver = false;
		this.lastMouseoverEvent = null;
		//private properties
		var series 	  = [];
		var options   = {};
		
	if (AppData.streamer == "spot")
		var itemName  ='assetPlatform_' + this.assetId + '_' + this.optionId + '_' + AppData.whiteLabelName;
	else
		var itemName  = (flowPage.getPlatformMode() == 'regular') ? 'assetPlatform_' + this.assetId + '_' + this.optionId + '_' + AppData.whiteLabelName
                        :'feed_assetPlatform_' + this.assetId + '_' + this.optionId + '_' + AppData.whiteLabelName;
       
            
        //var itemName  = 'assetPlatform_' + this.assetId + '_' + this.optionId + '_' + AppData.whiteLabelName;
		var container = container || null;
		var plot      = null;
		var chartId   = 'chart';
		var nextUpdate = null;
		var lastPos = null;
		var isPlatform = isPlatform || false;
		//var rpcCallUrl = AppData.url + 'home/getAssetGraphJSON/' + this.assetId;
		var fetchGraphData = {assetId: this.assetId, optionId: this.optionId, showPositions: this.showPositions};
		var option = option;
		/* Reference from setInterval function, needed when graph object being destruct */
		var intervalReference;
		
		var lastPositionTime = false;
		/*
		 * series[0] => stream graph
		 * series[1] => call positions graph
		 * series[2] => put positions graph
		 * */
		var graphDataMap = {'stream': 0, 'call': 1, 'put': 2};
		//callback function that fired after the graph redrawed
		var redrawCompletedCallback = null;
		var that = this;
		
		//private methods
		
		
		var startStreaming = function(){
			if (AppData.streamer != "spot")
				var page = General.initLightstreamer();
		
			var assetsToSubscribe = [];
			assetsToSubscribe.push (itemName);
			
			if (AppData.streamer == "spot") {
				Streamer.unsubscribe("assetPlatform");
				Streamer.subscribe(assetsToSubscribe, that.onItemUpdate);
			} else {
				page.removeTable('assetsTablePlatform');

				var assetsTable   = new NonVisualTable(assetsToSubscribe, ['rate', 'id', 'lastUpdated', 'color', 'pricingRate'], "MERGE");
				page.addTable(assetsTable, "assetsTablePlatform");
				assetsTable.onItemUpdate =  that.onItemUpdate; //Graphs.onItemUpdate;
			}

			loadChartData();
			
		}
		
		var loadChartData = function(){
			var closeLoading = false;
			if(!flowPage.dialogLoading.dialog('isOpen')){
				flowPage.dialogLoading.dialog('open');
				closeLoading = true;
			}
			 $.ajax({
	                url: AppData.url + 'home/getAssetGraphJSON',
	                type: 'POST',
	                dataType: 'json',
	                data: fetchGraphData, 
	                success: function (graphData) {
	                   
						options = graphData.options;
						
						///series = [ graphData.series[0],  graphData.series[1]]; positions graph
						//console.log(graphData.series)
						series = [];
						$.each(graphData.series, function(i, data){
							series.push(data);
							
						});
						var graphEL = $('#' + chartId);
						
						if (graphData.series.length || graphData.series.data.length) { //graph data is available
							if(option.assetId.bmoEnabled && AppData.featuresStatuses.buyMeOut){
								that.startBMO = options.grid.markings[1].xaxis.from;
								that.endBMO   = options.grid.markings[1].xaxis.to;
							}
							
							//draw the graph
							redraw();
							
							if(closeLoading)
								flowPage.dialogLoading.dialog('close');
							//Save current point to graphs array
							that.currRate = graphData.series[0].data.pop();
							var lastRate = that.currRate[1].toFixed(graphData.options.yaxis.tickDecimals);
							$(feedId).html(lastRate);

						} else { //No data!
							//Empty graph
							series[0].data = new Array();
							that.currRate = null;
							
							//draw the graph
							redraw(chartId);

							if (graphData === 'Not tradeable') {
								$(feedId).html('<div style="position:absolute;width:200px;">Not Tradeable</div>');
							} else {
								$(feedId).html('N/A');
							}
						}
					} //end success()
	            });
		}
		
		/**
	     * Calculate next graph update, at every round 30 seconds,
	     * if now the time is 12:11:21 then the update will occur in 12:11:30
	     */
	    var calculateNextUpdate = function() {
	    	if(!General.dateTime)
	    		return;

		var nextUpdateTemp = Math.floor( General.dateTime.getTime() / 30000 ) * 30 + 30;
	        nextUpdate = new Date(nextUpdateTemp * 1000);
	        
	    }	    
	    /*
	     * 
	     */
	    var redraw = function () {
	    	if(that.zoomMode)
	    		return;
	    	
			var graphEL = $('#' + chartId);
			
			if (plot != null) {
				graphEL.unbind();
			}

			// Save the label visibility for after the re-draw
			var labelVisibility = graphEL.find('div.legend').css('visibility');
			plot = $.plot(graphEL, series, options);
						
			//Highlight the last rate
			plot.highlight(0, series[0].data.length-1);

			//Bind the hover event to update the legend with current point
			graphEL.bind("plothover",  function (e, pos ,item, originalEvent) {
				that.lastMouseoverEvent = originalEvent;
				that.onGraphHover(pos, graphEL);
			});
			
			graphEL.bind("plotclick",  function (e, pos, item) {
				that.onPositionClick(e, pos, item);
			});
			graphEL.bind("mouseout",  function (e) {
				that.onMouseOutGraph(e);
				
			});
			
			graphEL.bind("plotselected",  that.zoom);
			graphEL.bind("plotunselected", that.zoomCancel); 
				
			if(typeof redrawCompletedCallback == 'function'){
				redrawCompletedCallback();
			}
			
			if(that.mouseOver){
				//if mouse was over the plot before the redraw
				var mouseverCallbackFunc = plot.getMouseMoveFunc();
				mouseverCallbackFunc(that.lastMouseoverEvent);
							
			}
			
		}
	    
	    var showLabel = function (time, rate) {
	    	
			var graphEL = $('#' + chartId);
			//Convert time back to UTC
			var timePieces = convertUnixTime(time);
			if(typeof rate == 'number'){
				var labelText = "Rate: " + rate.toFixed(options.yaxis.tickDecimals) + ' Time: ' + timePieces.join(':');
				legend = graphEL.find('.legendLabel');
				//Update the label element text
				legend.text(labelText);
		
				//Show the label
				graphEL.find('div.legend').css('visibility','visible');
			}
		}
	    /** 
	     * converting unix time in ms to string that represents current time
	     * 
	     */
	    var convertUnixTime = function(time){
	    	var time = (time - General.serverOffset);
			var d = new Date(time + AppData.timeZoneOffset);
			
			var hours   =  d.getHours();
			var minutes = d.getMinutes();
			var seconds = d.getSeconds();
			
			if ( hours < 10) hours     = '0' + hours;
	        if ( minutes < 10) minutes = '0' + minutes;
	        if ( seconds < 10) seconds = '0' + seconds;
	        
	        return  Array(hours, minutes, seconds);

	    }
	    
	    /**
	     * this function sorts points data of the stream graph 
	     *  insertion sort
	     */
	    var sort =  function () {
	        var len = series[0].data.length, i = -1, j, tmp;
	        
	        while (len--) {
	            tmp = series[0].data[++i];
	            j = i;
	            while (j-- && series[0].data[j][0] > tmp[0]) {
	            	series[0].data[j + 1] = series[0].data[j];
	            }
	            series[0].data[j + 1] = tmp;
	        }
	    }
	   
		//public methods
	    this.isPlotReady = function(){
	    	return (jQuery.isEmptyObject(plot)) ? false : true;
	    }
	    
		 /**
	     *
	     * Called by setInterval.
	     *
	     * When called first time, initializes lightstreamer graphs
	     *
	     * Periodically updates all graphs every round 30 seconds.
	     * (e.g 12:20:30 and 12:21:00 are proper update periods)
	     *
	     * @param timeString - current time in HH:MM:SS format
	     */
		this.onUpdateTime = function(){
			if (nextUpdate === null || typeof nextUpdate  == 'undefined') {
	            calculateNextUpdate();
	        }
			//Check if its time to update the graph
	        if (nextUpdate <= General.dateTime) {
	            nextUpdate = calculateNextUpdate();
	            if (series) {
	            	//If rate is valid (1 element is the rate)
	            	if ( that.currRate && that.currRate[1]) {
	            		if(that.isRescale){
		            		if (series[0].data.length >= 119) { //Asset graph
		            			//Remove the first rate
		            			series[0].data.shift();
		            			/* Rescale - the scale min is the new first data point time and
		            			 * the scale max is the latest data point time */
		            			var firstPoint = series[0].data[0];
		            			options.xaxis.min = firstPoint[0];
		            			options.xaxis.max =  that.currRate[0];
		            		}
	            		}
						//Add the new rate
						series[0].data.push(that.currRate);
						//Redraw the graph
						redraw();
						
					}
				}
	            nextUpdate = calculateNextUpdate();
	        } // end if
		}
	    
	    /**
	     * Lightstreamer callback, update rightmost point of each graph to the
	     * newly fetched asset rate.
	     */
	    this.onItemUpdate = function(item, itemUpdate, itemNameLS) {
	    	if ( nextUpdate === null ) {
				calculateNextUpdate();
			}
	    	
	        if (AppData.streamer == "spot" || itemUpdate.isValueChanged('pricingRate')) {
			if (AppData.streamer == "spot") {
				var data = itemUpdate;
				itemNameLS = item;

				var pricingRate = data.pricingRate;
				var rate        = data.rate;
				var color = data.color;
				var lastUpdated = data.lastUpdated;
			} else {
				var pricingRate = itemUpdate.getNewValue('pricingRate');
				var rate        = itemUpdate.getNewValue('rate');
				// -COLOR HERE
				var color = parseInt(itemUpdate.getNewValue('color'));
				var lastUpdated = itemUpdate.getNewValue('lastUpdated');
			}
	           
	            if (itemName  ==  itemNameLS) {
	            	//Update current rate array
					var d = new Date();
					var unixTime = new Date((d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear() + " " + lastUpdated);
					var offset = General.serverOffset + General.browserOffset;
					
					if(lastPositionTime && lastPositionTime > unixTime.getTime() + offset){
						return
					}				
					that.currRate  = new Array(unixTime.getTime() + offset, parseFloat(pricingRate));
					if (series[0].data.length > 0) { //At least 1 point
						//At least 2 points
						
						if (series[0].data.length > 1) {
							//Remove the last (current) rate
							series[0].data.pop();
						}
						//Add the new rate
						series[0].data.push(that.currRate);
							
						//Upgrade rate marking on asset graph
			
						options.grid.markings[options.grid.markings.length - 1].yaxis.from = that.currRate[1];
						options.grid.markings[options.grid.markings.length - 1].yaxis.to = that.currRate[1];
						
						redraw();
						
					}
		            $(that.feedId).html(pricingRate);
		                  
		            
	            }

	        }
	    } // end onItemUpdate()
	    
	    this.onGraphHover = function (pos,  graphEL) {
	    	var redrawGraph = false;
	    	//update mouse over graph flag to true
	    	that.mouseOver = true;
			
			if (!series[0].data.length)
				return;
	
			var axes = plot.getAxes();
			if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max ||
				pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) {
				return;
			}
			
			var textHandler = function(cursorPosition, rangeXaxis, textPlottedFlag, plottingEnableFlag){
				if(plottingEnableFlag){
					if( cursorPosition.x < rangeXaxis.max && cursorPosition.x > rangeXaxis.min){
						if(!textPlottedFlag)
							textPlottedFlag = true;
					}
					else{
						if(textPlottedFlag)
							redrawGraph = true;
						
						textPlottedFlag = false;
					}
					
					return textPlottedFlag;
				}
				else{
					return false;
				}
			}
			
			
			that.noTradingTextPlotted = textHandler(pos, {'min': option.noPositionTimeMS, 'max': axes.xaxis.max}, that.noTradingTextPlotted, true);
			
			that.bmoTextPlotted       = textHandler(pos, {'min': that.startBMO, 'max': that.endBMO}, that.bmoTextPlotted, option.assetId.bmoEnabled);
			
			if(redrawGraph){
				//needed for clearing of unnecessary text
				(that.zoomMode) ? that.zoom(false,  {xaxis:{'from':axes.xaxis.min, 'to':axes.xaxis.max}}) : redraw();
			}
			
			if(that.noTradingTextPlotted)
				(that.zoomMode) ? that.drawNoTradingText(axes.xaxis.min, axes.xaxis.max) : that.drawNoTradingText();
				
			if(that.bmoTextPlotted)
				(that.zoomMode) ? that.drawBMOEnabledText(axes.xaxis.min, axes.xaxis.max) : that.drawBMOEnabledText();
				
			
			var j;

			var lastElement = (series[0].data.length-1);
			// find the nearest points, x-wise
			for (j = 0; j < lastElement; ++j) {
				if (series[0].data[j][0] > pos.x) {
					break;
				}
			}
			
			lastPos = j;
			
			// now interpolate
			var y = 0, p1 = series[0].data[j-1], p2 = series[0].data[j];
			if (p1 == null || j == lastElement) { //First or last point
				y = p2[1];
			}else if (p2 == null) {
				y = p1[1];
			} else
				y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
			

			showLabel(pos.x, y, plot);
			

		}
	    
	    /* called when nouse noved out if the graph area */
	    this.onMouseOutGraph = function(e){
	    	var graphEL = $('#' + chartId);
	    	that.mouseOver = false;
	    	
	    	graphEL.find('div.legend')
	    		    .css('visibility','hidden');
	    	
	    	if(that.bmoTextPlotted || that.noTradingTextPlotted){//clear text
	    		redraw();
	    	}
	    }
	    //this function shows position rate
	    this.onPositionClick = function(e, pos, item){
	    	if (item) {
				var x = convertUnixTime(item.datapoint[0]),
                    y = item.datapoint[1].toFixed(5),
                    direction = null;
					
					//determine position direction
					$.each(graphDataMap, function(graphType, number){
						if(number == item.seriesIndex){
							direction = graphType;
							return false;
						}
							
					});
					
					if(typeof Graph.onPositionClickCallback == 'function'){
						Graph.onPositionClickCallback(x.join(':'), y, direction, {'x': item.datapoint[0], 'y': item.datapoint[1]});
					}
            }
            else {
                console.log('no data')         
            }

			
	    }
	    
	    this.zoom = function (event, ranges) {
	    	var graphEL = $('#' + chartId);
	    	that.zoomMode = true;
			//draw zoomed graph
			plot = $.plot(graphEL, series,
				   $.extend(true, {}, options, {
						xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to }
				   }));
			
			if(that.mouseOver){
				//if mouse was over the plot before the redraw
				var mouseverCallbackFunc = plot.getMouseMoveFunc();
				mouseverCallbackFunc(that.lastMouseoverEvent);
							
			}
			
		}
	    
	    this.zoomCancel = function (){
	    	that.zoomMode = false;
	    	redraw();
	    }
	    /**
	     *
	     * @param char timeUnit -> m - minutes, h - hours, d - days
	     * @param int ofsset - quantity of timeUnit (1,2...10 timeUnits)
	     * @param string direction  - dirction of movement  ->  -/+
	     * @param int minLimit min time border in ms
	     * @param int maxLimit nax time border in ms
	     */
	    this.move = function(timeUnit, offset, direction, minLimit, maxLimit){
	    	var minLimit = minLimit || null;
	    	var maxLimit = maxLimit || null;
	    	
	    	var minutinMs = 60 * 1000;
	    	var convertArr = {
	    			'm': minutinMs,
	    			'h': minutinMs * 60,
	    			'd': minutinMs * 60 * 24
	    	}
	    	if(direction == '-'){
	    		var newXaxisMin = options.xaxis.min - convertArr[timeUnit] * offset;
	    		var newXaxisMax = options.xaxis.max - convertArr[timeUnit] * offset;
	    	}
	    	if(direction == '+'){
	    		var newXaxisMin = options.xaxis.min + convertArr[timeUnit] * offset;
	    		var newXaxisMax = options.xaxis.max + convertArr[timeUnit] * offset;
	    	} 
	    	
	    	//max value of xaxis can't be larger then option end time
	    	
	    	if(newXaxisMax > option.endDateMS /*+ General.serverOffset*/){
	    		alert('limit exceeded');
	    		newXaxisMax = option.endDateMS;//set option end date as maximum xaxis value
	    		newXaxisMin = option.startDateMS;//set option start date as minimum xaxis value
	    	}
		    //get graph points from server
	    	$.ajax({
	    				url:  AppData.url + 'PlatformAjax/getGraphPoints/' +  newXaxisMin + '/' + newXaxisMax + '/' + that.assetId,
		                method: 'GET',
		                dataType: 'json',
		                success: function (points) {
		                	/*
		                	 * 3 lines below needed to place position on stream graph,
		                	 * otherwise, the positions points won't be on the strem graph
		                	 */	
		                	var streamGraphPoints = (AppData.isLoggedIn) ? points.concat(that.getGraphData('put'), that.getGraphData('call')) : points;
		                	series[0].data = streamGraphPoints;
		                	sort();
		                	//insert dummy point
		                	series[0].data.push(series[0].data[series[0].data.length-1])
		                			                	
		                	that.rescale(newXaxisMin, newXaxisMax);
		                	redraw();
		                }
	    	});
	    	
	    	
	    }
	    /*
	     * @param array point
	     * @param string direction (put or call)
	     * 
	     */
	    this.insertPosition = function(point, direction){
	    	lastPositionTime = point[0];
	    	
	    	//update stream graph
	    	that.insertPoint(point, 'stream');
	    	//dummy point
	    	that.insertPoint(point, 'stream');
	    	//sort the stream graph
	    	sort();
	    	//highlight last point
	    	plot.highlight(0, series[0].data.length-1);
	    	//update puty/call graph 
	    	that.insertPoint(point, direction);
	    	//redraw the graph
	    	redraw();
	    }
	    /*
	     *  @param array point -> [time, rate]
	     *  @param string graphType -> stream || put || call  
	     */
	    this.insertPoint = function(point, graphType){
	    	series[graphDataMap[graphType]].data.push(point);
	    }
	    
	    this.removePoint = function(point, graphType){
	    	var xAxes = parseInt(point[0]);
	    	var yAxes = parseFloat(point[1]);
	    	
	    	$.each(series[graphDataMap[graphType]].data, function(key, currentPoint){
	    		if(currentPoint[0] == point[0] && currentPoint[1] == point[1]){
	    			//remove the point
	    			series[graphDataMap[graphType]].data.splice(key, 1);
	    			//redraw the graph
	    			redraw();
	    		}
	    	});
	    }
	    
	    /*
	     * 
	     */
	    this.getGraphData = function(graphType){
	    	return series[graphDataMap[graphType]].data;
	    }
	    
	    /**
	     * 
	     * @param xAxisMin time is ms
	     * @param xAxisMax time is ms
	     * @param yAxisMin min rate value
	     * @param yAxisMax max rate value
	     * @returns null
	     */
	    this.rescale = function(xAxisMin, xAxisMax, yAxisMin, yAxisMax){
	    	options.xaxis.min = xAxisMin || options.xaxis.min;
	    	options.xaxis.max = xAxisMax || options.xaxis.max;
	    	options.yaxis.min = yAxisMin || options.yaxis.min;
	    	options.yaxis.max = yAxisMax || options.yaxis.max;
	    }
	    /*
	     * calculate offset of point on the ploting area related to the document
	     */
	    this.calculateGlobalPointOffset = function(xPos, yPos){
    		var o = plot.pointOffset({x: xPos, y: yPos});
	    	var containerOffset = that.getContainerOffset();
	    	containerOffset.top += o.top;
	    	containerOffset.left += o.left;
	    	
	    
	    	return containerOffset;
	    
	    }
	    //returns offset of the graph 
	    //container relative to the document
	    this.getContainerOffset = function(){
	    	return $('#' + container).offset();
	    }
	    
	    this.getContainerDimentions = function(){
	    	return {'width': $('#' + container).width(), 'height': $('#' + container).height()};
	    }
	    
	    this.drawBMOEnabledText = function(minXaxis, maxXaxis){
	    	
	    	if(option.assetId.bmoEnabled){
	    		var maxXaxis = maxXaxis || false;
	    		var minXaxis = minXaxis || false;
				
	    		var midRangePoint = that.getMidPointOfRange(that.startBMO, that.endBMO, minXaxis ,maxXaxis); 
				if(midRangePoint)
					that.drawText(langMain.buyMeOutZone, midRangePoint.x, midRangePoint.y, midRangePoint.fontSize);
			}
	    	
	    	
	    }
	    
	    this.drawNoTradingText = function(minXaxis, maxXaxis){
	    	var maxXaxis = maxXaxis || false;
    		var minXaxis = minXaxis || false;
			
    		var midRangePoint = that.getMidPointOfRange(option.noPositionTimeMS, options.xaxis.max -1, minXaxis ,maxXaxis); 
    		if(midRangePoint)
				that.drawText(langMain.noTradingZone, midRangePoint.x, midRangePoint.y, midRangePoint.fontSize);
	    }
	    
	    this.getMidPointOfRange = function(x1, x2, minXaxis, maxXaxis){
	    	var y1 = y1 || false;
	    	var y2 = y2 || false;
	    	
	    	var plotWidth  = plot.width();
	    	var plotHeight = plot.height();
	    	var plotOffset = plot.getPlotOffset();
	    	
	    	var minXaxis   = minXaxis || options.xaxis.min;
	    	var maxXaxis   = maxXaxis || options.xaxis.max;
	    	
	    	var msPerPix = (maxXaxis - minXaxis)/ plotWidth;
	    	
	    	var x1InPix = 0;
	    	var x2InPix = 0;
	    	
	    	//default font size;
	    	var fontSize = 14;
	    	
	    	//insure that the x1->x2 zone is visible
	    	if((x1 < minXaxis && x2 < minXaxis) || (x1 > maxXaxis && x2 > maxXaxis)){
	    		return false;
	    	}
	    	
	    	if(x1  > minXaxis && x1 < maxXaxis){
	    		x1InPix = (x1 - minXaxis) / msPerPix;
	    	}
	    	
	    	if(x2 > minXaxis && x2 > x1 && x2 < maxXaxis){
	    		x2InPix = (x2 - minXaxis) / msPerPix;
	    	}
	    	else if(x2 > maxXaxis){
	    		x2InPix = plotWidth;
	    	}
	    	
	    	
	    	var calcXPoint = parseInt((x2InPix - x1InPix)/2  + plotOffset.right + plotOffset.left + x1InPix);
	    	var calcYPoint = (plotHeight + plotOffset.top + plotOffset.bottom) / 2;
	    	
	    	//determine font size
	    	var interval = parseInt(x2InPix - x1InPix);
	    	
	    	
	    	if(interval > 140){
	    		fontSize = parseInt(interval / 10)
	    	}
	    	else if(interval < 14){
	    		fontSize = interval - 2;
	    	}
	    	//maximum font size = 35
	    	if(fontSize > 35)
	    		fontSize = 35;
	    	
	    	return {'x': calcXPoint, 'y': calcYPoint, 'fontSize': fontSize}

	    }
	    
	    this.setRedrawCompletedCallback = function(func){
	    	redrawCompletedCallback = func;
	    }
	    
	    /**
	     * stoping the setInterval and destructing the object
	     */
	    this.destruct = function(){
	    	clearInterval(intervalReference);
	    	delete that;
	    }
	    
	    this.drawText = function(text, x ,y, fontSize){
	    	var CT = new CanvasText;
	    	var date = new Date();
	    	var fontSize = fontSize || 14;
	    	
	    	var canvas = plot.getCanvas();
	    	var context = canvas.getContext("2d");
	    	var text = text;
	    	//console.log(text + ' = ' + text + ' x = ' + x + ' y = ' + y + ' font-size = ' + fontSize)
	    	
	    	CT.config({
	            canvas: 		canvas,
	            context:    	context,
	            fontFamily: 	'Arial',
	            fontSize:   	fontSize + 'px',
	            fontWeight: 	'bold',
	            fontStyle:      'italic',
	            fontColor:  	'#fff',
	            textAlign:  	'center',
	            textBaseline: 	'middle',
	            lineHeight: 	fontSize,
	            rotate:     	Math.PI/2
	        });
	    	
	    	CT.drawText({
	    	        text:text,
	    	        x: x - fontSize/4,
	    	        y: y,
	    	        boxWidth:plot.height(),
	    	        cacheId: 'textId _' + date.getTime() 
	    	});
	    	
	    }
	    
	    //init
	    //update global graph variable 
	    flowPage.graph = this;
	    //create chart container
	    
	   
	    if(this.assetId){
			$('<div/>').attr('id', chartId).appendTo('#' + container);
			
			//if platform graph send also the optionId
			//needed to determine axis properly
			if(!isPlatform)
				fetchGraphData.optionId = false;
			
			startStreaming();	
			intervalReference = setInterval (that.onUpdateTime, 1000, this);
			
	    }
	    
	    
	    
}
//static properties

Graph.onPositionClickCallback = null;


