// ************************************** //
// AJAX methods for the BHX flight boards //
// ************************************** //

// Enum type for direction
DirectionType = { Departures:0, Arrivals:1 }

// Function to handle flight board updates
function FlightBoardUpdate(directionType) {
    $('a#update').attr('style', 'background-image: url("/img/arrdep-lastupdated-loading.gif");');
    
    // Variables that contain param details.
    $params = "{}";
    $flightNumber = $("#arrDepSearchForm input[type='text']");
    $airline = $("#arrDepSearchForm select[id$='AirlineList']");
    $location = $("#arrDepSearchForm select[id$='LocationList']");
    
    // Params added if filters need to be applied.
    if ($flightNumber.val() != '') {
        $params = "{'filterBy':'FlightNumber', 'filterValue':'" + $flightNumber.val().replace("'", "\\'") + "'}";
    } else if ($airline.val() != '') {
        $params = "{'filterBy':'Airline', 'filterValue':'" + $airline.val().replace("'", "\\'") + "'}";
    } else if ($location.val() != '') {
        $params = "{'filterBy':'Location', 'filterValue':'" + $location.val().replace("'", "\\'") + "'}";
    }
    
    // AJAX methods according to direction
    if (directionType == DirectionType.Departures) {
        $url = "/services/AjaxWebServices.asmx/LatestDeparturesGet";
        $filteredUrl = "/services/AjaxWebServices.asmx/FilteredLatestDeparturesGet";
        $updateUrl = "/services/AjaxWebServices.asmx/DeparturesLastUpdate";
    } else {
        $url = "/services/AjaxWebServices.asmx/LatestArrivalsGet";
        $filteredUrl = "/services/AjaxWebServices.asmx/FilteredLatestArrivalsGet";
        $updateUrl = "/services/AjaxWebServices.asmx/ArrivalsLastUpdate";
    }
    
    // Clear any server-side error messages
    $('.serverMessage').remove();
    
    // Clear any client-side error messages
    $('.clientMessage').remove();
    
    if ($params == "{}") {
	    // No filters so return all flights.
	    $.ajax({
		    type: "POST",
		    contentType: "application/json; charset=utf-8",
		    url: $url,
		    data: $params,
		    dataType: "json",
		    success: function(results) {
			    AjaxSucceeded(results, directionType);
		    },
		    error: function(xhr, status, error) {
		        AjaxError();
		    }
	    });
	} else {
	    // Return flights for the filters applied.
	    $.ajax({
		    type: "POST",
		    contentType: "application/json; charset=utf-8",
		    url: $filteredUrl,
		    data: $params,
		    dataType: "json",
		    success: function(results) {
			    AjaxSucceeded(results, directionType);
		    },
		    error: function(xhr, status, error) {
		        AjaxError();
		    }
	    });
	}
	
	// Separate AJAX call to update the last updated time.
	$.ajax({
		type: "POST",
		contentType: "application/json; charset=utf-8",
		url: $updateUrl,
		data: "{}",
		dataType: "json",
		success: function(results) {
			LastUpdated(results);
	    },
	    error: function(xhr, status, error) {
	        AjaxLastUpdatedError();
	    }
	});
}

// Generic AJAX Error Handler
function AjaxError() {
    $error = '<div class="message warning clientMessage"><h3>Sorry, there was a problem&hellip;</h3><p>It wasn\'t possible to update the flight information. Please try again later, thank you.</p></div>';
    $('#arrDepSearch').after($error);
    $('.arrivalsDeparturesBoard').remove();
    $('a#update').removeAttr('style');
}

// Last updated AJAX Error Handler
function AjaxLastUpdatedError() {
    $('p.lastUpdated > em').text('Last updated: not available');
}

// Updates the last updated element with the result from 
// the AJAX call.
function LastUpdated(results) {
	$('p.lastUpdated > em').text(results.d);
}

