/**
 * @filename activityCharts.js
 * @description Initializes charts dynamically based on HTML DOM elements on the page. 
 * 
 * CONFLUENCE LINK HERE
 * 
 * @author Diana Chow
 *
 * Copyright(c) 2009, Garmin International
 */

/**
 * ChartComponentConstants
 */
var ChartComponentConstants = {
	// Major version of Flash required
	FLASH_MAJOR_VERSION: 10,
	// Minor version of Flash required
	FLASH_MINOR_VERSION: 0,
	// Revision of Flash required
	FLASH_REVISION: 0
};

/**
 * CSS values used to retrieve the elements that initialize the chart display 
 */
ChartCss = {
    CHART_CONTAINER: '.chartContainer',
    SWF_CONTAINER: '.swfContainer',
    CHART_SETTINGS: '.chartSettings',    
    CHART_TYPE: '.chartType',
    DOMAIN_FIELD: '.domainField',
    DOMAIN_UNIT: '.domainUnit',
    RANGE1_FIELD: '.range1Field',
    RANGE1_UNIT: '.range1Unit',
    TIME_SELECT: '.chartTimeSelect'
};

ChartIds = {
    TOGGLE_AVERAGE: '#toggleAverageCheckbox',
    TIMING_CHART: '#chartPanel_timingSwf',
    HEARTRATE_CHART: '#chartPanel_heartRateSwf',
    POWER_CHART: '#chartPanel_powerSwf'
}

ChartType = {
	AREA: 'area',
	BAR: 'bar',
	LINE: 'line',
	COLUMN: 'column'
};

amfQueue = new Array();
hostChart = null;

chartReady = function(chartId) {
    if( Activity.AMF == null) {
		// if we don't have a host chart yet then we need to designate one
		if (hostChart == null) {
			hostChart = jQuery('#'+chartId+'Swf')[0];
			
			// set the amfCallbackFunctionName
			hostChart.setParameter('amfCallbackFunctionName','amfReady');
			
			// set the file location and oauth header
			if($('axmLocationProxy') != null) {
				hostChart.loadFile(unescape($F("axmLocationProxy"))); 
			} else if ($('axmLocation') != null) {
				hostChart.setParameter('authHeader',$F("authHeader"));
				hostChart.loadFile(unescape($F("axmLocation"))); 
			}
		} else {
			amfQueue.push(chartId);
		}
    } else {
        jQuery('#'+chartId+'Swf')[0].setAMFData(Activity.AMF);
    }
};

amfReady = function(amf) {
    Activity.AMF = amf;
	for( var i=0; i < amfQueue.length; i++) {
        jQuery('#'+amfQueue[i]+'Swf')[0].setAMFData(Activity.AMF);
    }
}

