/*********************************************************************************/
/**			copyright (c) PlanetCalc.com, 2007  			**/
/**		    	Table renderer classes					*/
/*********************************************************************************/

function RecordsetHeader() {
	this.Columns = new Object();    
	this.Size = 0;

	this.AddColumn = function( name, dispname, formatter, description, chartKind ) {
		var column = new Object();
		column.name = name;
		column.dispname = dispname;
		column.formatter = formatter;
		column.description = description;
		column.chartKind = chartKind;
		this.Columns[name] = column;
		this.Size++;
	}
	this.GetLabel = function ( colname ) {
		var column = this.Columns[ colname ];
		var label = column.dispname;
		var desc = column.description;
		if ( desc ) {
			label = '<span title="' + desc + '">' + label + '</span>';
		}
		return label;
	}

	this.GetFormatter = function  ( colname ) {
		return this.Columns[ colname ]?this.Columns[ colname ].formatter:null;
	}

	this.HasColumn = function ( colname ) {
		return typeof(this.Columns[colname]) != "undefined" ;
	}
}

function RecordsetRenderer( placeholderid, maxNavigationPages ) {
	var css_names = {
		"tr_header":"tr_header", "th_link_notsorted":"th_notsorted", "th_link_sortedasc":"th_sortedasc",
		"th_link_sorteddesc":"th_sorteddesc", "tr_odd":"tr_odd", "tr_even":"tr_even", "div_nav":"recordset_navigation",
		"li_nav":"recordset_navigation", "li_nav_current":"recordset_navigation_current" };

	var me = this;

	var CalculateCurrentPage = function( rst ) {
		var items = Number(rst.QueryContext.items)
	 	return items?Math.floor( (Number(rst.QueryContext.from)+1)/items):0;
	}
	var CalculatePagesCount = function( rst ) {
		var items = Number(rst.QueryContext.items);
		return items?Math.floor( rst.GetTotal()/items)+((rst.GetTotal()%items)?1:0):0;
	}

	function TableWrapper( innerHTML ) {
		var size = BSGetElementSize( document.getElementById( placeholderid ) );
		var style = size.x?'style="' + BSGetMaxWidthProperty() + ':' + size.x + 'px"':'';
		return '<div class="table" ' + style + '><table class="recordset">' + innerHTML + '</table></div>';
	}

	this.RenderMessage= function( itemsPerPage, msg ) {
		var innerHTML = me.CreateTableHeader( "","", false );
		innerHTML += '<tr><td colspan="'+ me.Header.Size +'">' + msg + '</td></tr>';			
		innerHTML += me.GetEmptyLines( itemsPerPage-1 );
		document.getElementById( placeholderid ).innerHTML = TableWrapper( innerHTML );
	}

	this.GetEmptyLines = function ( linesCount ) {
		var innerHTML = "";
		var colspan = this.Header.Size;
		for (var i = 0; i < linesCount; ++i) {
			innerHTML += '<tr><td colspan="'+ colspan +'">&nbsp;</td></tr>';			
		}
		return innerHTML;
	}

	this.AddColumn = function( name, dispname, formatter, description, chartKind ) {
		me.Header.AddColumn( name, dispname, formatter, description, chartKind )
	}
	
	this.Render = function( recordset, columnClickSink, navigationSink ) {
		var innerHTML = me.CreateTable( recordset, columnClickSink?true:false, navigationSink?true:false );
		document.getElementById( placeholderid ).innerHTML = innerHTML;
		if ( navigationSink ) {
			AdviseLinks( GetNavigationId(),  GetNavigationPrefix(), navigationSink );
		}
		if ( columnClickSink ) {
			AdviseLinks( me.GetHeaderId(),  GetColumnHeaderPrefix(), columnClickSink );
		}
	}

	this.CreateTable = function( recordset, renderSorting, renderNavigation ) {
		var innerHTML = me.CreateTableHeader( recordset.QueryContext.sortcolumn, recordset.QueryContext.sortdirection, renderSorting );
		innerHTML += me.CreateTableData( recordset );
		if ( renderNavigation ) {
			innerHTML += me.CreateNavigation( CalculateCurrentPage( recordset ),  CalculatePagesCount( recordset ) );
		}

		return TableWrapper( innerHTML );
	}

	this.CreateTableHeader = function( sortcolumn, sortdirection, renderSorting ) {

		var data = '<thead><tr id="' + me.GetHeaderId() + '" class="' + css_names.tr_header + '">';
		for ( var colname in me.Header.Columns ) {
			var columnclass = css_names.th_link_notsorted;
			if (colname == sortcolumn) {
				columnclass = sortdirection == "ASC" ? css_names.th_link_sortedasc : css_names.th_link_sorteddesc;
			}
			data += "<th>"; 	
			if ( renderSorting ) {
				data += '<a href="" class="' + columnclass + '" id="' + GetColumnHeaderPrefix( ) + colname +'">';
			}
			data += me.Header.GetLabel( colname );
			if ( renderSorting ) {
				data += "</a>"
			}
			data += "</th>";
		}
		data += "</tr></thead>";
		return data;
	}

	this.CreateTableData = function ( recordset ) {
		var evenodd = 1;
		var records = recordset.GetRecordArray();
		var data = "<tbody>";
		for (var i = 0; i <records.length; i++) {
			data += me.CreateRowData( ( evenodd % 2 ? css_names.tr_odd : css_names.tr_even ), records[i] );
			evenodd++;
		}
		
		var itemsPerPage = recordset.QueryContext.items;
		if ( 0==itemsPerPage ) {
			itemsPerPage= recordset.GetCount();
		}
		data += me.GetEmptyLines( itemsPerPage-records.length );
		data += "</tbody>";
		return data;
	}

	this.CreateRowData = function( rowclass, record ) {
		var data = '<tr class="' + rowclass + '">';
		for ( var colname in me.Header.Columns ) {
			data += '<td class="td_'+ colname +'">';
			var formatter = me.Header.GetFormatter( colname );
			if (  formatter ) {
				data += formatter.Format( colname, record );
			} else {
				data += record[ colname ];
			}
			data += "</td>";
		}
		data += '</tr>';
		return data;
	}

	function GetNavigationPrefix( ) {
		return "nav_" + placeholderid + "_";
	}
	function GetColumnHeaderPrefix( ) {
		return "col_" + placeholderid + "_";
	}
	function GetNavigationId() {
		return "navigation_div_" + placeholderid;
	}

	this.GetHeaderId = function() {
		return "header_" + placeholderid;
	}

	this.CreateNavigation = function( currentPage, pagesCount ) {
		if ( pagesCount <= 1) {
			return "";
		}
		var innerHTML = '<tfoot><tr><td colspan="' + me.Header.Size + '">';
        	innerHTML+=  '<table class="' + css_names.div_nav + '" id="' + GetNavigationId() + '">';
		innerHTML += "<tr>";
		var startPage = currentPage-maxNavigationPages/2;
		var endPage = currentPage+maxNavigationPages/2;
		if ( startPage<0 ) {
			startPage = 0;
			endPage = maxNavigationPages>=pagesCount?pagesCount-1:maxNavigationPages;
		} else if ( endPage>pagesCount-1 ) {
			endPage = pagesCount-1;
			startPage = maxNavigationPages>pagesCount?0:pagesCount-maxNavigationPages;
		}

		innerHTML += CreateNavLinks( currentPage, startPage, endPage , pagesCount );
		innerHTML += "</tr>";                          
       		innerHTML += "</table></td></tr></tfoot>";
		return innerHTML;
	}
	
	function CreateNavLinks( current, link , last, total ) {
		var data = GetNaviLink( link>0?link-1:0, current!=0, "&lt;&lt;");
		while( link<= last ) {
			data +=GetNaviLink( link, current!=link, link+1 );
			link++;
		}
		data +=GetNaviLink( link==total?total-1:link, current!=total-1, "&gt;&gt;" );		
		return data;						
	}

	function GetNaviLink( id, renderUrl, label ) {
		return '<td class="' + (renderUrl?css_names.li_nav:css_names.li_nav_current) + '">' + 
		(renderUrl?'<a href="#" id="' + GetNavigationPrefix() + id + '">':'') + 
		label + (renderUrl?'</a>':'')  +'</td>';
	}

	function AdviseLinks( id, prefix, sink ) {
		if ( sink ) {
			var parent = document.getElementById( id );
			if ( parent ) {
				var childs = parent.getElementsByTagName("a");
				for(var i = 0; i<childs.length; ++i)	{
					var child = childs[i];
					var id = child.id.replace(prefix,"");					
					BSAdviseEvent( child, 'click', sink, id );
				}
			}
		}
	}

	this.Header = new RecordsetHeader();

}

function AjaxTableNoEmptyRowsRenderer( placeholderid, maxNavigationPages ) {
	this.inheritFrom = RecordsetRenderer;
	this.inheritFrom(placeholderid, maxNavigationPages);

	var me = this;

	this.GetEmptyLines = function ( linesCount ) {
		return "";
	}
}
