/* tested with jQuery 1.3.2 */
if(console === undefined)
{
	var console =
	{
		log: function() {},
		dir: function() {}
	};
}

var codeDialog = 
{
	ajaxHandlerURL : null,
	initContents : "<div><p id='prompt'></p><input id='code' value='' size=10 /><input type='hidden' id='target' value='' size=100 /><br/><div id='message'></div></div>",
	config :
	{
		width:500,
		dialogClass : 'codedialog',
		//draggable : false,
		//hide : 'slide',
		//show : 'slide',
		modal : true,
		resizable : false,
		title : "Enter Access Code",
		buttons : null,
		closeText : '&nbsp;',
		close : null

	},
	
	init : function(ajaxHandlerURL)
	{
		codeDialog.ajaxHandlerURL = ajaxHandlerURL;
		codeDialog.config.buttons =
			{				
				'Cancel' : codeDialog.close,
				'OK' : codeDialog.okPress
			};
		codeDialog.config.close = codeDialog.close;
	},
	
	prompt : function(evt)
	{		
		evt.preventDefault();
		$this = $(this);
		$popup = $(codeDialog.initContents);
		
		$popup.find('input#target')
				.val($this.attr('href'));
		
		$popup.find("#prompt")
				.html("Please enter your code for <b>"+$this.attr('desc')+"</b>");
		
		codeDialog.me = $popup.dialog(codeDialog.config);
		$(document).keypress(codeDialog.enterPressed);
	},

	enterPressed : function(evt)
	{
		if ((evt.which && evt.which == 13) || (evt.keyCode && evt.keyCode == 13)) 
		{
			if (codeDialog.me && codeDialog.me.dialog('isOpen'))
			{
				codeDialog.locateOkButton().click(); 
			}
		 }
	},
	
	locateOkButton : function()
	{
		return codeDialog.me.parent().find(":button:last"); // last in codeDialog.config.buttons - not necessarily visually last in the dialog
	},
	
	okPress : function(event, ui)
	{
		event.preventDefault();
		$this=$(this);
		
		// disable to prevent double-click problem
		codeDialog.locateOkButton().attr('disabled', 'disabled');
		
		parms = 
		{
			'login' : $this.find('input#target').val(),
			'code' : $this.find('input#code').val()
		};
		
		$.post(codeDialog.ajaxHandlerURL, parms, codeDialog.ajaxLoginDone, 'json');
	},
	
	ajaxLoginDone : function(data)
	{
		if (data.login !== undefined) 
		{
			if (data.login.substring(0,3) == 'OK:') 
			{
				codeDialog.cleanup();
				window.location = data.login.substring(3);
			}
			else 
			{
				codeDialog.me.find("div#message").html(data.login);
				
				// reenable OK button
				codeDialog.locateOkButton().attr('disabled', '');
			}
		}
	},
	
	close : function(event, ui)
	{
		event.preventDefault();
		codeDialog.cleanup();
	},
	
	cleanup : function()
	{
		$(document).unbind('keypress');
		codeDialog.me/*.dialog('close')*/.dialog('destroy');
		delete codeDialog.me;
	}
};

var autoCmplt = 
{
	$context : null,
	ajaxHandlerURL : null,
	config :
	{
		autocomplete :
		{
			//matchSubset : false,
			matchContains : true, // 'word'
			//cacheLength : 1,
			//scroll : false,
			max : 50,
			minChars : 2,
			//mustMatch :true,
			formatItem : '',
			formatResult : '',
			//autoFill:true,
			extraParams : {} // for ajax request
		}
	},
	
	init : function(ajaxHandlerURL, $context, resultCallback)
	{
		autoCmplt.ajaxHandlerURL = ajaxHandlerURL;
		
		autoCmplt.$context = $context;
		autoCmplt.resultCallback = resultCallback;
		//autoCmplt.$context.val('Type school name here');
		
		autoCmplt.config.autocomplete.formatItem = autoCmplt.formatItem;
		autoCmplt.config.autocomplete.formatResult = autoCmplt.formatItem;
		
		autoCmplt.$context		
			.result(autoCmplt.result)
			.autocomplete(autoCmplt.ajaxHandlerURL, autoCmplt.config.autocomplete);
	},	

	formatItem : function(resultsRow,
						  rowPosition, /* starting at 1*/
						  numItems)    /* in the list of results*/								
	{
		return resultsRow[0].split('::')[0];
	},

	result : function(evt, item)
	{
		if ( (item !== undefined) && (autoCmplt.resultCallback !== undefined)) 
		{
			parts = item[0].split('::');
			autoCmplt.resultCallback(parts[1], parts[2]);
			//delete autoCmplt.resultCallback;
		}
	},
	
	processing : function(flag)
	{
		if (flag) 
		{
			autoCmplt.$context.addClass('ac_loading');
		}
		else
		{
			autoCmplt.$context.removeClass('ac_loading');
		}
	}
};


