/*
	/static/scripts/gg.js
	provides core content for most GoGamecocks.com pages
	(c) 2010, The State Media Company
	Chris Hessert <chris.hessert@gmail.com>
	updated:  2011-08-25
*/

/* @minify true */

/*  declarations  */

var arMonths = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
var arDays = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
var ajaxTimeout = 30000;  // ajax function timeout in milliseconds (30,000 milliseconds = 30 seconds)
var vmixProxyUrl = 'http://www.gogamecocks.com/cgi-bin/vmix_proxy.php';
var vmixFeatures = 'height=728,width=1048,status=no,toolbar=no,location=no,menubar=no,directories=no,resizable=no,scrollbars=no';
var videoPreviewApi = 'media';
var videoPreviewAction = 'getMediaList';
var videoPreviewParamArray = new Array('include_partners=121', 'limit=5', 'exclude_genres=00002697,00001461', 'class_id=1', 'genre_ids=00009007');
var videoPreviewParams = paramsToString(videoPreviewParamArray);
var videoLandingPage = 'http://www.gogamecocks.com/videos';
var videoThumbWidth = 298;  // set video preview image width
var videoUrl = 'http://www.gogamecocks.com/static/ggmp/ggmp.html#vmix_media_id=';


/*  functions  */

// do things before the page loads
$(document).ready(function() {

	showToday();  // display date in navigation
	
	// show/hide submenus
	$('#navbar li').hover(
		function () {
			$('ul', this).slideDown(100);  //show its submenu
		},
		function () {
			$('ul', this).slideUp(100);  //hide its submenu
		}
	);

	$("#logo").click(function() {
		window.location = "http://www.gogamecocks.com";	// set the logo action
	});
	
	checkLoginStatus();  // verify login status
	
	getVideoPreviewData(videoPreviewApi, videoPreviewAction, videoPreviewParams);  // get video preview data
	
	$('.insider:gt(0) div.contents').hide().parent().removeClass('active').addClass('inactive');  // show only first insider content
	
	// show/hide HP insider content
	$('.insider h3').click(function() {
		if ($(this).parent().hasClass('inactive')) {
			$(this).parent().siblings('.insider').removeClass('active').addClass('inactive');  // change other status
			$(this).parent().removeClass('inactive').addClass('active');  // change this status
			$(this).parent().siblings('.insider').children('div.contents:visible').slideToggle('750');  // hide other insider content
			$(this).parent().children('div.contents').slideToggle('750');  // toggle slide-up/down event
		}	
	});

	stripeAllTables();  // stripe designated tables

});

// displays today's date in the navigation
function showToday() {
	var today = new Date();
	$('#today').html(arDays[today.getDay()]+', '+arMonths[today.getMonth()]+' '+today.getDate()+', '+today.getFullYear());	
}

// check login status
function checkLoginStatus() {
	var test = getCookie('gogamecocks_user_auth');
	$('#login').empty();  // remove previous content
	if (test != null && test != "") {
		// yes we have cookies
		var separator = test.indexOf('|');
		var userName = test.substring(0, separator);
		if (userName != ".threshold") {
			// we know who you are - say hello
			$('#login').append('<div class="left bold">Welcome, '+userName+'!</div>');
			$('#login').append('<div class="right"><input type="button" value="logout" onclick="logOut()" /></div>');
			$('#login').append('<div class="clear">');
		} else {
			// unkown visitor
			$('#login').append('<div class="center bold"><a href="http://gg.thestateonline.com">Login/Subscribe</a></div>');
		}
	} else {
		// no cookies for you
		$('#login').append('<p class="center"><a href="http://gg.thestateonline.com">Login</a></p>');
		$('#login').append('<p class="center"><a href="http://gg.thestateonline.com/"><img src="http://media.gogamecocks.com/static/images/site/subscribe.jpg" alt="gg.thestateonline.com" /></a></p>');
	}
}

// displays countdown timer to next event/game
function showCountdown(file, mode) {
	if (!file) {
		alert('No source file for countdown.');
		return false;  // bail if there's no file argument
	}
	$.ajax({
		type: 'GET',
		url: file,
		dataType: 'xml',
		timeout: ajaxTimeout,
		success: function(xml) {
			switch(mode) {
				case 0:
					showSportsEvent(xml);
					break;
				case 1:
					showEvent(xml);
					break;
				default:
					break;
			}
		}
	});
}

