Ext.define('Ext.ux.google.charts.Gantt', {
	extend: 'Ext.ux.google.charts.Charts',
	alias: ['widget.googleganttchart'],
	config: {
		store: null
	},
	ganttConfigs: [
		{
			name: 'id',
			render: function(val) {
				// Gantt Chart expect it to be string
				return String(val);
			}
		},
		{
			name: 'name'
		},
		{
			name: 'groupName'
		},
		{
			name: 'startDate',
			render: function(val) {
				return val ? Ext.Date.parse(val, 'Y-m-d') : null;
			}
		},
		{
			name: 'endDate',
			render: function(val, i_record, n_index) {
				// If startDate == endDate
				// Return endDate = null and duration must return 1 day in millisecond
				var s_starDateKey = this.ganttConfig.startDate || 'startDate';
				var s_startDate = i_record.get(s_starDateKey);
				var i_startDate = Ext.Date.parse(s_startDate, 'Y-m-d');
				var i_endDate = Ext.Date.parse(val, 'Y-m-d');

				if (i_startDate && i_endDate && i_startDate.getTime() != i_endDate.getTime()) {
					return i_endDate;
				}

				return null;
			}
		},
		{
			name: 'duration',
			render: function(val, i_record, n_index) {
				// If startDate == endDate
				// Return endDate = null and duration must return 1 day in millisecond
				var s_starDateKey = this.ganttConfig.startDate || 'startDate';
				var s_endDateKey = this.ganttConfig.endDate || 'endDate';

				var s_startDate = i_record.get(s_starDateKey);
				var s_endDate = i_record.get(s_endDateKey);
				var i_startDate = Ext.Date.parse(s_startDate, 'Y-m-d');
				var i_endDate = Ext.Date.parse(s_endDate, 'Y-m-d');

				if (i_startDate && i_endDate && i_startDate.getTime() == i_endDate.getTime()) {
					return 1 * 24 * 60 * 60 * 1000;
				}

				return null;
			}
		},
		{
			name: 'completed',
			render: function(val) {
				return val ? val : 0;
			}
		},
		{
			name: 'dependency',
			render: function(val) {
				return val ? val : null;
			}
		}
	],

	initComponent: function() {

		var i_cmp = this;
		var i_store = this.getStore();

		i_store.on({
			datachanged: {
				fn: function(i_store, a_records) {
					if (i_cmp.rendered) {
						i_cmp.renderGanttChart();
					}
				}
			}
		});

		i_cmp.callParent(arguments);
	},

	renderGanttChart: function() {
		var i_cmp = this;
		var i_store = this.getStore();
		var o_ganttConfig = this.ganttConfig;
		var i_dom = i_cmp.getInnerDom();
		var i_chart = i_cmp.getChartApi();
		var a_data = [];

		var a_tasks = i_store.getRange(0, i_store.getTotalCount());

		Ext.Array.each(a_tasks, function(i_record, n_index) {
			var data = [];

			Ext.Array.each(i_cmp.ganttConfigs, function(o_config) {
				var s_name = o_ganttConfig[o_config.name];

				if (!s_name) {
					s_name = o_config.name;
				}

				var val = i_record.get(s_name);

				if (o_config.render) {
					val = o_config.render.call(i_cmp, val, i_record, n_index);
				}

				data.push(val);
			});

			a_data.push(data);
		});

		if (a_data.length) {
			i_chart.load('current', {
				'packages': ['gantt']
			});

			i_chart.setOnLoadCallback(function() {
				var data;
				var chart;

				data = new google.visualization.DataTable();
				chart = new google.visualization.Gantt(i_dom);

				data.addColumn('string', 'Task ID');
				data.addColumn('string', 'Task Name');
				data.addColumn('string', 'Resource');
				data.addColumn('date', 'Start Date');
				data.addColumn('date', 'End Date');
				data.addColumn('number', 'Duration');
				data.addColumn('number', 'Percent Complete');
				data.addColumn('string', 'Dependencies');

				data.addRows(a_data);
				i_cmp.chartData = a_data;

				var n_height = a_data.length * 30 + 40;

				if (n_height < 170) {
					n_height = 170;
				}

				var o_opt = i_cmp.ganttOption || {};
				var options = {
					height: n_height,
					gantt: Ext.apply({
						trackHeight: 30
					}, o_opt)
				};

				chart.draw(data, options);
				google.visualization.events.addListener(chart, 'select', function() {
					i_cmp.doOnClick(chart.getSelection());
				});

				var f_layout = i_cmp.doLayout || i_cmp.updateLayout;

				f_layout.call(i_cmp);
			});
		}
	},
	doOnClick: function(a_data) {
		var i_store = this.getStore();
		var a_tasks = i_store.getRange(0, i_store.getTotalCount());

		// It supports multiple selection
		var data = Ext.Array.map(a_data, function(o_data) {
			return a_tasks[o_data.row];
		});
		this.fireEvent('itemclick', data);
	},
	listeners: {
		afterrender: {
			fn: function() {
				this.renderGanttChart();
			}
		}
	}
});
