
Namespace.register('aegoncz.funds');

/* FundViewChart Class
------------------------------------------------------------*/
aegoncz.funds.FundViewChart = new Class({
	
	Extends:aegoncz.funds.FundViewBase,
	
	detail:null,
	master:null,
	funds:[],
	granularityMultiplier:Browser.ie ? 3.0 : 1.5,
	pointSpread:2,
	
	initialize:function(container,colors) {
		
		this.parent(container,colors);
		
		// add detail and overview holders
		var domMaster = new Element('div',{'class':'chart-decorator'});
		
		var domDetail = new Element('div',{'class':'chart-decorator'});
			domDetail.adopt(new Element('div',{'class':'chart-wrapper'}));
		
		this.container.adopt(domDetail,domMaster);
		
		// set self reference
		var self = this;
		
		// init detail chart
		this.detail = new Highcharts.Chart({
			chart: {
				renderTo:domDetail.getElement('div'),
				margin:[10,1,90,40],
				height:320,
				showAxes:true,
				animation:false,
				events:{
					redraw:function(e) {
						self.setReady(this);
					}
				}
			},
			loading:{
				hideDuration:0,
				showDuration:0,
				enabled:false
			},
			credits:{
				enabled:false
			},
			title: {
				text:null
			},
			plotOptions:{
				line:{
					shadow:false,
					marker:{
						enabled:false
					},
					states:{
						hover:{
							enabled:false
						}
					}
				}
			},
			xAxis: {
				title:null,
				type:'datetime',
				lineColor:'#e0e0e0',
				gridLineWidth:0,
				tickPixelInterval:40,
				labels:{
					align:'left',
					rotation:90,
					x:-4,
					style: {
						font:'11px bold "Lucida Grande", "Lucida Sans Unicode",Verdana, Arial, Helvetica, sans-serif'
					},
					formatter:function(){
						return new Date(this.value).format('date');
					}
				}
			},
			yAxis: {
				title:null,
				lineColor:'#e0e0e0',
				gridLineColor:'#e0e0e0',
				lineWidth:1,
				tickPixelInterval:40
			},
			tooltip: {
				formatter: function() {
					return new Date(this.x).format('date') + ':<b>' + this.y + '</b>';
				},
				style: {
					padding: '5px 0 5px 18px'
				}
			},
			legend: {
				enabled:false
			}
		});
		
		// init overview chart
		this.master = new Highcharts.Chart({
			chart: {
				renderTo:domMaster,
				margin:[10,1,90,40],
				height:180,
				showAxes:true,
				zoomType:'x',
				animation:false,
				events:{
					selection:function(e) {
						self.fireEvent(mirabeau.events.Event.CHANGED,[e.xAxis[0].min,e.xAxis[0].max]);
						e.stop();
					},
					redraw:function(e) {
						self.setReady(this);
					}
				}
			},
			loading:{
				hideDuration:0,
				showDuration:0,
				enabled:false
			},
			credits:{
				enabled:false
			},
			title: {
				text:null
			},
			plotOptions:{
				line:{
					shadow:false,
					marker:{
						enabled:false
					},
					states:{
						hover:{
							enabled:false
						}
					}
				}
			},
			xAxis: {
				title:null,
				type:'datetime',
				maxZoom:this.day,
				lineColor:'#e0e0e0',
				gridLineWidth:0,
				tickPixelInterval:40,
				labels:{
					align:'left',
					rotation:90,
					x:-4,
					style: {
						font:'11px bold "Lucida Grande", "Lucida Sans Unicode",Verdana, Arial, Helvetica, sans-serif'
					},
					formatter:function(){
						return new Date(this.value).format('date');
					}
				}
			},
			yAxis: {
				title:null,
				lineColor:'#e0e0e0',
				gridLineColor:'#e0e0e0',
				lineWidth:1,
				tickPixelInterval:40
			},
			tooltip:{
				enabled:false
			},
			legend:{
				enabled:false
			}
		});
		
	}
	
});

