/**
 * Embed a OFC (flash chart) in HTML
 *
 * This script is designed to function with the DZ-Ichor pathed SWF  of OFC2
 * http://ofc2dz.com/
 *
 * Requires: prototype.js + swfobject.js
 * <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"></script>
 * <script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" type="text/javascript"></script>
 *
 * Example:
 *
 *  <div id="locationDistributionChart"></div>
 *  <script type="text/javascript">
 *      Event.observe(window,'load',function(){window['siteStatChart'] = new TsOfcChart('siteStatChart', '/ofcSiteStatisticsAsJson.do?siteId=$siteId');});
 *  </script>
 *
 *  You can also load data by Calling loadJSON()
 *  window['theChart'] = new TsOfcChart('theChart');  // Note: No data URL needed
 *  window['theChart'].loadJSON([YOUR JSON DATA])
 *
 *  JSON Example (simple line chart):
 *  {"title":"Page impressions for site 'tailsweep.com'","type":"line","seriesList":[{"name":"Page impressions","series":[{"label":"2009-12-26","value":"3326"},{"label":"2009-12-27","value":"3569"},{"label":"2009-12-28","value":"3567"}]}]}
 *
 *  Tip! Copy the JSON Example above and validate it using www.jsonlint.com for a better view.
 *
 *
 *  Custom colors
 *  window['theChart'].seriesColors = ["#0099CC", "#0066CC", "#0033CC", "#0000CC"]
 *
 */


