// Schema for info we'll grab from train items
var schema = {
	line : {
		full : [],
    min: []
	},
	cars : {
	},
	destination : {
	},
	time : {
	}
};

schema.line.full['RD'] = 'Red';
schema.line.full['BL'] = 'Blue';
schema.line.full['GR'] = 'Green';
schema.line.full['YL'] = 'Yellow';
schema.line.full['OR'] = 'Orange';
schema.line.full['No'] = 'No';
schema.line.full['--'] = '--';

schema.line.min['RD'] = 'red';
schema.line.min['BL'] = 'blue';
schema.line.min['GR'] = 'green';
schema.line.min['YL'] = 'yellow';
schema.line.min['OR'] = 'orange';
schema.line.min['No'] = 'no';
schema.line.min['--'] = 'no';

var loadingStation;

/* ==================== AJAX Call ==================== */

//reusable yql url
//u = api url, q = query parameters for the wmata api, t = time (additional yql query parameters mainly used for maxage)
var api = function (url,query,time){
	return 'http://query.yahooapis.com/v1/public/yql?format=json&env=store%3A%2F%2FZJCAEFOqt854UQKmGw5fhU'+time+'&q='+encodeURIComponent('set u="'+url+'"on m;set q="'+query+'"on m;select * from m;');
}

//callback that shows list of stations
var showStations = function (json){
	//sort stations
	var stations=json.query.results.json.Stations;
	stations.sort(function(a,b){
			   var first=a.Name.toUpperCase();
			   var second=b.Name.toUpperCase();
			   return (first<second) ? -1 : (first>second) ? 1 : 0;
	});
	
	//add each station to the ul
	var $stations = $('#stations');
	var stationList = 1;
	var stationInc = 1;
	var defaultStationIndex = 52; //52 == metro center
	var stationCode = getParameter();

	for (var key = 0; key < stations.length; key++){
		var station=stations[key];
		var $li = $(document.createElement('li')).addClass(schema.line.min[station.LineCode1]);
		var $stationName = $(document.createElement('span')).addClass('name').text(station.Name);
		var $line1 = createNewLineCode(station.LineCode1);
		
		$li.append($line1).data('stationCode', station.Code);
		
		// add second station line if it exists
		if ( station.LineCode2 ) {
			var $line2 = createNewLineCode(station.LineCode2);
			$li.append( $line2 );
		}
		
		$li.append($stationName);
		$('#stations ul:nth-child('+stationList+')').append($li);
		
		//is this the default station?
		if (stationCode == station.Code) {			
			defaultStationIndex = key;
		}
		
		stationInc++;
		if ( stationInc > 23) { stationInc = 1; stationList++; }	
	}

	//after all stations are appended, bind click event
	$stations.find('li').click(stationClick);

	//select the default station
	$stations.find('li').eq(defaultStationIndex).click();
};

var createNewLineCode = function(lineCode) {
	$line = $( document.createElement('span') )
	.addClass('line line-' + lineCode )
	return $line;
}

var stationClick = function(){
	var $this = $(this);
	
	loadingStation = $(this).html();
	
	// expose loading indicator
	$('h1').fadeOut();
	$('#trains').fadeOut();
	
	// UI touches
	var $stations = $('#stations');
	$stations.find('.selected').removeClass('selected');
	$(this).addClass('selected');
	
	// execute getting station info
	getStation($this.data('stationCode'),true);
};

function getIncidents(){
	$.ajax({
		   url:api('Incidents.svc/json/Incidents','t='+cache(600),''),
		   dataType:'jsonp',
		   jsonp:'callback',
		   jsonpCallback:'showIncidents'
		   });
}

//callback that shows all of the incidents
function showIncidents(json){
	
	//add each station to the ul - sometimes it's an array, sometimes not
	var 
    $incidents = $('#incidents'),
    content = ''
	;
	try {
		var incidentItems = json.query.results.json.Incidents;
		if ( incidentItems instanceof Array) {
			for (key in incidentItems){
				content += createIncidentContent( indcidentItems[key] );
			}
		} else {  
		    content += createIncidentContent( indcidentItems[key] );
		}
	} catch(e) {
	    content += '<li>There are no Metrorail alerts at this time.</li>';
	}
	
	$incidents.append(content);
}

