/**
 * Grid Control Class
 * 
 * This contol forms a sortable grid based on given array and parameters.
 *
 * Javascript 1.1
 * 
 * @author     Eihab Ibrahim <eihab@mindsetsoft.com>
 * @copyright  2005 Mindset Software Inc.
 * @license    doc/license.txt
 * @version    SVN: $Id: grid.js 2096 2006-08-21 17:45:50Z eihab $
 * @since      File available since Release 1.0
 */

Grid.prototype.render = render;
Grid.prototype.sort   = sort;

/**
 * Grid Constructor
 * 
 * This is the grid control constructor.
 * Instance name must be passed due to reflection limitation in JS
 * (or my knowledge of it).
 *
 * Given data array as described in data field (@see data)
 * a grid can be constructed as such:
 * <code>
 * var myGrid       = new Grid('myGrid'); // pass the instance name
 * myGrid.data      = data; // The data array
 * myGrid.tableID   = 'current'; // table ID (for styling, etc.)
 * myGrid.targetDiv = 'currentWorkContent'; // The div/object to render at
 *
 * myGrid.sort(2, 'asc'); // Start displaying by sorting the second column ascending
 * // Note: you can also use:
 * myGrid.render();  // This will display the grid without initial sorting
 * </code> 
 */
function Grid(instanceName) {
/**
 * Target Div
 * 
 * The Div (or container) that this grid will be rendered in
 *
 * @var string
 * @access public
 */
var targetDiv;

/**
 * Grid Data
 * 
 * This array must be formatted as:
 * ['column heading 1', 'column heading 2' ..]
 * ['column data 1 '  , 'column data 2' ..]
 *
 * Column data are objects formatted as:
 * object.title    // Text to be displayed (Required)
 * object.link     // Link to be attached to column text
 * object.class    // Special class to be added
 * object.location // Location to be added at the bottom e.g.: "location: hazard"
 * object.type     // Data type of the column (not implemented yet)
 *
 * Example:
 * <code>
 *	var data = new Array();
 *	data = [				
 *        // The first row is the heading
 *		[{"title"    :"Title"},
 *		 {"title"    :"Type"},
 *		 {"title"    :"Date"}]
 *		,
 *		
 *		// First data row:	
 *		[{"title"    :"Zero Warning",
 *          "link"    :"/zero",
 *		  "class"   :"private",
 *		  "location":"Plan > Zero Mitigation Assistance"  }
 *		,
 *		{"title" : "Web Page"}
 *		,
 *		{"title" : "March 11, 2006"}
 *		],
 *		
 *		// Second data row:
 *		[{"title"    :"Flood Warning",
 *		  "link"    :"/flood",
 *		  "class"   :"private",
 *		  "location":"Plan > Flood Mitigation Assistance"  }
 *		,
 *		{"title" : "Web Page"}
 *		,
 *		{"title" : "March 11, 2006"}
 *		 ]
 *		];
 *
 * </code>
 *
 * @var array
 * @access public
 */
var data;

/**
 * ID for the table to be rendered
 */
var tableID;

/**
 * Even rows class name
 */
var evenClass;
this.evenClass = 'even';

/**
 * Odd rows class name
 */
var oddClass;
this.oddClass  = 'odd';

/**
 * Table class name
 */
var tableClass;
this.tableClass  = 'grid';

/**
 * HTML Output
 */
var html;

/**
 * This instance name
 */
var name;
this.name = instanceName;

/**
 * Sort Ascending class name
 */
var asc;
this.asc = 'sortAsc';

/**
 * Sort Decsending class name
 */
var desc;
this.desc = 'sortDesc';

/**
 * Grid is currently sorted by
 */
var sortedBy;

/**
 * State of the sort (asc/desc)
 */
var state;
}

/**
 * Render the grid
 */
function render() {
	this.html    = '<table id="'+ this.tableID +'" class="'+ this.tableClass +'">';

	for (i=0; i<this.data.length; i++) {

		this.html += '<tr>';

		for(j=0; j<this.data[i].length; j++) {
			column = this.data[i][j];
			
			if (i==0) {
				this.html     += '<th scope="col" class="';
				
				if (this.sortedBy == j) {
					this.html += ' active';
				}
							
				if (column.className) {
					this.html += ' '+column.className;
				}
				
				this.html += '"><a href="javascript:'+this.name+'.sort('+j+')" ';
				
				if (this.sortedBy == j) {
					if (this.state == 'asc') {
						this.html += ' class="'+this.asc+'"';
					} else {
						this.html += ' class="'+this.desc+'"';
					}
				}
				
				this.html += '>';
				
				this.html += column.title;
				
				this.html += '</a></th>';
				
			} else {
				this.html += '<td class="';
				if (i%2) {
					this.html += this.evenClass;
				} else {
					this.html += this.oddClass;
				}
				
				this.html += '">';
				
				if (column.link) {
					this.html += '<a href="'+column.link+'"';
				}
				
				if (column.className && column.link) {
					this.html += ' class="'+column.className+'"';
				}
				
				if (column.link) {
				this.html += '>';
				}
				
				this.html += column.title;
		
				if (column.link) {
					this.html += '</a>';
				}
				
				if (column.location) {
					this.html += '<br />';
					this.html += '<span class="location">'+column.location+'</span>';
				}
				this.html += '</td>';
			}	
		}
		this.html += '</tr>';
	}
	
	this.html   += '</table>';

	document.getElementById(this.targetDiv).innerHTML = this.html;
}

/**
 * Sorts the grid
 *
 * @param int column       Column number to sort by (0 based)
 * @param string direction Direction to sort the column. values:
 *						   asc, desc. (optional)
 * @return void
 */
function sort(column, direction) {
	if (direction) {
		this.state = direction;
	}
	var sortedArray = new Array(this.data.length-1);
	for (i=1; i<this.data.length; i++) {
		if (this.data[i][column].sortBy) {
			sortedArray[i-1] = this.data[i][column].sortBy;
		} else {
			sortedArray[i-1] = this.data[i][column].title;
		}

	}

	sortedArray.sort();

	if (this.state && this.state == 'asc') {
		sortedArray.reverse();
		this.state = 'desc';
	} else {
		this.state = 'asc';	
	}
	
	this.sortedBy = column;
	
	var finalArray = new Array(this.data.length);
	finalArray[0] = this.data[0];
	
	for (i=0; i<sortedArray.length; i++) {
		var row;
		for (j=1; j<this.data.length; j++) {
			if (this.data[j][column].sortBy) {
				if (this.data[j][column].sortBy == sortedArray[i]) {				
					finalArray[(i+1)] = this.data[j];
					this.data.splice(j,1);
					break;
				}			
			} else{
				if (this.data[j][column].title == sortedArray[i]) {				
					finalArray[(i+1)] = this.data[j];
					this.data.splice(j,1);
					break;
				}
			}
		}
	}

	this.data = finalArray;
	this.render();
}