ChartComponent = {
		// available chart types are area, line, column, and bar
		init : function(){
			this.chartObjects = new Array();
			this.numCharts = null;
			this.containerElements = null;
			this.chartIds = new Array();
			
			this._detectChartContainers(ChartCss.CHART_CONTAINER, ChartCss.CHART_SETTINGS)
			
			for(var i=0; i < this.numCharts; i++) {
			    var chartContainer = this.containerElements[i];
				
    			// generate chart options
			    var chartOptions = this._generateChartOptions(chartContainer, i);
			    
    			// create chart object
    			var containerId = chartContainer.id;
    			var panelId = chartContainer.down(ChartCss.SWF_CONTAINER).id;
    			
    			var chartObject = new ActivityChart(containerId, panelId, chartOptions, {
    			    requiredVersion: {
    			        major: ChartComponentConstants.FLASH_MAJOR_VERSION,
    			        minor: ChartComponentConstants.FLASH_MINOR_VERSION,
    			        revision: ChartComponentConstants.FLASH_REVISION
    			    }
			    });
    			this.chartObjects.push(chartObject);
			}
			
			this.attachActionListeners();
		},
		
		attachActionListeners: function() {
		    // Average line toggle
		    jQuery(ChartIds.TOGGLE_AVERAGE).bind('click', function(e) {
		        var checkbox = jQuery(this);
	            jQuery(ChartCss.SWF_CONTAINER).each(function() {
	                var swfContainer = jQuery(this);
	                var chartObj = swfContainer.children()[0]; // flash object is always the immediate child
    		        if( checkbox.attr('checked') ) {
	                    chartObj.showAverageLine();
	                } else {
	                    chartObj.hideAverageLine();
	                }
	            });
		    });
		    
		    // Update units based on toggle
		    jQuery(ChartIds.TIMING_CHART).hear(EventBus.Events.CHANGE_TIMING_UNIT, function($self, data) {
		        $self[0].setRange1Display(data.field, data.unit);
		    });
		    jQuery(ChartIds.HEARTRATE_CHART).hear(EventBus.Events.CHANGE_HEARTRATE_UNIT, function($self, data) {
		        $self[0].setRange1Display(data.field, data.unit);
		    });
		    jQuery(ChartIds.POWER_CHART).hear(EventBus.Events.CHANGE_POWER_UNIT, function($self, data) {
		        $self[0].setRange1Display(data.field, data.unit);
		    });
		    
		    // Update time/moving time from select
		    jQuery(ChartCss.TIME_SELECT).bind('change', function() {
		        var timeSelect = jQuery(this);
		        var chartObj = timeSelect.parent().siblings(ChartCss.CHART_CONTAINER).children(ChartCss.SWF_CONTAINER).children()[0]; // flash object is always the immediate child
		        var timeSelectValue = timeSelect.attr('value');
	            chartObj.setDomainDisplay(timeSelectValue);
		    });
		},
	
		/**
		 * Detects the chart containers on the page. 
		 * Verifies same number of chart settings as chart containers.  
		 * Stores number of charts detected.
		 * Generates chart IDs for client charts.
		 */
		_detectChartContainers: function(containerClassname, settingsClassname) {
		    this.containerElements = $$(ChartCss.CHART_CONTAINER);
		    var settingsElements = $$(ChartCss.CHART_SETTINGS);
		    this.numCharts = this.containerElements.size();
		    
            if(this.numCharts != settingsElements.size() ) {
                throw new Error('Mismatching number of chart containers and chart settings. Check the DOM.');
            }
			this.chartIds = this._detectChartIds();
		},
		
		/**
		 * @param containerElement {Element} container element for the chart. Should contain settings for chart too.
		 * @param index {Number} the index of the chart in the list, used to determine host/client
		 * @return flash chart options to construct ActivityChart object
		 */
		_generateChartOptions: function(containerElement, index) {
		    
		    var chartSettings = containerElement.down(ChartCss.CHART_SETTINGS);
		    
		    var chartType = chartSettings.down(ChartCss.CHART_TYPE).innerHTML;
		    var domainField = chartSettings.down(ChartCss.DOMAIN_FIELD).innerHTML;
		    var range1Field = chartSettings.down(ChartCss.RANGE1_FIELD).innerHTML;
		    var configurations = {
	             formats: {
                    decimalSeparator: User.NUMBER_FORMAT == 'decimal_period' ? '.' : ',',
                    thousandSeparator: User.NUMBER_FORMAT == 'decimal_period' ? ',' : '.'
                 }
	        };
		    
		    // Set the options we know
		    var chartOptions = {
		        domainField: domainField
		        ,range1Field: range1Field
		        ,configurations: encodeURI(Object.toJSON(configurations)) // Prototype util method to get JSON string
		    };
		    
            chartOptions.chartId = this.chartIds[index];
            
			
		    //if(index == 0) {
		    //    chartOptions.dataSourceType = 'file';
		    //    if($('axmLocationProxy') != null) {
    		//		chartOptions.dataFile = $F("axmLocationProxy"); 
		    //    } else if ($('axmLocation') != null) {
    		//		chartOptions.dataFile = $F("axmLocation"); 
			//	    chartOptions.authHeader = escape($F("authHeader"));
		    //    }
		    //    chartOptions.amfCallbackFunctionName = 'amfReady';
		    //} else {
                chartOptions.dataSourceType = 'provided';
		    //}
		    
		    return chartOptions;
		},
		
		/**
		 * Generates unique client IDs for each chart.  Client IDs are based on the time that the generation occurs to 
		 * ensure uniqueness.
		 * @param clientSize {Number} number of clients to generate IDs for    
		 * @return {String} comma delimited string of unique IDs
		 */
		_detectChartIds: function() {
		    var chartIds = new Array();
		    jQuery(ChartCss.SWF_CONTAINER).each(function() {
                var swfContainer = jQuery(this);
		        chartIds.push(swfContainer.attr('id')); 
            });
		    
		    return chartIds;
		},
		
		/**
		 * Convert array contents to comma delimited string
		 */
		_flattenArray: function(stringArray) {
		    var string = '';
		    for( var i = 0; i < stringArray.length; i++) {
		        string += stringArray[i];
		        if(i < stringArray.length - 1) {
                    string += ','; 
		        }
		    }
		    return string;
		}

};
document.observe("dom:loaded", function() {
  ChartComponent.init();
});
