/**
 * Demonstration of some of Ext's features. Particularly the new Chart
 * component. Stock data is fetched from Yahoo API.
 * 
 * This is part of the Ext JS charts demo:
 * http://joefreeman.co.uk/blog/2009/07/stocks-with-ext-js-charts/
 * 
 * Copyright (C) 2009, Joe Freeman <joe.freeman@bitroot.com>
 * Available under http://en.wikipedia.org/wiki/MIT_License
 */

Ext.chart.Chart.CHART_URL = 'lib/ext-3.0-rc3/resources/charts.swf';

ExtStock = {
	
	init: function() {
		
		this.symbols = new Ext.util.MixedCollection();
		
		this.setupViewport();
		this.addSymbol('GOOG');
	},
	
	setupViewport: function() {
		
		this.headerPanel = new Ext.Panel({
			region: 'north',
			margins: '10 5 0 5',
			layout: 'hbox',
			items: [{
				xtype: 'panel',
				html: '<h1 class="app-title">ExtStock Demo</h1>',
				bodyStyle: 'background:none;',
				border: false
			},{
				xtype: 'button',
				text: 'Add Symbol...',
				icon: 'img/icons/add.png',
				handler: this.promptForSymbol,
				scope: this
			}],
			bodyStyle: 'background:none;',
			height: 30,
			border: false
		});
		
		this.dataPanel = new Ext.TabPanel({
			region: 'west',
			margins: '5 0 5 5',
			split: true,
			width: 300,
			activeTab: 0,
			enableTabScroll:true,
			items: [{
				title: 'About',
				cls: 'about-panel',
				autoLoad: {
					url: 'about.html'
				}
			}]
		});
		
		this.chartPanel = new Ext.Panel({
			region: 'center',
			margins: '5 5 5 0',
			layout: 'card'
		});
		
		new Ext.Viewport({
			layout: 'border',
			items: [this.headerPanel, this.dataPanel, this.chartPanel]
		});
	},
	
	promptForSymbol: function(button, event) {
		
		if (!this.symbolPrompt) {
			
			var store = new Ext.data.JsonStore({
				url: 'symbols.php',
				autoLoad: true,
				root: 'symbols',
				fields: ['symbol', 'name']
			});
			
			var symbolField = new Ext.form.ComboBox({
				store: store,
				displayField: 'symbol',
				tpl: '<tpl for="."><div class="x-combo-list-item">{name}</div></tpl>',
				typeAhead: true,
				mode: 'local',
				emptyText: 'Select a stock symbol...',
				selectOnFocus: true,
				fieldLabel: 'Symbol'
			});
			
			var submitFn = function(){
				this.addSymbol(symbolField.getValue());
				this.symbolPrompt.hide();
			};
			
			var form = new Ext.FormPanel({
				padding: 10,
				border: false,
				items: symbolField,
				keys: [{
					key: [10,13],
					fn: submitFn,
					scope: this
				}]
			});
			
			this.symbolPrompt = new Ext.Window({
				title: 'Add Symbol',
				iconCls: 'add-icon',
				modal: true,
				closeAction: 'hide',
				items: form,
				buttons: [{
					text: 'OK',
					handler: submitFn,
					scope: this
				},{
					text: 'Cancel',
					handler: function(b, e) {
						this.symbolPrompt.hide();
					},
					scope: this
				}],
				listeners: {
					show: function(win) {
						symbolField.setValue('');
						symbolField.focus(true, true);
					}
				}
			});
		}
		
		this.symbolPrompt.show(button);
	},
	
	addSymbol: function(symbol) {
		
		if (this.symbols.containsKey(symbol)) {
			
			var s = this.symbols.get(symbol)
			
			this.dataPanel.setActiveTab(s.dataPanel);
			this.chartPanel.getLayout().setActiveItem(s.chartPanel.getId());
			
			return;
		}
		
		var store = new Ext.data.JsonStore({
			baseParams: {
				symbol: symbol
			},
			autoLoad: true,
			url: 'data.php',
			root: 'data',
			fields: [{name: 'date', type: 'date', dateFormat: 'time'}, 'open', 'high', 'low', 'close', 'volume'],
			listeners: {
				exception: function(dataProxy, action, rs, params) {
					Ext.MessageBox.alert(
						'Couldn\'t load symbol',
						'Data for the symbol \'' + symbol + '\' could not be loaded. Maybe it doesn\'t exist?',
						function() {
							this.unloadSymbol(symbol);
						},
						this
					);
				},
				load: function(store, records, options) {
					this.symbols.get(symbol).dataView.getEl().unmask();
				},
				scope: this
			}
		});
		
		var chart = new Ext.chart.LineChart({
			store: store,
			id: 'chart-' + symbol,
			xField: 'date',
			xAxis: new Ext.chart.TimeAxis({
				labelRenderer : Ext.util.Format.dateRenderer('d/m/y'),
				majorTimeUnit: 'day'
            }),
			series: [{
				displayName: 'High',
				yField: 'high',
				style: {
					color: 0x88ff88,
					size: 1,
					lineSize: 1
				}
			},{
				displayName: 'Low',
				yField: 'low',
				style: {
					color: 0xff8888,
					size: 1,
					lineSize: 1
				}
			},{
				displayName: 'Close',
				yField: 'close',
				style: {
					color: 0x555555,
					size: 6,
					lineSize: 1
				}
			}],
			listeners: {
				itemmouseover: function(o){
					this.symbols.get(symbol).dataView.select(o.index);
				},
				scope: this
			},
			extraStyle: {
				legend: {
					display: 'right'
				},
				yAxis: {
					majorGridLines: {
						color: 0xdddddd
					}
				}
			},
			tipRenderer : function(chart, record, i, series){
				return (new Date(record.data.date)).format('jS M Y');
			}
		});
		
		this.chartPanel.add(chart);
		
		var dataView = new Ext.ListView({
			title: symbol,
			closable: true,
			store: store,
			emptyText: 'Loading...',
			singleSelect: true,
			columns: [
				{header: 'Date', dataIndex: 'date', tpl: '{date:date("jS M Y")}', width: 0.3},
				{header: 'Open', dataIndex: 'open'},
				{header: 'High', dataIndex: 'high'},
				{header: 'Low', dataIndex: 'low'},
				{header: 'Close', dataIndex: 'close'},
				{header: 'Volume', dataIndex: 'volume', width: 0.2}
			],
			style: 'background:#FFF;',
			listeners: {
				activate: function(panel) {
					this.chartPanel.getLayout().setActiveItem('chart-' + symbol);
				},
				close: function(panel) {
					this.unloadSymbol(symbol);
				},
				scope: this
			}
		});
		
		this.symbols.add(symbol, {
			store: store,
			dataView: dataView,
			chartPanel: chart
		});
		
		this.dataPanel.add(dataView);
		this.dataPanel.setActiveTab(dataView);
		
		dataView.getEl().mask('Fetching data...');
	},
	
	unloadSymbol: function(symbol) {
		
		var s = this.symbols.removeKey(symbol);
		
		this.dataPanel.remove(s.dataView);
		this.chartPanel.remove(s.chartPanel.getId());
	}
};

Ext.onReady(ExtStock.init, ExtStock);