var createIncidentContent = function (incident) {
	return '<li><em>'+incident.StartLocationFullName+'</em>'+incident.Description+'</li>';
};

//loads the train predications for a given station code
var stationIntervalID;
var selectedStationCode;
var getStation = function (code,clear){
	
	//save the station code for later
	selectedStationCode = code;
	
	//if this is a new function call, clear the previous interval call
	if (clear) {
		window.clearInterval(stationIntervalID);
		stationIntervalID=null;
	}
	
	$.ajax({
		   url:api('StationPrediction.svc/json/GetPrediction/'+code,'t='+cache(19),''),
		   dataType:'jsonp',
		   jsonp:'callback',
		   jsonpCallback:'showStation'
	});
	
	//refresh every 20 seconds
	if( !stationIntervalID ){
		stationIntervalID = window.setInterval(function(){
											   getStation(code);
											   },20000);
	}
};

//callback that shows station predications
var showStation = function (json) {
	
	// set title to current station
	$('h1').html(loadingStation);
	
	try {
		var trainItems = json.query.results.json.Trains;
		$trains = $('#trains').find('.train');
		
		$.each(trainItems, function(index, prediction){
			   
			   // edit text of trains table
			   $train = $trains.eq(index);
			   var className = 'line-'+prediction.Line
			   + ' car-'+prediction.Car
			   + ' dest-'+prediction.DestinationName.replace(' ', '-')
			   + ' time-'+prediction.Min;
			   $train.attr('class', 'train '+ className);
			   
			   //account for null car counts
			   var car = (prediction.Car != null) ? prediction.Car : '-';
			   
			   $train.find('.line span').html( '<div>'+prediction.Line+'</div>' );
			   $train.find('.cars span').html( '<div>'+car+'</div>' );
			   $train.find('.destination span').html( '<div>'+prediction.DestinationName+'</div>' );
			   $train.find('.time span').html( '<div>'+prediction.Min+'</div>' );
			   
			   $('h1').fadeIn();
			   $('#trains').fadeIn();			   
		});
		
		//set the proper url so users can link to a specific station
		var index = window.location.href.indexOf('#');
		var basicLocation = (index > -1) ? window.location.href.substring(0, index) : window.location.href;
		window.location.href = basicLocation + '#' + selectedStationCode;
		
	} catch(e) {
		console.log(e);
	}
}

//return cache time period - takes number of seconds for the cache period
function cache(s){var d=new Date();return ''+Math.round((d.getTime()/(s*10000))*10);}

//gets the query parameter after the #
function getParameter() {
	var regex = new RegExp("[\\#]([^&#]*)");
	var results = regex.exec(window.location.href);
	if( results == null )
		return "";
	else
		return results[1];
}

/* ==================== document ready ==================== */

$(function(){
  
  if (navigator.userAgent.indexOf("Firefox")!=-1) { $('body').addClass('moz'); }
  if (navigator.userAgent.indexOf("MSIE")!=-1) { $('body').addClass('ie moz'); }
  
  
  //loads all of the metro stations, adds stations to list
  //cache for 5 days
  $.ajax({
		 url:api('Rail.svc/json/JStations','','&_maxage=432001'),
		 cache:true,
		 dataType:'jsonp',
		 jsonp:'callback',
		 jsonpCallback:'showStations'
		});
  
  //loads all of the metro incidents every 10 minutes
  //getIncidents();
  //window.setInterval(getIncidents,600000);
  
  // create table markup
  var rows = [];
  for ( i=0; i < 6; i++) {
	var row = '<tr class="train">';
	for (key in schema ) {
		row += '<td class="'+key+'"><span></span></td>';
	}
	row += '</tr>';
	rows.push(row);
  }
  $('#trains').append(rows.join(''));
  
});