aegoncz.funds.FundViewChart.implement({
	
	setLoading:function(chart) {
		
		// if not loading already
		if (!chart.options.loading.enabled) {
			chart.showLoading();
			chart.options.loading.enabled = true;
		}
		
	},
	
	setReady:function(chart) {
		
		// if loading
		if (chart.options.loading.enabled) {
			chart.hideLoading();
			chart.options.loading.enabled = false;
		}
	},
	
	showLoading:function() {
		
		this.setLoading(this.master);
		this.setLoading(this.detail);
		
	},
	
	hideLoading:function() {
		
		this.setReady(this.master);
		this.setReady(this.detail);
		
	},
	
	setData:function(data) {
		
		// store funds
		for(var i=0;data.funds[i]!=undefined;i++) {
			this.funds[i] = data.funds[i];
		}
		
		this.setMaster();
	},
	
	filterData:function(data,granularity) {
		
		// filter data
		var count = data.length;
		var filtered = [];
		for	(var i=0;i<count;i+=granularity) {
			filtered.push(data[i]);
		}
		
		// add last entry
		filtered.push(data[count-1]);
		
		return filtered;
	},
	
	setMaster:function(data) {
		
		var i,j,granularity,data,filtered,pointCount,series,fund;
		
		// remove previously existing series overlapping with new series
		for(i=0;this.funds[i]!=undefined;i++) {
			series = this.master.get('series-' + this.funds[i].id);
			if (series) {
				series.remove(false);
			}
		}
		
		// draw received series
		for(i=0;this.funds[i]!=undefined;i++) {
			
			fund = this.funds[i];
			granularity = 1;
			filtered = null;
			pointCount = fund.data.length;
			
			if (pointCount > this.master.chartWidth / this.pointSpread) {
				granularity = Math.round((pointCount / this.master.chartWidth) * this.pointSpread * this.granularityMultiplier);
				if (granularity > 1) {
					filtered = this.filterData(fund.data,granularity);
				}
			}
			
			// set series object
			var series = {
				id:'series-' + fund.id,
				pointStart:fund.offset,
				pointInterval:this.day * granularity,
				name:fund.id,
				data:filtered || fund.data,
				animation:false,
				type:'line'
			};
			
			series.color = fund.average ? '#000' : this.colors[i];
			
			this.master.addSeries(series,false);
		}
		
		this.master.redraw();
	},
	
	setPeriod:function(from,to) {
		
		// show loading indicator
		this.setLoading(this.detail);
		
		// init period
		this.period.from = from;
		this.period.to = to;
		
		// mark period in master chart
		this.markPeriod();
		
		// draw the period
		this.drawPeriod.delay(250,this);
	},
	
	markPeriod:function() {
		
		if (this.period.from == null || this.period.to == null) {
			return;
		}
		
		// mark area on master chart
		this.master.xAxis[0].removePlotBand('period');
		this.master.xAxis[0].removePlotLine('period-from');
		this.master.xAxis[0].removePlotLine('period-to');
		
		this.master.xAxis[0].addPlotBand({
			id:'period',
			from:this.period.from,
			to:this.period.to,
			color:'rgba(0,0,0,.05)'
		});
		
		this.master.xAxis[0].addPlotLine({
			id:'period-from',
			color:'rgba(0,0,0,.25)',
			value:this.period.from,
			width:1
		});
		
		this.master.xAxis[0].addPlotLine({
			id:'period-to',
			color:'rgba(0,0,0,.25)',
			value:this.period.to,
			width:1
		});
	},
	
	drawPeriod:function() {
		
		if (this.period.from == null || this.period.to == null) {
			return;
		}
		
		var fund = null;
		var data = null;
		var date = null;
		var detailSeries = null;
		var entries = 0;
		
		// hide all series in detail chart
		for	(var i=this.detail.series.length;i--;) {
			this.detail.series[i].hide();
		}
		
		// loop through funds
		for (var i=0;this.funds[i]!=undefined;i++) {
			
			
			// get series reference
			fund = this.funds[i];
			data = [];
			pointCount = fund.data.length;
			
			for (var j=0;j<pointCount;j++) {
				
				date = fund.offset + (j * this.day);
				
				// get data in period
				if (date > this.period.from && date < this.period.to) {
					data.push({
						x:date,
						y:fund.data[j]
					});
				}
			}
			
			// get new point count after data range
			pointCount = data.length;
			
			if (pointCount > 0) {
				
				var granularity = 1;
				var filtered = null;
				
				if (pointCount > this.detail.chartWidth / this.pointSpread) {
					granularity = Math.round((pointCount / this.detail.chartWidth) * this.pointSpread * this.granularityMultiplier);
					if (granularity > 1) {
						filtered = this.filterData(data,granularity);
					}
				}
				
				// get data
				data = filtered || data;
				
				// check if series exists in detail chart
				detailSeries = this.detail.get('series-' + fund.id);
				
				if (detailSeries) {
					
					// update detail data
					detailSeries.options.pointStart = this.period.from;
					detailSeries.setData(data,false);
					detailSeries.show();
					
				}
				else {
					
					// create new series
					detailSeries = {
						id:'series-' + fund.id,
						pointStart:this.period.from,
						pointInterval:this.day * granularity,
						name:fund.id,
						data:data,
						animation:false,
						type:'line'
					};
					
					detailSeries.color = detailSeries.name === 'AVG' ? '#000' : this.colors[i];
					
					this.detail.addSeries(detailSeries,false);
				}
			}
		}
		
		this.detail.redraw();
	}
});

