function LeaderboardFilterTypes () {}

LeaderboardFilterTypes.game       = 0;
LeaderboardFilterTypes.platform   = 1;
LeaderboardFilterTypes.solo_band  = 2;
LeaderboardFilterTypes.instrument = 3;
LeaderboardFilterTypes.score_type = 4;
LeaderboardFilterTypes.song_range = 5;
LeaderboardFilterTypes.song       = 6;

function LeaderboardGameTypes () {}

LeaderboardGameTypes.rb1 = 'RB1';
LeaderboardGameTypes.rb2 = 'RB2';

function LeaderboardPlatformTypes () {}

LeaderboardPlatformTypes.xbox = 'Xbox';
LeaderboardPlatformTypes.ps3  = 'PS3';
LeaderboardPlatformTypes.wii  = 'Wii';

function LeaderboardFilter (container_id, table)
{
	this.container_id = container_id;
	this.table        = table;

	this.filter_states = [];

	this.filter_states [LeaderboardFilterTypes.game]       = LeaderboardGameTypes.rb2;
	this.filter_states [LeaderboardFilterTypes.platform]   = LeaderboardPlatformTypes.xbox;
	this.filter_states [LeaderboardFilterTypes.solo_band]  = 'BAND';
	this.filter_states [LeaderboardFilterTypes.instrument] = 'GUITAR';
	this.filter_states [LeaderboardFilterTypes.score_type] = 'CAREER';
	this.filter_states [LeaderboardFilterTypes.song_range] = 'AtoE';
	this.filter_states [LeaderboardFilterTypes.song]       = null;

	this.page = 1;

	this.filter_dependencies = [];
	this.filter_dependencies [LeaderboardFilterTypes.game] = [];
	this.filter_dependencies [LeaderboardFilterTypes.game] [LeaderboardGameTypes.rb1] = [];

	this.filter_dependencies [LeaderboardFilterTypes.game] [LeaderboardGameTypes.rb1] [0] = {
		filter_type:    LeaderboardFilterTypes.platform,
		default_state:  LeaderboardPlatformTypes.xbox,
		allowed_states: [ LeaderboardPlatformTypes.xbox, LeaderboardPlatformTypes.ps3 ]
	};

	this.filter_dependencies [LeaderboardFilterTypes.game] [LeaderboardGameTypes.rb1] [1] = {
		filter_type:    LeaderboardFilterTypes.instrument,
		default_state:  'GUITAR',
		allowed_states: [ 'GUITAR', 'DRUMS', 'VOCALS' ]
	};

	this.filter_dependencies [LeaderboardFilterTypes.solo_band] = [];
	this.filter_dependencies [LeaderboardFilterTypes.solo_band] ['SOLO'] = [];

	this.filter_dependencies [LeaderboardFilterTypes.solo_band] ['SOLO'] [0] = {
		filter_type:    LeaderboardFilterTypes.score_type,
		default_state:  'CAREER',
		allowed_states: [ 'CAREER', 'SONG' ]
	};
}

LeaderboardFilter.prototype.setPage = function (page)
{
	this.table.sendRequest (this.filter_states, this.page = page);

	this.updateURLHash ();
}

LeaderboardFilter.prototype.setFilter = function (filter_type, value)
{
/* read form element values */

	if (filter_type == LeaderboardFilterTypes.score_type)
		value = Form.Element.getValue (
			this.filter_states [LeaderboardFilterTypes.solo_band] + '_SCORE_TYPE_SELECTOR');

	if (filter_type == LeaderboardFilterTypes.song_range)
		value = Form.Element.getValue ('alphaselector');

	if (filter_type == LeaderboardFilterTypes.song)
		value = Form.Element.getValue (
			this.filter_states [LeaderboardFilterTypes.game]       + '_' +
			this.filter_states [LeaderboardFilterTypes.platform]   + '_' +
			this.filter_states [LeaderboardFilterTypes.song_range] + '_SONG_SELECTOR');

/* autoselect solo if an instrument is selected and always process, otherwise
 * only process if a new value is entered */

	var filter_states_next = [];

	if (filter_type == LeaderboardFilterTypes.instrument)
		filter_states_next [LeaderboardFilterTypes.solo_band] = 'SOLO';
	else
		if (this.filter_states [filter_type] == value)
			return;

	filter_states_next [filter_type] = value;

/* add dependencies to the state transition list */

	if (
		typeof (this.filter_dependencies [filter_type])         != 'undefined' &&
		typeof (this.filter_dependencies [filter_type] [value]) != 'undefined'
	) {
		for (var i = 0; i < this.filter_dependencies [filter_type] [value].length; ++i) {
			var dependency = this.filter_dependencies [filter_type] [value] [i];
			var allowed    = false;
			
			for (var j = 0; ! allowed && j < dependency.allowed_states.length; ++j)
				allowed = (dependency.allowed_states [j] == this.filter_states [dependency.filter_type]);

			if (! allowed)
				filter_states_next [dependency.filter_type] = dependency.default_state;
		}
	}

	if (filter_type == LeaderboardFilterTypes.solo_band)
		filter_states_next [LeaderboardFilterTypes.score_type] =
			Form.Element.getValue (value + '_SCORE_TYPE_SELECTOR');

	this.page = 1;

	this.updateFilterStates (filter_states_next);

	this.updateURLHash ();
}