var tierList =
{
	$context : null,
	asOf : 0,
	ajaxHandlerURL : '/twcsrv.php',
	interval : null,
	displayAll : false,
	ids: {},
	slideSpeed : 30,
	maxSlideDuration: 1250,
	
	config :
	{
		update_pollTime : 30000,
		scrollTo :
		{
			duration:500,
			offset:-40
		}
	},
	
	init : function(selector, asOf, format, loadingMsg, initOrg)
	{
		tierList.asOf = asOf;
		tierList.ajaxHandlerURL = tierList.ajaxHandlerURL+'?format='+format;
		tierList.$context = $(selector);
						
		$(document).ready
		(
			function()
			{
				if (loadingMsg !== undefined) 
				{
					tierList.$context
							.html(loadingMsg)
							.load(tierList.ajaxHandlerURL, {'reload': initOrg}, tierList.start);
				}
				else 
				{
					tierList.start();
				}			
			}
		);
	},
	
	start : function()
	{
		tierList.autocompleteInit();		
		codeDialog.init(tierList.ajaxHandlerURL);

		// Setup event delegation for the slidecontrols
		tierList.$context
			.find('.tier .slidecontrol')
			.live('click', tierList.slidecontrolclick)
			;	
		
		// Initial load of ids[]
		tierList.logIds(tierList.$context, false);
		
		tierList.$context
			.find('#showAll')
			.live('click',tierList.showAll);

		tierList.$context
			.find('#hideAll')
			.live('click',tierList.hideAll);
				
		if (tierList.config.update_pollTime > 0)
		{
			tierList.interval = setInterval(tierList.ajaxGetUpdates, tierList.config.update_pollTime);
		}
		
		tierList.$context
			.find('.surveyLogin, .reportLogin')
			.live('click',codeDialog.prompt);
	},
	
	logIds : function($elem, displayAllFlag)
	{
		if (displayAllFlag === false)
		{
			tierList.displayAll = false;
			//tierList.ids = {'state': '', 'org': '', 'site': ''};
			tierList.ids = {'state': ['*'], 'org': ['*'], 'site': []}; // For performance: add '*' for any that are not included in the $elem.find at end of this function
		}
		else if (displayAllFlag === true)
		{
			tierList.displayAll = true;
			tierList.ids = {'state': ['*'], 'org': ['*'], 'site': ['*']};
		}

		if ( !tierList.displayAll)
		{
			//$elem.find('.tier.state, .tier.org, .tier.site').each(tierList.getIds); // Add new arrivals to ids[]
			$elem.find('.tier.site').each(tierList.saveId); // Add new arrivals to ids[]
		}
	},
	
	saveId : function(index, val)
	{
		$this = $(this);
		
		if ($this.hasClass('site'))
		{
			tierList.ids['site'].push($this.attr('id'));
		}
		else if ($this.hasClass('org'))
		{
			tierList.ids['org'].push($this.attr('id'));
		} 
		else if ($this.hasClass('state'))
		{
			tierList.ids['state'].push($this.attr('id'));
		} 			
	},

	idsParms : function()
	{
		return {
			'state': tierList.ids.state.join(','),
			'org': tierList.ids.org.join(','),
			'site': tierList.ids.site.join(',')
		};		
	},
	
	ajaxlocateDetails : function(detailsId)
	{
		$.post(tierList.ajaxHandlerURL, {'detailId':detailsId}, tierList.ajaxlocateDetailsDone, 'json');
	},

	ajaxlocateDetailsDone : function(data)
	{
		if (data.details !== undefined)
		{
			$.each(data.details, tierList.loadDetail);
		}
	},

	loadDetail : function(tierId, details)
	{
		$tier = tierList.$context 
			.find('.tier#'+tierId);
			
		$newDetails = tierList.locateDetails($tier)
			 			.html(details);

		// Now the content is loaded, display it
		tierList.openDetails($tier);
		
		// While display (animation) is on going, update our list displayed IDs	
		tierList.logIds($tier);
	},
		
	ajaxGetUpdates : function()
	{
		parms = tierList.idsParms();
		parms.previousAsOf = tierList.asOf;
		
		$.post(tierList.ajaxHandlerURL, parms, tierList.ajaxGetUpdatesDone, 'json');
	},
			
	ajaxGetUpdatesDone : function(data)
	{
		tierList.$context
			.find('.updated')
			.removeClass('updated');
		
		if (data.asOf !== undefined)
		{
			tierList.asOf = data.asOf;
			
			tierList.$context 
				.find('#asOf #value')
				.text(tierList.asOf)
				.addClass('updated');
		}
		
		if (data.updates !== undefined)
		{
			$.each(data.updates, tierList.loadUpdate);
		} 
	},

	loadUpdate : function(tierId, values)
	{
		$tier = tierList.$context
					.find('.tier#'+tierId);
		$overview = tierList.locateOverview($tier);
		
		var applyUpdate = function(key, value)
		{
			$elem = $overview
				.find(key);
				
			if ($elem.html() != value)
			{
				$elem.html(value).addClass('updated');
			}
		}		
	
		if ($overview.length != 0)
		{
			$.each(values, applyUpdate);			
		}
	},
		
	slidecontrolclick : function(evt)
	{		
		evt.preventDefault();
		$this=$(this);
		
		$tier = tierList.locateTier($this);			
		$details = tierList.locateDetails($tier);
			
		$slideControl = tierList.locateSlideControl($tier);
			
		if ($slideControl.hasClass('open'))
		{
			$slideControl //.html("<a href='?select="+id+"'>&nbsp;</a>")
				.addClass('closed')
				.removeClass('open');
				
			numItems = $details.find('> div').length;	
			$details
				.slideUp(tierList.slideDuration(numItems), tierList.slideDone);
		}
		else
		{
			tierList.openDetails($tier);
		}
	},
	
	openDetails : function($tier, callback)
	{
		if (callback !== undefined) 
		{
			tierList.openDetailsCallback = callback;
		}
		
		$details = tierList.locateDetails($tier);
		$slideControl = tierList.locateSlideControl($tier);
		if ($details.is(':empty'))
		{
			$slideControl 
				.addClass('processing');
				
			$details.
				hide(); // Move to init() ?
				
			tierList.ajaxlocateDetails($tier.attr('id'));
		}
		else
		{
			$slideControl //.html("<a href='?select='>&nbsp;</a>") 
				.addClass('open')
				.removeClass('closed');
				
			numItems = $details.find('> div').length;
			$details
				.slideDown(tierList.slideDuration(numItems), tierList.slideDone);	
		}
	},
	
	slideDuration: function(numItems)
	{
		return (numItems < 4) ? 0 : Math.min(tierList.maxSlideDuration, (numItems * tierList.slideSpeed));
	},
	
	slideDone : function()
	{
		tierList.locateSlideControl($(this))
			.removeClass('processing');	
			
		if (tierList.openDetailsCallback !== undefined)
		{
			//tierList.openDetailsCallback();
			setTimeout(tierList.openDetailsCallback, 0); // for IE's benifit
			delete tierList.openDetailsCallback;
		}		
	},
	
	showAll : function(evt)
	{
		evt.preventDefault();
		
		// unbind/die first ? 

		tierList.$context
			.find('.tier.org .slidecontrol')  // .closed
			.addClass('processing');
		
		// Quicker to do a complete rebuild than 'click' each closed tier
		tierList.$context.load(tierList.ajaxHandlerURL, {'reload': '*'}, tierList.showAllDone);
	},

	showAllDone : function()
	{
		tierList.logIds(tierList.$context, true);
		tierList.autocompleteInit();
	},
		
	hideAll : function(evt)
	{
		evt.preventDefault();
		
		// unbind/die first ? 
		
		tierList.$context
			.find('.tier.org .slidecontrol') // .open
			.addClass('processing');
		
		// Quicker to do a complete rebuild than 'click' each open tier
		tierList.$context
			.load(tierList.ajaxHandlerURL, {'reload': ''}, tierList.hideAllDone);
	},
	
	hideAllDone : function()
	{	
		tierList.logIds(tierList.$context, false);			
		tierList.autocompleteInit();
	},
	
	locateTier : function($elem)
	{
		return $elem.parents('.tier:first');
	},
	
	locateSlideControl : function($elem)
	{
		return tierList.locateOverview($elem).find('.slidecontrol:first'); // find('> .slidecontrol');
	},
	
	locateOverview : function($elem)
	{
		$tier = ($elem.hasClass('tier')) ? $elem : tierList.locateTier($elem);
		return $tier.find('.overview:first'); //.find('> .overview');
	},
	
	locateDetails : function($elem)
	{
		$tier = ($elem.hasClass('tier')) ? $elem : tierList.locateTier($elem);
		return $tier.find('.details:first'); //.find('> .details');
	},
	
				
	autocompleteResult : function(masterSiteID, orgID)
	{
		autoCmplt.processing(true);
		$org = tierList.$context
			.find('.tier.org#'+orgID);
		
		// start a scroll to the org while the org's details are loading
		//$.scrollTo($org, tierList.config.scrollTo);
		var scrollToSite = function()
		{
			$site = tierList.$context
				.find('.tier.site#'+masterSiteID);
			$site.addClass('scrolledTo');	
			$.scrollTo($site, tierList.config.scrollTo);
			autoCmplt.processing(false);
		}
		
		
		tierList.openDetails($org, scrollToSite);
	},
	
	autocompleteInit : function()
	{
		autoCmplt.init( tierList.ajaxHandlerURL,
					tierList.$context.find("#tierlistautocomplete"),
					tierList.autocompleteResult);
	}
}
