(function($){

var TravelPlanner = this.TravelPlanner = {

	rootURL: 'http://www.southeastasia.org/index.php',
	
	currency: 'USD',
	
	routeTypes: {
		'-1': 'ferry',
		'-2': 'land',
		'-3': 'flight'
	},
	
	capitals: {
		'brunei darussalam': 3,
		'cambodia': 34,
		'indonesia': 16,
		'laos': 41,
		'malaysia': 22,
		'myanmar': 42,
		'philippines': 29,
		'singapore': 38,
		'thailand': 5,
		'vietnam': 14
	}
	
};

TravelPlanner.Data = {
	name: null,
	currency: TravelPlanner.currency,
	destinations: []
	/*
		// destination
		{
			location: {
				uid: 234234234,
				id: 12,
				name: 'Sydney, Australia',
				airportCode: 'SYD',
				hotelCode: 835,
				lat: 0,
				lng: 1
			},
			hotel: {
				id: 'ed7xxxxxxxxxxxxx',
				name: 'Pan Pacific Hotel',
				address: 'some road',
				url: '/hotels/some-road',
				price: 133.00,
				nights: 2,
				datetime: 0123123
			},
			activities: [
				{
					id: 23,
					name: 'Boat Quay'
				},
				{
					id: 13,
					name: 'Boat Quay again'
				}
			],
			// Return flight 1
			transport: {
				type: 'flight',
				to: 'BGO',
				price: 130.00,
				departDatetime: 01235445,
				returnDatetime: 01235445,
				referLocation: null,
				'return': true,
				airlineName: 'AirAsia',
			}
		}
	*/
};

$.extend(TravelPlanner, {
	
	sub: function(e, fn){
		$(TravelPlanner).bind('_' + e, fn);
	},
	
	pub: function(e, data){
		if (!data) data = [];
		console.log('TravelPlanner pub: ' + e + ' - ' + data.join(' '));
		$(TravelPlanner).trigger('_' + e, data);
	},
	
	init: function(){
		
		TravelPlanner.initHomeAirportAutocomplete();
		TravelPlanner.loadDestinations();
		TravelPlanner.Sidebar.init();
		TravelPlanner.loadCurrencies();
		
		// active states for the itineraries
		$('#itinerary .destination').live('click', function(e){
			var el = $(this);
			var id = el.attr('id');
			TravelPlanner.pub('focusItineraryDestination', [id]);
		});
		
		// active states for the itineraries
		$('#itinerary .filters ul li a').live('click', function(e){
			var el = $(this);
			var id = el.attr('id');

			if ($('#itinerary').hasClass(id)){
				$('#itinerary').removeClass();
			}else{
				$('#itinerary').removeClass();
				$('#itinerary').addClass(id);
			}
			
			var destinationItems = $('.destination-item');
			destinationItems.removeClass('has-hotel');
			destinationItems.removeClass('has-activity');
			$.each(destinationItems, function(i, d){
				if ($(d).find('.hotel').length > 0) $(d).addClass('has-hotel');
				if ($(d).find('.activity').length > 0) $(d).addClass('has-activity');
			});
			
			return false;
		});
		
		// currency changer
		$('#currency-changer').change(function(){
			var el = $(this);
			el.attr('disabled', true);
			TravelPlanner.currency = el.val();

			var priceClasses = '#itinerary .price .amount, #sidebar .amount, #total-amount .amount, .sidebar-info-content .amount';
			currencyClasses = '#itinerary .price .currency, #sidebar .priceCurrency, #total-amount .currency, #sidebar .currency, .sidebar-info-content .currency';
			TravelPlanner.Currency.convertClass(priceClasses, currencyClasses, TravelPlanner.currency);
			
			// convert all prices to the new currency in the Data
			var convertAmount = TravelPlanner.Currency.convertAmount;
			$.each(TravelPlanner.Data.destinations, function(i, destination){
				if (destination.transport.price){
					destination.transport.price = convertAmount(destination.transport.price, TravelPlanner.currency, TravelPlanner.Data.currency);
				}
				if (destination.hotel && destination.hotel.price){
					destination.hotel.price = convertAmount(destination.hotel.price, TravelPlanner.currency, TravelPlanner.Data.currency);
				}
			});

			TravelPlanner.Data.currency = TravelPlanner.currency;
			TravelPlanner.renderDestinations();

			return false;
		});
		
		var triggeredShowHideEdit = false;
		TravelPlanner.sub('renderDestinations', function(){
			$('#currency-changer').attr('disabled', false);
			if (!triggeredShowHideEdit){
				triggeredShowHideEdit = true;
				$('#itinerary .destination:not(.active)').live('mouseover', function(){
					$(this).find('.edit-destination').show();
				});
				$('#itinerary .destination-item:not(.return):last').live('mouseover', function(){
					$(this).find('.remove-destination').show();
				});
				$('#itinerary .destination').live('mouseout', function(){
					$(this).find('.edit-destination, .remove-destination').hide();
				}).live('click', function(){
					$(this).find('.edit-destination, .remove-destination').hide();
				});
			}
		});
		
		$('#itinerary .destination-item .remove-destination').live('click', function(){
			var el = $(this);
			var uid = el.attr('href').split('#')[1];
			if (confirm('Are you sure you want to remove this destination?')){
				TravelPlanner.removeDestination(uid);
			}
			return false;
		});
		
		TravelPlanner.sub('focusItineraryDestination', function(e, id, dontUpdateSidebar){
			var el = $('#' + id);
			switch (id){
				case 'homeairport':
					el.addClass('active').siblings().removeClass('active');
					TravelPlanner.currentItinerary = id;
					if (TravelPlanner.setHomeAirport && TravelPlanner.hasHomeFlight){
						$('#sidebar-home').show().siblings('.sidebar-item').hide();
						TravelPlanner.pub('updateSidebar', [id]);
					} else {
						$('#sidebar-intro').show().siblings('.sidebar-item').hide();
					}
					break;
				case 'add-destination':
					el.addClass('active').siblings().removeClass('active');
					$('#sidebar-intro').show().siblings('.sidebar-item').hide();
					break;
				default:
					if (el.hasClass('active')) return;
					el.addClass('active').siblings().removeClass('active');
					var uid = $.trim(id).split('-')[1];
					TravelPlanner.currentItinerary = 'destination-' + uid;
					var destination = TravelPlanner.Utils.getDestinationByUID(uid);
					if (destination){
						if (TravelPlanner.Data.destinations.length>2 && destination.transport['return']){
							$('#sidebar-return').show().siblings('.sidebar-item').hide();
						} else {
							$('#sidebar-trip').show().siblings('.sidebar-item').hide();
						}
						if (!dontUpdateSidebar) TravelPlanner.pub('updateSidebar', [uid]);
					} else {
						$('#sidebar-home').show().siblings('.sidebar-item').hide();
					}
			}
		});

		TravelPlanner.hasChanges = false;
		
		var addDestinationBusy = false;
		TravelPlanner.sub('addDestination', function(){
			TravelPlanner.hasHomeFlight = true;
			addDestinationBusy = false;
			$('#destinationLoading').hide();
			TravelPlanner.renderDestinations();
			TravelPlanner.hasChanges = true;
		});
		
		TravelPlanner.sub('updateDestination', function(){
			TravelPlanner.hasChanges = true;
		});
		
		window.onbeforeunload = function(e){
			if (TravelPlanner.hasChanges){
				if (!e) e = window.event;
				e.cancelBubble = true;
				e.returnValue = 'You did some changes in this trip.';
				if (e.stopPropagation){
					e.stopPropagation();
					e.preventDefault();
				}
			}
		};
		
		var controlsShown = false;
		TravelPlanner.sub('renderDestinations', function(){
			if (!controlsShown && TravelPlanner.Data.destinations.length >= 2){
				// show the filters and controls
				$('#itinerary .filters').slideDown('slow');
				controlsShown = true;
			}
		});
		
		TravelPlanner.sub('message', function(e, type, msg, data){
			var message = null;
			var messageContainer = null;
			
			switch (type){
				
				case 'error':
					switch (msg){
						
						case 'sameDestination':
							messageContainer = $('#itinerary-message');
							addDestinationBusy = false;
							$('#destinationLoading').hide();
							message = "Sorry, you can't add the same destination again.";
							break;
						
						case 'noDirectFlight':
							messageContainer = $('#itinerary-message');
							addDestinationBusy = false;
							$('#destinationLoading').hide();
							var from_id = data.from_id;
							var to_id = data.to_id;
							var from = TravelPlanner.destinations[from_id];
							var to = TravelPlanner.destinations[to_id];
							
							var id = '';
							var name = '';
							var country = '';
							
							if (data.suggest){
								id = data.suggest;
								var d = TravelPlanner.destinations[id];
								name = d.name;
								country = d.country;
							} else {
								var fromCapital = TravelPlanner.capitals[from.country.toLowerCase()];
								var toCapital = TravelPlanner.capitals[to.country.toLowerCase()];
								if (from_id != fromCapital){
									var destination = TravelPlanner.destinations[fromCapital];
									id = fromCapital;
									name = destination.name;
									country = destination.country;
								} else if (to_id != toCapital){
									var destination = TravelPlanner.destinations[toCapital];
									id = toCapital;
									name = destination.name;
									country = destination.country;
								} else {
									// If no direct flights between country capitals, well, that sucks.
								}
							}
							
							message = "Sorry, there are no direct flights from " + from.name + ' to ' + to.name + '.';
							if (id && name){
								message += '<br>You may try adding <a href="#' + id + '" class="suggested-destination">'
									+ name + ', ' + country + '</a> first.';
							}
							break;
						
						case 'noHomeAirport':
							messageContainer = $('#homeairport-message');
							message = "Please add your home airport first before adding itineraries.";
							break;
						
					}
					break;
				
			}
			
			if (!messageContainer) return;
			
			if (message){
				messageContainer.html(message).css('display', 'block');
			} else {
				messageContainer.hide();
			}
		});
		
		$('#travelplanner #itinerary-message .suggested-destination').live('click', function(){
			var el = $(this);
			var id = el.attr('href').split('#')[1];
			$('#destinationsSelect').val(id).trigger('change');
			$('#travelplanner .link-accept-destination').click();
			return false;
		});
		
		$('#travelplanner .link-accept-destination').click(function(){
			if (addDestinationBusy) return false;
			var id = $('#destinationsSelect').val();
			if (id == '') return false;
			if (!TravelPlanner.destinations[id]) return false;
			
			addDestinationBusy = true;
			$('#destinationLoading').show();
			
			setTimeout(function(){
				$('#destinationsSelect')[0].selectedIndex = 0; // reset back to the first value
			}, 1000);
			
			var routesList = $('#add-destination .routes-list').empty();
			
			TravelPlanner.addDestination(id);
			
			return false;
		});

		$('#homeairport .flight-name, #homeairport .flight .date').live('click', function(e){
			e.preventDefault();
			if (this.className.indexOf('date') != -1) setTimeout(function(){
				$('#flights-depart-date').focus();
			}, 200);
		});
		
		$('#itinerary .destination-item .flight-name, #itinerary .destination-item .flight .date, #itinerary .destination-item .surface-name, #itinerary .destination-item .surface .date').live('click', function(e){
			e.preventDefault();
			$('#sidebarTabs .transport-tab').click();
			if (this.className.indexOf('date') != -1) setTimeout(function(){
				$('#transport-depart-date').focus();
			}, 200);
		});
		
		$('#itinerary .hotel-name, #itinerary .hotel .date').live('click', function(e){
			e.preventDefault();
			$('#sidebarTabs .hotels-tab').click();
			if (this.className.indexOf('date') != -1) setTimeout(function(){
				$('#hotels-check-in-date').focus();
			}, 200);
		});

		$('#itinerary .activity-name').live('click', function(e){
			e.preventDefault();
			$('#sidebarTabs .thingstodo-tab').click();
		});
		
		TravelPlanner.sub('loadDestinations', function(e){
			// do some awesome shit
			TravelPlanner.User.init();
			setTimeout(function(){
				if (TravelPlanner.sharedTrip){
					TravelPlanner.loadTrip(TravelPlanner.sharedTrip);
				}
			}, 1000);
		});
	},
	
	initHomeAirportAutocomplete: function(){
		var field = $('#homeAirportField').focus();
		field.autocomplete('/api/flight_locations', {
			minChars: 3,
			max: 5,
			delay: 300
		}).result(function(e, item){
			TravelPlanner.homeAirport = {
				fullName: item[0],
				id: parseInt(item[1], 10),
				name: item[2],
				country: item[3],
				airportCode: item[4],
				countryCode: item[5],
				currency: item[6]
			};
			$('#homeairport').show().click().find('.link-accept').focus();
		});

		TravelPlanner.sub('setHomeAirport', function(){
			TravelPlanner.setHomeAirport = true;
		});
		
		var acceptHomeAirportBusy = false;
		$('#homeairport .link-accept').click(function(){
			if (acceptHomeAirportBusy) return false;
			acceptHomeAirportBusy = true;
			var displayHomeAirport = function(){
				TravelPlanner.pub('setHomeAirport');
				
				var uid = TravelPlanner.Utils.genUID();
				TravelPlanner.currency = TravelPlanner.homeAirport.currency;
				
				TravelPlanner.Data.destinations[0] = {
					uid: uid,
					location: {
						name: TravelPlanner.homeAirport.name,
						country: TravelPlanner.homeAirport.country,
						airportCode: TravelPlanner.homeAirport.airportCode
					},
					transport: {
						type: 'flight' // the first destination is always a Flight
					},
					hotel: {},
					activities: []
				};
				
				// Reverse geocode the homeAirport
				// The results will come later, but not needed that early, so it's safe
				var geocoder = new google.maps.Geocoder();
				console.log('Getting latlng for ' + TravelPlanner.homeAirport.fullName);
				geocoder.geocode({address: TravelPlanner.homeAirport.fullName}, function(results, status){
					if (status == google.maps.GeocoderStatus.OK && results.length){
						var loc = results[0].geometry.location;
						var lat = loc.lat();
						var lng = loc.lng();
						console.log('Home airport latlng is ' + lat + ', ' + lng);
						TravelPlanner.Data.destinations[0].location.lat = loc.lat();
						TravelPlanner.Data.destinations[0].location.lng = loc.lng();
					}
				});
				
				var done = function(){
					var priceClasses = '#itinerary .price .amount';
					currencyClasses = '#itinerary .price .currency, #sidebar .priceCurrency, #total-amount .currency';
					TravelPlanner.Currency.convertClass(priceClasses, currencyClasses, TravelPlanner.currency);
					
					$('#homeAirportText').text(TravelPlanner.homeAirport.name + ', ' + TravelPlanner.homeAirport.country);
					$('.homeairport-field').hide();
					TravelPlanner.renderDestinations();
					acceptHomeAirportBusy = false;
				};
				
				// convert all prices to the new currency in the Data
				var convertAmount = TravelPlanner.Currency.convertAmount;
				$.each(TravelPlanner.Data.destinations, function(i, destination){
					if (destination.transport.price){
						destination.transport.price = convertAmount(destination.transport.price, TravelPlanner.currency, TravelPlanner.Data.currency);
					}
					if (destination.hotel && destination.hotel.price){
						destination.hotel.price = convertAmount(destination.hotel.price, TravelPlanner.currency, TravelPlanner.Data.currency);
					}
				});
				TravelPlanner.Data.currency = TravelPlanner.currency;
				$('#currency-changer').val(TravelPlanner.currency);
				
				// V2
				// Means another destination after the first one has been added
				// which then means there are at least two destinations now
				if (TravelPlanner.hasHomeFlight){
					var destinations = TravelPlanner.Data.destinations;
					var firstDestination = destinations[0];
					var lastDestination = destinations[destinations.length-1];
					var from = firstDestination.location.airportCode;
					var to = lastDestination.location.airportCode;
					
					TravelPlanner.currentItinerary = 'homeairport';
					
					if ($.inArray(firstDestination.location.country.toLowerCase(), TravelPlanner.countries) != -1){
						TravelPlanner.requestFlightBestPrice({
							from: from,
							to: to
						}, function(data){
							$.extend(firstDestination.transport, {
								from: from,
								to: to,
								airlineName: data.onewayAirlineName || null,
								price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
								'return': false
							});
							TravelPlanner.requestFlightBestPrice({
								from: to,
								to: from
							}, function(data){
								$.extend(lastDestination.transport, {
									from: to,
									to: from,
									airlineName: data.onewayAirlineName || null,
									price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
									'return': false,
									departDate: null,
									returnDate: null
								});
								done();
							});
						});
					} else {
						TravelPlanner.requestFlightBestPrice({
							from: from,
							to: to
						}, function(data){
							var t = {
								airlineName: data.returnAirlineName || null,
								price: convertAmount(data.returnPrice, TravelPlanner.currency) || null,
								'return': true
							};
							$.extend(firstDestination.transport, t, {
								from: from,
								to: to
							});
							$.extend(lastDestination.transport, t, {
								from: to,
								to: from,
								departDate: null,
								returnDate: null
							});
							done();
						});
					}
				} else {
					done();
					$('#add-destination').show().click();
					$('.destinations').removeClass('no-timeline');
					$('#destinationsSelect').focus();
				}
				
			};
			if (TravelPlanner.homeAirport && !_.isEmpty(TravelPlanner.homeAirport)){
				displayHomeAirport();
			} else {
				setTimeout(displayHomeAirport, 1000);
			}
			return false;
		});
		
		$('#changeHomeAirport').click(function(){
			$('.homeairport-field').toggle();
			$('#homeAirportField').focus().select();
			return false;
		});
	},
	
	loadDestinations: function(){
		var destinationSelect = $('#destinationsSelect').attr('disabled', true);
		$.ajax({
			url: '/api/destinations',
			dataType: 'json',
			success: function(data){
				TravelPlanner._destinations = data;
				TravelPlanner.destinations = {};
				TravelPlanner.countries = [];
				$.each(data, function(i, d){
					TravelPlanner.countries.push(d.country.toLowerCase());
					TravelPlanner.destinations[d.id] = d;
				});
				TravelPlanner.countries = TravelPlanner.Utils.arrayUnique(TravelPlanner.countries);
				
				// Initialize Map
				TravelPlanner.Map.init();
				
				// Populate Select field
				var html = '';
				data.sort(function(a, b){
					an = a.name.toLowerCase();
					bn = b.name.toLowerCase();
					if (an<bn) return -1;
					if (an>bn) return 1;
					return 0;
				});
				$.each(data, function(i, d){
					html += '<option value="' + d.id + '">' + d.name + '</option>';
				});
				destinationSelect.append(html).attr('disabled', false);
				destinationSelect.change(function(){
//					$('#itinerary .routes-list').empty();
					$('#itinerary-message').hide();
					var id = destinationSelect.val();
					var optionalSection = $('#add-destination .optional-section');
					if (optionalSection.length && id && TravelPlanner.destinations[id]){
						optionalSection.show();
					} else {
						optionalSection.hide();
					}
				});
				
				// TravelPlanner.generateRoute.init();
				TravelPlanner.pub('loadDestinations');
			},
			error: function(){
				setTimeout(TravelPlanner.loadDestinations, 1000);
			}
		});
	},
	
	loadCurrencies: function(){
		var currencySelect = $('#currency-changer');
		currencySelect.attr('disabled', true);
		var currencies = TravelPlanner.Currency.getCurrencies();
		var html = '';
		$.each(currencies, function(i, c){
			html += '<option value="' + c + '">' + c + '</option>';
		});
		currencySelect.html(html);
		
		// select the TravelPlanner.currency by default
		currencySelect.val(TravelPlanner.currency);
		currencySelect.attr('disabled', false);
	},
	
	flightBestPrices: {},
	
	requestFlightBestPrice: function(data, fn){
		if (data.from && data.to && TravelPlanner.flightBestPrices[data.from + '|' + data.to]){
			var response = TravelPlanner.flightBestPrices[data.from + '|' + data.to];
			fn(response);
		} else {
			$.ajax({
				url: '/api/flight_best_price',
				data: data,
				dataType: 'json',
				success: function(response){
					TravelPlanner.flightBestPrices[data.from + '|' + data.to] = response;
					fn(response);
				},
				error: function(){
					setTimeout(function(){
						TravelPlanner.requestFlightBestPrice(data, fn);
					}, 1000);
				}
			});
		}
	},
	
	requestRoutings: function(data, fn){
		if (!data || !data.from_id || !data.to_id) return;
		console.log('Requesting route from '
			+ TravelPlanner.destinations[data.from_id].name + ' (' + data.from_id + ')'
			+ ' to '
			+ TravelPlanner.destinations[data.to_id].name + ' (' + data.to_id + ')');
		
		$.ajax({
			url: '/api/routings',
			data: data,
			dataType: 'json',
			success: fn,
			error: function(){
				_.delay(TravelPlanner.requestRoutings, data, fn);
			}
		});
	},
	
	requestRoutes: function(data, fn){
		if (!data) return;
		if (data.from_id && data.to_id){
			console.log('Requesting route from '
				+ TravelPlanner.destinations[data.from_id].name + ' (' + data.from_id + ')'
				+ ' to '
				+ TravelPlanner.destinations[data.to_id].name + ' (' + data.to_id + ')');
		}
		$.ajax({
			url: '/api/routes',
			data: data,
			dataType: 'json',
			success: fn,
			error: function(){
				setTimeout(function(){
					TravelPlanner.requestRoutes(data, fn);
				}, 1000);
			}
		});
	},
	
	addDestination: function(id){
		id = parseInt(id, 10);
		if (_.isNaN(id)) return;
		var transport = 'flight';
		
		var uid = TravelPlanner.Utils.genUID();
		TravelPlanner.currentItinerary = 'destination-' + uid;
		
		var destinations = TravelPlanner.Data.destinations;
		var destinationsLen = destinations.length;
		var prevDestination = destinations[destinationsLen-1];
		var destination = TravelPlanner.destinations[id];
		
		var convertAmount = TravelPlanner.Currency.convertAmount;
		
		var done = function(){
			TravelPlanner.pub('addDestination', [id]);
		};
		
		var reqBestPrice = TravelPlanner.requestFlightBestPrice;
		var reqRoutings = TravelPlanner.requestRoutings;
		
		var destinationHash = {
			uid: uid,
			location: {
				id: id,
				name: destination.name,
				country: destination.country,
				airportCode: destination.airportCode,
				hotelLocationCode: destination.hotelLocationCode,
				hotelID: destination.hotelID,
				lat: destination.lat,
				lng: destination.lng
			},
			transport: {
				type: 'flight'
			}
		};
		
		prevDestination.transport.type = transport;
		
		if (destinationsLen == 1){
			
			if (destination.id == prevDestination.location.id){
				TravelPlanner.pub('message', ['error', 'sameDestination']);
				return;
			}
			
			TravelPlanner.currentItinerary = 'homeairport';
			
			var from = prevDestination.location.airportCode || prevDestination.location.hotelLocationCode;
			var to = destination.airportCode || destination.hotelLocationCode;
			
			// referLocation refers to one another. Awesome.
			
			$.extend(destinationHash.transport, {
				from: to,
				to: from,
				referLocation: prevDestination.uid
			});
			
			$.extend(prevDestination.transport, {
				from: from,
				to: to,
				referLocation: uid
			});
			
			// depart date
			var firstDepartDate = $('#add-destination .optional-section .datepicker');
			if (firstDepartDate.length){
				var date = firstDepartDate.datepicker('getDate');
				if (date) prevDestination.transport.departDate = (+date);
			}
			
			// If the destination is in Southeast Asia
			// the to and fro would be one-ways
			// So, have to do TWO best price requests
			if ($.inArray(prevDestination.location.country.toLowerCase(), TravelPlanner.countries) != -1){
				reqBestPrice({
					from: from,
					to: to
				}, function(data){
					$.extend(prevDestination.transport, {
						airlineName: data.onewayAirlineName || null,
						price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
						'return': false
					});
					reqBestPrice({
						from: to,
						to: from
					}, function(data){
						$.extend(destinationHash.transport, {
							airlineName: data.onewayAirlineName || null,
							price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
							'return': false
						});
						destinations.push(destinationHash);
						done();
					});
				});
			} else {
				reqBestPrice({
					from: from,
					to: to
				}, function(data){
					var t = {
						airlineName: data.returnAirlineName || null,
						price: convertAmount(data.returnPrice, TravelPlanner.currency) || null,
						'return': true
					};
					$.extend(prevDestination.transport, t);
					$.extend(destinationHash.transport, t);
					destinations.push(destinationHash);
					done();
				});
			}
			
		} else { // more than one destinations!
			
			var from_id = prevDestination.location.id;
			if (destinationsLen>2 && !!prevDestination.transport['return']) from_id = destinations[destinationsLen-2].location.id;
			
			reqRoutings({
				from_id: from_id,
				to_id: id
			}, function(data){
				if (!data || typeof data != 'object') return;
				if (data.direct){
					run();
				} else if (data.surfaceOnly){
					transport = 'surface';
					prevDestination.transport.type = 'surface';
					run();
				} else if (data.suggest){
					TravelPlanner.pub('message', ['error', 'noDirectFlight', {
						from_id: from_id,
						to_id: id
					}]);
				} else {
					// assume it's same destination
					TravelPlanner.pub('message', ['error', 'sameDestination']);
				}
			});
			
			var run = function(){
				if (destinationsLen == 2){

					if (destination.id == prevDestination.location.id){
						TravelPlanner.pub('message', ['error', 'sameDestination']);
						return;
					}

					var from = prevDestination.location.airportCode || prevDestination.location.hotelLocationCode;
					var to = destination.airportCode || destination.hotelLocationCode;

					// If prev destination is a return type flight
					if (prevDestination.transport['return']){

						prevDestination.transport.type = 'flight';

						var clonePrevDestination = $.extend(true, {}, prevDestination, {
							uid: TravelPlanner.Utils.genUID(),
							transport: {
								// from is the same as prevDestination
								to: to,
								referLocation: null,
								'return': false,
								departDate: null,
								returnDate: null
							}
						});

						// prevDestination becomes the last one
						// and these hotels and activities are already in clonePrevDestination
						prevDestination.hotel = {};
						prevDestination.activities = [];

						if (transport == 'flight'){
							reqBestPrice({
								from: from,
								to: to
							}, function(data){
								$.extend(clonePrevDestination.transport, {
									airlineName: data.onewayAirlineName || null,
									price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null
								});
								reqBestPrice({
									from: to,
									to: from
								}, function(data){
									$.extend(destinationHash.transport, {
										from: to,
										to: from,
										airlineName: data.onewayAirlineName || null,
										price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
										'return': false
									});
									// Adds the two new destinations IN BETWEEN the 2-item array
									// eg: Adding 4 and 5 into [1,9] becomes [1,4,5,9]
									destinations.splice(1, 0, clonePrevDestination, destinationHash);
									done();
								});
							});
						} else {
							$.extend(clonePrevDestination.transport, {
								type: transport,
								airlineName: null,
								price: null
							});
							$.extend(destinationHash.transport, {
								type: transport,
								from: to,
								to: from
							});
							destinations.splice(1, 0, clonePrevDestination, destinationHash);
							done();
						}

					} else {

						$.extend(prevDestination.transport, {
							from: from,
							to: to
						});

						var reqLastToFirst = function(){
							// destinations[0] because this new destination goes back to home airport
							var firstDestination = destinations[0];
							firstDestination.transport.referLocation = null;
							var firstDestinationAirportCode = firstDestination.location.airportCode;
							reqBestPrice({
								from: to,
								to: firstDestinationAirportCode
							}, function(data){
								$.extend(destinationHash.transport, {
									from: to,
									to: firstDestinationAirportCode,
									airlineName: data.onewayAirlineName || null,
									price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
									'return': false
								});
								destinations.push(destinationHash);
								done();
							});
						};

						if (transport == 'flight'){
							reqBestPrice({
								from: from,
								to: to
							}, function(data){
								$.extend(prevDestination.transport, {
									airlineName: data.onewayAirlineName || null,
									price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
									'return': false,
									referLocation: null
								});
								reqLastToFirst();
							});
						} else {
							$.extend(prevDestination.transport, {
								airlineName: null,
								price: null
							});
							reqLastToFirst();
						}

					}

				} else { // more than two destinations!

					var from = prevDestination.location.airportCode || prevDestination.location.hotelLocationCode;
					var to = destination.airportCode || destination.hotelLocationCode;

					// If prev destination is a return type flight
					if (prevDestination.transport['return']){

						prevDestination.transport.type = 'flight';

						var prevPrevDestination = destinations[destinationsLen-2];
						prevFrom = prevPrevDestination.location.airportCode || prevPrevDestination.location.hotelLocationCode;

						// This one is a crazy case.
						// If you want to add a new destination that's the same as the last or second last of destinations,
						// you get zombies eating your brainz!
						if (destination.id == prevDestination.location.id || destination.id == prevPrevDestination.location.id){
							TravelPlanner.pub('message', ['error', 'sameDestination']);
							return;
						}
						
						prevPrevDestination.transport.to = to;
						$.extend(destinationHash.transport, {
							from: to,
							to: from
						});
						
						var reqSecondLastToLast = function(){
							
							var to_id = prevDestination.location.id;
							
							reqRoutings({
								from_id: id,
								to_id: to_id
							}, function(routing){
								if (!routing || typeof routing != 'object') return;
								if (routing.direct){
									reqBestPrice({
										from: to,
										to: from
									}, function(data){
										$.extend(destinationHash.transport, {
											airlineName: data.onewayAirlineName || null,
											price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
											'return': false
										});
										destinations.splice(destinationsLen-1, 0, destinationHash);
										done();
									});
								} else { // defaults to 'surface' if no flights
									$.extend(destinationHash.transport, {
										type: 'surface',
										airlineName: null,
										price: null,
										'return': false
									});
									destinations.splice(destinationsLen-1, 0, destinationHash);
									done();
									if (!routing.surfaceOnly){
										setTimeout(function(){
											TravelPlanner.pub('message', ['error', 'noDirectFlight', {
												from_id: id,
												to_id: to_id
											}]);
										}, 1000);
									}
								}
							});
							
						};

						if (transport == 'flight'){
							reqBestPrice({
								from: prevFrom,
								to: to
							}, function(data){
								$.extend(prevPrevDestination.transport, {
									airlineName: data.onewayAirlineName || null,
									price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
									'return': false
								});
								reqSecondLastToLast();
							});
						} else {
							$.extend(prevPrevDestination.transport, {
								type: transport,
								airlineName: null,
								price: null
							});
							prevDestination.transport.type = 'flight';
							reqSecondLastToLast();
						}

					} else {

						if (destination.id == prevDestination.location.id){
							TravelPlanner.pub('message', ['error', 'sameDestination']);
							return;
						}

						var firstDestinationAirportCode = destinations[0].location.airportCode;
						prevDestination.transport.to = to;
						$.extend(destinationHash.transport, {
							from: to,
							to: firstDestinationAirportCode
						});

						var reqLastToFirst = function(){
							reqBestPrice({
								from: to,
								to: firstDestinationAirportCode
							}, function(data){
								$.extend(destinationHash.transport, {
									airlineName: data.onewayAirlineName || null,
									price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
									'return': false
								});
								destinations.push(destinationHash);
								done();
							});
						};

						if (transport == 'flight'){
							reqBestPrice({
								from: from,
								to: to
							}, function(data){
								$.extend(prevDestination.transport, {
									airlineName: data.onewayAirlineName || null,
									price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
									'return': false
								});
								reqLastToFirst();
							});
						} else {
							$.extend(prevDestination.transport, {
								airlineName: null,
								price: null
							});
							reqLastToFirst();
						}

					}

				}
			};
		}
	},
	
	removeDestination: function(uid){
		if (!uid) return;
		var destinationData = TravelPlanner.Utils.getDestinationByUID(uid, true);
		if (!destinationData) return;
		
		var destination = destinationData.destination;
		var destinations = TravelPlanner.Data.destinations;
		var destLen = destinations.length;
		var index = destinationData.i;
		var firstDestination = destinations[0];
		var lastDestination = destinations[destLen-1];
		
		// If return, destination to be deleted should be second last,
		// else, it's the last one
		var _return = lastDestination.transport['return'];
		if (_return && destLen>2 && index != destLen-2) return;
		if (!_return && index != destLen-1) return;
		
		var arrayErase = TravelPlanner.Utils.arrayErase;
		var reqBestPrice = TravelPlanner.requestFlightBestPrice;
		var convertAmount = TravelPlanner.Currency.convertAmount;
		
		// erase it!
		arrayErase(destinations, destination);
		
		var done = function(){
			TravelPlanner.renderDestinations();
			// force hide the sidebar stuff
			$('#sidebar-intro').show().siblings('.sidebar-item').hide();
			// recalc the total amount
			$('#total-amount').show().find('.amount').text(TravelPlanner.Utils.formatPrice(TravelPlanner.computeTotalAmount()));
			TravelPlanner.Map.resetMap();
		};
		
		if (destLen == 2){
			firstDestination.transport = {
				type: 'flight'
			};
			done();
		} else if (_return && destLen == 4){
			var prevDestination = destinations[index-1];
			var prevTransport = prevDestination.transport;
			$.extend(lastDestination.transport, {
				hotel: prevTransport.hotel,
				activities: prevTransport.activities
			});
			arrayErase(destinations, prevDestination);
			done();
		} else {
			var prevDestination = destinations[index-1];
			
			if (_return){
				prevDestination.transport.to = lastDestination.location.airportCode || lastDestination.location.hotelLocationCode;
				
				var from_id = prevDestination.location.id;
				var to_id = lastDestination.location.id;
				
				// If the destination before and after removed destination is the same??
				if (from_id == to_id){
					$.extend(lastDestination.transport, {
						hotel: prevTransport.hotel,
						activities: prevTransport.activities
					});
					arrayErase(destinations, prevDestination);
					done();
				} else {
					TravelPlanner.requestRoutings({
						from_id: from_id,
						to_id: to_id
					}, function(data){
						if (!data || typeof data != 'object') return;
						if (data.direct){
							reqBestPrice({
								from: prevDestination.location.airportCode,
								to: lastDestination.location.airportCode
							}, function(d){
								$.extend(prevDestination.transport, {
									type: 'flight',
									airlineName: d.onewayAirlineName || null,
									price: convertAmount(d.onewayPrice, TravelPlanner.currency) || null,
									'return': false
								});
								done();
							});
						} else if (data.surfaceOnly){
							$.extend(prevDestination.transport, {
								type: 'surface',
								airlineName: null,
								price: null,
								'return': false
							});
							done();
						} else if (data.suggest){
							done();
							setTimeout(function(){
								TravelPlanner.pub('message', ['error', 'noDirectFlight', {
									from_id: from_id,
									to_id: to_id
								}]);
							}, 1000);
						} else {
							// not sure what will happen here :)
						}
					});
				}
				
			} else {
				prevDestination.transport.to = firstDestination.location.airportCode || firstDestination.location.hotelLocationCode;
				
				if (prevDestination.location.airportCode){
					reqBestPrice({
						from: prevDestination.location.airportCode,
						to: firstDestination.location.airportCode
					}, function(data){
						$.extend(prevDestination.transport, {
							type: 'flight',
							airlineName: data.onewayAirlineName || null,
							price: convertAmount(data.onewayPrice, TravelPlanner.currency) || null,
							'return': false
						});
						done();
					});
				} else {
					$.extend(prevDestination.transport, {
						type: 'surface',
						airlineName: null,
						price: null,
						'return': false
					});
					done();
				}
				
			}
		}
	},
	
	renderDestinations: function(){
		var destinations = TravelPlanner.Data.destinations;
		if (destinations.length < 1) return;
		
		var $homeairport = $('#homeairport');
		$('#itinerary .destination-item').remove();
		$('#add-destination .optional-section').remove();
		$('#add-destination').removeClass('return');
		
		if (destinations.length == 1){
			$('#homeairport .itinerary-items').hide().html('');
			TravelPlanner.pub('renderDestinations');
		} else {
			var pad = TravelPlanner.Utils.padZero;
			var formatPrice = TravelPlanner.Utils.formatPrice;
			var itemsHTML = '';

			var last = destinations.length-1;
			$.each(destinations, function(i, destination){
				var dTransport = destination.transport;
				var airlineName = dTransport.airlineName || '';

				// first destination is the home airport
				if (i == 0){

					var dateClass = 'no-date';
					var year = '';
					var month = '';
					var day = '';
					var bookingURL = '#';
					var date = dTransport.departDate;
					if (date){
						var d = new Date(date);
						dateClass = '';
						year = d.getFullYear();
						var _month = d.getMonth();
						month = TravelPlanner.Utils.getMonthName(_month);
						day = d.getDate();
						var params = {
							siteId: 'sea.org',
							ts_code: 'abaa6',
							cabinClass: 'Economy',
							dateformat: '%d/%m/%Y',
							dateformat_js: 'dd/mm/yy',
							from: dTransport.from,
							origin: dTransport.from,
							to: dTransport.to,
							destination: dTransport.to,
							outboundDate: pad(day) + '/' + pad(_month+1) + '/' + year
						};
						if (dTransport['return']){
							var rDate = dTransport.returnDate;
							if (rDate){
								var rD = new Date(rDate);
								var rYear = rD.getFullYear();
								var rMonth = rD.getMonth();
								var rDay = rD.getDate();
								params.inboundDate = pad(rDay) + '/' + pad(rMonth+1) + '/' + rYear;
							}
						}
						bookingURL = 'http://bookings.southeastasia.org/flights/progress.html?' + $.param(params);
					} else {
						bookingURL = 'http://bookings.southeastasia.org/flights/airfares/' + dTransport.from + '/' + dTransport.to;
						if (!dTransport['return']) bookingURL += '/single-trip-airfares.html';
					}

					var flightAmount = dTransport.price ? formatPrice(TravelPlanner.Currency.convertAmount(dTransport.price, TravelPlanner.currency, TravelPlanner.Data.currency)) : '';
					var html = _.template(TravelPlanner.Templates.itineraryFlight, {
						flightName: dTransport.from + ' to ' + dTransport.to,
						dateClass: dateClass,
						year: year,
						month: month,
						day: day,
						flightType: dTransport['return'] ? 'Return' : 'One-way',
						flightAirlineName: airlineName,
						flightText: airlineName ? 'from' : '',
						flightAmount: flightAmount,
						currency: dTransport.price ? TravelPlanner.currency : '',
						bookingURL: bookingURL,
						hidden: ''
					});

					$homeairport.find('.itinerary-items').html(html).show();

				} else if (last>1 && i==last && destination.transport['return']){

					var lastItemHTML = TravelPlanner.markupDestination(destination, i);
					$('#add-destination').after(lastItemHTML);
					$('#add-destination').next('.destination').andSelf().addClass('return');

				} else {

					itemsHTML += TravelPlanner.markupDestination(destination, i);

				}
			});
			
			$homeairport.after(itemsHTML);
			$('#itinerary').removeClass();
			
			$('#total-amount').show().find('.amount').text(TravelPlanner.Utils.formatPrice(TravelPlanner.computeTotalAmount()));
			
			TravelPlanner.pub('renderDestinations');
			
			TravelPlanner.pub('focusItineraryDestination', [TravelPlanner.currentItinerary]);
		}
	},
	
	computeTotalAmount: function(returnObj){
		var destinations = TravelPlanner.Data.destinations;
		var actualTotal = 0;
		var total = 0;
		var plus = false;
		
		var l = destinations.length-1;
		$.each(destinations, function(i, destination){
			if (destination.transport.price){
				if (i<l || !destination.transport['return']){
					var price = parseFloat(destination.transport.price, 10);
					actualTotal += price;
					total += Math.round(price);
				}
			} else {
				plus = true;
			}
			if (destination.hotel && destination.hotel.price){
				var price = parseFloat(destination.hotel.price, 10) * destination.hotel.nights;
				actualTotal += price;
				total += Math.round(price);
			} else {
				plus = true;
			}
		});
		
		if (returnObj){
			return {
				actualTotal: actualTotal,
				total: total,
				plus: plus
			};
		}
		
		return total;
	},
	
	markupDestination: function(destination, i){
		var dTransport = destination.transport;
		var airlineName = dTransport.airlineName || '';

		var pad = TravelPlanner.Utils.padZero;
		var convertAmount = TravelPlanner.Currency.convertAmount;
		var formatPrice = TravelPlanner.Utils.formatPrice;
		
		var content = '';
		
		if (destination.hotel && destination.hotel.name){
			var hotel = destination.hotel;
			var price = hotel.price ? formatPrice(convertAmount((hotel.price * hotel.nights), TravelPlanner.currency, TravelPlanner.Data.currency)) : '';
			var text = hotel.nights + ' night' + (hotel.nights>1 ? 's' : '') + (price ? ' from ' : '');
			
			var dateClass = 'no-date';
			var year = '';
			var _month = '';
			var month = '';
			var day = '';
			var date = hotel.checkInDate;
			if (date){
				var d = new Date(date);
				dateClass = '';
				year = d.getFullYear();
				_month = d.getMonth();
				month = TravelPlanner.Utils.getMonthName(_month);
				day = d.getDate();
			}
			
			var bookingURL = '#';
			var params = {
				reqDomain: 'www.wego.com',
				reqFrom: 'hotels',
				reqTo: 'search/create',
				ts_code: 'abaa6',
				wg_location_code_hotels: destination.location.hotelLocationCode,
				wg_location_id_hotels: destination.location.hotelID,
				wg_rooms: 1,
				wg_guests: 1,
				wg_star_rating: 'Any',
				wg_origin_hotels: destination.location.name + ', ' + destination.location.country
			};
			if (date){
				var nights = destination.location.nights || 3;
				var outDate = new Date(date + (nights*24*60*60*1000)); // miliseconds
				$.extend(params, {
					wg_checkIn_date: pad(day) + '/' + pad(_month+1) + '/' + year,
					wg_checkOut_date: pad(outDate.getDate()) + '/' + pad(outDate.getMonth()+1) + '/' + outDate.getFullYear()
				});
			}
			bookingURL = 'http://bookings.southeastasia.org/widgets/searchbox?' + $.param(params);
			
			content += _.template(TravelPlanner.Templates.itineraryHotel, {
				dateClass: dateClass,
				year: year,
				month: month,
				day: day,
				hotelName: TravelPlanner.Utils.wrapText(hotel.name, 29),
				hotelTitle: hotel.name,
				hotelText: text,
				hotelAmount: price,
				currency: price ? TravelPlanner.currency : '',
				bookingURL: bookingURL
			});
		}
		
		if (destination.activities && destination.activities.length){
			$.each(destination.activities, function(i, activity){
				content += _.template(TravelPlanner.Templates.itineraryActivity, {
					activityName: activity.name
				});
			});
		}
		
		var dateClass = 'no-date';
		var year = '';
		var _month = '';
		var month = '';
		var day = '';
		if (dTransport['return']){ // the last destination could be a return type flight
			var date = dTransport.returnDate;
			if (date){
				var d = new Date(date);
				dateClass = '';
				year = d.getFullYear();
				_month = d.getMonth();
				month = TravelPlanner.Utils.getMonthName(_month);
				day = d.getDate();
			}
		} else {
			var date = dTransport.departDate;
			if (date){
				var d = new Date(date);
				dateClass = '';
				year = d.getFullYear();
				_month = d.getMonth();
				month = TravelPlanner.Utils.getMonthName(_month);
				day = d.getDate();
			}
		}
		
		switch (destination.transport.type){
			default:
			case 'flight':
				var bookingURL = '#';
				var date = dTransport.departDate;
				if (date){
					var params = {
						siteId: 'sea.org',
						ts_code: 'abaa6',
						cabinClass: 'Economy',
						dateformat: '%d/%m/%Y',
						dateformat_js: 'dd/mm/yy',
						from: dTransport.from,
						origin: dTransport.from,
						to: dTransport.to,
						destination: dTransport.to,
						outboundDate: pad(day) + '/' + pad(_month+1) + '/' + year
					};
					if (dTransport['return']){
						var rDate = dTransport.returnDate;
						if (rDate){
							var rD = new Date(rDate);
							var rYear = rD.getFullYear();
							var rMonth = rD.getMonth();
							var rDay = rD.getDate();
							params.inboundDate = pad(rDay) + '/' + pad(rMonth+1) + '/' + rYear;
						}
					}
					bookingURL = 'http://bookings.southeastasia.org/flights/progress.html?' + $.param(params);
				} else {
					bookingURL = 'http://bookings.southeastasia.org/flights/airfares/' + dTransport.from + '/' + dTransport.to;
					if (!dTransport['return']) bookingURL += '/single-trip-airfares.html';
				}
				
				var _return = dTransport['return'];
				
				content += _.template(TravelPlanner.Templates.itineraryFlight, {
					flightName: dTransport.from + ' to ' + dTransport.to,
					dateClass: dateClass,
					year: year,
					month: month,
					day: day,
					flightType: dTransport['return'] ? 'Return' : 'One-way',
					flightAirlineName: _return ? '' : airlineName,
					flightText: _return ? '' : (airlineName ? 'from' : ''),
					flightAmount: _return ? '' : (dTransport.price ? formatPrice(convertAmount(dTransport.price, TravelPlanner.currency, TravelPlanner.Data.currency)) : ''),
					currency: _return ? '' : (dTransport.price ? TravelPlanner.currency : ''),
					bookingURL: _return ? '' : bookingURL,
					hidden: _return ? 'hidden' : ''
				});
				break;
				
			case 'surface':
				content += _.template(TravelPlanner.Templates.itinerarySurface, {
					surfaceName: dTransport.from + ' to ' + dTransport.to,
					dateClass: dateClass,
					year: year,
					month: month,
					day: day,
					surfaceAmount: dTransport.price ? formatPrice(dTransport.price) : '',
					currency: dTransport.price ? TravelPlanner.currency : ''
				});
				break;
		}
		
		return _.template(TravelPlanner.Templates.itinerary, {
			uid: destination.uid,
			i: i,
			destinationName: destination.location.name + ', ' + destination.location.country,
			content: content
		});
	},
	
	updateDestination: function(uid){
		if (!uid) return;
		
		var section = $('#destination-' + uid);
		if (!section.length) return;
		
		var destination = TravelPlanner.Utils.getDestinationByUID(uid);
		if (destination == null) return;
		
		var heading = section.find('h3 strong[class]');
		var i = heading.attr('class').split('-')[1];
		
		var html = TravelPlanner.markupDestination(destination, i);
		section.after(html);
		section.remove();

		$('#total-amount').show().find('.amount').text(TravelPlanner.Utils.formatPrice(TravelPlanner.computeTotalAmount()));

		// reset filters:
		$('#itinerary').removeClass();
		TravelPlanner.pub('updateDestination');
		TravelPlanner.pub('focusItineraryDestination', ['destination-' + uid, true]);
		
		TravelPlanner.highlightDestination(uid);
	},
	
	highlightDestination: function(uid){
		if (!uid) return;
		var destination = $('#destination-' + uid);
		if (!destination.length) destination = $('#homeairport');
		destination.find('.itinerary-items').effect('highlight');
	},
	
	loadTrip: function(data){
		if (!data) data = TravelPlanner.Data;
		if (typeof data == 'string') data = $.secureEvalJSON(data);
		if (!data.destinations || !data.destinations.length) return;
		
		// If everything is valid, assign back
		TravelPlanner.Data = data;
		
		var destinations = TravelPlanner.Data.destinations;
		
		// Some cleaning up
		var firstDest = destinations[0];
		var firstLoc = firstDest.location;
		TravelPlanner.setHomeAirport = TravelPlanner.hasHomeFlight = true;
		$('#homeAirportText').text(firstLoc.name + ', ' + firstLoc.country);
		$('#homeAirportField').val(firstLoc.name).focus().click().blur(); // some magic for autocomplete to do magic.
		$('#homeairport .homeairport-field').hide();
		$('#add-destination').show();
		$('#itinerary .destinations').removeClass('no-timeline');
		TravelPlanner.currency = TravelPlanner.Data.currency;
		$('#currency-changer').val(TravelPlanner.currency).trigger('change');
		$('#trip-title').val(data.name);
		
		TravelPlanner.renderDestinations();
		TravelPlanner.Map.resetMap();
	}
	
	/*
	markupRoutes: function(data){
		if (!data || !data.length) return;
		
		var destinations = TravelPlanner.destinations;
		var html = '<ul>';
		$.each(data, function(i, dat){
			html += '<li><a href="#" data-route="' + data.toString() + '">';
			$.each(dat, function(i, d){
				var dest = destinations[d];
				if (d>=0){
					html += '<strong title="' + dest.airportCode + '">' + dest.name + '</strong> ';
				} else {
					html += '<img src="icon-' + TravelPlanner.routeTypes[d] + '.png" alt="&rarr;"> ';
				}
			});
			html += '</a></li>';
		});
		html += '</ul>';
		return html;
	},
	
	getDestinationsFromRoute: function(route, outputString){
		if (!route || !route.length) return;
		
		var _route = route.slice(1);
		var r = [];
		var ro = [];
		for (var i=0, j=0, l=_route.length; i<l; i+=2, j++){
			r[j] = {
				destination: _route[i+1],
				transport: _route[i]
			};
			ro[j] = _route[i+1] + ':' + _route[i];
		}
		
		if (outputString) return ro.join('|');
		
		return r;
	}
	*/
});

TravelPlanner.Utils = {
	
	genUID: function(){
		return (+new Date()).toString(36);
	},
	
	getCurrentUID: function(){
		var currentItinerary = TravelPlanner.currentItinerary.split('-');
		if (currentItinerary.length > 1){
			return currentItinerary[1];
		}
		return null;
	},

	getDestinationIndex: function(destination){
		var destinations = TravelPlanner.destinations;
		var index = 0;
		$.each(destinations, function(i, d){
			if (d.name.toLowerCase() === destination.toLowerCase()) index = i;
		});
		return index;
	},

	getDestinationByUID: function(uid, full){
		if (!uid) return;
		var destinations = TravelPlanner.Data.destinations;
		for (var i=0, l=destinations.length; i<l; i++){
			var d = destinations[i];
			if (d.uid == uid){
				if (full){
					return {
						i: i,
						destination: d
					};
				} else {
					return d;
				}
			}
		}
		return null;
	},
	
	wrapText: function(str, limit, wordWrap){
		if (str.length > limit) str = $.trim(str.substr(0, limit-3)) + '...';
		if (wordWrap){
			words = str.split(' ');
			words.pop();
			str = words.join(' ') + '...';
		}
		return str;
	},
	
	formatPrice: function(strValue, showCents){
		strValue = strValue.toString().replace(/\$|\,/g, '');
		var dblValue = parseFloat(strValue);
		
		var blnSign = (dblValue == (dblValue = Math.abs(dblValue)));
		dblValue = Math.floor(dblValue * 100 + 0.50000000001);
		var intCents = dblValue % 100;
		var strCents = intCents.toString();
		dblValue = Math.floor(dblValue/100);
		if (!showCents && intCents>=50) dblValue++;
		dblValue = dblValue.toString();
		if (intCents<10) strCents = '0' + strCents;
		for (var i=0, l=Math.floor((dblValue.length-(1+i))/3); i<l; i++){
			var s = dblValue.length - (4 * i + 3);
			dblValue = dblValue.substring(0, s) + ',' + dblValue.substring(s);
		}
		var price = (blnSign ? '' : '-') + dblValue;
		if (showCents) price += '.' + strCents;
		return price;
	},
	
	monthNames: 'jan feb mar apr may jun jul aug sep oct nov dec'.split(' '),
	
	getMonthName: function(num){
		return TravelPlanner.Utils.monthNames[num];
	},
	
	padZero: function(str){
		str = '' + str; // convert to string
		if (str.length == 1) str = '0' + str;
		return str;
	},
	
	arrayUnique: function(arr){
		var a = [];
		var l = arr.length;
		for(var i=0; i<l; i++) {
			for(var j=i+1; j<l; j++) {
				// If this[i] is found later in the array
				if (arr[i] === arr[j]) j = ++i;
			}
			a.push(arr[i]);
		}
		return a;
	},
	
	arrayErase: function(arr, item){
		for (var i = arr.length; i--; i){
			if (arr[i] === item) arr.splice(i, 1);
		}
		return arr;
	}
	
};

TravelPlanner.Currency = {

	getCurrencies: function(){
		return 'AUD GBP CAD CNY EUR HKD INR IDR ILS JPY KRW MYR NZD PKR PHP RUB SAR SGD ZAR SEK CHF TWD THB USD AED VND'.split(' ');
	},
	
	convertAmount: function(amount, toCurrency, fromCurrency){
		if (!exchangeRates || !amount || !toCurrency) return false;
		if (!fromCurrency) fromCurrency = 'USD';
		if (fromCurrency == toCurrency) return amount; // incase something weird happens

		if (fromCurrency !== 'USD') amount = amount/exchangeRates[fromCurrency];
		
		var convertedAmount = amount * exchangeRates[toCurrency];
		
		return Math.round(convertedAmount*100)/100;
	},

	// currency convert class set
	convertClass: function(classPrice, classCurrency, toCurrency){
		if (!exchangeRates || !classPrice || !toCurrency || !classCurrency) return false;

		var amount = 0;
		var elPrice = $(classPrice);
		var elCurrency = $(classCurrency);
		var fromCurrency = elCurrency.eq(0).html();

		$.each(elPrice, function(i, el){
			el = $(el);
			amount = parseFloat(el.html());

			if (!isNaN(amount)) amount = TravelPlanner.Currency.convertAmount(amount, toCurrency, fromCurrency);
			el.html(amount);
		});

		$.each(elCurrency, function(i, el){
			el = $(el);
			currency = el.html();
			if (currency.length>0) el.html(toCurrency);
		});

		return;
	}	
};

// Console
if (!window.console){
	var names = 'log debug info warn error assert dir dirxml group groupEnd time timeEnd count trace profile profileEnd'.split(' ');
	window.console = {};
	for (var i=names.length; i--; i) window.console[names[i]] = function(){};
}

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

})(jQuery);