// Function that applies the correct CSS classes to each
// row according to the order and comment.
function FlightBoardItemCssClassUpdate(row, comment) {
	if (comment.indexOf('Arrived') != -1) {
		if (row.attr('class').indexOf('light') != -1) {
			row.attr('class', 'light landed');
		} else {
			row.attr('class', 'dark landed');
		}
	} else if (comment.indexOf('Expected') != -1) {
		if (row.attr('class').indexOf('light') != -1) {
			row.attr('class', 'light expected');
		} else {
			row.attr('class', 'dark expected');
		}
	} else if (comment.indexOf('Departed') != -1) {
		if (row.attr('class').indexOf('light') != -1) {
			row.attr('class', 'light departed');
		} else {
			row.attr('class', 'dark departed');
		}
	} else if (comment.indexOf('Final Call') != -1 || comment.indexOf('Boarding') != -1) {
		if (row.attr('class').indexOf('light') != -1) {
			row.attr('class', 'light finalcall');
		} else {
			row.attr('class', 'dark finalcall');
		}
	} else if (comment.indexOf('Cancelled') != -1) {
		if (row.attr('class').indexOf('light') != -1) {
			row.attr('class', 'light cancelled');
		} else {
			row.attr('class', 'dark cancelled');
		}
	} else if (comment.indexOf('Delayed') != -1) {
		if (row.attr('class').indexOf('light') != -1) {
			row.attr('class', 'light delayed');
		} else {
			row.attr('class', 'dark delayed');
		}
	} else if (comment.indexOf('Check In') != -1 || comment.indexOf('Gate Closed') != -1) {
		if (row.attr('class').indexOf('light') != -1) {
			row.attr('class', 'light checkin');
		} else {
			row.attr('class', 'dark checkin');
		}
	} else {
		if (row.attr('class').indexOf('light') != -1) {
			row.attr('class', 'light');
		} else {
			row.attr('class', 'dark');
		}
	}
}

