// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.report_dump");

$.extend(frappe.report_dump, {
	data: {},
	last_modified: {},
	with_data: function(doctypes, callback) {
		var pre_loaded = keys(frappe.report_dump.last_modified);
		return frappe.call({
			method: "frappe.desk.report_dump.get_data",
			type: "GET",
			args: {
				doctypes: doctypes,
				last_modified: frappe.report_dump.last_modified
			},
			freeze: true,
			callback: function(r) {
				// creating map of data from a list
				$.each(r.message, function(doctype, doctype_data) {
					frappe.report_dump.set_data(doctype, doctype_data);
				});

				// reverse map names
				$.each(r.message, function(doctype, doctype_data) {
					// only if not pre-loaded
					if(!in_list(pre_loaded, doctype)) {
						if(doctype_data.links) {
							$.each(frappe.report_dump.data[doctype], function(row_idx, row) {
								$.each(doctype_data.links, function(link_key, link) {
									if(frappe.report_dump.data[link[0]][row[link_key]]) {
										row[link_key] = frappe.report_dump.data[link[0]][row[link_key]][link[1]];
									} else {
										row[link_key] = null;
									}
								})
							})
						}
					}
				});

				callback();
			}
		})
	},
	set_data: function(doctype, doctype_data) {
		var data = [];
		var replace_dict = {};
		var make_row = function(d) {
			var row = {};
			$.each(doctype_data.columns, function(idx, col) {
				row[col] = d[idx];
			});
			row.id = row.name;
			row.doctype = doctype;
			return row;
		}
		if(frappe.report_dump.last_modified[doctype]) {
			// partial loading, make a name dict
			$.each(doctype_data.data, function(i, d) {
				var row = make_row(d);
				replace_dict[row.name] = row;
			});

			// replace old data
			$.each(frappe.report_dump.data[doctype], function(i, d) {
				if(replace_dict[d.name]) {
					data.push(replace_dict[d.name]);
					delete replace_dict[d.name];
				} else if(doctype_data.modified_names.indexOf(d.name)!==-1) {
					// if modified but not in replace_dict, then assume it as cancelled
					// don't push in data
				} else {
					data.push(d);
				}
			});

			// add new records
			$.each(replace_dict, function(name, d) {
				data.push(d);
			})
		} else {

			// first loading
			$.each(doctype_data.data, function(i, d) {
				data.push(make_row(d));
			});
		}
		frappe.report_dump.last_modified[doctype] = doctype_data.last_modified;
		frappe.report_dump.data[doctype] = data;
	}
});