LeaderboardFilter.prototype.updateURLHash = function ()
{
	var hash_str;

	hash_str  = 'game='       + this.filter_states [LeaderboardFilterTypes.game];
	hash_str += ',platform='  + this.filter_states [LeaderboardFilterTypes.platform];
	hash_str += ',solo_band=' + this.filter_states [LeaderboardFilterTypes.solo_band];

	if (this.filter_states [LeaderboardFilterTypes.solo_band] == 'SOLO')
		hash_str += ',instrument=' + this.filter_states [LeaderboardFilterTypes.instrument];

	hash_str += ',score_type=' + this.filter_states [LeaderboardFilterTypes.score_type];

	if (this.filter_states [LeaderboardFilterTypes.score_type] == 'SONG') {
		hash_str += ',song_range=' + this.filter_states [LeaderboardFilterTypes.song_range];
		hash_str += ',song='       + this.filter_states [LeaderboardFilterTypes.song];
	}

	hash_str += ',page=' + this.page;

	window.location.hash = hash_str;
}

LeaderboardFilter.prototype.updateFilterStates = function (filter_states_next)
{
	for (var i in filter_states_next) {
		if (
			typeof (filter_states_next [i] != 'undefined') &&
			this.filter_states [i] != filter_states_next [i]
		) {
			Element.select (this.container_id, '.' + this.filter_states [i] + '_FILTER').invoke ('hide');
			Element.select (this.container_id, '.' + filter_states_next [i] + '_FILTER').invoke ('show');

			this.filter_states [i] = filter_states_next [i];
		}
	}

	var selector_id = 
		this.filter_states [LeaderboardFilterTypes.game]       + '_' +
		this.filter_states [LeaderboardFilterTypes.platform]   + '_' +
		this.filter_states [LeaderboardFilterTypes.song_range] + '_SONG_SELECTOR';

	this.filter_states [LeaderboardFilterTypes.song] = Form.Element.getValue (selector_id);

	this.table.sendRequest (this.filter_states, this.page);
}

LeaderboardFilter.prototype.parseURL = function ()
{
	var param_pairs = [];
	param_pairs = window.location.hash.substring (1).split (',');

	var filter_states_load = [];

	for (i = 0; i < param_pairs.length; ++i) {
		pair = [];
		pair = param_pairs [i].split ('=');

		if (pair [0] == 'game')
			filter_states_load [LeaderboardFilterTypes.game]       = pair [1];
		else if (pair [0] == 'platform')
			filter_states_load [LeaderboardFilterTypes.platform]   = pair [1];
		else if (pair [0] == 'solo_band')
			filter_states_load [LeaderboardFilterTypes.solo_band]  = pair [1];
		else if (pair [0] == 'instrument')
			filter_states_load [LeaderboardFilterTypes.instrument] = pair [1];
		else if (pair [0] == 'score_type')
			filter_states_load [LeaderboardFilterTypes.score_type] = pair [1];
		else if (pair [0] == 'song_range')
			filter_states_load [LeaderboardFilterTypes.song_range] = pair [1];
		else if (pair [0] == 'song')
			filter_states_load [LeaderboardFilterTypes.song]       = pair [1];
		else if (pair [0] == 'page')
			this.page = pair [1];
		else
			;
	}

	this.updateFilterStates (filter_states_load);

/* update select menus */

	Form.Element.setValue (
		this.filter_states [LeaderboardFilterTypes.solo_band] + '_SCORE_TYPE_SELECTOR',
		this.filter_states [LeaderboardFilterTypes.score_type]);

	Form.Element.setValue ('alphaselector', this.filter_states [LeaderboardFilterTypes.song_range]);

	Form.Element.setValue (
		this.filter_states [LeaderboardFilterTypes.game]       + '_' +
		this.filter_states [LeaderboardFilterTypes.platform]   + '_' +
		this.filter_states [LeaderboardFilterTypes.song_range] + '_SONG_SELECTOR',
		this.filter_states [LeaderboardFilterTypes.song]);
}

function LeaderboardTable (container_id, indicator_id)
{
	this.container_id = container_id;
	this.indicator_id = indicator_id;
}

LeaderboardTable.prototype.sendRequest = function (filter_states, page)
{
	var outer_this = this;

	new Ajax.Updater (
		this.container_id,
		'/leaderboards/retrieve-table',
		{
			method: 'post',

			parameters: {
				game:       filter_states [LeaderboardFilterTypes.game],
				platform:   filter_states [LeaderboardFilterTypes.platform],
				solo_band:  filter_states [LeaderboardFilterTypes.solo_band],
				instrument: filter_states [LeaderboardFilterTypes.instrument],
                                score_type: filter_states [LeaderboardFilterTypes.score_type],
                                song:       filter_states [LeaderboardFilterTypes.song],
				page:       page
			},

			onComplete: function (req, json)
			{
				new Effect.Fade (outer_this.indicator_id, { duration: 3 });
				new Effect.Fade (outer_this.container_id, { from: 0.1, to: 1.0 });
			},

			onCreate: function (req, json)
			{
				new Effect.Appear (outer_this.indicator_id);
				new Effect.Fade   (outer_this.container_id, { to: 0.1 });
			}
		});
}