// Main AJAX call processing function.
function AjaxSucceeded(results, directionType) {
    $table = $('table.arrivalsDeparturesBoard');
   
    // Check flight information table exists
    if ($table.length <= 0) {
        // Create base table markup
        if (directionType == DirectionType.Departures) {
            $table = '<table class="arrivalsDeparturesBoard" summary="Live flight information at Birmingham Airport"><thead><tr><th class="location">Flying to</th><th class="airline">Airline</th><th class="flight">Flight no.</th><th class="scheduled">Scheduled</th><th class="estimated">Terminal</th><th class="details">Details</th></tr></thead><tfoot><tr class="light"><td colspan="6"><a href="#">Back to top / find a flight</a></td></tr></tfoot><tbody><tr id="newblank" class="light"><td class="location"><div></div></td><td class="airline"><div></div></td><td class="flight"><div></div></td><td class="scheduled"><div></div></td><td class="estimated"><div></div></td><td class="details"><div></div></td></tr></tbody></table>';
        } else {
        $table = '<table class="arrivalsDeparturesBoard" summary="Live flight information at Birmingham Airport"><thead><tr><th class="location">Arriving from</th><th class="airline">Airline</th><th class="flight">Flight no.</th><th class="scheduled">Scheduled</th><th class="estimated">Terminal</th><th class="details">Details</th></tr></thead><tfoot><tr class="light"><td colspan="6"><a href="#">Back to top / find a flight</a></td></tr></tfoot><tbody><tr id="newblank" class="light"><td class="location"><div></div></td><td class="airline"><div></div></td><td class="flight"><div></div></td><td class="scheduled"><div></div></td><td class="estimated"><div></div></td><td class="details"><div></div></td></tr></tbody></table>';
        }
        
        $('#content > .formWrapper').after($table);
    }
    
	// Load JSON data and current rows into variables.
	$data = results.d;
	$rows = $('table.arrivalsDeparturesBoard > tbody > tr');
	
	if ($data.length > 0) {
	    // If there are too more rows in the table than the data
	    // then remove rows
	    if ($rows.length > $data.length) {
		    for (j=0;j<=$rows.length - $data.length;j++) {
			    $rows.eq($rows.length - j).remove();
		    }
    		
		    // Reload rows collection with the rows removed.
		    $rows = $('table.arrivalsDeparturesBoard > tbody > tr');
	    }
    	
	    // If there are not enough rows in the table compared with 
	    // the data then add empty rows
	    if ($data.length > $rows.length) {
		    for (k=0;k<$data.length - $rows.length;k++) {
			    $cssClass = 'light';
    		    
		        if (($rows.length % 2) != 0) {
			        if (($rows.length + k) % 2 != 0) {
				        $cssClass = 'dark';
			        }
			    } else {
			        if (($rows.length + k + 1) % 2 != 0) {
				        $cssClass = 'dark';
			        }
			    }
    			
			    // Creates the markup for a new row.
			    $newrow = '<tr id="new' + k + '" class="' + $cssClass + '"><td class="location"><div></div></td><td class="airline"><div></div></td><td class="flight"><div></div></td><td class="scheduled"><div></div></td><td class="estimated"><div></div></td><td class="details"><div></div></td></tr>';
			    if ($rows.length > 1) {
			        $lastRow = $rows.eq($rows.length - 1);
			        $lastRow.after($newrow);
			    } else {
			        $('table.arrivalsDeparturesBoard > tbody').append($newrow);
			    }
		    }
    		
		    // Reload rows collection with the new rows added.
		    $rows = $('table.arrivalsDeparturesBoard > tbody > tr');
	    }
    	
	    // Update row content according to data    
	    for (i=0;i<$rows.length;i++) {
		    // Get the row specific values into local variables
		    $row = $rows.eq(i);
		    $rowId = $row.attr('id');
    		
		    $location = $('tr#' + $rowId + ' > td.location > div');
		    $airline = $('tr#' + $rowId + ' > td.airline > div');
		    $flight = $('tr#' + $rowId + ' > td.flight > div');
		    $scheduled = $('tr#' + $rowId + ' > td.scheduled > div');
		    $terminal = $('tr#' + $rowId + ' > td.estimated > div');
		    $comment = $('tr#' + $rowId + ' > td.details > div');
    		
		    $rowDivs = $('tr#' + $rowId + ' div');
    		
		    // Have rows changed order
		    if ($rowId != $data[i].FlightId) {
			    $rowDivs.slideUp().delay(500);
    			
			    // Update row specific values
			    $rowId = $data[i].FlightId;
			    $row.attr('id', $rowId);
    			
			    if (directionType == DirectionType.Departures) {
			        $location.text($data[i].FlightTo);
			    } else {
			        $location.text($data[i].FlightFrom);
			    }
			    $airline.text($data[i].Airline);
			    $flight.text($data[i].FlightNumber);
			    $scheduled.text($data[i].FlightTimeString);
			    $terminal.text($data[i].Terminal);
			    $comment.text($data[i].Comment);
    			
			    $rowDivs.slideDown().delay(500);
    			
			    FlightBoardItemCssClassUpdate($row, $data[i].Comment);
		    } else {
			    $hasChanged = false;
    			
			    // Check for any changes in the row
			    if (directionType == DirectionType.Departures && ($location.text() != $data[i].FlightTo || $terminal.text() != $data[i].Terminal || $scheduled.text() != $data[i].FlightTimeString || $comment.text() != $data[i].Comment)) {
			        $hasChanged = true;
			    } else if ($location.text() != $data[i].FlightFrom || $terminal.text() != $data[i].Terminal || $scheduled.text() != $data[i].FlightTimeString || $comment.text() != $data[i].Comment) {
			        $hasChanged = true;
			    }
    			
			    if ($hasChanged) {
				    $rowDivs.slideUp().delay(500);
    				
				    // Update row specific values
				    if (directionType == DirectionType.Departures) {
			            $location.text($data[i].FlightTo);
			        } else {
			            $location.text($data[i].FlightFrom);
			        }
			        $airline.text($data[i].Airline);
			        $flight.text($data[i].FlightNumber);
				    $scheduled.text($data[i].FlightTimeString);
				    $terminal.text($data[i].Terminal);
				    $comment.text($data[i].Comment);
    				
				    $rowDivs.slideDown().delay(500);
    				
				    FlightBoardItemCssClassUpdate($row, $data[i].Comment);
			    }
		    }                    
	    } 
	} else {
	    $noResults = '<div class="message warning clientMessage"><h3>Sorry, there wasn\'t a match</h3><p>No flights have been found for the location or flight number entered. Please try again.</p></div>';
        $('#arrDepSearch').after($noResults);
        $('.arrivalsDeparturesBoard').remove();
	}
	
	$('a#update').removeAttr('style');               
}