frappe.provide("frappe.views");
frappe.views.GridReport = Class.extend({
	init: function(opts) {
		this.filter_inputs = {};
		this.preset_checks = [];
		this.tree_grid = {show: false};
		var me = this;
		$.extend(this, opts);

		this.wrapper = $('<div class="grid-report"></div>').appendTo(this.page.main);
		this.page.main.find(".page").css({"padding-top": "0px"});

		if(this.filters) {
			this.make_filters();
		}
		this.make_waiting();

		this.get_data_and_refresh();
	},
	bind_show: function() {
		// bind show event to reset cur_report_grid
		// and refresh filters from url
		// this must be called after init
		// because "frappe.container.page" will only be set
		// once "load" event is over.

		var me = this;
		$(this.page).bind('show', function() {
			// reapply filters on show
			frappe.cur_grid_report = me;
			me.get_data_and_refresh();
		});

	},
	get_data_and_refresh: function() {
		var me = this;
		this.get_data(function() {
			me.apply_filters_from_route();
			me.refresh();
		});
	},
	get_data: function(callback) {
		var me = this;

		frappe.report_dump.with_data(this.doctypes, function() {
			if(!me.setup_filters_done) {
				me.setup_filters();
				me.setup_filters_done = true;
			}
			callback();
		});
	},
	setup_filters: function() {
		var me = this;
		$.each(me.filter_inputs, function(i, v) {
			var opts = v.get(0).opts;
			if(opts.fieldtype == "Select" && inList(me.doctypes, opts.link)) {
				$(v).add_options($.map(frappe.report_dump.data[opts.link],
					function(d) { return d.name; }));
			} else if(opts.fieldtype == "Link" && inList(me.doctypes, opts.link)) {
				opts.list = $.map(frappe.report_dump.data[opts.link],
					function(d) { return d.name; });
				me.set_autocomplete(v, opts.list);
			}
		});

		// refresh
		this.page.set_primary_action(__("Refresh"), function() {
			me.get_data(function() {
				me.refresh();
			});
		});

		// reset filters button
		if (this.filter_inputs) {
			this.page.add_menu_item(__("Reset Filters"), function() {
				me.init_filter_values();
				me.refresh();
			}, true);
		}

		this.page.add_menu_item(__("Print"), function() {
			frappe.render_grid({grid: me.grid, title: me.page.title })
		}, true);

		// range
		this.filter_inputs.range && this.filter_inputs.range.on("change", function() {
			me.refresh();
		});

		// chart check
		if(this.setup_chart_check)
			this.setup_chart_check();
	},
	set_filter: function(key, value) {
		var filters = this.filter_inputs[key];
		if(filters) {
			var opts = filters.get(0).opts;
			if(opts.fieldtype === "Check") {
				filters.prop("checked", cint(value) ? true : false);
			} if(opts.fieldtype=="Date") {
				filters.val(frappe.datetime.str_to_user(value));
			} else {
				filters.val(value);
			}
		} else {
			msgprint(__("Invalid Filter: {0}", [key]))
		}
	},
	set_autocomplete: function($filter, list) {
		var me = this;
		$filter.autocomplete({
			source: list,
			select: function(event, ui) {
				$filter.val(ui.item.value);
				me.refresh();
			}
		});
	},
	init_filter_values: function() {
		var me = this;
		$.each(this.filter_inputs, function(key, filter) {
			var opts = filter.get(0).opts;
			if(sys_defaults[key]) {
				filter.val(sys_defaults[key]);
			} else if(opts.fieldtype=='Select') {
				filter.get(0).selectedIndex = 0;
			} else if(opts.fieldtype=='Data') {
				filter.val("");
			} else if(opts.fieldtype=="Link") {
				filter.val("");
			}
		});

		this.set_default_values();
	},

	set_default_values: function() {
		var values = {
			from_date: dateutil.str_to_user(sys_defaults.year_start_date),
			to_date: dateutil.str_to_user(sys_defaults.year_end_date)
		}

		var me = this;
		$.each(values, function(i, v) {
			if(me.filter_inputs[i] && !me.filter_inputs[i].val())
				me.filter_inputs[i].val(v);
		})
	},

	make_filters: function() {
		var me = this;
		$.each(this.filters, function(i, v) {
			v.fieldname = v.fieldname || v.label.replace(/ /g, '_').toLowerCase();
			var input = null;
			if(v.fieldtype=='Select') {
				input = me.page.add_select(v.label, v.options || [v.default_value]);
			} else if(v.fieldtype=="Link") {
				input = me.page.add_data(v.label);
				input.autocomplete({
					source: v.list || [],
				});
			} else if(v.fieldtype==='Button' && v.label===__("Refresh")) {
				input = me.page.set_primary_action(v.label, null, v.icon);
			} else if(v.fieldtype==='Button') {
				input = me.page.add_menu_item(v.label, null, true);
			} else if(v.fieldtype==='Date') {
				input = me.page.add_date(v.label);
			} else if(v.fieldtype==='Label') {
				input = me.page.add_label(v.label);
			} else if(v.fieldtype==='Data') {
				input = me.page.add_data(v.label);
			} else if(v.fieldtype==='Check') {
				input = me.page.add_check(v.label);
			}

			if(input) {
				input && (input.get(0).opts = v);
				if(v.cssClass) {
					input.addClass(v.cssClass);
				}
				input.keypress(function(e) {
					if(e.which==13) {
						me.refresh();
					}
				})
			}
			me.filter_inputs[v.fieldname] = input;
		});
	},
	make_waiting: function() {
		this.waiting = frappe.messages.waiting(this.wrapper, __("Loading Report")+"...");
	},
	load_filter_values: function() {
		var me = this;
		$.each(this.filter_inputs, function(i, f) {
			var opts = f.get(0).opts;
			if(opts.fieldtype=='Check') {
				me[opts.fieldname] = f.prop('checked') ? 1 : 0;
			} else if(opts.fieldtype!='Button') {
				me[opts.fieldname] = f.val();
				if(opts.fieldtype=="Date") {
					me[opts.fieldname] = dateutil.user_to_str(me[opts.fieldname]);
				} else if (opts.fieldtype == "Select") {
					me[opts.fieldname+'_default'] = opts.default_value;
				}
			}
		});

		if(this.filter_inputs.from_date && this.filter_inputs.to_date && (this.to_date < this.from_date)) {
			msgprint(__("From Date must be before To Date"));
			return;
		}

	},

	make_name_map: function(data, key) {
		var map = {};
		key = key || "name";
		$.each(data, function(i, v) {
			map[v[key]] = v;
		})
		return map;
	},

	reset_item_values: function(item) {
		var me = this;
		$.each(this.columns, function(i, col) {
			if (col.formatter==me.currency_formatter) {
				item[col.id] = 0.0;
			}
		});
	},

	round_item_values: function(item) {
		var me = this;
		$.each(this.columns, function(i, col) {
			if (col.formatter==me.currency_formatter) {
				item[col.id] = flt(item[col.id], frappe.defaults.get_default("float_precision") || 3);
			}
		});
	},

	round_off_data: function() {
		var me = this;
		$.each(this.data, function(i, d) {
			me.round_item_values(d);
		});
	},

	refresh: function() {
		this.waiting.toggle(false);
		if(!this.grid_wrapper)
			this.make();
		this.show_zero = $('.show-zero input:checked').length;
		this.load_filter_values();
		this.setup_columns();
		this.setup_dataview_columns();
		this.apply_link_formatters();
		this.prepare_data();
		this.round_off_data();
		this.prepare_data_view();
		// chart might need prepared data
		show_alert("Updated", 2);
		this.render();
		this.setup_chart && this.setup_chart();
	},
	setup_dataview_columns: function() {
		this.dataview_columns = $.map(this.columns, function(col) {
			return !col.hidden ? col : null;
		});
	},
	make: function() {
		var me = this;
		this.chart_id = 'chart-' + cstr(cint(Math.random() * 10000000000));

		// chart wrapper
		this.chart_area = $('<div class="chart" id="'+ this.chart_id +'"></div>').appendTo(this.wrapper);

		this.page.add_menu_item(__("Export"), function() { return me.export(); }, true);

		// grid wrapper
		this.grid_wrapper = $("<div style='height: 500px; border: 1px solid #aaa; \
			background-color: #eee; margin-top: 15px;'>")
			.appendTo(this.wrapper);
		this.id = frappe.dom.set_unique_id(this.grid_wrapper.get(0));

		// zero-value check
		$('<div class="checkbox show-zero">\
				<label><input type="checkbox"> '+__('Show rows with zero values')
			+'</label></div>').appendTo(this.wrapper);

		this.bind_show();

		frappe.cur_grid_report = this;
		$(this.wrapper).trigger('make');

	},
	apply_filters_from_route: function() {
		var me = this;
		if(frappe.route_options) {
			$.each(frappe.route_options, function(key, value) {
				me.set_filter(key, value);
			});
			frappe.route_options = null;
		} else {
			this.init_filter_values();
		}
		this.set_default_values();

		$(this.wrapper).trigger('apply_filters_from_route');
	},
	options: {
		editable: false,
		enableColumnReorder: false
	},
	render: function() {
		// new slick grid
		this.grid = new Slick.Grid("#"+this.id, this.dataView, this.dataview_columns, this.options);
		var me = this;

		if (!frappe.dom.is_touchscreen()) {
			this.grid.setSelectionModel(new Slick.CellSelectionModel());
			this.grid.registerPlugin(new Slick.CellExternalCopyManager({
				dataItemColumnValueExtractor: function(item, columnDef, value) {
					return item[columnDef.field];
				}
			}));
		}

		// bind events
		this.dataView.onRowsChanged.subscribe(function (e, args) {
			me.grid.invalidateRows(args.rows);
			me.grid.render();
		});

		this.dataView.onRowCountChanged.subscribe(function (e, args) {
			me.grid.updateRowCount();
			me.grid.render();
		});

		this.tree_grid.show && this.add_tree_grid_events();
	},
	prepare_data_view: function() {
		// initialize the model
		this.dataView = new Slick.Data.DataView({ inlineFilters: true });
		this.dataView.beginUpdate();
		this.dataView.setItems(this.data);
		if(this.dataview_filter) this.dataView.setFilter(this.dataview_filter);
		if(this.tree_grid.show) this.dataView.setFilter(this.tree_dataview_filter);
		this.dataView.endUpdate();
	},
	export: function() {
		frappe.tools.downloadify(frappe.slickgrid_tools.get_view_data(this.columns, this.dataView),
			["Report Manager", "System Manager"], this.title);
		return false;
	},
	apply_filters: function(item) {
		// generic filter: apply filter functiions
		// from all filter_inputs
		var filters = this.filter_inputs;
		if(item._show) return true;

		for (i in filters) {
			if(!this.apply_filter(item, i)) {
				return false;
			}
		}

		return true;
	},
	apply_filter: function(item, fieldname) {
		var filter = this.filter_inputs[fieldname].get(0);
		if(filter.opts.filter) {
			if(!filter.opts.filter(this[filter.opts.fieldname], item, filter.opts, this)) {
				return false;
			}
		}
		return true;
	},
	apply_zero_filter: function(val, item, opts, me) {
		// show only non-zero values
		if(!me.show_zero) {
			for(var i=0, j=me.columns.length; i<j; i++) {
				var col = me.columns[i];
				if(col.formatter==me.currency_formatter && !col.hidden) {
					if(flt(item[col.field]) > 0.001 ||  flt(item[col.field]) < -0.001) {
						return true;
					}
				}
			}
			return false;
		}
		return true;
	},
	show_zero_check: function() {
		var me = this;
		this.wrapper.bind('make', function() {
			me.wrapper.find('.show-zero').toggle(true).find('input').click(function(){
				me.refresh();
			});
		});
	},
	is_default: function(fieldname) {
		return this[fieldname]==this[fieldname + "_default"];
	},
	date_formatter: function(row, cell, value, columnDef, dataContext) {
		return dateutil.str_to_user(value);
	},
	currency_formatter: function(row, cell, value, columnDef, dataContext) {
		return repl('<div style="text-align: right; %(_style)s">%(value)s</div>', {
			_style: dataContext._style || "",
			value: ((value==null || value==="") ? "" : format_number(value))
		});
	},
	text_formatter: function(row, cell, value, columnDef, dataContext) {
		return repl('<span style="%(_style)s" title="%(esc_value)s">%(value)s</span>', {
			_style: dataContext._style || "",
			esc_value: cstr(value).replace(/"/g, '\"'),
			value: cstr(value)
		});
	},
	check_formatter: function(row, cell, value, columnDef, dataContext) {
		return repl('<input type="checkbox" data-id="%(id)s" \
			class="chart-check" %(checked)s>', {
				"id": dataContext.id,
				"checked": dataContext.checked ? 'checked="checked"' : ""
			})
	},
	apply_link_formatters: function() {
		var me = this;
		$.each(this.dataview_columns, function(i, col) {
			if(col.link_formatter) {
				col.formatter = function(row, cell, value, columnDef, dataContext, for_print) {
					// added link and open button to links
					// link_formatter must have
					// filter_input, open_btn (true / false), doctype (will be eval'd)
					if(!value) return "";

					if(for_print) {
						return value;
					}

					var me = frappe.cur_grid_report;

					if(dataContext._show) {
						return repl('<span style="%(_style)s">%(value)s</span>', {
							_style: dataContext._style || "",
							value: value
						});
					}

					// make link to add a filter
					var link_formatter = me.dataview_columns[cell].link_formatter;
					if (link_formatter.filter_input) {
						var html = repl('<a href="#" \
							onclick="frappe.cur_grid_report.set_filter(\'%(col_name)s\', \'%(value)s\'); \
								frappe.cur_grid_report.refresh(); return false;">\
							%(value)s</a>', {
								value: value,
								col_name: link_formatter.filter_input,
								page_name: frappe.container.page.page_name
							});
					} else {
						var html = value;
					}

					// make icon to open form
					if(link_formatter.open_btn) {
						var doctype = link_formatter.doctype
							? eval(link_formatter.doctype)
							: dataContext.doctype;
						html += me.get_link_open_icon(doctype, value);
					}
					return html;
				}
			}
		})
	},
	get_link_open_icon: function(doctype, name) {
		return repl(' <a href="#Form/%(doctype)s/%(name)s">\
			<i class="icon icon-share" style="cursor: pointer;"></i></a>', {
			doctype: doctype,
			name: encodeURIComponent(name)
		});
	},
	make_date_range_columns: function() {
		this.columns = [];

		var me = this;
		var range = this.filter_inputs.range.val();
		this.from_date = dateutil.user_to_str(this.filter_inputs.from_date.val());
		this.to_date = dateutil.user_to_str(this.filter_inputs.to_date.val());
		var date_diff = dateutil.get_diff(this.to_date, this.from_date);

		me.column_map = {};
		me.last_date = null;

		var add_column = function(date) {
			me.columns.push({
				id: date,
				name: dateutil.str_to_user(date),
				field: date,
				formatter: me.currency_formatter,
				width: 100
			});
		}

		var build_columns = function(condition) {
			// add column for each date range
			for(var i=0; i <= date_diff; i++) {
				var date = dateutil.add_days(me.from_date, i);
				if(!condition) condition = function() { return true; }

				if(condition(date)) add_column(date);
				me.last_date = date;

				if(me.columns.length) {
					me.column_map[date] = me.columns[me.columns.length-1];
				}
			}
		}

		// make columns for all date ranges
		if(range=='Daily') {
			build_columns();
		} else if(range=='Weekly') {
			build_columns(function(date) {
				if(!me.last_date) return true;
				return !(dateutil.get_diff(date, me.from_date) % 7)
			});
		} else if(range=='Monthly') {
			build_columns(function(date) {
				if(!me.last_date) return true;
				return dateutil.str_to_obj(me.last_date).getMonth() != dateutil.str_to_obj(date).getMonth()
			});
		} else if(range=='Quarterly') {
			build_columns(function(date) {
				if(!me.last_date) return true;
				return dateutil.str_to_obj(date).getDate()==1 && in_list([0,3,6,9], dateutil.str_to_obj(date).getMonth())
			});
		} else if(range=='Yearly') {
			build_columns(function(date) {
				if(!me.last_date) return true;
				return $.map(frappe.report_dump.data['Fiscal Year'], function(v) {
						return date==v.year_start_date ? true : null;
					}).length;
			});

		}

		// set label as last date of period
		$.each(this.columns, function(i, col) {
			col.name = me.columns[i+1]
				? dateutil.str_to_user(dateutil.add_days(me.columns[i+1].id, -1))
				: dateutil.str_to_user(me.to_date);
		});
	},
	trigger_refresh_on_change: function(filters) {
		var me = this;
		$.each(filters, function(i, f) {
			me.filter_inputs[f] && me.filter_inputs[f].on("change", function() {
				me.refresh();
			});
		});
	}
});

frappe.views.GridReportWithPlot = frappe.views.GridReport.extend({
	setup_chart: function() {
		var me = this;
		if (in_list(["Daily", "Weekly"], this.filter_inputs.range.val())) {
			this.wrapper.find("#" + me.chart_id).toggle(false);
			return;
		}
		var chart_data = this.get_chart_data ? this.get_chart_data() : null;
		
		this.chart = new frappe.ui.Chart({
			wrapper: me.wrapper,
			bind_to: "#" + me.chart_id,
			data: chart_data
		});
	},

	setup_chart_check: function() {
		var me = this;
		me.wrapper.bind('make', function() {
			me.wrapper.on("click", ".chart-check", function() {
				var checked = $(this).prop("checked");
				var id = $(this).attr("data-id");
				if(me.item_by_name) {
					if(me.item_by_name[id]) {
						me.item_by_name[id].checked = checked ? true : false;
					}
				} else {
					$.each(me.data, function(i, d) {
						if(d.id==id) d.checked = checked;
					});
				}
				me.setup_chart();
			});
		});
	},

	get_chart_data: function() {
		var me = this;
		
		var plottable_cols = [];
		$.each(me.columns, function(idx, col) {
			if(col.formatter==me.currency_formatter && !col.hidden && col.plot!==false) {
				plottable_cols.push(col.field);
			}
		})
		
		var data = {
			x: 'x',
			'columns': [['x'].concat(plottable_cols)]
		};
		
		$.each(this.data, function(i, item) {
			if (item.checked) {
				var data_points = [item.name];
				$.each(plottable_cols, function(idx, col) {
					data_points.push(item[col]);
				})
				data["columns"].push(data_points);
			}
		});
		return data
	}
});


frappe.views.TreeGridReport = frappe.views.GridReportWithPlot.extend({
	make_transaction_list: function(parent_doctype, doctype) {
		var me = this;
		var tmap = {};
		$.each(frappe.report_dump.data[doctype], function(i, v) {
			if(!tmap[v.parent]) tmap[v.parent] = [];
			tmap[v.parent].push(v);
		});
		if (!this.tl) this.tl = {};
		if (!this.tl[parent_doctype]) this.tl[parent_doctype] = [];

		$.each(frappe.report_dump.data[parent_doctype], function(i, parent) {
			if(tmap[parent.name]) {
				$.each(tmap[parent.name], function(i, d) {
					me.tl[parent_doctype].push($.extend(copy_dict(parent), d));
				});
			}
		});
	},
	add_tree_grid_events: function() {
		var me = this;
		this.grid.onClick.subscribe(function (e, args) {
			if ($(e.target).hasClass("toggle")) {
				var item = me.dataView.getItem(args.row);
				if (item) {
					if (!item._collapsed) {
						item._collapsed = true;
					} else {
						item._collapsed = false;
					}

					me.dataView.updateItem(item.id, item);
				}
				e.stopImmediatePropagation();
			}
		});
	},
	tree_formatter: function (row, cell, value, columnDef, dataContext) {
		var me = frappe.cur_grid_report;
		value = value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
		var data = me.data;
		var spacer = "<span style='display:inline-block;height:1px;width:" +
			(15 * dataContext["indent"]) + "px'></span>";
		var idx = me.dataView.getIdxById(dataContext.id);
		var link = me.tree_grid.formatter(dataContext);

		if(dataContext.doctype) {
			link += me.get_link_open_icon(dataContext.doctype, dataContext.name);
		}

		if (data[idx + 1] && data[idx + 1].indent > data[idx].indent) {
			if (dataContext._collapsed) {
				return spacer + " <span class='toggle expand'></span>&nbsp;" + link;
			} else {
				return spacer + " <span class='toggle collapse'></span>&nbsp;" + link;
			}
		} else {
			return spacer + " <span class='toggle'></span>&nbsp;" + link;
		}
	},
	tree_dataview_filter: function(item) {
		var me = frappe.cur_grid_report;
		if(!me.apply_filters(item)) return false;

		var parent = item[me.tree_grid.parent_field];
		while (parent) {
			if (me.item_by_name[parent]._collapsed) {
				return false;
			}
			parent = me.parent_map[parent];
		}
		return true;
	},
	prepare_tree: function(item_dt, group_dt) {
		var group_data = frappe.report_dump.data[group_dt];
		var item_data = frappe.report_dump.data[item_dt];

		// prepare map with child in respective group
		var me = this;
		var item_group_map = {};
		var group_ids = $.map(group_data, function(v) { return v.id; });
		$.each(item_data, function(i, item) {
			var parent = item[me.tree_grid.parent_field];
			if(!item_group_map[parent]) item_group_map[parent] = [];
			if(group_ids.indexOf(item.name)==-1) {
				item_group_map[parent].push(item);
			} else {
				msgprint(__("Ignoring Item {0}, because a group exists with the same name!", [item.name.bold()]));
			}
		});

		// arrange items besides their parent item groups
		var items = [];
		$.each(group_data, function(i, group){
			group.is_group = true;
			items.push(group);
			items = items.concat(item_group_map[group.name] || []);
		});
		return items;
	},
	set_indent: function() {
		var me = this;
		$.each(this.data, function(i, d) {
			var indent = 0;
			var parent = me.parent_map[d.name];
			if(parent) {
				while(parent) {
					indent++;
					parent = me.parent_map[parent];
				}
			}
			d.indent = indent;
		});
	},

	export: function() {
		var msgbox = msgprint($.format('<p>{0}</p>\
			<p><input type="checkbox" name="with_groups" checked="checked"> {1}</p>\
			<p><input type="checkbox" name="with_ledgers" checked="checked"> {2}</p>\
			<p><button class="btn btn-primary"> {3}</button>', [
				__('Select To Download:'),
				__('With Groups'),
				__('With Ledgers'),
				__('Download')
			]));

		var me = this;

		$(msgbox.body).find("button").click(function() {
			var with_groups = $(msgbox.body).find("[name='with_groups']").prop("checked");
			var with_ledgers = $(msgbox.body).find("[name='with_ledgers']").prop("checked");

			var data = frappe.slickgrid_tools.get_view_data(me.columns, me.dataView,
				function(row, item) {
					if(with_groups) {
						// add row
						for(var i=0; i<item.indent; i++) row[0] = "   " + row[0];
					}
					if(with_groups && (item.is_group == 1 || item.is_group)) {
						return true;
					}
					if(with_ledgers && (item.is_group != 1 && !item.is_group)) {
						return true;
					}

					return false;
			});

			frappe.tools.downloadify(data, ["Report Manager", "System Manager"], me.title);
			return false;
		})

		return false;
	},

});