// displays countdown data for a sports schedule event
function showSportsEvent(xml) {
	if ($(xml).find('schedule')) {
		var sport = $(xml).find('schedule').attr('sport');  // set sport
		var season = $(xml).find('schedule').attr('season');  // set season (year)
		var now = new Date();
		$('#countdown').show();  // show the countdown
		// find next game
		var i = 0;  // initiate counter (loop only once)
		$(xml).find('game').each(function() {
			var gameDate = mysqlDatetimeToDate($(this).find('date').text());
			if (i == 0 && gameDate >= now) {
				var opponent = $(this).attr('opponent');
				var conference = $(this).attr('conference');
				var location = $(this).find('location').text();
				var media = $(this).find('media').text();
				var usc = $(this).find('score').attr('usc');
				var opp = $(this).find('score').attr('opp');
				var m = gameDate.getMonth();
				var d = gameDate.getDate();
				var month = arMonths[gameDate.getMonth()].substr(0,3);
				var day = arDays[gameDate.getDay()].substr(0,3);
				var hrs = gameDate.getHours();
				var mins = gameDate.getMinutes();
				var time = toFormattedTime(hrs, mins)  // format game time
				var info = day+', '+d+' '+month+' @'+time;
				if (media !== '') {
					info += ' on '+media;
				}
				if (location === 'Columbia, SC') {
					opponent = 'vs. '+opponent;
				} else {
					opponent = 'at '+opponent;
				}
				showClock(gameDate);  // start countdown timer
				$('#event').append('<div class="teams">');
				$('#event div.teams').append('<div style="float:left;text-align:left;">USC</div>');
				$('#event div.teams').append('<div style="float:right; text-align:right">'+opponent+'</div>');
				$('#event div.teams').append('<div class="clear">');
				$('#event').append('<div class="info">');
				$('#event div.info').append('<p>'+info+'<br />from '+location+'</p>');  // show game info
				i++;  // bump the counter
			}
		});
	}
}

// displays countdown data for an event listing (not a sports schedule)
function showEvent(xml) {
	if ($(xml).find('events')) {
		$('#countdown').show();  // show the countdown
		var now = new Date();
		var i = 0;  // initiate counter
		$(xml).find('event').each(function() {
			var name = $(this).attr('name');
			var date = mysqlDatetimeToDate($(this).find('date').text());
			var location = $(this).find('location').text();
			var html = $(this).find('html').text();
			var story_url = $(this).find('story_url').text();
			showClock(date);  // start countdown timer
			$('#event').append('<h3>'+name+'</h3>');
			if (location !== '') {
				$('#event').append('<p class="place">'+location+'</p>');  // add location, if present
			}
			if (html !== '') {
				$('#event').append(html);  // add HTML if present
			}
		});
	}
}
		
// displays a countdown timer to the given date/time
function showClock(date) {
	if (!date) {
		alert('Missing date argument.');
		return false;
	}
	$('#clock').countdown({
		until: date,
		format: 'dHMS',
		labels: ['years', 'months', 'weeks', 'days', 'hours', 'mins', 'secs'],
		layout:
			'<div id="timer">'+
				'<div id="timer_days"><div class="timer_numbers">{dnn}</div><div class="timer_label">days</div></div>'+
				'<div id="timer_hours"><div class="timer_numbers">{hnn}</div><div class="timer_label">hours</div></div>'+
				'<div id="timer_minutes"><div class="timer_numbers">{mnn}</div><div class="timer_label">mins</div></div>'+
				'<div id="timer_seconds"><div class="timer_numbers">{snn}</div><div class="timer_label">secs</div></div>'+
				'<div class="clear"></div>'+
			'</div>'
	});
}

// deletes auth cookie, reloads home page
function logOut() {
	deleteCookie('gogamecocks_user_auth', '/', '.gogamecocks.com');
	window.location = "http://www.gogamecocks.com";
}

// returns latest video as JSON data
function getVideoPreviewData(api, action, params) {
	var url = buildApiUrl(api, action, params);  // build proxy url for data call
	$.ajax({
		type: 'GET',
		url: url,
		dataType: 'json',
		timeout: ajaxTimeout,
		success: function(result) {
			buildVideoPreviews(result);
		}
	});
}

// builds video preview content
function buildVideoPreviews(result) {
	var data = new Array();
	if (result.media) {
		data = result.media;
	} else if (result.length > 0) {
		data = result;
	} else {
		return false;
	}
	for (var i = 0; i < data.length; i++) {
		var content = '';
		var id = data[i].id;  // set video id
		var token = data[i].token;  // set video token
		var urlThumb = data[i].thumbnail[0].url;  // set photo thumbnail url
		var description = data[i].description;  // set photo caption
		var urlPlayback = 'http://www.gogamecocks.com/static/ggmp/ggmp.html#vmix_media_id='+id+'&playlist=Latest';  // set onClick to open this video on the video landing page
		var urlPreview = 'http://image.vmixcore.com/imgman.jpg?width='+videoThumbWidth+'&url='+urlThumb;  // set preview image source
		var timestamp = new String(new Date().getTime());
		var windowName = 'MediaPlayer'+timestamp;
		$('#video_previews').append('<img src="'+urlPreview+'" alt="'+description+'" onclick="launchMediaPlayer(\''+urlPlayback+'\', \''+windowName+'\', \''+vmixFeatures+'\')" />');
	}
	startVideoPreviewShow();
}