var TsOfcChart = Class.create(
{
			initialize : function(chartId, dataURL, seriesColors) {
				this.chartId = chartId;
				this.dataURL = dataURL;
				this.type = null;
				this.title = null;
				this.seriesname = null;
				this.seriesList = null;
				this.data=null;
				this.bgImage = "http://www.tailsweep.com/images/tailsweep_watermark2.png";
				this.maxXLabels = 25; // TODO: Read this from JSON

				this.tip = null;
				this.isOFCEmbedded = false;
				this.seriesColors = seriesColors || ["#0099CC", "#0066CC", "#0033CC", "#0000CC"];

				this.width = 660;
				this.height = 300;

				this.getData(this.dataURL);
			},

			embedOFC : function() {
				swfobject.embedSWF("/swf/open-flash-chart2-dz-embedded-font.swf",this.chartId, this.width, this.height, "9.0.0", null, {"get-data" : "window['" + this.chartId+ "'].ofcInit", "id" :this.chartId}, {"wmode" : "transparent"	}, null, function(e) {this.swfLoaded(e);}.bind(this));
			},

			/*
			 * Callback for OFC get-data (fired when OFC is loaded)
			 * */
			ofcInit : function() {
				 this.idOFCEmbedded = true;
				 return this.data;
			},

			/*
			 * Callback for embedSWF
			 *
			 * Event contains
			 * success
			 * id
			 * ref - Element reference
			 *
			 * */
			swfLoaded : function(e) {
				if (e.success) {
					/* Keep a reference to the  <object> */
					this.ofcChart = e.ref;
				}
			},

			getData : function(url) {
				new Ajax.Request(url, {
					method : 'get',
					onComplete : this.handleAjaxResponse.bind(this)
				});

				return false;
			},

			handleAjaxResponse : function(res) {
				var resObj = null;
				try {
					/* console.log(res.responseText); */
					var JSON = res.responseText.evalJSON();
					this.loadJSON(JSON);

				} catch (e) {					
					/*alert(e);*/
				}
			},

			loadJSON: function(JSON) {
				this.title = JSON["title"];
				this.seriesname = JSON["seriesName"];
				this.seriesList = JSON["seriesList"];
				this.type = JSON["type"];
				this.tip = JSON["tip"];
				this.yMax = JSON["yMax"];

				if (this.type === "line") {
					this.data = this.getLineChart();
				} else if (this.type === "bar") {
					this.data = this.getBarChart();
				} else if (this.type === "pie") {
					this.data = this.getPieChart();
				}

				if(!this.isOFCEmbedded){
					this.embedOFC();
				}
				else{
					this.ofcChart.load(this.data);
				}
			},

			getLineChart : function() {
				var s = '{"title":{"text":"' + this.title + '","style": "{font-size: 20px; color:#666666; font-family: Verdana; text-align: center;}"},';

				s += '"elements":[';

				var maxValue = 0;
				var numOfXLabels = this.seriesList[0].series.length;  // How many values are available for display on the x-axis

				/* Loop each series in seriesList */
				for(var j=0; j < this.seriesList.length; j++)
				{
					var series = this.seriesList[j].series;
					var theTip = "#x_label#<br>#val#";
                    if(this.seriesList[j].tip)
                    {
                        theTip = this.seriesList[j].tip;
                    }
					/* "on-show":{"type":""} disables the initial graph animation */
					s += '{"on-show":{"type":""},"type":"area","alpha":0.7,'
						+ '"colour":"'+this.seriesColors[j]+'",'
						+ '"text":"' + this.seriesList[j].name + '",'
						+ '"fill-alpha": 0.1,"fill": "'+this.seriesColors[j]+'",'
						+ '"font-size": 10,'
						+ '"dot-style": {"type": "hollow-dot","dot-size": 4,"halo-size": 0,'
						+ '"tip":"'+  theTip + '",'
						+ '"colour": "'+this.seriesColors[j]+'"},';
					s += '"values":[';

					/* Insert values */
					for ( var i = 0; i < series.length; i++) {
						var value = parseInt(series[i].value);

						if(isNaN(value))
						{
							value=null;
						}
						/*s += '{"x":'+i+' ,';
						if(isNaN(value))
						{
							s+= '"y":0}';
						}
						else
						{
							s+= '"y":' + value + '}';
						}*/

						s+= value;
						if (value > maxValue) {
							maxValue = value;
						}
						if (i < (series.length - 1)) {
							s += ",";
						}
					}
					s += ']}';
					if (j < (this.seriesList.length - 1)) {
						s += ",";
					}
				}
				s += '],';

				/* Format X-axis */
				s += '"x_axis":{"min":0, "max":'+numOfXLabels+ ',"visible-steps":0, "steps":'+numOfXLabels+',"stroke":1,"tick_height":5,"offset":10,"colour":"#aaaaaa","grid-colour":"#cccccc","labels": {"rotate":320,';

				/* Insert labels */
				s += '"labels":[';

				/* This is an ugly hack to hide labels when there are many of them */
				var visibleSteps = parseInt(numOfXLabels/this.maxXLabels); //Calculate which gap we should have between each visible step (x-axis label)
				var stepCounter = 0;
				if(series)
				{
				  for ( var i = 0; i < series.length; i++) {
					  stepCounter++;

						  var label = series[i].label;
						 // s += '"' + label + '"';
						  s += '{"x":'+i+',"text":"' + label + '",';
						  if(visibleSteps==0 || stepCounter == visibleSteps)
						  {
							  s+= '"visible":true,';
							  stepCounter=0;
						  }
						  else
						  {
							  s+= '"visible":false,';
						  }
						  s+= '"justify":"left"}';
						  if (i < (series.length - 1)) {
							  s += ",";
						  }
				  }
				}
				s+=']';

				s += '}},';

				/* Format Y-axis */
				var yMax = this.getOfcMax(maxValue);

				if (this.yMax > 0)
				{
					yMax = this.yMax;
				}

				s += '"y_axis":{"stroke":2, "tick_height":5,"tick_length":3,"colour":"#cccccc","grid-colour": "#cccccc","offset":0,"min":0,"max":"';
				s += yMax;
				s += '","visible-steps":10, "steps":"' +this.getOfcYsteps(yMax) + '"';

				/* Format Background */
				s += '},"bg_colour":"#ffffff","bg_image":"'+this.bgImage+'","bg_image_x":"center","bg_image_y":"middle"}';

				return s;
			},

			getBarChart : function() {
				var s = '{"title":{"text":"' + this.title + '","style": "{font-size: 20px; color:#666666; font-family: Verdana; text-align: center;}"},';

				s += '"elements":[';

				/* Loop each series in seriesList */
				for(var j=0; j < this.seriesList.length; j++)
				{
					var theTip = "#x_label#<br>#val#";
                    if(this.seriesList[j].tip)
                    {
                        theTip = this.seriesList[j].tip;
                    }
                    var series = this.seriesList[j].series;

					/* "on-show":{"type":""} disables the initial graph animation */
					s += '{"on-show":{"type":""},"type":"bar",'
							+ '"tip":"'+  theTip + '",'
							+ '"barwidth":0.9,"alpha":0.7,"colour":"'+this.seriesColors[j] + '",'
                            + '"text":"'+  this.seriesList[j].name + '",'
							+ '"font-size": 10,"fill-alpha":0.2,';
					s += '"values":[';
					var max = 0;
					for ( var i = 0; i <series.length; i++) {
						var value = parseInt(series[i].value);
						s += series[i].value; /* Bar value should be formatted already in the JSON response. We can't always force it to be an Integer */
						if (value > max) {
							max = value;
						}
						if (i < (series.length - 1)) {
							s += ",";
						}
					}
					s += ']}';
					if (j < (this.seriesList.length - 1)) {
						s += ",";
					}
				}
				s += '],';
				s += '"x_axis":{"visible-steps": 10, "steps":"2","stroke":2,"tick_height":5,"offset":10,"colour":"#aaaaaa","grid-colour":"#cccccc","labels": {"steps":"2", "rotate":320,';
				s += '"labels":[';

				if(series)
				{
				  for ( var i = 0; i < series.length; i++) {
					  var label = series[i].label;
					  s += '"' +label + '"';
					  if (i < (series.length - 1)) {
						  s += ",";
					  }
				  }
				}
				s += ']}},';
				var yMax = this.getOfcMax(max);

				s += '"y_axis":{"stroke":2, "tick_height":5,"tick_length":3,"colour":"#cccccc","grid-colour": "#cccccc","offset":0,"min":0,"max":"';
				s += yMax;
				s += '","steps":"' +this.getOfcYsteps(yMax) + '"';
				s += '},"bg_colour":"#ffffff","bg_image":"'+this.bgImage+'","bg_image_x":"center","bg_image_y":"middle"}';

				return s;
			},

			getPieChart : function() {
				var s = '{"title":{"text":"' + this.title + '","style": "{font-size: 20px; color:#666666; font-family: Verdana; text-align: center;}"},';

				s += '"elements":[';

				/* Loop each series in seriesList (Can you really do this in a pie chart ???) */
				for(var j=0; j < this.seriesList.length; j++)
				{
					var series = this.seriesList[j].series;

					s += '{"type":"pie","animate": [ { "type": "fade" }, { "type": "bounce", "distance": 10 }],'
							+ '"tip":"'+  this.seriesList[j].tip + '",'
							+ '"alpha":0.7,"colours":'+ this.seriesColors.toJSON() + ','
                            + '"text":"'+  this.seriesList[j].name + '",'
							+ '"font-size": 10,"fill-alpha":0.2,';
					s += '"values":[';

					for ( var i = 0; i <series.length; i++) {
						var value = parseInt(series[i].value);
						s += '{"value":'+series[i].value+', "label":"'+series[i].label+'"}';
						if (i < (series.length - 1)) {
							s += ",";
						}
					}
					s += '],"radius": 100}';
					if (j < (this.seriesList.length - 1)) {
						s += ",";
					}
				}
				s += '],';
				s += '"bg_colour":"#ffffff","bg_image":"'+this.bgImage+'","bg_image_x":"center","bg_image_y":"middle"}';

				return s;
			},

			getOfcYsteps : function(yMax)
			{
				var ySteps = 1;

				if(yMax > 200000){
					ySteps = 50000;
				}
				else if(yMax > 20000){
					ySteps = 10000;
				}
				else if(yMax > 2000){
					ySteps = 1000;
				}
				else if(yMax > 200){
					ySteps = 100;
				}
				else if(yMax > 20)
				{
					ySteps =  10;
				}
				else if(yMax > 1)
				{
					ySteps =  1;
				}
				else if(yMax > 0.5)
				{
					ySteps =  0.1;
				}

				/* console.log("yMax=" +yMax+ " ySteps=" + ySteps); */
				return  ySteps;
			},

			getOfcMax : function(val) {
				var max = parseInt(val);
				if (max < 1) {
					return 1;
				}

				var mod = Math.pow(10, ("" + max).length - 1);
				max = max - (max % mod) + mod;

				return max;
			}
});