Ext.define('Ext.ux.frappe.charts.Gantt', {
	extend: 'Ext.container.Container',
	mixins: [
		"Ext.mixin.Mashup"
	],
	requiredScripts: [
		"/portfolio/app/ux/frappe/frappe-gantt.js",
		"/portfolio/app/ux/frappe/moment.js",
		"/portfolio/app/ux/frappe/snap.svg-min.js",
		"/portfolio/app/ux/frappe/ganttstyle.css"
	],
	requires: [
		"Ext.ux.frappe.charts.Charts"
	],
	alias: [
		'widget.frappeganttchart'
	],
	config: {
		store: null,
		chart: null,
		svg: null
	},
	autoScroll: true,
	listeners: {
		boxready: {
			fn: function(i_container) {

				i_container.setHeight(i_container.getHeight());
				var i_element = i_container.getEl();
				var i_dom = i_element.dom;

				var i_chart = i_container.getChart();

				i_chart.change_view_mode('Week', i_dom);
			}
		},
		render: {
			fn: function(i_container) {

				var i_svg = i_container.getSvg();
				var i_chart = new Gantt("#" + i_svg.id, i_container.getData());
				i_container.setChart(i_chart);
			}
		}
	},
	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: 'procentDone',
			render: function (val) {
				return val ? val : 0;
			}
		},
		{
			name: 'dependency',
			render: function (val) {
				return val ? val : null;
			}
		}
	],

	initComponent: function () {

		var i_self = this;
		i_self.callParent(arguments);

		var i_store = this.getStore();

		i_store.on({
			datachanged: {
				fn: function (i_store, a_records) {
					if (i_self.rendered) {
						var i_chart = i_self.getChart();
						i_chart.refresh(i_self.getData());
					}
				}
			}
		});

		var i_svg = Ext.widget("ux.frappe.charts.charts", {
			flex: 1
		});

		i_self.setSvg(i_svg);
		i_self.add(i_svg);
	},

	mapNames: function (name) {
		switch (name) {
			case 'startDate':
				return 'start';
			case 'endDate':
				return 'end';
			case 'groupName':
				return 'custom_class';
			case 'procentDone':
				return 'progress';
			case 'description':
				return 'name';
			default:
				return name;
		}
	},

	getData: function () {

		var i_cmp = this;
		var i_store = this.getStore();
		var o_ganttConfig = this.ganttConfig;
		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);
				data[i_cmp.mapNames(s_name)] = val;
			});
			a_data.push(data);
		});

		return a_data;
	},

	doOnClick: function (xa_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);
	}
});
