function aggregatereport_controller()
{
	this.meta = null;
	this.index = new Array();
	this.hash = new Array();
	this.sortby = new Array();
	this.chart = null;

	this.preinit = function()
	{
		this.meta = this.portlet.metadata();

		var curr = this;
		var i = 0;
		var ta = [this.meta.groupby, this.meta.measures];
		for(var k in ta)
		{
			var mv = ta[k];
			for(var gbk in mv)
			{
				var gbv = mv[gbk];
				if(gbv.sort)
				{
					if(gbv.sort > 0)
						this.sortby[i] = 1;
					else if(gbv.sort < 0)
						this.sortby[i] = -1;
				}
				if(gbv.value && typeof gbv.value == "string")
					gbv.value = eval("val = "+gbv.value);
				gbv.value = gbv.value ? gbv.value : function(val, row)
				{
					if(val == null)
						return "";
					else if(this.type && this.format)
						return formatdata(val, this.format, this.type);
					else
						return val;
				}
				this.index[i] = gbv;
				this.hash[gbk] = i;
				i++;
			}
		}

		this.graph.data.sort(function(a, b)
		{
			for(var sk in curr.sortby)
			{
				var sv = curr.sortby[sk];
				if(sv)
				{
					if(a[sk] < b[sk])
						return sv>0?-1:1;
					else if(a[sk] > b[sk])
						return sv>0?1:-1;
				}
			}
			return 0;
		});

		if(this.meta.chart)
		{
			if(this.meta.chart.y)
				this.chart = new MultiSeries(this);
			else
				this.chart = new SingleSeries(this);
			for(var ri in this.graph.data)
				this.chart.process(this.graph.data[ri]);
			//console.dir(this.chart);
		}
	}

	this.callback = function()
	{
		aggregatereport_controller.prototype.callback.call(this);
		try{
			if(this.graph.data && this.graph.data.length > 0){
				var chartmeta = this.meta.chart;
				if(chartmeta)
				{
					// Copied from preinit to here for chart render when applying filter
					if(this.meta.chart.y)
						this.chart = new MultiSeries(this);
					else
						this.chart = new SingleSeries(this);
					for(var ri in this.graph.data)
						this.chart.process(this.graph.data[ri]);
					var fcid = this.id+"-chart";
					var fcdiv = $("#"+fcid);
					var fchart = new FusionCharts(OrangeScapeCDNPath+"/Charts/"+this.chart.meta.type+".swf", this.id+"-pane", fcdiv.attr("width"), fcdiv.attr("height"), "0", "1" );
					var fcjson = this.chart.json();
					fchart.setTransparent(true);
					fchart.setJSONData(fcjson);
					fchart.render(fcid);
					fcdiv.show();
				}
				$("#"+this.id+" .table ."+this.meta.theme).tableSorter({sortColumn: 0}).sortStop(function(e, col){
					$(this).tableUnGroup();
					$(this).tableGroup({groupColumn: 1, groupClass: 'group', useNumChars: 0});
				});
			}
		}catch(err){
			this.error("Error in "+this.id+" while rendering chart. Reason: "+err);
		}
	}

	this.getValue = function(name, row)
	{
		var ind = this.hash[name];
		return row[ind];
	}

	this.getDisplay = function(name)
	{
		var result = this.meta.groupby[name];
		if(result == null) result = this.meta.measures[name];
		if(result.display)
			return result.display;
		else
			return name;
	}

	this.locateLayoutTemplate = function(){return "layout";}

	this.locateViewTemplates = function(){return {table:"table",parameter:"parameter"};}

	this.setTitle = function(){return "Report";}

	this.registerKeys = function(){}

	this.unRegisterKeys = function(){}

}
aggregatereport_controller.prototype = new report_controller;

function SingleSeries(report)
{
	this.meta = report.meta.chart;
	this.report = report;
	this.data = new Array();
	this.template = TrimPath.parseDOMTemplate("series1");

	this.process = function(row)
	{
		var cval = this.report.getValue(this.meta.x, row);
		var val = this.report.getValue(this.meta.data, row);

		var aval = this.data[cval];
		val = (typeof val == "string") ? parseFloat(val) : val;
		this.data[cval] = aval ? aval+val : val;
	}

	this.json = function()
	{
		return this.template.process(this.report);
	}
}

function MultiSeries(report)
{
	this.meta = report.meta.chart;
	this.report = report;
	this.x = new Array();
	this.y = new Array();
	this.data = new Array();
	this.template = TrimPath.parseDOMTemplate("series2");

	this.process = function(row)
	{
		var xval = this.report.getValue(this.meta.x, row);
		var yval = this.report.getValue(this.meta.y, row);
		var val = this.report.getValue(this.meta.data, row);

		this.x[xval+""] = xval;
		this.y[yval+""] = yval;

		var lkey = [xval,yval];

		var aval = this.data[lkey];
		val = (typeof val == "string") ? parseFloat(val) : val;
		this.data[lkey] = aval ? aval+val : val;
	}

	this.json = function()
	{
		return this.template.process(this.report);
	}
}
