function gz_Models() {
	// -- Customizable Settings -- //
	this.updateFadeOnTime = 500; 				//in milliseconds
	this.updateFadeOffTime = 1000; 				//in milliseconds
	this.updateFadeColorFrom = '#FFFFFF';		//
	this.updateFadeColorTo = '#ffff99';			//
	this.spreadChoicesRange = 2; 				//on each side of spread	
	this.defaultAlgoView = 'settings'; 			//settings or values,
	this.url_all = '/ajax/gamezone/load_gz_model_output.php';	//url of picks,lines,sim_games request
	this.url_algos = '/ajax/gamezone/load_gz_model_factors.php';	//url of algos request
	this.PromptForUpdate		= true;			//display update notificaton, start autoupdate timer
	this.AutoUpdate				= false;
	this.AutoUpdateFirstTime 	= 4; 			//FIRST time it takes for an auto update after moving a slider
	this.AutoUpdateTime 		= 2; 			//time it takes for an auto update after moving a slider
	
	// Defining Starting Variables
	this.factors = [];
	this.TOs = {};
	this.spinners = {};
	this.star_sets = {};
	this.picks = {};
	this.alerts = {};
	this.lines = {};
	this.pops = {};
}

gz_Models.prototype = {
	
	
	// -- Startup and Master Request Functions -- //
	
	Selected : function() {
		
		if (!gz_Models.loaded) {
			gz_Models.RequestAlgos();	
		}
		
	},
	
	Refresh : function() {	
		//If not already requesting data
		if (!gz_Models.spinners['sim_games'] || !gz_Models.spinners['sim_games'].loading) {
			
			gz_Models.Ar = new Ajax();
			gz_Models.Ar.fire( gz_Models.url_all , gz_Models.RefreshCallback, gz_Models.LoadAllParams());
			//if (gz_Models.loaded) { //Don't show spinners if loading for the first time
				Removeclass( $i('gz_block_predictions'), 'gz_loading_show');
				Removeclass( $i('gz_model_wrapper'), 'gz_loading_others');
				clearInterval(gz_Models.INT_autoUpdate);
				gz_Models.spinners['picks_table'] = new Spinner($i('gz_block_predictions_inner'), 'Predictions');
				gz_Models.spinners['sim_games'] = new Spinner($i('gz_sim_games_list'), 'Similar Historical Matchups');
			 	
				gz_Models.factorTable.reDraw();
			//}
		}
		
	},	
	
	
	abortRefresh : function() {
		if (!gz_Models.spinners['sim_games'] || !gz_Models.spinners['sim_games'].loading && gz_Models.Ar) {
			if(gz_Models.Ar) {
				gz_Models.Ar.abort();			
				delete gz_Models.Ar;
			}
			
			if (gz_Models.spinners['picks_table']) {
				gz_Models.spinners['picks_table'].destroy();
				gz_Models.spinners['sim_games'].destroy();
			}
		}
	},
	
	LoadAllParams : function() {
		//send list of factors, selected filter, and importance
		//send adjusted spread
		
		var data = { factors:{} };
		var changed = {};
		
		//Get Factor Data
		if ( gz_Models.factorTable ) {
			for(var i in gz_Models.factorTable.factors) {
				f = gz_Models.factorTable.factors[i];
				data.factors[i] = {
					factor_id : f.factor_id,
					lookup_name : f.lookup_name,
					selected_filter : f.selected_filter,
					importance : f.importance.value,
					changed : f.changed
				};
				if (!isObjectEmpty(f.changed))  {
					changed[f.factor_id] = data.factors[i];
				}
			}
		
			createCookie('gz_changed', JSON.stringify(changed), gz_Models.factorTable.o.cookie_expire);
		}

		//Get Adjusted Spread
		data.spread = gz_Models.spread;
		
		return 'data=' + JSON.stringify( data ) + gz_Models.postVarStr();
		
	},
	
	RefreshCallback : function(r) {//ProfileStart('refreshCallback');
		
		//try {
			var data = JSON.parse(r);	
			//ProfileSplit('refreshCallback', 'json');
			gz_Models.LoadRequest_Picks(data);
			//ProfileSplit('refreshCallback', 'LoadRequest_Picks');
			gz_Models.LoadRequest_Lines(data);
			//ProfileSplit('refreshCallback', 'LoadRequest_Lines');
			gz_Models.LoadRequest_SimGames(data);
			//ProfileSplit('refreshCallback', 'LoadRequest_SimGames');

			if (gz_Models.postVars.debug) {
				gz_Models.LoadRequest_SimGamesDebug(data);
			}
			
			gz_Models.loaded = true;
			if ($i('gz_loading_model')) { $i('gz_loading_model').style.display = 'none'; }
			
			setupTooltips();
			//ProfileSplit('refreshCallback', 'setupTooltips');

		//} catch(e) {
		//	alerterror(e);
		//}
		
	},
	
	
	
	// -- Algorithm Inputs Table Functions -- //	
	
	RequestAlgos : function() {
		
		var A = new Ajax();
		A.fire(  gz_Models.url_algos , gz_Models.LoadRequest_Algos, gz_Models.LoadAllParams()); 
		
	},
	
	LoadRequest_Algos : function(r, data) {
	//	try {
		
		gz_Models.factorTable = new gz_Table( {
											 	data: 		data?data:false,
												
											 	r: r,
											 	tbody:		$i('gz_algos_body'),
												json_var:	'factors',
												
												cookie: 	'gz_changed',
												
												rowFilter: 	gz_Models.Algo_RowFilter,
												events:		{
													onFinish : gz_Models.Algo_Table_onFinish,
													onFilterChanged : gz_Models.Algo_Table_onFilterChanged,
													rowAddedChanged : gz_Models.Algo_Table_rowAddedChanged
													}
											 } );
		gz_Models.factorTable._load();
		
		//setup events, load set all row
		//if (r) { gz_Models.factorTable.rParsed.setAllFilterCopy = '9'; } //for testing

		if (r && gz_Models.factorTable.rParsed.setAllFilterCopy && $i('gz_algos_foot') != null) { //setup show all row
			$i('gz_algos_foot').style.display = ( navigator.appName == 'Microsoft Internet Explorer' ? "block" : "table-footer-group");
			
			var setAllFilter = CreateSelect('gz_algos_set_all_filter_td', gz_Models.factorTable.factors[ gz_Models.factorTable.rParsed.setAllFilterCopy ].values, false, 'filter_label', 'filter_id', '-- choose --');
			$i('gz_algos_set_all_filter_td').appendChild( setAllFilter );
			
			setAllFilter.onchange = function() { gz_Models.factorTable.SetAllFilters(this.value, this); }
		}
		
		//} catch(e) { alerterror(e); }
	},
				
	Algo_RowFilter : function(f) {
		//Add slider
		f.elements.td_importance	= createNodeN('TD', {'class':'gz_a_settings'} );
		f.elements.td_slider 		= createNodeN('div', {id:'gz_slider_'+f.factor_id} );
		f.elements.td_importance.appendChild( f.elements.td_slider );
		f.elements.tr.appendChild( f.elements.td_importance );
		
		importanceData = f.importance;
		f.importance = new Slider(f.elements.td_slider, {'event': gz_Models.SliderChanged, event_args:{factor_id:f.factor_id}, ticks:5, spacing:16, label_l:'Lo', label_r:'Hi', label_width:23, handle_width:17} );
		f.importance.set( importanceData, false);		
		
		return f;		
	},
	
	Algo_Table_rowAddedChanged : function(a) {				
		gz_Models.SliderChanged(a, true);
	},
	
	Algo_Table_onFinish : function() {
		gz_Models.AlgoToggleView( gz_Models.defaultAlgoView );
	try {
		// show intro?
		//gz_Models.factorTable.rParsed.show_intro = 1; //for testing
		
		gz_Models.postVars.show_prediction = (gz_Models.factorTable.changed || (gz_Models.factorTable.rParsed && !gz_Models.factorTable.rParsed.show_intro)) ? 1 : 0;
	
		if (gz_Models.factorTable.rParsed &&  gz_Models.factorTable.rParsed.show_intro && !gz_Models.factorTable.changed ) {
		//if ( gz_Models.factorTable.rParsed.show_intro ) {			
			
			if ($i('gz_pop_welcome')) {
				gz_Models.pops['welcome'] =  new tr_pop( {
									type:'blank',
									content:$i('gz_pop_welcome').innerHTML,
									showClose:false,
									forceTop: 50,
									parent: $i('gz_model_wrapper')
								} );
			}
			
		} else {
			
			gz_Models.loadedSimGamesBefore = true;
			
			//Get Picks and Sim Tables
			gz_Models.Refresh();
			
		}
	
	
		if ( $i('gz_loading_model') ) { $i('gz_loading_model').style.diplay = 'none'; }
		} catch(e) { alert(e); }
	},
	
	Algo_Show : function() {	
		gz_Models.pops['welcome'].hide();
		gz_Models.factorTable.reDraw();
		gz_Models.postVars.show_prediction = 1;
	},
	
	Algo_Table_onFilterChanged : function(f, noRefresh) {
		gz_Models.ChangedItem( (f._default.selected_filter != f.selected_filter) , f.elements.td_filter, f.factor_id, 'filter' );

		if (!noRefresh) {
			gz_Models.disablePredictions();
		}
	},
	
	SliderChanged : function(a, noRefresh) {		
		var f = gz_Models.factorTable.factors[ a.factor_id ];

		gz_Models.ChangedItem( (f._default.importance != f.importance.value) , f.elements.td_importance, a.factor_id, 'importance' );
		
		if (!noRefresh) {
			gz_Models.disablePredictions();
		}
	},
	
	SetAllSliders : function(val) { 
		if (val * 1 >= 0) { 
			for(var i in gz_Models.factorTable.factors) {
				if (gz_Models.factorTable.factors[i].importance) { 
					gz_Models.factorTable.factors[i].importance.set( val, true);
				}
			}
		}
		$i('gz_algos_set_all_importance').selectedIndex = 0;
	},
	
	disablePredictions : function() {
		if (gz_Models.PromptForUpdate) {
			if ( !$i('gz_block_predictions').className.match('gz_loading_show') ) { //not already visible
				gz_Models.abortRefresh();
				Addclass( $i('gz_block_predictions'), 'gz_loading_show');
				gz_Models.resetAutoUpdate();
				$i('gz_picks_loading_msg').innerHTML = 'You have changed time and/or importance settings. Click below to update predictions.';
				$i('gz_picks_loading_btn').innerHTML = 'Update Predictions';
				if (gz_Models.AutoUpdate) { $i('gz_picks_loading_auto_update').style.display = 'block'; }
		   }
		} else {
			gz_Models.Refresh();	
		}
	},
	
	isFirstUpdate : function() {
		if (!gz_Models.autoUpdateAlready) {
			gz_Models.autoUpdateAlready = true;
			return true;
		}
	},
	
	resetAutoUpdate : function() {
		if (gz_Models.AutoUpdate) {
			clearInterval(gz_Models.INT_autoUpdate);
			gz_Models.setTillAutoUpdate( gz_Models.isFirstUpdate() ? gz_Models.AutoUpdateFirstTime : gz_Models.AutoUpdateTime );
			gz_Models.INT_autoUpdate = setInterval( gz_Models.setTillAutoUpdate, 1000, null );
		} else {
			$i('gz_picks_loading_auto_update').style.display = 'none';	
		}
	},
	
	setTillAutoUpdate : function( t  ) {
		if (t) {
			gz_Models.tillAutoUpdate = t;
		} else {
			gz_Models.tillAutoUpdate += -1;	
			
			if (gz_Models.tillAutoUpdate == 0) {
				gz_Models.Refresh();
			}
		}
		$i('gz_picks_loading_time').innerHTML = gz_Models.tillAutoUpdate;
	},
	
	ChangedItem : function(factorChanged, el, fi, what) {
		if (factorChanged) {
			gz_Models.factorTable.factors[ fi ].changed[what] = true;
			Addclass( el , 'gz_changed' ); //uncomment to enable showing changes
			
			$i('gz_a_changed_msg').style.display = ( navigator.appName == 'Microsoft Internet Explorer' ? "block" : "table-row");	 //uncomment to enable showing changes		
			return true;
			
		} else {
			delete gz_Models.factorTable.factors[ fi ].changed[what];
			Removeclass( el , 'gz_changed' );	 //uncomment to enable showing changes			
		}	
		

		for( var i in gz_Models.factorTable.factors ) {
			if ( !isObjectEmpty(gz_Models.factorTable.factors[i].changed) ) {
				$i('gz_a_changed_msg').style.display = ( navigator.appName == 'Microsoft Internet Explorer' ? "block" : "table-row");;  //uncomment to enable showing changes
				return true;
			}
		}
		
		$i('gz_a_changed_msg').style.display = 'none';  //uncomment to enable showing changes
	},
	
	RestoreDefaults : function() {
		eraseCookie('gz_changed');
		gz_Models.LoadRequest_Algos(null, gz_Models.factorTable.o.data);
		gz_Models.Refresh();
		var changed_tds = getElementsByClassName( $i('gz_algos_body'), 'td', 'gz_changed');
		for(var i in changed_tds) {
			Removeclass( changed_tds[i], 'gz_changed' );	
		}
		$i('gz_a_changed_msg').style.display = 'none';
	},
	
	AlgoToggleView : function(view) {
		if (gz_Models.factorTable) {
			if (gz_Models.algo_view) {
				Removeclass( $i('gz_opts_algo_' + gz_Models.algo_view) , 'tr_selected');
			}
			if ( view == 'settings' ) {
				gz_Models.factorTable.setColSpan( $i('gz_alogs_set_all_importance_td') , 1 );
				Addclass( $i('gz_algos') , 'gz_show_settings' );
				Removeclass( $i('gz_algos') , 'gz_show_values' );
			} else {
				gz_Models.factorTable.setColSpan( $i('gz_alogs_set_all_importance_td') , 3 );
				Removeclass( $i('gz_algos') , 'gz_show_settings' );
				Addclass( $i('gz_algos') , 'gz_show_values' );
			}	
			Addclass( $i('gz_opts_algo_' + view) , 'tr_selected');
			gz_Models.algo_view = view;
			
			gz_Models.factorTable.reDraw();
		}
	},
	
	
	
	
	
	// -- Predictions Table Functions -- //
	
	LoadRequest_Picks : function(data) {
			
		GM = gz_Models;
		SH = $i('gz_star_chart');
		A = $i('gz_alerts');
		
		
		//update star set
		for(var i in data.star_set) {
			
			if (data.star_set[i].label) {
				
				p = data.star_set[i];
				GMp = GM.star_sets[ p.label ];
				
				if (! GMp ) {
					GMp = {data:p,elements:{}};
					GMp.elements.tr = createNodeN('TR');
					GMp.elements.label = createNodeN('TD', {'class':'tr_al', innerHTML:p.label});
					GMp.elements.value = createNodeN('TD', {innerHTML:p.value});
					GMp.elements.stars = createNodeN('TD', {innerHTML:GM.GenStars(p.stars)});
					
					if (SH != null) {
						SH.appendChild(GMp.elements.tr);
						GMp.elements.tr.appendChild(GMp.elements.label);
						GMp.elements.tr.appendChild(GMp.elements.value);
						GMp.elements.tr.appendChild(GMp.elements.stars);					
					}
				} else {
					if ( p.value != GMp.data.value ) {
						GMp.elements.value.innerHTML = p.value;
						GM.UpdateNode( GMp.elements.value );
					}	
					if ( p.stars != GMp.data.stars ) {
						GMp.elements.stars.innerHTML = GM.GenStars(p.stars);
						GM.UpdateNode( GMp.elements.stars );
					}	
					GMp.data = p;
				}
				
				GM.star_sets[ p.label ] = GMp;
				
			}
		}
		
		
		//update predictions
		for(var i in data.picks) {
			
			if ( data.picks[i].label ) {
				GM.picks[ data.picks[i].label ] = gz_Models.UpdateValueRow( data.picks[i], GM.picks[ data.picks[i].label ] , $i('gz_picks') );			
			
				if (GM.spinners['picks_table']) { 
					GM.spinners['picks_table'].destroy();
				}	
			}
		}
		
		
		//update alerts
		var curDate = new Date();
		var curTime = curDate.getTime();
		for(var i in data.alerts) {
			p = data.alerts[i];
			
			if (p.label) {
			
				GMp = GM.alerts[ p.label ];
				
				if (! GMp ) {
					GMp = {data:p,elements:{}};
					GMp.elements.li = createNodeN('LI');
					GMp.elements.label = createNodeN('A', {innerHTML:p.label});
					if (p.tooltip) {
						GMp.elements.tooltip = createNodeN('span', {'class':'tr_tooltip',innerHTML:p.tooltip});
						GMp.elements.label.appendChild( GMp.elements.tooltip );
					}
					
					if (A != null) {
						A.appendChild(GMp.elements.li);
						GMp.elements.li.appendChild(GMp.elements.label);
						if (gz_Models.firstPicksLoaded) {
							GM.UpdateNode( GMp.elements.label );
						}
						GMp.updated = curTime;
					}
				} else {
					GMp.updated = curTime;
				}
				
				GM.alerts[ p.label ] = GMp;
			
			}
		}
		
		//remove alerts
		var nAlerts = 0;
		for(var i in GM.alerts) {
			if (GM.alerts[i] && GM.alerts[i].updated < curTime) {
				gz_Models.FadeRemove( GM.alerts[i].elements.li );
				GM.alerts[i] = false;
			} else {
				nAlerts++;
			}
		}
		
		if ($i('gz_no_alerts') != null) {
			$i('gz_no_alerts').style.display = (nAlerts == 0) ? 'block' : 'none';
		}
		
		gz_Models.firstPicksLoaded = true;
		
	},
	
	GenStars : function(s) {
		if (s==0) {
			return '<span class="gz_stars"></span>';
		} else {
			return '<span class="gz_stars"><span class="gz_stars_'+s+'"></span></span>';
		}
	},
	
	// -- //
	
	LoadRequest_Lines : function(data) {			
		
		if (!gz_Models.loaded) { //Only run the on first load - this will change if lines are ever updated
			//Create Spread Dropdowns
		
			if (!data.spread) {
				data.spread = {};
				data.spread.visitor = data.spread.home = 0;
			}
			
			if ($i('gz_ps_visitor') != null && $i('gz_ps_home') != null) {
				var gz_ps_visitor = CreateSelect('gz_ps_visitor_select', gz_Models.SpreadRange(data.spread.visitor), data.spread.visitor);
				var gz_ps_home = CreateSelect('gz_ps_home_select', gz_Models.SpreadRange(data.spread.home), data.spread.home);			
				$i('gz_ps_visitor').appendChild( gz_ps_visitor );			
				$i('gz_ps_home').appendChild( gz_ps_home );
				gz_ps_visitor.onchange = gz_Models.SpreadChanged;
				gz_ps_home.onchange = gz_Models.SpreadChanged;
				
				gz_Models.spread = data.spread;
				gz_Models.spreadDefault = new clone(data.spread);
				$i('gz_spread_last_update').innerHTML = gz_Models.spread.last_updated;
				$i('gz_spread_last_update').parentNode.style.display = gz_Models.spread.last_updated ? 'block' : 'none'
			}			
			
			//Fill Value Table
			for(var i in data.lines) {
				
				if ( data.lines[i].label ) {
					GM.lines[ data.lines[i].label ] =  gz_Models.UpdateValueRow( data.lines[i], GM.picks[ data.lines[i].label ] , $i('gz_lines') );			
				}

			}
		}
		
	},
	
	
	SpreadChanged : function() {
		//Get values from dropdowns
		var home = $i('gz_ps_home_select').value;
		var visitor = $i('gz_ps_visitor_select').value;
		
		//flip alternate dropdown to match inverse
		if (home != gz_Models.spread.home) {
			visitor = home * -1 + '';
			$i('gz_ps_visitor_select').value = visitor;
			if ($i('gz_ps_visitor_select').value != visitor) {
				FillSelect( $i('gz_ps_visitor_select') , gz_Models.SpreadRange(visitor) , visitor );
			}
		} else {
			home = visitor * -1 + '';	
			$i('gz_ps_home_select').value = home;
			if ($i('gz_ps_home_select').value != visitor) {
				FillSelect( $i('gz_ps_home_select') , gz_Models.SpreadRange(home) , home );
			}
		}
		gz_Models.spread.visitor = visitor;
		gz_Models.spread.home = home;
		
		//update spread if displayed as factor
		if (gz_Models.factorTable.factors[14]) {
			gz_Models.factorTable.factors[14].elements.td_values[gz_Models.factorTable.o.noFilterId].home.innerHTML = home;
			gz_Models.factorTable.factors[14].elements.td_values[gz_Models.factorTable.o.noFilterId].visitor.innerHTML = visitor;
		}
		
		//update predictions
		gz_Models.disablePredictions();
		
		if ( gz_Models.spread.home != gz_Models.spreadDefault.home ) {
			Addclass( $i('gz_block_lines') , 'gz_spread_changed' );
		} else {
			Removeclass( $i('gz_block_lines') , 'gz_spread_changed' );				
		}
	},	
	
	resetPointSpread : function() {
		$i('gz_ps_home_select').value = gz_Models.spreadDefault.home;
		$i('gz_ps_visitor_select').value = gz_Models.spreadDefault.visitor;
		
		gz_Models.SpreadChanged();
	},
	
	
	// ---------- Similar Games Table Functions ------------- //
	
	LoadRequest_SimGames : function(data) {
		
		/*if (!gz_Models.loadedSimGamesBefore) {
			gz_Models.pops['sim_games'] =  new tr_pop( {
									type:'confirm',
									question:"Don't forget to check similar historical games below!",
									confirmText:'Close',
									hideCancelBtn:true,
									forceTop: 50,
									parent: $i('gz_model_wrapper'),
									onConfirm: function(p) { p.hide(); gz_Models.factorTable.reDraw(); return true; }
								} );
			
			gz_Models.loadedSimGamesBefore = true;
		}*/
		
	
		
		//Determine show segments
		if ($i('gz_sim_games_opts') != null) {
			if (!gz_Models.initedSimSegments) { gz_Models.sim_segments = [];
				var as = $i('gz_sim_games_opts').getElementsByTagName('A');
				for(var i in as) {
					v = as[i].innerHTML * 1;
					if (v > 0) {
						gz_Models.sim_segments[v] = v;
						AddStyleRule('#gz_sim_games_list_table.gz_table_segment_'+v+' .gz_table_segment_'+v, 'display:' + ( navigator.appName == 'Microsoft Internet Explorer' ? "block" : "table-row") );
						
						as[i].onclick = gz_Models.ShowNumSimGames;
						as[i].setAttribute('id', 'gz_table_segment_'+v);
						
						if (as[i].className.match('tr_selected')) {
							gz_Models.sim_segment_selected = v;					
						}
					}
				}
				gz_Models.sim_segments.reverse();
				gz_Models.initedSimSegments = true;
			}
			//ProfileSplit('refreshCallback', 'Determine show segments');
			
			
			//Load in updated table
			$i('gz_sim_games_list').innerHTML = data.sim_games;
			//ProfileSplit('refreshCallback', 'load innerHTML');
			
			
			//Section table into show segments
			var trs = $i('gz_sim_games_list_table').getElementsByTagName('TR');
			for(var i=0; i<trs.length; i++) {			
				for(var s in gz_Models.sim_segments) {
					if ( i <= gz_Models.sim_segments[s] ) {
						trs[i].className += ' gz_table_segment_' + gz_Models.sim_segments[s];
					}// else { break; }
				}
			}
			//ProfileSplit('refreshCallback', 'section table');
			
			gz_Models.ShowNumSimGames(null, gz_Models.sim_segment_selected);
			//ProfileSplit('refreshCallback', 'shownumsimgames');
			
			if (gz_Models.spinners['sim_games']) {
				gz_Models.spinners['sim_games'].destroy();
			}
			//ProfileSplit('refreshCallback', 'destroy spinner');
		}

	},
	
	LoadRequest_SimGamesDeug : function(data) {
		$i('gz_sim_games_debug_list').innerHTML = data.sim_games_debug;
	},
	
	ShowNumSimGames : function(e, n) {	
		if (!n) { n = this.innerHTML; }
		if (gz_Models.sim_segment_selected) {
			$i('gz_sim_games_list_table').className = $i('gz_sim_games_list_table').className.replace('gz_table_segment_'+gz_Models.sim_segment_selected, '');
			$i('gz_table_segment_'+gz_Models.sim_segment_selected).className = $i('gz_table_segment_'+gz_Models.sim_segment_selected).className.replace('tr_selected', '');
		}
		$i('gz_sim_games_list_table').className += ' gz_table_segment_' + n;
		$i('gz_table_segment_'+n).className += ' tr_selected';
		gz_Models.sim_segment_selected = n;
		
		gz_Models.factorTable.reDraw();
	},
	
	
	
	
	// -- General DOM Functions -- //
	
	UpdateValueRow : function( update, data , table ) {
		var cols = new Array('home', 'visitor', 'span');
		
		//column span changed, redo row		
		if (data && update.span != data.data.span) {
			var newData = gz_Models.UpdateValueRow( update , false , table );
			table.insertBefore( newData.elements.tr , data.elements.tr );
			table.removeChild( data.elements.tr );
			return newData;
		}
		
		if (! data ) {
			data = {data:update,elements:{}};
			data.elements.tr = createNodeN('TR');
			data.elements.label = createNodeN('TD', {'class':'tr_al', innerHTML:update.label});
			
			if (table != null) {
				table.appendChild(data.elements.tr);
				data.elements.tr.appendChild(data.elements.label);
				
				if (update.span) {
					data.elements.span = createNodeN('TD', {innerHTML:update.span,align:'center'});
					gz_Models.factorTable.setColSpan( data.elements.span , 2 );
				
					data.elements.tr.appendChild(data.elements.span);					
				} else {
					data.elements.home = createNodeN('TD', {innerHTML:update.home,align:'center'});
					data.elements.visitor = createNodeN('TD', {innerHTML:update.visitor,align:'center'});					
				
					data.elements.tr.appendChild(data.elements.home);
					data.elements.tr.appendChild(data.elements.visitor);	
				}			
				
				if (update.tooltip) {
					data.elements.tooltip = createNodeN('span', {'class':'tr_tooltip',innerHTML:update.tooltip});
					data.elements.label.appendChild( data.elements.tooltip );
				}
			}			
		} else {
			for(c in cols) {
				col = cols[c];
				if ( update[col] != data.data[col] ) {
					data.elements[col].innerHTML = update[col];
					GM.UpdateNode( data.elements[col] );
				}	
			}
			data.data = update;
		}
		
		return data;
	},
	
	UpdateNode : function(n, alt) {		
		if (!n.id) {
			n.setAttribute('id', 'id_' + Math.round( Math.random()*100000000 ));
		}
		if (!gz_Models.TOs[n.id]) {
			var from = alt ? alt.from : this.updateFadeColorFrom; 
			var to = alt ? alt.to : this.updateFadeColorTo;
			clearInterval(gz_Models.TOs[n.id]);
			NLBfadeBg(n.id, from, to, this.updateFadeOnTime);		
			gz_Models.TOs[n.id] = setTimeout( 'gz_Models.UpdateNodeOff("'+n.id+'", "'+n.style.backgroundColor+'", "'+from+'", "'+to+'" )' , this.updateFadeTimeOn );
		}
	},
	UpdateNodeOff : function(id, bg, from, to) {
		clearInterval(gz_Models.TOs[id]);
		NLBfadeBg(id, to, from, this.updateFadeOffTime);
		gz_Models.TOs[id] = setTimeout( 'gz_Models.UpdateNodeFinish("'+id+'", "'+bg+'")' , this.updateFadeOffTime );	
	},
	UpdateNodeFinish : function(id, bg) {
		clearInterval(gz_Models.TOs[id]);
		gz_Models.TOs[id] = $i(id).style.backgroundColor = bg;
	},
	
	FadeRemove : function(n) {
		if (!n.id) {
			n.setAttribute('id', 'id_' + Math.round( Math.random()*100000000 ));
		}
		t = this.updateFadeOnTime + this.updateFadeOffTime;
		
		opacity(n.id, 100, 0, t);
		setTimeout( '$i("'+n.id+'").parentNode.removeChild( $i("'+n.id+'") )' , t );
	},
	
	
	
	// -- General Functions -- //
	
	SpreadRange : function(s) {
		spreadCenter = (s + '').replace(/\+/, '') * 1;
		spreadValues = [];
		for(var i=spreadCenter-gz_Models.spreadChoicesRange; i<spreadCenter+gz_Models.spreadChoicesRange; i+=0.5) {
			spreadValues.push( {'label':Spread(i), 'value':i} );
		}	
		return spreadValues;
	},
	
	postVarStr : function() {			
		var qStr = '';
		
		postVars = this.postVars;
		for(var i in postVars) {
			qStr += '&' + i + '=' + postVars[i];
		}
		return qStr;
	}
	
}

gz_Models = new gz_Models();