// fires up the video preview slideshow (sidebar)
function startVideoPreviewShow() {
	$("#video_previews").cycle({
		fx: 'fade',
		timeout: 15000,
		before: function() {
			$("#video_caption").html("");
		},
		after: function() {
			$("#video_caption").html(this.alt); 
		}
	});
}

// launches selected video in MediaPlayer
function launchMediaPlayer(url, name, features) {
	var somePlayer = document.getElementById("vmix_player_swf");
	if (somePlayer != null) {
		somePlayer.call("pause");
	}
	window.open(url, name, features);  // open video landing page
}

// returns array of data from db_sports
function getTopRecruitsData(source, year, max) {
	// check arguments
	if (!source) {
		alert('Missing source argument.');
		return false;
	}	
	var ajaxTimeout = 30000;
	var proxyUrl = 'http://www.gogamecocks.com/cgi-bin/proxySportsRosters.php?';
	var source = new String(source);
	proxyUrl += 'src='+source;
	if (year) {
		var year = new String(year);
		proxyUrl += '&yr='+year;
	}
	$.ajax({
		type: 'GET',
		url: proxyUrl,
		dataType: 'json',
		timeout: ajaxTimeout,
		success: function(result) {
			showTopRecruits(result, max);
		}
	});
}

// displays top recruits list on home page
function showTopRecruits(result, max) {
	if (!result) {
		alert('Top recruit feed failed.');
		return false;
	}
	var data = [];
	data = result;
	var year = data.year;
	var players = data.players;
	$('#top_recruits').append('<h3>Class of '+year+' recruits</h3>');
	$('#top_recruits').append('<table>');
	$('#top_recruits table').append('<tbody>');
	for (var i = 0; i < max; i++) {
		var name = players[i].first_name+' '+players[i].last_name;
		var position = players[i].position_id;
		var height = Math.floor(players[i].height/12)+'-'+Math.round(players[i].height%12);
		var weight = players[i].weight;
		var urlStory = players[i].url_story;
		if (urlStory) {
			name = '<a href="'+urlStory+'">'+name+'</a>';
		}
		$('#top_recruits table tbody').append('<tr><td>'+name+'</td><td class="right">'+position+'</td><td class="right">('+height+', '+weight+')</td></tr>');
	}
	$('#top_recruits').append('<p class="right bold"><a href="/class'+year+'/">Full list of recruits</a></p>');
}

// limits numer of "more headlines" to display from top stories
function showMoreHeadlines(i) {
	var num = 5;  // default
	if (i) {
		num = i;  // take argument, if available
	}
	$('#more_headlines').children('div.headline').children('div.stack').children('div.story:lt('+num+')').show();
}

// displays a full schedule		
function showFullSchedule(file, div_id, l, p) {
	if (!file || !div_id) {
		alert('Missing arguments for full schedule.');
		return false;
	}
	var now = new Date();
	$.ajax({
		type: 'GET',
		url: file,
		dataType: 'xml',
		timeout: ajaxTimeout,
		success: function(xml) {
			if ($(xml).find('schedule')) {
				var sport = $(xml).find('schedule').attr('sport');
				var season = $(xml).find('schedule').attr('season');
				var roster = $(xml).find('schedule').attr('roster_url');

				// generate table id
				var id = sport.replace(/\s+/g, '_').toLowerCase();
				id = id.replace(/\W/g, '') + '_full';
				$('#'+div_id).append('<table id="'+id+'" class="full_schedule" cellpadding="0" cellspacing="0">');
				$('#'+id).prepend('<thead>');
				if (roster !== '' && roster != null) {
					$('#'+id+' thead').append('<tr><td colspan="5" class="center"><a href="'+roster+'">USC '+sport+' roster</a></tr>');  // add link to USC team roster if specified
				}
				$('#'+id+' thead').append('<tr><td class="right">Date</td><td>Time</td><td>Opponent</td><td>Location</td><td class="center">TV/Score</td></tr>');

				// show schedule
				var i = 0;  // initiate counter
				$(xml).find('game').each(function() {
					var opponent = $(this).attr('opponent');
					var conference = $(this).attr('conference');
					var gameDate = mysqlDatetimeToDate($(this).find('date').text());
					var location = $(this).find('location').text();
					var media = $(this).find('media').text();
					var usc = $(this).find('score').attr('usc');
					var opp = $(this).find('score').attr('opp');
					var story = $(this).find('story_url').text();
					var date = gameDate.getDate()+' '+arMonths[gameDate.getMonth()].substr(0,3);
					var hrs = gameDate.getHours();
					var mins = gameDate.getMinutes();
					var time = '';
					var score = '';
					var info = '';
					var myClass = '';

					if (gameDate < now) {
						myClass += ' prev';  // indicate previous games
					} else if (i == 0 && gameDate >= now) {
						myClass += ' next';  // indicate next game
						i++;  // bump the counter so we only do this once
					}

					if (conference == 1) {
						opponent += '*';  // indicate conference opponents
					}

					if (story !== '') {
						opponent = '<a href="'+story+'">'+opponent+'</a>';
					}

					if (location === 'Columbia, SC') {
						myClass += ' home';
					} else {
						myClass += ' away';
					}
					
					if (media === '') {
						media = 'TBD';
					}

					if (hrs == null) {
						hrs = 0;
					}
					if (mins == null) {
						mins = 0;
					}
					time = toFormattedTime(hrs, mins);  // show game time

					if (parseInt(usc) > parseInt(opp)) {
						score = 'W '+usc+'-'+opp;
					} else if (parseInt(usc) < parseInt(opp)) {
						score = 'L '+usc+'-'+opp;
					} else {
						score = usc+'-'+opp;
					}

					// choose to display game broadcast location or score
					if (gameDate >= now) {
						info = media;
					} else {
						info = score;
					}
							
					$('#'+id).append('<tr class="'+myClass+'"><td class="right">'+date+'</td><td>'+time+'</td><td>'+opponent+'</td><td>'+location+'</td><td class="center">'+info+'</td></tr>');
				});
				$('#'+id).append('<tr class="legend"><td colspan="5" class="center"><br /><span style="color: #990000;">= home game</span>&nbsp;&nbsp;* conference game</td></tr>');
				$('#'+id+' tbody tr.legend').show();		

				// decide which rows to show
				if (l == 0) {
					$('#'+id).find('tbody tr').show();  // if limit = 0, show all games
				} else {
					var n = $('#'+id).find('tbody tr.next').index();  // get index of next game
					var r = ($('#'+id+' tbody tr.next').nextAll().length); // get count of remaining games after next
					if ((l - p) > r) {
						p = l - r;  // if (limit - previous) is more than the remaining games, p becomes (limit - remaining games)
					}
					l = l - p;  // limit reduced by number of previous games displayed
					$('#'+id).find('tbody tr.next').show();  // show next game
					$('#'+id+' tbody tr').slice((n - p), n).show();  // show preceding games
					$('#'+id+' tbody tr').slice(n, (n + l)).show();  // show following games
				}
			}
		}
	});
}

