
Table_class = function(args) {
	
	this.props = args;

	this.name = args.name || "displayonly";
	this._data = args.data || null;
	this._sort = args.sort || null;
	this.noSortLinks = args.noSortLinks || false;	
	this.noHeading = args.noHeading || false;	
	this._headingGroups = args.headingGroups || [];	
	this._headings = args.headings || [];
	this._sortasc = !!args.sortasc; // (!! converts to bool representation)
	this.customSort = args.customSort || null;
	this.onDrawComplete = args.onDrawComplete || null;
	this._sortListener = null;
	this.table = Element.get("table-"+this.name);
	this.theads = Element.parseSelector("thead.sortable",this.table);
	if (this.theads.length) {
		this.thead = this.theads[0];
	}

	this.tbodies = Element.parseSelector("tbody",this.table);
	if (this.tbodies.length) {
		this.tbody = this.tbodies[0];
	}

	//recurseObject({o:this._data,n:"this._data",buffer:0,text:0,level:500,inline:0,nowrite:0});

}

Table_class.prototype.getSortLinks = function() {
	if (!this._sortLinks) {
		this._sortLinks = Element.parseSelector("a",this.thead);
	}

	return this._sortLinks;
}


Table_class.prototype.data = function(arg) {
	if (arg !== undefined) {
		this._data = arg;
	}
	return this._data;
}

Table_class.prototype.headings = function(arg) {
	if (arg !== undefined) {
		this._headings = arg;
	}
	return this._headings;
}

Table_class.prototype.headingGroups = function(arg) {
	if (arg !== undefined) {
		this._headingGroups = arg;
	}
	return this._headingGroups;
}

Table_class.prototype.fireDrawComplete = function(){
	
	if( this.onDrawComplete ){

		eval( this.onDrawComplete )();
		
	};
	
};


Table_class.prototype.sort = function(arg,firstsort) {
	if (arg !== undefined) {

		if (this._sort == arg) {
			this._sortasc = !this._sortasc;
		}
		else if (firstsort) {
			this._sortasc = /asc/.test(firstsort) ? true : false;
		}

		this._sort = arg;
		// remove sorting from all links
		Element.removeClass(this.getSortLinks(),"sort(?:asc|dsc)");
		// add sorting
		Element.addClass(this.name+"-sort-"+this._sort,(this._sortasc?"sortasc":"sortdsc"));

		if (this.customSort) {
			try {
				eval(this.customSort+"({sort:'"+this._sort+"',sortasc:"+this._sortasc+"})");
			}
			catch(e) { }
			return;
		}
		this.drawBody();
	}
	
	return {sort:this._sort,sortasc:this._sortasc};
}


Table_class.prototype.drawBody = function() {

	if (!this.tbody) {
		this.tbody = Element.create("tbody",{},null,this.table);
	}

	var headings = this.headings();
	var data = this.data();

	if (this._sort && !this.customSort) {
		data = SortByField(this.data(),this._sort,this._sortasc, true);
	}

	Element.removeChildNodes(this.tbody);

	var headings = this.headings();

	// fix so align: can simply be "left" or "right"
	for (var i=0; i < headings.length; i++) {
		if (headings[i].align) {
			headings[i].align = headings[i].align.toString().match(/left/i) ? "alignLeft" : "alignRight";
		}
	}
	
	var tr, td;
	
	var fieldValue, cellClass;
	for (var i=0; i<data.length;i++) {
 		var rowClass = data[i].highlight? "highlight" : "";
		var tr = Element.create("tr",{className:rowClass},null,this.tbody);

		for (var x=0;x<headings.length;x++) {
			fieldValue = (data[i][headings[x].field+"_format"] || (data[i][headings[x].field]!=null?data[i][headings[x].field]:""));
			cellClass = (headings[x].field == this._sort) ? "currentsymbol ":"";
			cellClass += (headings[x].align || " alignRight");
			cellClass += (x == 0 && data[i].extraIndent) ? " extraIndent" : "";

			td = Element.create("td",{className:cellClass},fieldValue,tr);
		}

	}
	this.fireDrawComplete();

}







/* Creating tables client side */

var TableCreator_class = function ( oArgs ) {

	this._name 	     = oArgs.name;
	this._parent	 = oArgs.parent;
	this._headings   = oArgs.headings;
	this._hLen		 = this._headings.length;
	this._data 	     = oArgs.data;
	this._dLen		 = this._data.length;
	this._sort		 = oArgs.sort || false;
	this._initSort   = oArgs.initSort || false;
	this._delayed	 = oArgs.RT? false : true;

	this._initSortOrder  = oArgs.initSortOrder || false; 

	if(this._initSort) {
		
		SortByField( this._data, this._initSort, this._initSortOrder, true);	
	}

	this._table;
	this._headers   = new Array();
	this._rows	    = new Array();
	this._sortData  = new Array();
	
	this.createTable();
};


TableCreator_class.prototype.loopHeadings = function ( func, args ) {
	
	for(var i = 0; i < this._hLen; i++) {
	
		func.apply(this, [i, this._headings[i], this._hLen].concat(args));
	}
};


TableCreator_class.prototype.loopData = function ( func, args ) {

	if(!this._dLen) {
		this.handleNoData();
		return;	
	}
	
	for(var i = 0; i < this._dLen; i++) {
		
		func.apply(this, [i, this._data[i], this._dLen].concat(args));
	}
};


