var tspl = new Object();

tspl.sorting = function (propArray)
{
	var table;
	var cols = 1;
	var colids = new Array();
	var colnames = new Array();
	var coltype = new Array();
	var colsort = new Array();
	var colalign = new Array();
	var sorted = new Array();
	var sortclass;
	var rows = 0;
	var data;
	var pagesize = 10;
	var pages = 1;
	var curpage = 0;
	var sortedcol;
	var sortorder = 'none';
	var rowheight = 20;
	var paging;

	if(propArray)
		this.__setInitProperties(propArray);

	if(tspl.sortCount)
	{
		tspl.sortObject[sortCount] = this;
		tspl.sortCount++;
	}
	else
	{
		tspl.sortObject = new Array();
		tspl.sortObject[0] = this;
		tspl.sortCount = 1;
	}

	this.__initHeader();
	this.__initData();
	this.__initSort();
	this.__initFooter();
}

tspl.sorting.prototype =
{
	// {{{ __setInitProperties()
    /**
     *	Fill object with data sent to the constructor
     *	@param Array props - Associative Array("Object") of properties
     *
     * @private
     */
	__setInitProperties : function(props)
	{
		if(props.table)
			this.table = props.table;
		if(props.cols)
			this.cols = props.cols;
		if(props.colids)
			this.colids = props.colids;
		if(props.colnames)
			this.colnames = props.colnames;
		if(props.coltype)
			this.coltype = props.coltype;
		if(props.colsort)
			this.colsort = props.colsort;
		if(props.colalign)
			this.colalign = props.colalign;
		else
			this.colalign = new Array(this.cols);
		if(props.sortclass)
			this.sortclass = props.sortclass;
		else
		{
			this.sortclass = new Array(3);
			this.sortclass[0] = "asc";
			this.sortclass[1] = "desc";
			this.sortclass[2] = "none";
		}
		if(props.rows)
			this.rows = props.rows;
		else
			this.rows = 0;

		this.sorted = new Array(this.cols);
		for(i=0;i<this.cols;i++)
			this.sorted[i] = new Array(this.rows);

		if(props.pagesize)
			this.pagesize = props.pagesize;
		else
			this.pagesize = 10;
		if(props.pages)
			this.pages = props.pages;
		else
			this.pages = 1;
		if(props.curpage)
			this.curpage = props.curpage;
		else
			this.curpage = 0;
		if(props.paging)
			this.paging = props.paging;
		else
			this.paging = this.table + '_paging';

		if(props.data)
		{
			this.data = new Array(props.data.length);
			for(i=0;i<this.data.length;i++)
			{
				this.data[i] = new Array(props.data[i].length);
				for(j=0;j<this.data[i].length;j++)
					this.data[i][j] = props.data[i][j];
			}
			alert(this.data);
		}
	}
	// }}}
	,
	// {{{ __initHeader()
    /**
     *	Fill header with links to sort data
     *	@param
     *
     * @private
     */
	__initHeader : function()
	{
		var head;
		var tmp = $e(this.table).getElementsByTagName('thead');
		if(tmp.length)
			head = tmp[0];
		else
		{
			head = document.createElement('thead');
			var tr = document.createElement('tr');
			tr.className = 'titlerow';
			for(i=0;i<this.cols;i++)
			{
				var th = document.createElement('th');
				th.innerHTML = this.colnames[i];
				tr.appendChild(th);
			}
			head.appendChild(tr);
			$e(this.table).appendChild(head);
		}
		var th = head.getElementsByTagName('th');
		for(i=0;i<this.cols;i++)
		{
			if(th[i])
			{
				th[i].id = this.colids[i];
				if(this.colsort[i])
				{
					th[i].style.cursor = 'pointer';
					th[i].onclick = this.sort;
					th[i].setAttribute('sortid', tspl.sortCount - 1);
					th[i].setAttribute('sortorder', 'none');
					th[i].className = this.sortclass[2];
				}
			}
		}
	}
	// }}}
	,
	__initData : function()
	{
		if($e(this.table).getElementsByTagName('tbody').length)
		{
			if(!this.data)
			{
				var trs = $e(this.table).getElementsByTagName('tbody')[0].getElementsByTagName('tr');

				if(trs.length == 1)
				{
					if(trs[0].getElementsByTagName('td').length == 1)
					{
						this.rows = 0;
						this.data = new Array(0);
						this.pages = 0;
						this.sorted = new Array(this.cols);
						for(i=0;i<this.cols;i++)
							this.sorted[i] = new Array(this.rows);
						return;
					}
				}
				this.rows = trs.length;
				this.data = new Array(trs.length);
				this.pages = parseInt(this.rows / this.pagesize);
				if(this.rows > (this.pages * this.pagesize))
					this.pages++;

				this.sorted = new Array(this.cols);
				for(i=0;i<this.cols;i++)
					this.sorted[i] = new Array(this.rows);

				for(i=0;i<trs.length;i++)
				{
					this.data[i] = new Array();
					var tds = trs[i].getElementsByTagName('td');
					for(j=0;j<tds.length;j++)
						this.data[i][j] = tds[j].innerHTML;
				}
			}
		}
		else
		{
			var body = document.createElement('tbody');
			$e(this.table).appendChild(body);
		}
	}
	,
	// {{{ __initFooter()
    /**
     *	Fill footer with links to page
     *	@param
     *
     * @private
     */
	__initFooter : function()
	{
		var node = $e(this.paging);
		if(!node)
		{
			var foot = $e(this.table).getElementsByTagName('tfoot');
			if(foot.length)
				foot = foot[0];
			else
			{
				foot = document.createElement('tfoot');
				$e(this.table).appendChild(foot);
			}
			var footer = document.createElement('tr');
			footer.style.verticalAlign = 'middle';
			var node = document.createElement('th');
			node.colSpan = this.cols;
			node.style.textAlign = 'right';
			node.id = this.paging;
			footer.appendChild(node);
			foot.appendChild(footer);
		}
		if(this.rows)
			node.innerHTML = 'Showing <span id="' + this.table + '_start">' + (this.__getStart() + 1) + '</span> to <span id="' + this.table + '_end">' + this.__getEnd() + '</span> of ' + this.rows + ' records.&nbsp;&nbsp;&nbsp;&nbsp;';
		else
			node.innerHTML = 'Showing <span id="' + this.table + '_start">0</span> to <span id="' + this.table + '_end">0</span> of 0 records.&nbsp;&nbsp;&nbsp;&nbsp;';

		node.innerHTML += '<img src="images/tree/first.gif" border="0" style="cursor:pointer;" pageid="' + (tspl.sortCount - 1) + '" pagenum="0"></img>';
		node.innerHTML += '<img src="images/tree/prev.gif" border="0" style="cursor:pointer;" pageid="' + (tspl.sortCount - 1) + '" pageshift="-1"></img>';
		node.innerHTML += '<span id="' + this.table + '_curpage">' + (this.curpage+1) + '</span>';
		node.innerHTML += '<img src="images/tree/next.gif" border="0" style="cursor:pointer;" pageid="' + (tspl.sortCount - 1) + '" pageshift="1"></img>';
		node.innerHTML += '<img src="images/tree/last.gif" border="0" style="cursor:pointer;" pageid="' + (tspl.sortCount - 1) + '" pagenum="' + (this.pages-1) + '"></img>';

		var imgs = node.getElementsByTagName('img');
		for(i=0;i<imgs.length;i++)
			imgs[i].onclick = this.page;
	}
	// }}}
	,
	// {{{ __initSort()
    /**
     *	Cache data sort order
     *	@param
     *
     * @private
     */
	__initSort : function()
	{
		for(i=0;i<this.cols;i++)
		{
			if(this.colsort[i])
			{
				var trs = $e(this.table).getElementsByTagName('tbody')[0].getElementsByTagName('tr');
				var data = new Array(trs.length);
				for(j=0;j<trs.length;j++)
				{
					var tds = trs[j].getElementsByTagName('td');
					data[j] = new Array(tds.length+1);
					data[j][0] = j;
					for(k=0;k<tds.length;k++)
						data[j][k+1] = tds[k].innerHTML;
				}

				for(m=0;m<data.length-1;m++)
					for(n=m+1;n<data.length;n++)
					{
						var mval = data[m][i+1];
						var nval = data[n][i+1];
						switch(this.coltype[i])
						{
							case 'int':
								mval = parseInt(mval);
								nval = parseInt(nval);
								break;
							case 'float':
								mval = parseFloat(mval);
								nval = parseFloat(nval);
								break;
						}
						if(nval < mval)
							this.swap(data[m],data[n]);
					}

				for(s=0;s<this.rows;s++)
					this.sorted[i][s] = data[s][0];
			}
		}
	}
	// }}}
	,
	swap : function(a1,a2)
	{
		if(a1.length != a2.length)
			return;
		var tmp = new Array(a1.length);
		for(s=0;s<a1.length;s++)
		{
			tmp[s] = a1[s];
			a1[s] = a2[s];
			a2[s] = tmp[s];
		}
	}
	,
	sort : function(col)
	{
		var parentid = this.getAttribute('sortid');
		var parent = tspl.sortObject[parentid];

		if(parent.sortedColumn)
			parent.sortedColumn.className = parent.sortclass[2];
		parent.sortedColumn = this;

		var order = this.getAttribute('sortorder');
		var className = this.className;
		if(order == 'none')
		{
			order = 'asc';
			className = parent.sortclass[0];
		}
		else
			if(order == 'asc')
			{
				order = 'desc';
				className = parent.sortclass[1];
			}
			else
			{
				order = 'none';
				className = parent.sortclass[2];
			}
		this.setAttribute('sortorder',order);
		this.className = className;

		var id = this.id;
		var colno = -1;
		for(i=0;i<parent.cols;i++)
			if(parent.colids[i] == id)
			{
				colno = i;
				break;
			}
		if(colno == -1 || parent.colsort[colno] == false)
			return;
		else
		{
			parent.sortedcol = colno;
			parent.sortorder = order;
			parent.redraw();
		}
	}
	,
	page : function(col)
	{
		var parentid = this.getAttribute('pageid');
		var parent = tspl.sortObject[parentid];

		var page = this.getAttribute('pagenum');
		var pagechange = this.getAttribute('pageshift');

		if(pagechange && pagechange != 0)
			parent.curpage = parseInt(parseInt(parent.curpage) + parseInt(pagechange));
		else
			parent.curpage = page;

		if(parent.curpage < 0)
			parent.curpage = 0;
		if(parent.curpage >= parent.pages)
			parent.curpage = (parent.pages - 1);

		$e(parent.table + '_curpage').innerHTML = parseInt(parent.curpage) + 1;
		$e(parent.table + '_start').innerHTML = parseInt(parent.__getStart()) + 1;
		$e(parent.table + '_end').innerHTML = parseInt(parent.__getEnd());

		parent.redraw();
	}
	,
	__getStart : function()
	{
		var start = (this.curpage * this.pagesize);
		if(start < 0)
			return 0;
		if(start > this.rows)
			return this.rows;
		else
			return start;
	}
	,
	__getEnd : function()
	{
		var end = ((this.curpage+1) * this.pagesize);
		if(end < 0)
			return 0;
		if(end > this.rows)
			return this.rows;
		else
			return end;
	}
	,
	redraw : function()
	{
		var tbody;
		var tmp = $e(this.table).getElementsByTagName('tbody');
		if(tmp.length)
		{
			tbody = tmp[0];
			tbody.innerHTML = '';
		}
		else
		{
			tbody = document.createElement('tbody');
			$e(this.table).appendChild(tbody);
		}

		var colno = this.sortedcol;
		var order = this.sortorder;

		var start = this.__getStart();
		var end = this.__getEnd();

		for(i=start;i<end;i++)
		{
			var tr = document.createElement('tr');
			tr.style.height = this.rowheight + 'px';
			for(j=0;j<this.cols;j++)
			{
				var td = document.createElement('td');
				td.style.textAlign = this.colalign[j];
				td.style.height = this.rowheight + 'px';

				if(order == 'asc')
					td.innerHTML = this.data[this.sorted[colno][i]][j];
				else
					if(order == 'desc')
						td.innerHTML = this.data[this.sorted[colno][this.rows - i - 1]][j];
					else
						td.innerHTML = this.data[i][j];
				tr.appendChild(td);
			}
			tbody.appendChild(tr);
		}
		var padding = this.pagesize - (end - start);
		for(i=0;i<padding;i++)
		{
			var tr = document.createElement('tr');
			tr.style.height = this.rowheight + 'px';
			for(j=0;j<this.cols;j++)
			{
				var td = document.createElement('td');
				td.style.height = this.rowheight + 'px';
				td.innerHTML = '&nbsp;';
				tr.appendChild(td);
			}
			tbody.appendChild(tr);
		}
	}
}
