function dateChange(y, m, d, a, calObj, eventArgs, force) {
	if (force || a.className.match('tr_active')) {
		$i('date_output').innerHTML = m + '/' + d;
		
		setTimeout(function(){picksTable.timeChanged(picksTable, $i('date'))}, 70); //wait for calendar object to finish (race condition)
		return false;
	}
	return true;
}


function picksTable(o) {
	this.filterTable = o.filterTable;
	this.picksTableId = o.picksTableId;
	this.tableBody = o.tableBody;
	this.o = o;
	
	this.filters = {};
	this.filterSets = {};
	this.linkBacks = {};
	this.postVars = o.postVars ? o.postVars : {};
	this.countdowns = {};
	this.countdownInt;
	
	var self = this;
	this.aRef = new simpleAjax( {type:'ctn', url:'/ajax/league/picks_controller.php?type=apply_filter', callback:function(r){self.refreshCallback(self,r);}, ctn:this.tableBody} );
	this.aUp = new simpleAjax( {type:'json', url:'/ajax/league/picks_controller.php?type=refresh_column', callback:function(r){self.updateColumnsCallback(self,r);}} );
}
picksTable.prototype = {
	
	init : function() {
		var self = this;		
		
		// add events to time controls
		if ($i('time_week') && $i('week')) {
			$i('time_week').onclick = $i('time_date').onclick = function() { self.timeChanged(self, this); }
			$i('week').onchange = $i('date').onchange = function() { self.timeChanged(self, this); }
			this.postVars.time = $i('time_week').checked ? 'week' : 'date';
			this.postVars.week = $i('week').value;
		} else {
			this.postVars.time = 'date';
		}
		this.postVars.date = $i('date').value;
		
		// Find all filter fields - apply events - load into params object
		if (this.filterTable) {
			var flags, flagSet, valueElement;
			var inputs = this.filterTable.getElementsByTagName('input');
			var f=0;
	
			for(var i in inputs) {	
					
				if (inputs[i].tagName != 'INPUT') { continue; }
				/*
				Checkboxes should be formated as follows:
				compare = attribute to check on each row
					can be:
					- name of attribute
					- json array of attributes: [atr1,atr2,atr2]
				value = match compare with this to show row
					can be:
					- single value
					- json array of values: [1,2,3]
				
					can be:
					- name of attribute
					- json array of attributes: [atr1,atr2,atr2]	
				valueElement = should get the value from another element (typically a dropdown)
					can be:
					- id of element			
				*/
	
				if (inputs[i].type == 'checkbox') {
					
					// Determine flags to check against
					flagSet = inputs[i].getAttribute('compare');
					if (flagSet.match(/\[/)) {
						flags = eval(flagSet);
					} else {
						flags = [flagSet];
					}
					
					// Get object to check value for
					if (inputs[i].getAttribute('valueElement')) {
						valueElement = $i(inputs[i].getAttribute('valueElement'));
						
						// link the valueElement to the checkbox
						inputs[i].setAttribute('id', 'link_' + Math.random());
						valueElement.setAttribute('linkedTo', inputs[i].id);
						valueElement.onchange = function() { self.filterChanged(self, this); }				
					} else {
						valueElement = inputs[i];				
					}
									
					// add filter
					this.filters[ f ] = {
						self: inputs[i],
						flagsToCheck: flags, //probably should add an option to allow AND or OR setting, default to OR for now
						valueElement: valueElement					
					}
				
					// add event 
					inputs[i].onclick = function() { self.filterChanged(self, this); }
					
					// add checkbox to filter set (to compare when making checkboxes have radio behavior)
					if (!this.filterSets[ inputs[i].getAttribute('group') ]) { this.filterSets[ inputs[i].getAttribute('group') ] = []; }
					this.filterSets[ inputs[i].getAttribute('group') ].push( inputs[i] );
					
					f++;
					
				}
					
			}
		}
		
		if (this.o.autoUpdate) {
			var self = this;
			this.autoUpdateInt = setInterval(function() 
			{ 
				
				if (!self.autoUpdateCount) { self.autoUpdateCount = 0; }
				self.autoUpdateCount++;
				if (self.autoUpdateCount < self.o.autoUpdateMax) {
					self.refresh(self,true);
				} else {
					
					// Check if refresh row is already there
					
					var rowExists = $i(self.picksTableId).parentNode.getElementsByTagName('div');
					if (!rowExists[0] || !rowExists[0].className.match('tr_info_row')) {							
						
						// Add refresh row
						var refreshRow = document.createElement('div');
						refreshRow.className = 'tr_info_row';
						refreshRow.innerHTML = '<a onclick="'+self.o.variableName+'.refresh()">Refresh</a>';
						$i(self.picksTableId).parentNode.insertBefore(refreshRow, $i(self.picksTableId));
						
					}
					
				}
			}, this.o.autoUpdate);
		}
		
		// Add model events
		if (this.o.pickModels) {
			
			var lis = this.o.pickModels.getElementsByTagName('input');
			for(var i=0; i<lis.length; i++) {
				if (lis[i].tagName == 'INPUT') {
					lis[i].onclick = function() { 
						var obj;
						if (this.tagName == 'A') {
							obj = self.linkBacks[this.id];
							obj.checked = true;
						} else {
							obj = this;	
						}
						self.modelChanged(self, obj );
					}
					
					// preselected
					if (lis[i].checked) lis[i].onclick();
					
					// add event to it's partner link if it exists
					var linkId =lis[i].getAttribute('linkId');
					if (linkId && $i(linkId)) {
						this.linkBacks[linkId] = lis[i];
						$i(linkId).onclick = lis[i].onclick;	
					}
				}
			}
			
		}
		
	},
	
	/* --- */
	
	filter : function() {
		
		var rows, i, f, c, v, valueSet, values, filters, flags;
		var show, matched;
		
		// Make a filter array with the pre-extracted values only for checked items to speed up things inside the loop
		filters = [];
		for(f in this.filters) {
					
			if (this.filters[f].self.checked) {
				
				// Get list of possible values
				valueSet = this.filters[f].valueElement.value;
				if (valueSet.match(/\[/)) {
					values = eval(valueSet);
				} else {
					values = [valueSet];
				}
				// Check values against flag for this row
				
				filters.push( {
					filter:this.filters[f],
					values:values
					} );
				
			}
			
		}	
		
		// run through the rows and drop any that don't match all of the filters
		showCount = 0;
		zebraN = 0;
		rows = $i(this.picksTableId).getElementsByTagName('TR');
		for(var i=0; i<rows.length; i++) {
			if (rows[i].tagName == 'TR' && rows[i].parentNode.tagName != 'THEAD') {
				
				// run through filters and check row
				if (filters.length == 0) {
					show = true;
				} else {
					show = true;
					for(f in filters) { // compare: has to match all
						matched = false;
						flags = filters[f].filter.flagsToCheck
						values = filters[f].values;
						for(c in flags) { // compare: match at least one					
							for(v in values) { // compare: match at least one
								if (values[v] == 0 || rows[i].getAttribute(flags[c]) == values[v]) {
									matched = true;
									break; break; // flag matches at least one of the values, move on
								}
							}
						}
						if (!matched) { 
							show = false;
							break; // the rows flag didn't match any allowed values, so move on to the next row
						}	
					}
				}
				
				rows[i].style.display = show ? ( navigator.appName == 'Microsoft Internet Explorer' ? "block" : "table-row") : 'none';			
				if (show) {
					showCount++;
					
					// redrawing alt shading
					if ( zebraN%2 != 0) {
						Addclass( rows[i] , 'tr_alt' );
					} else {
						Removeclass( rows[i] , 'tr_alt' );
					}
					zebraN++;
				}
				
			}
		}
		
		
		if (!this.footerMsg || !this.footerMsg.parentNode) {
			this.footerMsg = createNodeN('div', {align:'center','class':'no_match'});
			this.footerMsg.innerHTML = 'No games match';
			$i(this.picksTableId).parentNode.insertBefore(this.footerMsg, $i(this.picksTableId).nextSibling);
		}
		this.footerMsg.style.display = showCount ? 'none' : 'block';
		
	},
	
	filterChanged : function(obj, ele) {
	
		if (ele.type == 'checkbox') {
			// Unselect any other checkboxes in the filter set
			for(var i in obj.filterSets[ele.getAttribute('group')]) {
				if (ele != obj.filterSets[ele.getAttribute('group')][i]) {
					obj.filterSets[ele.getAttribute('group')][i].checked = false;
				}
			}
		} else if (ele.type.match('select')) {
			$i(ele.getAttribute('linkedTo')).checked = true;
			obj.filterChanged( obj, $i(ele.getAttribute('linkedTo')));
			return false;
		}
				
		// Update Table
		obj.filter();
		
	},
	
	/* --- */
	
	timeChanged : function(obj, ele) {

		if (ele.type == 'radio') {
			obj.postVars.time = ele.value;
		} else {
			obj.postVars.time = ele.id;
			obj.postVars[ele.id] = ele.value;
			
			if (!$i('time_'+ele.id).checked) {
				$i('time_'+ele.id).checked = true;
			}
		}

		obj.refresh();
		
	},
	
	/* --- */
	
	refresh : function(obj, noSpinner) {
		obj = !obj ? this : obj;
		clearInterval(obj.countdownInt);
		this.aRef.spinner = !noSpinner;
		this.aRef.send( obj.postVars );	
	},
	
	refreshCallback : function(self, r) {		
		self.refreshTable();
	},
	
	refreshTable : function() {
		//try {
		
		var self = this;
		
		// Set up sorting
		this.sortTable = new sortableTable2( this.picksTableId, {
			eventSorted: function(sortTable){ 
				self.sortedIndex = sortTable.currentColumn;
				self.sortedDir = sortTable.sortDir;
			},
			defaultSortIndex : this.sortedIndex ? this.sortedIndex : 0,
			startDir : this.sortedDir ? this.sortedDir : false
		} );
		
		// Filter results
		this.filter();
		
		
		// Start countdown timers
		var c=0;
		this.countdowns = {};
		countCells = getElementsByClassName($i(this.picksTableId), 'TD', 'tr_countdown');
		for(var i=0; i<countCells.length; i++) {
			if (countCells[i].tagName == 'TD') {
				this.countdowns[i] = {
					date : new Date(),
					cell : countCells[i]
				};
				this.countdowns[i].date.setTime( countCells[i].getAttribute('countDown')  * 1000);
				c++;
			}
		}
		if (c > 0) {
			var self = this;
			this.updateCountdowns(this);
			this.countdownInt = setInterval(function() { self.updateCountdowns(self); }, 30000); //only updates every 30 seconds since we aren't tracking seconds
		}
		
		//} catch(e) { alert(e); }
		
	},
	
	// -- //
	
	updateCountdowns : function(obj) {
		var now = new Date();	
		
		for(var i in obj.countdowns) {
			if (obj.countdowns[i]) {
				
				date = obj.countdowns[i].date;
				cell = obj.countdowns[i].cell;
				
				var dif = (date.getTime() - now.getTime() ) /1000;
				
				if (dif < 0) { cell.innerHTML = ''; }
				
				var d = Math.floor( dif /60/60/24 );
				var hr = Math.floor( dif /60/60 ) - (d*24);
				var mn = Math.floor( dif /60 ) - (hr*60);
				var s = Math.floor( dif ) - (hr*60*60) - (mn*60);
				
				if (mn == 0 && hr>0) { mn = 60; hr--; }
				
				cell.innerHTML = 'Kickoff in<br>';
				if ( hr > 0 || d > 0 ) { 
					
					if (d > 24) cell.innerHTML += d + 'day' + (d==1?'':'s') + ' ';					
					if (hr > 0) cell.innerHTML += hr + 'hr' + (hr==1?'':'s') + ' ';
					if (d < 24 && m > 0) cell.innerHTML += mn + 'min' + (mn==1?'':'s');
				}
								
			}
		}		
	},
	
	// -- //
	
	modelChanged : function(obj, ele) {
		
		obj.postVars.model = ele.value;
		obj.refresh();
		
	}
	
}

if (navigator.userAgent.match(/firefox/i)) { document.body.className += ' firefox'; }