TableCreator_class.prototype.handleNoData = function () {

	Element.create("tbody", {}, [
		Element.create("tr", {}, [
			Element.create("td", {colSpan:this._hLen}, "We're sorry, there is currently no data available at this time.")
		])
	], this._table);	
};


TableCreator_class.prototype.createTable = function () {
	
	this._table = Element.create( "table", {
		
				 id:"table-" + this._name
				,className:"WSODTable vertical stretchy"
				,cellpadding:"0"
				,cellspacing:"0"
	});
	
	this.loopHeadings( this.addCols );
	this.loopHeadings( this.addHeader );
	this.loopData( this.addBody );
};


TableCreator_class.prototype.addCols = function () {

	Element.create("col", {}, null, this._table);	
};


TableCreator_class.prototype.addHeader = function ( i, data, total ) {
	
	if( !this._headerElement ) {
		
		var head 		    = Element.create( "thead", {}, [], this._table );
		this._headerElement = Element.create( "tr", {}, null, head );
	};
	
	var klass = this.makeCamelClass( data.align || "left", "align" );
	var th    = Element.create( "th", {className:"alignBotton " + klass }, [], this._headerElement);
	var field;
	var a;
			 
	if( this._sort && data.sort ) {

		a = Element.create( "a", {href:"javascript:void(0);", field:data.field}, data.label, th );
		this._headers.push( a );
	} 
	else {
		Element.setHTML( th, data.label == "clientBuySell" || data.label == "delayed" || data.label == "morelink"? "&nbsp;" : data.label );	
	}
};


TableCreator_class.prototype.addBody = function ( i, data, total ) {
	
	if(!this._tableBody)
		
		this._tableBody = Element.create( "tbody", {}, null, this._table);
		
	
	
	var tr = Element.create( "tr", {}, null, this._tableBody );
	
	this._rows.push( tr );
	this.loopHeadings( this.addCells, [ data, tr ] );
	
	
	var _data = data;
		_data.element = tr;
		
	this._sortData.push( _data );
};


TableCreator_class.prototype.addCells = function ( i, headingData, total, cellData, parent ) {
	
	var klass = this.makeCamelClass( headingData.align || "left", "align" );
	var field = cellData[ headingData.field + "_format" ] || cellData[ headingData.field ];
	var field_raw = cellData[ headingData.field ];
	
	
	if(headingData.format && field) {

		field = WSDOM.Format[headingData.format.method](field,headingData.format.format, headingData.format.color);	
		
	} else if(headingData.label) {
		
		switch(headingData.label) {
			
			case "delayed":	
				field = this._delayed? Element.create("span", {className:"iconBackground iconDelayed"}, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;") : "&nbsp;";
				break;
				
			case "clientBuySell":
				
				field = [
					 Element.create("a", {className:"normal", target:"vendorLinks", href:gSessionSeedDomain+"/cgi-bin/apps/u/ThirdPartyUrlLauncher/new?target=buyBttn&param="+field_raw}, "Buy")
					,'&nbsp;'
					,Element.create("a", {className:"normal", target:"vendorLinks", href:gSessionSeedDomain+"/cgi-bin/apps/u/ThirdPartyUrlLauncher/new?target=sellBttn&param="+field_raw}, "Sell")
				];
				break;
				
			case "morelink":
				var aTag;
				field = Element.create("div", {className:"mi"} ,
					[
						aTag = Element.create("a", {
							href:"javascript:void(0)", 
							id:"morelink_"+cellData.Symbol, 
							className:"normal", 
							onmouseover:"showMoreTitle(this);"							
						}, [
						Element.create("div", {id:"more_" + cellData.Symbol,  className:"moreicon"})
					])
				]);
				
				aTag.onclick = function() {
	                generateResearchMore(cellData.Symbol, cellData.Symbol, cellData.CompanyName, cellData.Exchange, '', '');
					return false;
                }

				
				break;
				
			default:
				field = field;
		}
	}
	
	if(headingData.creator) {
		
		var vals = window[headingData.creator.context][headingData.creator.method]( cellData[headingData.field] );
		
		field = vals.format;
		cellData[headingData.field] = vals.raw;
		
	}
	
	if(headingData.classname) {
		klass += " " + headingData.classname;	
	}
	
	Element.create( "td", {className:klass}, field, parent );
};


TableCreator_class.prototype.makeCamelClass = function( elem, prepend ) {
	
	prepend = prepend || "";
	
	var klass = elem.slice(0,1).toUpperCase() + elem.slice(1);
		klass = prepend + klass;
		
	return klass;
};


TableCreator_class.prototype.bindSortableEvents = function () {
	
	Events.add({
		 element:this._headers
		,type:'click'
		,handler:this.sortTable
		,context:this
	});
};


TableCreator_class.prototype.sortTable = function ( ev, el ) {
	
	el.blur();
	
	Element.removeClass( this._headers, "current" );
	Element.addClass( el, "current" );
	
	Element.removeClass( this._headers, 'dsc' );
	Element.removeClass( this._headers, 'asc' );
	Element.addClass( el, this._initSort? 'asc':'dsc');
	
	var field = el.getAttribute("field");
	
	this._sortData  = SortByField( this._sortData, field, this._initSort, true );
	
	this._initSort = !this._initSort;
	
	var i   = 0,
		len = this._sortData.length;
		
	for(; i < len; i++) {
		
		Element.addChild( this._tableBody, this._sortData[i].element );	
	}
};


TableCreator_class.prototype.draw = function () {
	
	if( this._sort ) {
		this.bindSortableEvents();
	}
	
	Element.addChild( this._parent, this._table );
	
	return this._table;
};