// controls number of "most popular" headlines to display:  default=10
function showMostPopularHeadlines(i) {
	var num = 9;
	if (i) {
		num = i-1;
	}
	$('#popular_stories ul li:gt('+num+')').hide();  // hide list elements with an index higher than (int-1) because index is 0-based
}

// displays an abbrerviated schedule: date, time/score, opponent
function showMiniSchedule(file, div_id) {
	if (!file || !div_id) {
		alert('Missing arguments for mini schedule.');
		return false;
	}
	var now = new Date();
	$.ajax({
		type: 'GET',
		url: file,
		dataType: 'xml',
		timeout: ajaxTimeout,
		success: function(xml) {
			if ($(xml).find('schedule')) {
				var sport = $(xml).find('schedule').attr('sport');
				var season = $(xml).find('schedule').attr('season');
				var roster = $(xml).find('schedule').attr('roster_url');

				// generate table id
				var id = sport.replace(/\s+/g, '_').toLowerCase();
				id = id.replace(/\W/g, '') + '_mini';
				$('#'+div_id).append('<table id="'+id+'" class="mini_schedule">');
				$('#'+id).prepend('<thead>');
				$('#'+id+' thead').append('<tr><td colspan="3" class="center"><h3>USC '+sport+'<br />'+season+' Schedule</h3></td></tr>');
				if (roster !== '' && roster != null) {
					$('#'+id+' thead').append('<tr><td colspan="3" class="center"><a href="'+roster+'">USC '+sport+' roster</a></tr>');
				}
				$('#'+id+' thead').append('<tr><td class="right"><br />Date</td><td class="center">Time/<br />Score</td><td><br />Opponent</td></tr>');
			
				// show schedule
				var i = 0;  // initiate counter
				$(xml).find('game').each(function() {
					var opponent = $(this).attr('opponent');
					var conference = $(this).attr('conference');
					var location = $(this).find('location').text();
					var gameDate = mysqlDatetimeToDate($(this).find('date').text());
					var usc = $(this).find('score').attr('usc');
					var opp = $(this).find('score').attr('opp');
					var story = $(this).find('story_url').text();
					var date = (gameDate.getMonth() + 1) + '/' + gameDate.getDate();
					var hrs = gameDate.getHours();
					var mins = gameDate.getMinutes();
					var time = '';
					var score = '';
					var info = '';
					var myClass = '';
				
					if (gameDate < now) {
						myClass += ' prev';  // indicate past games
					} else if (i == 0 && gameDate > now) {
						myClass += ' next';  // indicate next game
						i++;  // bump the counter so we only do this once
					}

					if (conference == 1) {
						opponent += '*';  // indicate conference opponents
					}

					if (story !== '') {
						opponent = '<a href="'+story+'">'+opponent+'</a>';
					}

					// format game time
					if (hrs == null) {
						hrs = 0;
					}
					if (mins == null) {
						mins = 0;
					}
					time = toFormattedTime(hrs, mins);
					
					if (location === 'Columbia, SC') {
						myClass += ' home';  // indicate home games
					} else {
						myClass += ' away';  // everything else is an away game (used for CSS)
					}

					// format score
					if (parseInt(usc) > parseInt(opp)) {
						score = 'W '+usc+'-'+opp;
					} else if (parseInt(usc) < parseInt(opp)) {
						score = 'L '+usc+'-'+opp;
					} else {
						score = usc+'-'+opp;
					}

					// display game time or score
					if (gameDate >= now) {
						info = time;  // show game time
					} else {
						info = score;  // show score
					}

					$('#'+id).append('<tr class="'+myClass+'"><td class="right">'+date+'</td><td class="center">'+info+'</td><td>'+opponent+'</td></tr>');
				});
				$('#'+id).append('<tr class="legend"><td colspan="3" class="center"><br /><span style="color: #990000;">= home game</span>&nbsp;&nbsp;* conference game</td></tr>');
			}
		}
	});
}

