﻿package com.comp
{
	import com.controller.ChartController;
	import com.controller.CSVParser
	import fl.accessibility.ButtonAccImpl;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.text.TextField;
	import fl.controls.DataGrid;
	import fl.containers.ScrollPane;
	import fl.controls.ScrollPolicy;
	import fl.data.DataProvider;
	import fl.controls.Button;
	import fl.controls.ColorPicker;
	import fl.events.ColorPickerEvent;
	import flash.text.TextFormat;
	import com.MyPicker;
	
	
	/**
	 * ...
	 * @author Vivek Kumar
	 */
	public class chartDataGrid
	{
		private var c_xmlCaptivateParams:XMLList;
		private var c_chartControllerObj:ChartController;
		private var c_iTotalColumns:Number;
		private var c_iTotalRows:Number;
		private var c_dataGrid:DataGrid;
		private var c_objData:Object;
		private var newRows:Number;
		private var newColumns:Number;
		private var loader:Loader;
		private var xmlOut:String;
		private var loadedClip:MovieClip;
		private var c_nextBtn:Button;
		private var c_objRootRef;
		private var c_xmlCaptivateCustomizations:XMLList;
		private var c_backBtn:Button;
		public var c_mcScrollPane:ScrollPane;
		private var mcGrid:MovieClip;
		private var insText:TextField;
		private var c_mcBG:mcBG;
		private var c_toolTipText:TextField;
		private var xTipPos:Number;
		private var yTipPos:Number;
		
		private var browseTxt:TextField;
		private var browseBut:BrowseBtn;
		private var fileRef:FileReference;
		private var csvParser:CSVParser;
		
		public function chartDataGrid()
		{
			init()
		}
		
		private function init():void
		{
			
			c_chartControllerObj = ChartController.getInstance();
			c_objRootRef = c_chartControllerObj.c_objRootRef;
			c_xmlCaptivateParams = c_chartControllerObj.c_xmlCaptivateParams.table;
			c_xmlCaptivateCustomizations = c_chartControllerObj.c_xmlCaptivateParams.customizations
			
			c_iTotalColumns = c_xmlCaptivateParams.column.length();
			setGridData();
		}
		
		private function setGridData():void {
			c_iTotalColumns = c_chartControllerObj.c_xmlConfigParams.columns;
			c_iTotalRows = c_chartControllerObj.c_xmlConfigParams.rows;
			
			var _iMaxRowCount = 0;
			c_objData= new Object();
			
			for (var i = 0; i < c_iTotalRows; i++)
			{
				c_objData["row_" + i] = new Object();
				for (var j = 0; j < c_iTotalColumns; j++ )
				{
					if (c_xmlCaptivateParams.row[i] != undefined && c_xmlCaptivateParams.row[i] != "undefined" && c_xmlCaptivateParams.row[i] != null && c_xmlCaptivateParams.row[i].column[j] != "undefined")
					{
						c_objData["row_" + i]["column_" + j] = c_xmlCaptivateParams.row[i].column[j];
					}else {
						c_objData["row_" + i]["column_" + j] = "";
					}
				}
			}
		}
		public function drawGrid():void
		{
			if (c_mcScrollPane == null)
			{
				c_mcBG = new mcBG();
				c_mcBG.x = 0;
				c_mcBG.y = 0;
				c_objRootRef.addChild(c_mcBG);
				
				c_mcScrollPane = new ScrollPane();
				c_mcScrollPane.horizontalScrollPolicy = ScrollPolicy.AUTO;
				c_mcScrollPane.verticalScrollPolicy = ScrollPolicy.AUTO;
				
				mcGrid = new MovieClip();
				mcGrid.name = "mcGrid";
				mcGrid.graphics.beginFill(0xFF00CC, 0);
				mcGrid.graphics.lineStyle(0, 0, 0);
				mcGrid.graphics.drawRect(0, 0, c_chartControllerObj.c_xmlConfigParams.gridWidth, Number(c_chartControllerObj.c_xmlConfigParams.gridHeight) + 30);				
				mcGrid.graphics.endFill();

				generateColumnColors()
				
				var dp:DataProvider = new DataProvider();
				for (var i = 0; i < c_iTotalRows; i++)
				{
					dp.addItem(c_objData["row_" + i]);
				}
				
				c_dataGrid = new DataGrid();
				c_dataGrid.name = "c_dataGrid";
				c_dataGrid.editable = true;
				c_dataGrid.showHeaders = false;
				c_dataGrid.setSize(c_chartControllerObj.c_xmlConfigParams.gridWidth,c_chartControllerObj.c_xmlConfigParams.gridHeight)
				c_dataGrid.move(0, 40);	
				mcGrid.addChild(c_dataGrid);
				
				var mcLine:MovieClip = new MovieClip();
				mcLine.graphics.lineStyle(1, 0xB7BABC, 1);
				mcLine.graphics.moveTo(0, 40);
				mcLine.graphics.lineTo(c_chartControllerObj.c_xmlConfigParams.gridWidth, 40);
				mcGrid.addChild(mcLine);
				
				
				c_mcScrollPane.source = mcGrid;
				
				c_objRootRef.addChild(c_mcScrollPane);
				
				c_mcScrollPane.setSize(c_chartControllerObj.c_xmlConfigParams.spWidth, c_chartControllerObj.c_xmlConfigParams.spHeight)
				c_mcScrollPane.move(7, 7);
				c_mcScrollPane.update();
				c_dataGrid = MovieClip(c_mcScrollPane.content).getChildByName("c_dataGrid") as DataGrid;
				for (var j = 0; j < c_iTotalColumns; j++ )
				{
					c_dataGrid.addColumn("column_" + j);
				}
				c_dataGrid.dataProvider = dp;			
				
				browseTxt = new TextField();
				browseTxt.x = c_mcScrollPane.x;
				browseTxt.y = c_mcScrollPane.y + c_mcScrollPane.height + 5;
				browseTxt.border = true;
				browseTxt.type = "dynamic"
				browseTxt.selectable = false;
				browseTxt.width = c_mcScrollPane.width - 110;
				browseTxt.height = 20
				c_objRootRef.addChild(browseTxt);
				
				browseBut = new BrowseBtn();
				browseBut.x = 296;
				browseBut.y = c_mcScrollPane.y + c_mcScrollPane.height + 6;
				//browseBut.label = "Browse";
				browseBut.addEventListener(MouseEvent.CLICK, browseButtonHandler);
				c_objRootRef.addChild(browseBut);
				
				
				csvParser = new CSVParser("charts");
				csvParser.addEventListener(IOErrorEvent.IO_ERROR, IOErrorHandler)
				csvParser.addEventListener(Event.COMPLETE, CSVParsed);
			
				createInstructionAndButton();	
				
			}
			else
			{
				c_mcScrollPane.visible = true;
				insText.visible = true;
				c_backBtn.visible = true;
			}
		}
		
		private function browseButtonHandler(e:MouseEvent):void 
		{
			fileRef = new FileReference();
			fileRef.addEventListener(Event.COMPLETE, onLoaded);
			fileRef.addEventListener(Event.SELECT, fileSelectHandler);
			fileRef.browse(getFileTypes());
		}
		
		private function getFileTypes():Array
		{
			return new Array(new FileFilter("CSV Files (*.csv)", "*.csv"));
		}
		
		private function fileSelectHandler(e:Event):void 
		{
			fileRef.load();
			fileRef.removeEventListener(Event.SELECT, fileSelectHandler);
		}
		
		private function onLoaded(e:Event){
			
			var myText = fileRef["data"].readUTFBytes(fileRef["data"].length);
			var file:FileReference = FileReference(e.target);
			browseTxt.htmlText = "<font face='Arial' size='12'>"+ file.name + "</font>";
			csvParser.loadFile(myText);
		}
		
		private function IOErrorHandler(e:IOErrorEvent):void 
		{
			//fileNameTxt.text = "An IOError";
		}
		
		private function CSVParsed(e:Event):void 
		{
			c_xmlCaptivateParams = XMLList(csvParser.xml);
			redrawGrid();
		}
		
		
		private function redrawGrid() {
			
			var newColumns = c_xmlCaptivateParams.row[0].column.length();
			var newRows = c_xmlCaptivateParams.row.length();
			
			if(newColumns > c_iTotalColumns){
				var diff =  newColumns - c_iTotalColumns
				for (var j = diff; j < (diff+diff); j++ )
				{
					c_dataGrid.addColumn("column_" + j);
				}
				c_chartControllerObj.c_xmlConfigParams.columns = newColumns
				c_iTotalColumns = newColumns;
			}
			
			if(newRows > c_iTotalRows){
				c_chartControllerObj.c_xmlConfigParams.rows = newRows
				c_iTotalRows = newRows
			}
			
			//c_objData = null;
			//c_objData = new Object();
			for (var i = 0; i < c_iTotalRows; i++)
			{
				c_objData["row_" + i] = new Object();
				for (j = 0; j < c_iTotalColumns; j++ )
				{
					if (c_xmlCaptivateParams.row[i] != undefined && c_xmlCaptivateParams.row[i] != "undefined" && c_xmlCaptivateParams.row[i] != null && c_xmlCaptivateParams.row[i].column[j] != "undefined")
					{
						c_objData["row_" + i]["column_" + j] = c_xmlCaptivateParams.row[i].column[j];
					}
				}
			}
			var dp:DataProvider = new DataProvider();
			for (i = 0; i < c_iTotalRows; i++)
			{
				dp.addItem(c_objData["row_" + i]);
			}
			c_dataGrid.dataProvider = dp;
		}
		private function createInstructionAndButton():void
		{
			insText = new TextField();
			insText.x = c_mcScrollPane.x;
			insText.y = browseBut.y + browseBut.height + 5;
			insText.width = c_mcScrollPane.width - 100;
			insText.autoSize = "left";
			insText.selectable = false;
			insText.wordWrap = true;
			insText.htmlText = "<font face='Arial' size='12'>*X\\Y – where column X is Data labels and column Y is Legends</font>"
			c_objRootRef.addChild(insText);
			
			c_backBtn = new Button();
			c_objRootRef.addChild(c_backBtn);
			c_backBtn.x = 296;
			c_backBtn.y = browseBut.y + browseBut.height + 5;
			c_backBtn.label = "Back";
			c_backBtn.addEventListener(MouseEvent.CLICK, generateChartParams);
		}
		
		/*private function generateChart1(e:MouseEvent):void 
		{
			generateChart();
		}*/
		
		private function generateColumnColors():void
		{
			/* Drawing Colorpicker on the top of the datagrid */
			var initXPos = c_chartControllerObj.c_xmlConfigParams.xPos;
			var initYPos = c_chartControllerObj.c_xmlConfigParams.yPos;
			
			var textColor:TextField = new TextField();
			textColor.htmlText = "<font face='Arial' size='12'><b>Colors: </b></font>";
			textColor.selectable = false;
			textColor.x = initXPos;
			textColor.y = initYPos;
			initXPos = Number(initXPos) + 90;
			mcGrid.addChild(textColor);
			
			for (var k = 1; k < c_iTotalColumns; k++)
			{
				var colorPick:ColorPicker = new MyPicker();
				colorPick.name = "Column " + k;
				mcGrid.addChild(colorPick);
				
				var xmlColorProp = c_xmlCaptivateCustomizations.textProperties.color.@columnColor;
				
				var arrColumnColor = xmlColorProp.split(",");
				
				colorPick.selectedColor = (arrColumnColor[k-1]);
				
				colorPick.x = initXPos;
				colorPick.y = initYPos;
				colorPick.width = c_chartControllerObj.c_xmlConfigParams.colorPicker.width;
				colorPick.height = c_chartControllerObj.c_xmlConfigParams.colorPicker.height;
				
				initXPos = colorPick.x + colorPick.width + 57;
				colorPick.addEventListener(ColorPickerEvent.CHANGE, columnColorHandler);
				colorPick.addEventListener(ColorPickerEvent.ENTER, columnColorHandler);
				colorPick.addEventListener(MouseEvent.MOUSE_OVER, createToolTip);
				colorPick.addEventListener(MouseEvent.MOUSE_OUT, removeToolTip);
			}			
		}
		
		private function removeToolTip(e:MouseEvent):void 
		{
			c_objRootRef.removeChild(c_toolTipText);
		}
		
		private function createToolTip(e:MouseEvent):void 
		{
			c_toolTipText = new TextField();
			c_toolTipText.selectable = false;			
			c_toolTipText.autoSize = "left";
			c_toolTipText.wordWrap = true;
			c_toolTipText.x = c_toolTipText.mouseX
			c_toolTipText.y = c_toolTipText.mouseY + 20;
			c_toolTipText.border = true;
			c_toolTipText.background = true
			c_toolTipText.backgroundColor = 0xFFFFCD;
			c_toolTipText.htmlText = "<font face='Arial' size='9'>" + e.currentTarget.name + "</font>";
			c_toolTipText.width = c_toolTipText.textWidth + 5;
			c_objRootRef.addChild(c_toolTipText)
		}
		
		private function generateChartParams(e:MouseEvent):void 
		{
			c_mcScrollPane.visible = false;
			insText.visible = false;
			e.target.visible = false;
			c_objRootRef.hasData = false;
			c_objRootRef.update();
		}
		
		private function columnColorHandler(e):void 
		{
			
			var xmlColorProp = c_xmlCaptivateCustomizations.textProperties.color.@columnColor;
			var arrColumnColor:Array = xmlColorProp.split(",");
			var myCP:ColorPicker = e.currentTarget as ColorPicker;
			var selectedColor = myCP.selectedColor;			
			var colorPickerID = Number(e.currentTarget.name.split(" ")[1]);
			
			arrColumnColor[colorPickerID-1] = selectedColor;
			c_xmlCaptivateCustomizations.textProperties.color.@columnColor = arrColumnColor.join(",");
			c_chartControllerObj.c_xmlCaptivateParams.customizations.textProperties.color.@columnColor = arrColumnColor.join(",");
			MovieClip(c_objRootRef).myData = c_chartControllerObj.c_xmlCaptivateParams.toString();
		}
		
		public function generateChart():void
		{
			getFinalObject();
			objectToString();
			loadCharts();
		}
		
		private function getFinalObject():Object
		{
			var tempObj = new Object();
			newRows= 0;
			newColumns= 0;
			var data = "";

			for (var i = 0; i < c_iTotalRows; i++)
			{
				var rowEmpty = true;
				for (var j = 0; j < c_iTotalColumns; j++ )
				{
					
					data = String(c_objData["row_" + i]["column_" + j]);

					if ( data != "" && data != "undefined")
					{
						rowEmpty = false;
					}
				}
				
				if (!rowEmpty) {
					tempObj["row_" + newRows] = new Object();
					
					for ( j = 0; j < c_iTotalColumns; j++ )
					{
						data = String(c_objData["row_" + i]["column_" + j]);
						tempObj["row_" + newRows]["column_" + j] = data
					}
					
					
					//added for empty row
					var strTemp = tempObj["row_" + newRows]["column_" + 0];
					tempObj["row_" + newRows]["column_" + 0] = (strTemp == "") ? ("Row"+newRows) : strTemp
					//empty row ends here
					
					
					
					newRows++;
				}
				
				
			}
			
			var arrColumns:Array = new Array();
			for (i = 0; i < c_iTotalColumns; i++)
			{
				var columnEmpty = true;
				for (j = 0; j < newRows; j++ )
				{
					data = String(tempObj["row_" + j]["column_" + i]);
					
					if (data != "" && data != "undefined")
					{
						columnEmpty = false;
					}
				}
				if (!columnEmpty) {
					arrColumns.push(i);
				}
			}

			newColumns = arrColumns.length;
			var tempObj_1 = new Object();
			for (i = 0; i < newRows; i++)
			{
				tempObj_1["row_" + i] = new Object();
				for (j = 0; j < newColumns; j++ )
				{
					
					data = String(tempObj["row_" + i]["column_" + arrColumns[j]]);
					tempObj_1["row_" + i]["column_" + j] = data
					//added for empty column
					if(i==0){
						tempObj_1["row_" + i]["column_" + j] = data == "" ? ("Column"+j) : data
					}
					//empty column ends here
				}
			}
			
			return tempObj_1;
		}
		
		public function objectToString():String
		{
			
			XML.prettyPrinting = false
			XML.prettyIndent = 0;
			var chartCustom = c_xmlCaptivateCustomizations.toString();
			
			var tempObj_1 = getFinalObject();
			c_objData = new Object();
			c_objData = tempObj_1;
			
			// ===========To convert object to XML String============
			xmlOut= "<root><table>"
			for (var k = 0; k < newRows; k++) 
			{
				xmlOut += "<row>"
				for (var l = 0; l < c_iTotalColumns; l++)
				{
					if ( c_objData["row_" + k]["column_" + l] != undefined && c_objData["row_" + k]["column_" + l] != "undefined" && c_objData["row_" + k]["column_" + l] != null)
					{
						xmlOut += ("<column>" + c_objData["row_" + k]["column_" + l] + "</column>")
					}
					
				}
				xmlOut += "</row>"
			}
			xmlOut += "</table>"
			
			xmlOut += chartCustom;
			xmlOut += "</root>"

			//===========================================================
			//==============Converting Data string to XML Object=========
			//var dataXML:XML = new XML(xmlOut);
			//===========================================================
			return xmlOut;
		}
		
		private function loadCharts()
		{
			var chartToLoad = c_xmlCaptivateCustomizations.chart.@type;
			var request:URLRequest;
			if (chartToLoad == 1)
			{
				request = new URLRequest("ColumnCharts.swf");
			}
			else if (chartToLoad == 2)
			{
				request = new URLRequest("BarCharts.swf");
			}
			else if (chartToLoad == 3)
			{
				request = new URLRequest("PieCharts.swf");
			}
			var myLoaderContext:LoaderContext = new LoaderContext();
			myLoaderContext.applicationDomain = ApplicationDomain.currentDomain;
			
			loader = new Loader()
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onApplicationLoaded);
			loader.load(request, myLoaderContext);
			c_objRootRef.addChild(loader);			
		}
		
		private function onApplicationLoaded(e:Event):void 
		{
			loadedClip = loader.content as MovieClip;
			loadedClip.addEventListener(Event.ENTER_FRAME, onFlexAppLoaded);
			
		}
		
		public function move(x:Number, y:Number):void
		{
			xTipPos = x;
			yTipPos = y;
		}
		
		private function onFlexAppLoaded(e:Event):void 
		{
			if (loadedClip.application != null) {
				try{
					loadedClip.removeEventListener(Event.ENTER_FRAME, onFlexAppLoaded);

					var applicationRef = loadedClip.application;
					loadedClip.application.setDisplacement(xTipPos, yTipPos);
					loadedClip.application.setBgColor(int(c_xmlCaptivateCustomizations.chart.@bgcolor));
					loadedClip.application.setChartTitle(c_xmlCaptivateCustomizations.chart.@title);
					loadedClip.application.setChartStyle(c_xmlCaptivateCustomizations.chart.@style);
					loadedClip.application.setLegendStyle(c_xmlCaptivateCustomizations.chart.@legendStyle);
					
					var fontRef = c_xmlCaptivateCustomizations.textProperties.font;
					applicationRef.setTextProp(fontRef.@face, fontRef.@size);
					
					var decorationRef = c_xmlCaptivateCustomizations.textProperties.textDecoration;
					applicationRef.setTextDec(decorationRef.@bold, decorationRef.@underline, decorationRef.@italic);
					
					var colorRef = c_xmlCaptivateCustomizations.textProperties.color;
					applicationRef.setTextColor(colorRef.@textColor);
					applicationRef.setColumnColor(colorRef.@columnColor);
					
					loadedClip.application.setData(xmlOut);
				}catch(ae)
				{
					
				}
				c_objRootRef.isReadyForSnapshot = true;
			}
		}
		
		
	}
	
}