/* ChartManager
** This is to abstract the selection and rendering of different FusionCharts.
** Requires MooTools v1.2 and FusionCharts v3
*/

var BaseChart = new Class({
	options: {
		heading: 'A Chart!',
		mediaUrl: '/media/',
		swfUrl: '',
		scriptName: '',
		chartId: 'somethinUnique',
		width: 600,
		height: 300,
		debugMode: 0,
		registerWithJs: 0
	},
	chart: null,

	initialize: function(o) {
		this.setOptions(o);
	},
	
	createChart: function() {
		this.chart = new FusionCharts(
						this.options.mediaUrl + this.options.swfUrl,
						this.options.chartId,
						this.options.width,
						this.options.height,
						this.options.debugMode,
						this.options.registerWithJs
					);
	},

	render: function(target, stateUrl) {
		this.createChart();
		this.chart.setDataURL(stateUrl + this.options.scriptName + '/');
		this.chart.addParam("wmode","transparent");
		this.chart.render(target);
	}
});
BaseChart.implement(new Options);

var BarChart = new Class({
	Extends: BaseChart,
	options: {
		swfUrl: 'fusion_charts/Column3D.swf'
	}
});

var LineChart = new Class({
	Extends: BaseChart,
	options: {
		swfUrl: 'fusion_charts/MSLine.swf'
	}
});

var ScatterChart = new Class({
	Extends: BaseChart,
	options: {
		swfUrl: 'fusion_charts/Scatter.swf'
	}
});

var LogScatterChart = new Class({
    Extends: BaseChart,
    options: {
        swfUrl: 'fusion_charts/LogScatter.swf'
    }
});

var MSBarChart = new Class({
	Extends: BaseChart,
	options: {
		swfUrl: 'fusion_charts/MSColumn3D.swf'
	}
});

var MSAreaChart = new Class({
	Extends: BaseChart,
	options: {
		swfUrl: 'fusion_charts/MSArea.swf'
	}
});

var ChartManager = new Class({
	options: {
		baseDataUrl:'/',
		stateUrl:'/',
		auctionRange:'3',
		priceRange:'medianprices',
		priceRanges: {
			all:[null, null],
			medianprices:[null,null],
			top:[15000,null],
			excellent:[15000,30000],
			good:[3000,30000],
			fair:[3000,15000],
			low:[null, 3000],
			custom:[null, null]
		}
	},
	elContainer: null,
	elChartContainer: null,
	elChartHeading: null,
	elPriceAdjusterContainer: null,
	charts: null,
	selectedChartId: '',
	selectedAuctionRange: '3',
	selectedPriceRange: 'medianprices',
	marketSummary:null,

	initialize: function(e, priceAdjusterContainer, src, o) {
		this.setOptions(o);
		this.selectedAuctionRange = this.options.auctionRange;
	        this.selectedPriceRange = this.options.priceRange;
		this.elContainer = $(e);
		this.elPriceAdjusterContainer = $(priceAdjusterContainer)
		this.elChartContainer = this.elContainer.getElement('.chartContainer');
		this.elChartHeading = this.elContainer.getElement('.chartHeading');
		this.charts = {};
	        this.marketSummary = new MarketSummary(
	            this.elContainer.getElement('.remoteMarketSummary'),
		    $(src),
		    {}
		);
		
		var priceForm = this.elPriceAdjusterContainer.getElement('#priceRangeForm');
	        priceForm.addEvent('submit', this._ui_setPriceRangeCustom.bindWithEvent(this));
	},

	addCharts: function(cs) {
		cs.each(function(c) {
			this.charts[c.options.chartId] = c;
		}, this);
	},
	
	getStateUrl: function(usePriceRange) {
		url = 'range/' + this.selectedAuctionRange + '/';
		url += this._priceRangeUrl();
		return url; 
	},
	
	_priceRangeUrl: function() {  
		if(this.selectedPriceRange == 'all')
			return '';
		// we now have at least one limit on price
		var url = 'price_range/';
		var prange = this.options.priceRanges[this.selectedPriceRange];
		if(prange[0] == null && prange[1] == null)
			return '';
		if(prange[0] == null) //must be a max-cap
			return url + '0-' + prange[1] + '/';
		url += prange[0];
		if(prange[1] != null)
			url += '-' + prange[1];
		return url + '/';
	},

	_setPriceRangeForm: function(low_price, high_price) {
	        var prl = this.elPriceAdjusterContainer.getElement('input.lowPriceRange');
	        var prh = this.elPriceAdjusterContainer.getElement('input.highPriceRange');
	        prl.set('value', low_price);
	        prh.set('value', high_price);
	},

	_ui_setPriceRangeCustom: function(e) {
	        var evt = Event(e);
	        evt.stop();
	        this.setPriceRangeCustom();
	},

	_ui_selectPriceRange: function(e) {
	        var cboPriceRange = this.elPriceAdjusterContainer.getElement('select.priceRangePicker');
	        var selectedVal = cboPriceRange.get('value');
	        if(this.selectedPriceRange==selectedVal) 
			return;
		var prange = this.options.priceRanges[this.selectedPriceRange];
	        if(prange[0] == null && prange[1] == null && selectedVal=='custom')
			return;
		this._setPriceRangeForm(selectedVal);
		this.setPriceRange(selectedVal);
	},

	setPriceRange: function(value) {
	        var selectedVal = value;
	        if(this.selectedPriceRange==selectedVal) 
			return;
		this.selectedPriceRange = selectedVal;
		var prange = this.options.priceRanges[selectedVal];
	        if(prange[0] == null && prange[1] == null && selectedVal=='custom')
			return;
		this._setPriceRangeForm(prange[0], prange[1]);
		this.showChart(this.selectedChartId, true);		
	},
	
	setPriceRangeCustom: function(lowPriceValue, highPriceValue) {
		// TODO: get price range from form fields
		var txtLow = this.elPriceAdjusterContainer.getElement('input.lowPriceRange');
		var txtHigh = this.elPriceAdjusterContainer.getElement('input.highPriceRange');
//		var lowPrice = parseInt(txtLow.get('value'));
//		var highPrice = parseInt(txtHigh.get('value'));
		var lowPrice = parseInt(lowPriceValue);
		var highPrice = parseInt(highPriceValue);
		lowPrice = isNaN(lowPrice) ? null : lowPrice;
		highPrice = isNaN(highPrice) ? null : highPrice;
		this.options.priceRanges.custom = [lowPrice, highPrice];    
		this.selectedPriceRange = 'custom'
		this._setPriceRangeForm(lowPrice, highPrice);
		this.showChart(this.selectedChartId, true);
	},

	setDateRange: function(dateRange) {
		if(this.selectedAuctionRange && this.selectedAuctionRange == dateRange) 
			return;
		this.selectedAuctionRange = dateRange;	
		this.showChart(this.selectedChartId, true);
	},

	showChart: function(cId, force) {
		if(cId == this.selectedChartId && !force)
			return;
		this.selectedChartId = cId;
		var chart = this.charts[cId];
		//this.elChartHeading.set('text', chart.options.heading);
		var stateUrl = this.options.baseDataUrl + this.getStateUrl();
		var chartUrl = '/auctions/xml' + stateUrl;
		//console.log('rendering ' + chartUrl);
		this.marketSummary.updateWithState(stateUrl);
		chart.render(this.elChartContainer, chartUrl);
	}
});
ChartManager.implement(new Options);