// sets a cookie
function setCookie() {
	if (arguments.length < 2) {
		return;
	}
	var name = arguments[0];
	deleteCookie(name);
	var value = arguments[1];
	var days = 0;
	if (arguments.length > 2) {
		days = parseInt(arguments[2]);
	}
	var exp = '';
	if (days > 0) {
		var now = new Date();
		expiry = now.getTime() + (days * 24 * 60 * 60 * 1000);
		now.setTime(expiry);
		exp = '; expires=' + now.toGMTString();
	}
	document.cookie = name + "=" + escape(String(value)) + '; path=/' + exp;
}

// retrieves cookie values
function getCookie(name) {
	var cookiecontent = new String();
	if (document.cookie.length > 0) {
		var cookiename = name+ '=';
		var cookiebegin = document.cookie.indexOf(cookiename);
		var cookieend = 0;
		if (cookiebegin > -1) {
			cookiebegin += cookiename.length;
			cookieend = document.cookie.indexOf(";",cookiebegin);
			if (cookieend < cookiebegin) {
				cookieend = document.cookie.length;
			}
			cookiecontent = document.cookie.substring(cookiebegin,cookieend);
		}
	}
	return unescape(cookiecontent);
}

// eats cookies for breakfast
function deleteCookie(name, path, domain) {
	if (getCookie(name)) document.cookie = name + "=" + ( ( path ) ? ";path=" + path : "") + ( ( domain ) ? ";domain=" + domain : "" ) + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

// returns query string formatted for proxy calls from an array
function paramsToString(array) {
	var myString = new String();
	for ( var i = 0; i < array.length; i++ ) {
		myString += array[i] + ";";  // add array elements separated by semi-colons
	}
	return myString;
}

// returns a proxied url for data connections
function buildApiUrl(api, action, params) {
	var myApi = '?api=' + api;
	var myAction = '&action=' + action;
	var myParams = '&params=' + escape(params);
	return vmixProxyUrl + myApi + myAction + myParams;
}

// returns a formatted time string
function toFormattedTime(hrs, mins) {
	var time = '';
	var meridian = 'a';
	if (mins < 10) {
		mins = '0' + mins;  // pad with 0 if less than two digits
	}
	if (hrs == 0 && mins == 0) {
		time = 'TBD';  // format date/time as unknown
	} else {
		if (hrs >= 12) {
			if (hrs > 12) {
				hrs = hrs - 12;  // subtract 12 hrs
			}
			meridian = 'p';
		}
		time = hrs+':'+mins+meridian;
	}
	return time;
}
		
// returns a javascript Date() object from a MySQL datetime field value, input as:  '2007-06-05 15:26:02'
function mysqlDatetimeToDate(datetime) {
	var regex=/^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9]) (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/;
	var parts=datetime.replace(regex,"$1 $2 $3 $4 $5 $6").split(' ');
	return new Date(parts[0],parts[1]-1,parts[2],parts[3],parts[4],parts[5]);
}

// stripe individual table with id = 'tableName', using color hex codes (like #990000) 'oddColor' and 'evenColor'
function stripeTable(tableName, oddColor, evenColor) {
	if (!tableName || !oddColor || !evenColor) {
		return false;  // bail if we're missing variables
	}
	$('#'+tableName+' tr:not(:has(th)):nth-child(odd)').css('background-color', oddColor);
	$('#'+tableName+' tr:not(:has(th)):nth-child(even)').css('background-color', evenColor);
}

// stripe all tables with class = 'tableizer-table' or 'story-table' and != 'no-stripes'
function stripeAllTables() {
	$('tbody').each(function() {
		if(!$(this).parent().hasClass('no-stripes') && ($(this).parent().hasClass('tableizer-table') || $(this).parent().hasClass('story-table'))) {
			$(this).find('tr:not(:has(th)):nth-child(odd)').addClass('story-table-odd');
			$(this).find('tr:not(:has(th)):nth-child(even)').addClass('story-table-even');
		}
	});
}

