package com.indindi.Raster
{
	// import statements
	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	
	import com.indindi.Text.*;
	
	import com.indindi.Raster.TimePerf;

	public class ActiveGraphTimePerf extends Sprite
	{
		private const WIDTH:Number = 50, HEIGHT:Number = 200;
		private const NB_PLOTS:Number = 21;

		private var itr:Number;

		// display-related properties
		private var graphBackground:Sprite;
		private var backX:Number, backY:Number;
		
		private var _timePerf:TimePerf;
		
		private var _drawPerfsObjects:Array;
		private var _colorPalet:Array;
		
		private var isMouseDown:Boolean;
		
		public function ActiveGraphTimePerf(parentMC:MovieClip, timePerf:TimePerf, interval:Number=0, verbose:Boolean=false, drawData:Boolean=true, degree:int=2):void
		{
			
			_timePerf = timePerf;
			_drawPerfsObjects = new Array();

			// instantiate drawing objects
			graphBackground = new Sprite();
			// draw graphBackground
			graphBackground.graphics.beginFill(0x00FF99, 0.5);
			graphBackground.graphics.drawRect(0,0,WIDTH,HEIGHT);
			graphBackground.graphics.endFill();

//			graphBackground.graphics.lineStyle(0.5,0xFFFFFF);
//			graphBackground.graphics.drawRect(0,0,WIDTH,HEIGHT-1);
			// add to display list
			this.addChild(graphBackground);
			
			_colorPalet = [0xFFFF0000, 
						  0xFF00FF00,
						  0xFF0000FF,
						  0xFF00FFFF,
						  0xFFFF00FF,
						  0xFFFFFF00,
						  0xFFFFFFFF,
						  0xFF000000
						  ];
			
			var legendBD:BitmapData = new BitmapData(50, 15*_timePerf.GetNbPerfs(), true, 0x55000000);
			
			var i:int = 0;
			for (var a_perf_nom:String in _timePerf.GetPerfs()) {
				var obj:Object = new Object();
				obj.nom = a_perf_nom;
				obj.history = new Array();
				obj.plot = 0;
				obj.plotLine = new Shape();
				obj.plotLength = 0;
				
				_drawPerfsObjects.push(obj);
				this.addChild(obj.plotLine);
				
				// Draw Legend
				var a_legendBD:BitmapData = new BitmapData(50, 15, true, 0x55000000);
				a_legendBD.fillRect(new Rectangle(5, 5, 5, 5), _colorPalet[i]);
			
				var MyText:DText = new DText(parentMC.getFontBD(), 9, 16, 7);
				MyText.draw(a_legendBD, obj.nom, 15, 0);
				
				legendBD.copyPixels(a_legendBD, a_legendBD.rect, new Point(0, i*15)); 
				

				i++;
			}
			var legendBitmap:Bitmap = new Bitmap(legendBD);
			legendBitmap.x = 0;
			legendBitmap.y = 200;
			this.addChild(legendBitmap);
			
			var contour:Shape = new Shape();
			contour.graphics.lineStyle(0.5,0xFFFFFF);
			contour.graphics.drawRect(0,0,WIDTH,HEIGHT);
			contour.x = 0;
			contour.y = 0;
			addChild(contour);

			// implements clicking and dragging behavior
			backX = x, backY = y;
			graphBackground.addEventListener(MouseEvent.MOUSE_DOWN, handleDrag, false, 0, true);
			graphBackground.addEventListener(MouseEvent.MOUSE_UP, handleDrag, false, 0, true);
			this.addEventListener(Event.ADDED_TO_STAGE, loadDrag, false, 0, true);

			isMouseDown = false;
		}
		
		// trackMem- determines whether the GC has run, outputs active memory
		private function trackTimePerfs():void
		{
			//trace("_drawPerfsObjects.length = "+_drawPerfsObjects.length);
			for (var i:int; i<_drawPerfsObjects.length; i++) {
				_drawPerfsObjects[i].plot = HEIGHT*(_timePerf.GetPerfs())[_drawPerfsObjects[i].nom];
			}
		}

		// drawMem- updates graph and textbox
		public function drawTimePerfs():void
		{
			trackTimePerfs();
			
			for (var i:int; i<_drawPerfsObjects.length; i++) {
				var obj:Object = _drawPerfsObjects[i];
				
				obj.plotLine.graphics.clear();
	
				// history array never exceeds a certain length
				if (obj.plotLength == NB_PLOTS) {
					obj.history.shift();
					obj.plotLength--;
				}
	
				// add plot to data set
				obj.history.push(obj.plot);
				obj.plotLength = obj.history.length;
				
				// If the graph's long enough,
				if (obj.plotLength > 1) {
					obj.plotLine.graphics.lineStyle(2.5, _colorPalet[i]);

					// then plot the graph.
					obj.plotLine.graphics.moveTo(1, 1+HEIGHT-(obj.history[0]));
					for (itr = 1; itr < obj.plotLength; itr++) {
						obj.plotLine.graphics.lineTo(WIDTH*itr/(obj.plotLength-1), HEIGHT-obj.history[itr]);
					}
				}
			}
		}
		
		private function handleDrag(e:Event):void
		{
			// based on the event type,
			switch (e.type) {
				case MouseEvent.MOUSE_DOWN :
					// start dragging,
					backX = x; backY = y;
					isMouseDown = true;
					startDrag();
					break;
				case MouseEvent.MOUSE_UP :
					// stop dragging,
					isMouseDown = false;
					stopDrag();
					break;
				case Event.MOUSE_LEAVE :
					// or reset the positiong, in case it's been dragged off the Stage
					if (isMouseDown) {
						stopDrag();
						x = backX; y = backY;
						break;
					}
			}
		}
		private function loadDrag(e:Event):void
		{
			this.stage.addEventListener(Event.MOUSE_LEAVE, handleDrag, false, 0, true);
		}
	}
}