
/*===============================================================================
	TimeZonePicker.js
	John Larson
	3/21/09
	
	Component for choosing a Time Zone in a way that coordinates with a
	country select.
	
	Example:
	<select id="countrySelect">
	  <option value="1">USA</option>
	  <option value="2">Canada</option>
	  <option value="3">Great Britain</option>
	</select>
	<select id="timeZoneSelect"></select>
	<input type="checkbox" id="viewAllToggle">
	
	new TimeZonePicker('countrySelect', 'timeZoneSelect',
		'AJAXAction.asp?a=loadCountryTimeZones',
		{ CountryIDParameterName: 'CountryID', viewAllToggle: 'viewAllToggle'} );
	
	would add an onChange event to countrySelect that will to an AJAX call to
	AJAXAction to reload the options of timeZoneSelect, and add an onClick
	event to viewAllToggle to reload options of timeZoneSelect by passing
	[CountryID]=0 to the AJAX call.

===============================================================================*/


var TimeZonePicker = new Class({
	
	Implements: [Options, Events],
	
	options: {
		CountryIDParameterName:	'CountryID',
		loadTimeZonesInitially:	false,
		viewAllToggle:			null,
		viewAllCountryID:		0,
		initialViewAllState:	false
	},

	initialize: function(countrySelect, timeZoneSelect, timeZoneLoadURL, options){
		
		this.setOptions(options)
		
		this.countrySelect = $(countrySelect);
		this.timeZoneSelect = $(timeZoneSelect);
		this.timeZoneLoadURL = timeZoneLoadURL;
		
		if(!this.countrySelect)
			throw('Non-existent countrySelect passed to TimeZonePicker constructor.');
		if(!this.timeZoneSelect)
			throw('Non-existent timeZoneSelect passed to TimeZonePicker constructor.');
		
		
		this.countrySelect.addEvent('change', this.setCountryTimeZoneOptions.bind(this));
		
		if(this.options.viewAllToggle) {
			this.viewToggle = $(this.options.viewAllToggle);
			if(this.viewToggle) {
				this.viewToggle.addEvent('click', this.toggleViewAllTimeZones.bind(this));
				this.viewingAll = this.options.initialViewAllState; // keep tabs for toggle!
			}
		}
		
		this.timeZoneCache = {};
		
		if(this.options.loadTimeZonesInitially)
			this.reloadTimeZoneOptions();
		
	},
	
	setCountryTimeZoneOptions: function() {
		
		if(this.viewingAll) return;
		
		var CountryID = this.countrySelect.value;
		this.currentCountryID = CountryID;
		if(this.timeZoneCache[CountryID])
			this.setTimeZoneOptions(this.timeZoneCache[CountryID]);
		else 
			this.loadCountryTimeZoneOptions(CountryID)
	},
	
	loadCountryTimeZoneOptions: function(CountryID) {
		var me = this;
		new Ajax(this.timeZoneLoadURL, {
			method: 'post',
			data: this.options.CountryIDParameterName + '=' + encodeURIComponent(CountryID),
			onComplete: function() {
				// we expect back an array of 2-element arrays: [TimeZoneID, timeZoneName]:
				// save it immediately to our Cache and load our options:
				me.timeZoneCache[CountryID] = JSON.decode(this.response.text);
				me.setTimeZoneOptions(me.timeZoneCache[CountryID]);
			}
		}).request();
	},
	
	setTimeZoneOptions: function(timeZoneSet) {
		
		var theSelect = this.timeZoneSelect;
		
		// keep tabs on the current option:
		var currentValue = theSelect.value;
		var currentOption = theSelect.options[theSelect.selectedIndex];
		
		theSelect.options.length = 0;  // clear all
		
		theSelect.options.add(currentOption); // add back the current option
		
		// Add in all options of our given set:
		for(i = 0; i < timeZoneSet.length; i++) {
			theSelect.options.add(new Option(timeZoneSet[i][1], timeZoneSet[i][0]));
			if(timeZoneSet[i][0] == currentValue) { // our current one is in this given set
				// no need to have it specially placed at the top, so..
				theSelect.remove(0);
			}
		}
		theSelect.value = currentValue; // still!
	},
	
	toggleViewAllTimeZones: function() {
		
		this.viewingAll = !this.viewingAll;
		
		if(this.viewingAll) {
			if(this.timeZoneCache[this.options.viewAllCountryID])
				this.setTimeZoneOptions(this.timeZoneCache[this.options.viewAllCountryID]);
			else
				this.loadCountryTimeZoneOptions(this.options.viewAllCountryID);
		}
		else
			this.setCountryTimeZoneOptions();
	}
	
});