// returns feet and inches from an integer (inches)
function toFeetAndInches(int) {
	if (!int) {
		alert('Missing inches argument');
		return false;  // abort if we're missing inches
	}
	var feet = Math.floor(int/12);
	var inches = Math.round(int%12);
	var height = feet+'\'-'+inches+'"';
	return height;
}


/*  rosters  */

// returns roster as JSON data
function getRosterData(source, year) {
	// check arguments
	if (!source) {
		alert('Missing source argument.');
		return false;
	}
	var ajaxTimeout = 30000;
	var proxyUrl = 'http://www.gogamecocks.com/cgi-bin/proxySportsRosters.php?';
	var source = new String(source);
	proxyUrl += 'src='+source;
	if (year) {
		var year = new String(year);
		proxyUrl += '&yr='+year;
	}
	$.ajax({
		type: 'GET',
		url: proxyUrl,
		dataType: 'json',
		timeout: ajaxTimeout,
		success: function(result) {
			showRoster(result);
		}
	});
}

// selects correct roster display function
function showRoster(result) {
	if (!result) {
		alert('Missing JSON data.');
		return false;
	}
	var data = new Array();
	data = result;
	switch(data['source']) {
		case 'tblBaseballPlayers':
			showBaseballRoster(data);
			break;
		case 'tblFootballRoster':
			break;
		case 'tblFootballRecruits':
			showFootballRecruits(data);
			break;
		default:
			break;			
	}		
}

// displays baseball roster
function showBaseballRoster(data) {
	if (!data) {
		alert('Missing data.');
		return false;
	}

	// container
	if ($('#container').length == 0) {
		$('#mi_content').append('<div id="container">');
	}
	
	// toolbar
	if ($('#toolbar').length == 0) {
		$('#container').append('<div id="toolbar">');
		$('#container').append('<div class="clear">');
		$('#toolbar').append('<div class="number right"><input class="menu" type="button" value="NO" onclick="sortList(\'ul#data\', \'div.number\')" /></div>');
		$('#toolbar').append('<div class="name left"><input class="menu" type="button" value="NAME" onclick="sortList(\'ul#data\', \'div.name\')" /> </div>');
		$('#toolbar').append('<div class="position center"><input class="menu" type="button" value="POS" onclick="sortList(\'ul#data\', \'div.sortPosition\')" /></div>');
		$('#toolbar').append('<div class="bats center"><input class="menu" type="button" value="B" onclick="sortList(\'ul#data\', \'div.bats\')" /></div>');
		$('#toolbar').append('<div class="throws center"><input class="menu" type="button" value="T" onclick="sortList(\'ul#data\', \'div.throws\')" /></div>');
		$('#toolbar').append('<div class="height"><input class="menu" type="button" value="HT" onclick="sortList(\'ul#data\', \'div.sortHeight\')" /></div>');
		$('#toolbar').append('<div class="weight"><input class="menu" type="button" value="WT" onclick="sortList(\'ul#data\', \'div.weight\')" /></div>');
		$('#toolbar').append('<div class="state"><input class="menu" type="button" value="STATE" onclick="sortList(\'ul#data\', \'div.state\')" /></div>');
		$('#toolbar').append('<div class="clear">');
	}
	
	// roster
	if ($('#data').length == 0) {
		$('#container').append('<ul id="data">');
	}
	
	// fill roster
	for (var i = 0; i < data['players'].length; i++) {
		var playerId = data['players'][i].player_id;
		var name = (data['players'][i].first_name+' '+data['players'][i].last_name).toUpperCase();
		var number = parseInt(data['players'][i].number);
		var position1 = data['players'][i].position1;
		var position2 = data['players'][i].position2;
		var bats = data['players'][i].bats;
		var throws = data['players'][i].throws;
		var height = parseInt(data['players'][i].height);
		var weight = parseInt(data['players'][i].weight);
		var classYear = data['players'][i].class_year;
		var school = data['players'][i].school;
		var city = data['players'][i].city;
		var state = data['players'][i].state;
		var vmixId = parseInt(data['players'][i].vmix_id);
		var urlBio = data['players'][i].url_bio;
		var urlPhoto = data['players'][i].url_photo;
		var urlMore = data['players'][i].url_story;
		var notes = data['players'][i].notes;
		var positionOne = data['players'][i].positionOne;
		var positionSort = parseInt(data['players'][i].sortPosition);
		var displayHeight = toFeetAndInches(height);
		var hometown = data['players'][i].city+', '+data['players'][i].state;
		
		$('ul#data').append('<li id="'+playerId+'" class="inactive">');
		
		// stats line
		$('li#'+playerId).append('<div class="statline">');
		$('#'+playerId+' div.statline').click(function() {
			$(this).parent().children('div.info').slideToggle('750');  // toggle slide-up/down event
			if ($(this).parent().hasClass('active')) {
				$(this).parent().removeClass('active').addClass('inactive');
				$(this).css('background', 'url(http://media.gogamecocks.com/static/images/site/down_black_16.png) no-repeat right center');
			} else {
				$(this).parent().removeClass('inactive').addClass('active');
				$(this).css('background', 'url(http://media.gogamecocks.com/static/images/site/up_black_16.png) no-repeat right center');
			}
		});
		$('li#'+playerId+' div.statline').append('<div class="number right numeric">'+number+'</div>');  // jersey number
		$('li#'+playerId+' div.statline').append('<div class="name">'+name+'</div>');  // name
		$('li#'+playerId+' div.statline').append('<div class="position center">'+position1+'</div>');  // position
		$('li#'+playerId+' div.statline').append('<div class="sortPosition hidden numeric">'+positionSort+'</div>');  // position sort
		$('li#'+playerId+' div.statline').append('<div class="bats center">'+bats+'</div>');  // bats
		$('li#'+playerId+' div.statline').append('<div class="throws center">'+throws+'</div>');  // throws
		$('li#'+playerId+' div.statline').append('<div class="height">'+displayHeight+'</div>');  // displayed height
		$('li#'+playerId+' div.statline').append('<div class="sortHeight hidden numeric">'+height+'</div>');  // sort height
		$('li#'+playerId+' div.statline').append('<div class="weight numeric">'+weight+'</div>');  // weight
		$('li#'+playerId+' div.statline').append('<div class="state">'+state+'</div>');  // state
		$('li#'+playerId+' div.statline').append('<div class="clear">');
		
		// detailed info
		$('li#'+playerId).append('<div class="info">');
		if (urlPhoto) {
			$('li#'+playerId+' div.info').css('background', 'url('+urlPhoto+') no-repeat left top');  // preview photo
		}
		$('li#'+playerId+' div.info').append('<div class="text">');
		$('li#'+playerId+' div.info').append('<div class="more right">');
		$('li#'+playerId+' div.info').append('<div class="clear">');
		$('li#'+playerId+' div.text').append('<div class="label">POSITION:</div><div class="data">'+positionOne+'</div><div class="clear">');  // position description
		$('li#'+playerId+' div.text').append('<div class="label">BATS-THROWS:</div><div class="data">'+bats+'-'+throws+'</div><div class="clear"></div>');  // bats/throws
		$('li#'+playerId+' div.text').append('<div class="label">CLASS:</div><div class="data">'+classYear+'</div><div class="clear"></div>');  // class year
		$('li#'+playerId+' div.text').append('<div class="label">PREV. SCHOOL:</div><div class="data">'+school+'</div><div class="clear">');  // school
		$('li#'+playerId+' div.text').append('<div class="label">HOMETOWN:</div><div class="data">'+hometown+'</div><div class="clear">');  // hometown
		
		// more
		if (urlBio) {
			$('li#'+playerId+' div.more').append('<div><input class="extra" type="button" value="Bio" onclick="window.open(\''+urlBio+'\', \'thisBio\', \'\')" /></div>');  // bio
		}
		if (vmixId) {
			$('li#'+playerId+' div.more').append('<div><input class="extra" type="button" value="Video" onclick="window.open(\''+videoUrl+vmixId+'\', \'thisVideo\', \''+vmixFeatures+'\')" /></div>');
		}
		if (urlMore) {
			$('li#'+playerId+' div.more').append('<div><input class="extra" type="button" value="More" onclick="window.open(\''+urlMore+'\', \'thisStory\', \'\')" /></div>');
		}
	}		
}

// displays football roster
function showFootballRoster(data) {}

// displays football recruits
function showFootballRecruits(data) {
	if (!data) {
		alert('Missing data.');
		return false;
	}

	// container
	if ($('#container').length == 0) {
		$('#mi_content').append('<div id="container">');
	}

	// toolbar
	if ($('#toolbar').length == 0) {
		$('#container').append('<div id="toolbar">');
		$('#container').append('<div class="clear">');
		$('#toolbar').append('<div class="name left"><input class="menu" type="button" value="NAME" onclick="sortList(\'ul#data\', \'div.name\')" /> </div>');
		$('#toolbar').append('<div class="position center"><input class="menu" type="button" value="POS" onclick="sortList(\'ul#data\', \'div.sortPosition\')" /></div>');
		$('#toolbar').append('<div class="height"><input class="menu" type="button" value="HT" onclick="sortList(\'ul#data\', \'div.sortHeight\')" /></div>');
		$('#toolbar').append('<div class="weight"><input class="menu" type="button" value="WT" onclick="sortList(\'ul#data\', \'div.weight\')" /></div>');
		$('#toolbar').append('<div class="state"><input class="menu" type="button" value="STATE" onclick="sortList(\'ul#data\', \'div.state\')" /></div>');
		$('#toolbar').append('<div class="clear">');
	}
	
	// data (roster)
	if ($('#data').length == 0) {
		$('#container').append('<ul id="data">');
	}
	
	// fill list
	for (var i = 0; i < data['players'].length; i++) {			
		var playerId = data['players'][i].player_id;
		var year = parseInt(data['players'][i].year);
		var name = (data['players'][i].first_name+' '+data['players'][i].last_name).toUpperCase();
		var positionId = data['players'][i].position_id;
		var height = parseInt(data['players'][i].height);
		var weight = parseInt(data['players'][i].weight);
		var school = data['players'][i].school;
		var state = data['players'][i].state;
		var vmixId = parseInt(data['players'][i].vmix_id);
		var urlBio = data['players'][i].url_bio;
		var urlPhoto = data['players'][i].url_photo;
		var urlMore = data['players'][i].url_story;
		var notes = data['players'][i].notes;
		var position = data['players'][i].position;
		var positionSort = parseInt(data['players'][i].sortPosition);
		var displayHeight = toFeetAndInches(height);
		var hometown = data['players'][i].city+', '+data['players'][i].state;
		
		$('ul#data').append('<li id="'+playerId+'" class="inactive">');
		
		// stats line
		$('li#'+playerId).append('<div class="statline">');
		$('#'+playerId+' div.statline').click(function() {
			$(this).parent().children('div.info').slideToggle('750');  // trigger slide-up/down event
			if ($(this).parent().hasClass('active')) {
				$(this).parent().removeClass('active').addClass('inactive');
				$(this).css('background', 'url(http://media.gogamecocks.com/static/images/site/down_black_16.png) no-repeat right center');
			} else {
				$(this).parent().removeClass('inactive').addClass('active');
				$(this).css('background', 'url(http://media.gogamecocks.com/static/images/site/up_black_16.png) no-repeat right center');
			}
		});
		$('li#'+playerId+' div.statline').append('<div class="name">'+name+'</div>');  // name
		$('li#'+playerId+' div.statline').append('<div class="position">'+positionId+'</div>');  // position
		$('li#'+playerId+' div.statline').append('<div class="sortPosition hidden numeric">'+positionSort+'</div>');  // position sort
		$('li#'+playerId+' div.statline').append('<div class="height">'+displayHeight+'</div>');  // displayed height
		$('li#'+playerId+' div.statline').append('<div class="sortHeight hidden numeric">'+height+'</div>');  // sort height
		$('li#'+playerId+' div.statline').append('<div class="weight numeric">'+weight+'</div>');  // weight
		$('li#'+playerId+' div.statline').append('<div class="state">'+state+'</div>');  // state
		$('li#'+playerId+' div.statline').append('<div class="clear">');
		
		// detailed info
		$('li#'+playerId).append('<div class="info">');
		if (urlPhoto) {
			$('li#'+playerId+' div.info').css('background', 'url('+urlPhoto+') no-repeat left top');  // preview photo
		}
		$('li#'+playerId+' div.info').append('<div class="text">');
		$('li#'+playerId+' div.info').append('<div class="more">');
		$('li#'+playerId+' div.info').append('<div class="clear">');
		$('li#'+playerId+' div.text').append('<div class="label">POSITION:</div><div class="data">'+position+'</div><div class="clear">');  // position description
		$('li#'+playerId+' div.text').append('<div class="label">SCHOOL:</div><div class="data">'+school+'</div><div class="clear">');  // school
		$('li#'+playerId+' div.text').append('<div class="label">HOMETOWN:</div><div class="data">'+hometown+'</div><div class="clear">');  // hometown
		
		// more
		if (urlBio) {
			$('li#'+playerId+' div.more').append('<div><input class="extra" type="button" value="Bio" onclick="window.open(\''+urlBio+'\', \'thisBio\', \'\')" /></div>');  // bio
		}
		if (vmixId) {
			$('li#'+playerId+' div.more').append('<div><input class="extra" type="button" value="Video" onclick="window.open(\''+videoUrl+vmixId+'\', \'thisVideo\', \''+vmixFeatures+'\')" /></div>');  // video
		}
		if (urlMore) {
			$('li#'+playerId+' div.more').append('<div><input class="extra" type="button" value="More" onclick="window.open(\''+urlMore+'\', \'thisStory\', \'\')" /></div>');  // more stories
		}
	}
}

// sorts data (roster) by designated columns
function sortList(id, column) {
	var $list = $(id);
	var $listElements = $(id+' li').get();
	var dir = $(column).hasClass('asc') ? -1 : 1;  // change direction if we're already in ascending order
	var numeric = $(column).hasClass('numeric') ? 1 : 0;  // true/false
	$listElements.sort(function(a, b) {
		if (numeric) {
			return parseInt($(a).find(column).text()) > parseInt($(b).find(column).text()) ? (1 * dir) : (-1 * dir);
		} else {
			return $(a).find(column).text() > $(b).find(column).text() ? (1 * dir) : (-1 * dir);
		}
	});
	$.each($listElements, function(index, row) {
		$list.append(row);
	});
	dir == 1 ? $(column).addClass('asc') : $(column).removeClass('asc');
}
