// Requires jQuery

function Roundtrip (depCity, destCity, depDate, retDate, settings) {
// Default options
var options = {
	flightbox_div: "flightbox_content",
	template: "dateliner",
	tpl_dir: "components/templates/",
	func_dir: "../common/ajax/",
	lang: "en",
	currency: "EUR",
	currency_symbol: "€",
	data_mode: "release", 
	data_filter: "", 
	onClick: function () {},
	view_days: 19,
	diff_days: 2,
	view_flights: 10,
	num_prices: 5,
	day_height : 15
};
var menu_info = {
	loading: "loading",
	price: "slider-price",
	priceInput: "priceInput",
	sourcemenu: "sourcemenu"
}
// Internal variables
var loadingEl;
var that = this;
var config = {};
var elm = {};
var descr_base = "";
var flightbox_html = "";
var dom = new DT_DOM(depDate, retDate);
var showNum;
var flights = [];
var flights_sel = [];
var sources = [];
var filters = {};
var status_text = [];
var status_priority = {"check": 0, "recheck": 1, "ready": 1, "loading": 2, "finish": 3};

// Internal functions
function init () {
	that.setOptions(settings);
	filters.ranges = {dep: options.diff_days, ret: options.diff_days};
	
	loadingEl = $("#"+menu_info.loading);
	loadConfig();
}
function loadConfig () {
	$.ajax({async: false, type: "GET", url: options.tpl_dir+options.template+"/config.js.php", data: {lang: options.lang}, dataType: "json", success: function (json) {
		config = json;
		status_text = [config.LANGTEXT.checking_flights, config.LANGTEXT.loading_flights, config.LANGTEXT.loading_flights, ""];
		
	}, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#error-infos').append('<p>'+"ERROR loading config: "+textStatus+"\n"+XMLHttpRequest.responseText+'</p>');}
	});
}
function loadDOMtpl () {
	$.ajax({async: false, type: "GET", dataType: "html", url: options.tpl_dir+options.template+"/flightbox.tpl.html", success: function (html) {
		flightbox_html = html;
		dom.init($("#"+options.flightbox_div), flightbox_html, {diff_days: options.diff_days, view_days: options.view_days, word_day: config.LANGTEXT.word_day, word_month: config.LANGTEXT.word_month, day_height: options.day_height, lang: options.lang, currency: options.currency_symbol});
	}, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#error-infos').append('<p>'+textStatus+'</p>');}});
	
	$.ajax({async: false, type: "GET", dataType: "html", url: options.tpl_dir+options.template+"/day.elm.tpl.html", success: function (html) {
		elm.day = html;
		dom.dayAxis(elm.day);
	}, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#error-infos').append('<p>'+textStatus+'</p>');}});
	
	$.ajax({async: false, type: "GET", dataType: "html", url: options.tpl_dir+options.template+"/color.elm.tpl.html", success: function (html) {
		elm.color = html;
		dom.setColorAxis(config.color_axis.from.color, config.color_axis.to.color, config.color_axis.from.value, config.color_axis.to.value);
		dom.drawColorBar(elm.color, config.color_axis.bins);
	}, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#error-infos').append('<p>'+textStatus+'</p>');}});
	
	$.ajax({type: "GET", dataType: "html", url: options.tpl_dir+options.template+"/flight.elm.tpl.html", success: function (html) {
		elm.flight = html;
	}, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#error-infos').append('<p>'+textStatus+'</p>');}});
	
	$.ajax({type: "GET", dataType: "html", url: options.tpl_dir+options.template+"/description.tpl.html", success: function (html) {
		elm.descr = html;
	}, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#error-infos').append('<p>'+textStatus+'</p>');}});
	
	$.ajax({type: "GET", dataType: "html", url: options.tpl_dir+options.template+"/price.elm.tpl.html", success: function (html) {
		elm.price = html;
	}, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#error-infos').append('<p>'+textStatus+'</p>');}});
}
/*function buildFlightbox () {
	dom.init($("#flightbox_content"), flightbox_html, {diff_days: options.diff_days});
	dom.dayAxis(elm.day);
	
}
*/function loadFlights () {
	calcFlights();
	for (i in sources) {
		var elm_div = $("<li class='menublock enable' id='suppliers_sel-"+sources[i].id+"'> - "+sources[i].name+" <span class='numFlights'</span><div class='loading_status'></div></li>");
		$("#"+menu_info.sourcemenu+" ul").append(elm_div);
		checkSource(i);
	}
}
function calcFlights () {
	$.ajax({async: false, type: "GET", url: options.func_dir+"calcflights.ajax.php", data: {
		   ajaxKey: ajaxKey,
		   depCity: depCity,
		   destCity: destCity,
		   depDate: depDate.toDateString(),
		   retDate: retDate.toDateString(),
		   D_days: options.diff_days,
		   mode: options.data_mode,
		   currency: options.currency
		},
		dataType: "json", success: function (json) {
			sources=json;
		}, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#error-infos').append('<p>'+textStatus+'</p>');}
	});
}
function checkSource (source, ref) {
	if (ref!=null) ref=null;
	updateStatus();
	outputState(config.LANGTEXT.checking_flights, $("#suppliers_sel-"+sources[source].id));
	$.ajax({async: true, type: "GET", url: options.func_dir+"checkstatus.ajax.php", dataType: "json", data: {
			ajaxKey: ajaxKey,
			filter: options.data_filter,
			id: sources[source].id
		},
		success: function(json) {
			sources[source].status = json.status;
			if (json.FlightsList !== null && json.FlightsList.length > 0) parseFlights(json.FlightsList, source);
			updateStatus();
			if (json.status != "finish") {
				var refname="checkTM_"+new Date().valueOf();
				eval("var "+refname+"=new checkSourceTimeout("+source+");");
				eval(refname+".timeout();");
			} else {
				outputState("", $("#suppliers_sel-"+sources[source].id));
			}
		}, error: function (XMLHttpRequest, textStatus, errorThrown) {$('#error-infos').append('<p>'+"Error update (roundtrip) flights status ("+textStatus+"):\n"+XMLHttpRequest.responseText+"EOF"+'</p>');}
	});
}
function checkSourceTimeout (source) { // workaround to use setTimeout with parameters
	var that=this;
	this.timeout = function () {
		setTimeout(callCheckSource,5000);
	}
	function callCheckSource () {
		checkSource(source,that);
	}
};
/*function loadSource (source) {
	if (sources[source].status == "ready" || sources[source].status == "recheck") {
		sources[source].status = "loading";
		updateStatus();
		outputState(config.LANGTEXT.loading_flights, $("#suppliers_sel-"+sources[source].id));
		$.ajax({async: true, type: "GET", url: options.func_dir+"loadflights.ajax.php", data: {
			ajaxKey: ajaxKey,
			id: sources[source].id,
			sessid: sources[source].sessid
		},
		dataType: "json", success: function (json) {
			parseFlights(json, source);
		}, error: function (XMLHttpRequest, textStatus, errorThrown) {alert("Error loading roundtrip flights ("+textStatus+"):\n"+XMLHttpRequest.responseText+"EOF"); var debug_div = $("<div>"+"Error loading flights ("+textStatus+"):<br />"+XMLHttpRequest.responseText+"</div>"); $("#flightbox_content").append(debug_div);}
	});
	} else if (sources[source].status == "check") {
		checkSource(source);
	}
}*/
function parseFlights(data, source, recheck) {
	var num_flights = data.length;
	$.merge(flights, data);
	flights = array_unique(flights , compareUnique_str);
	outputTotalFlights(sources[source].id, num_flights);
	if (flights.length > 0) {
		var max_p = getPriceMax(flights);
		var min_p = getPriceMin(flights);
		filters.price = {from: min_p, to: max_p, min: min_p, max: max_p};
		that.syncMenu();
		drawFlights();
	}
	/*if (recheck == null || recheck == false) {
		sources[source].status = "finish";
		updateStatus();
		outputState("", $("#suppliers_sel-"+sources[source].id));
	}*/

	//alert("I loaded "+data.length+" flights");
}
function drawFlights () {
	var f_sel = [];
	
	var max_price = 0;
	var min_price = -1;
	for (i in flights) {
		var dep = new Date(Date.parse(flights[i].dep_takeoff));
		var ret = new Date(Date.parse(flights[i].ret_takeoff));
		if (Math.abs(dep.diff(depDate)) <= filters.ranges.dep && Math.abs(ret.diff(retDate)) <= filters.ranges.ret) { // check days range
			// start time range check
			var timedepcheck = false;
			if (filters.timedep == null) {
				timedepcheck = true;
			} else {
				for (n in filters.timedep) {
					if (dep.getUTCHours() >= filters.timedep[n].from && dep.getUTCHours() <= filters.timedep[n].to) {
						timedepcheck = true;
						break;
					}
				}
			}
			
			var timeretcheck = false;
			if (filters.timeret == null) {
				timeretcheck = true;
			} else {
				for (n in filters.timeret) {
					if (ret.getUTCHours() >= filters.timeret[n].from && ret.getUTCHours() <= filters.timeret[n].to) {
						timeretcheck = true;
						break;
					}
				}
			}
			// end time range check

			
			if (timedepcheck && timeretcheck) { // check time range
				if (min_price == -1) min_price = flights[i].price;
				if (flights[i].price > max_price) max_price = flights[i].price;
				if (flights[i].price < min_price) min_price = flights[i].price;
				if (flights[i].price >= filters.price.from && flights[i].price <= filters.price.to) { // check price range
					f_sel.push(flights[i]);
				}
			}
		}
	}
	showNum = Math.min(options.view_flights, f_sel.length);

	dom.cleanFlights();
	if (showNum>0) {
		f_sel.sort(sortByPrice);
		while (f_sel[0].price >= f_sel[showNum-1].price-1) showNum += 1;

		dom.setPriceAxis(getPriceMax(f_sel, showNum), 310, getPriceMin(f_sel), 10);
		dom.drawPriceAxis(elm.price, options.currency_symbol.toUpperCase(), options.num_prices, 0.2);
		
		filters.price.max = max_price;
		filters.price.min = min_price;		
		that.syncMenu();
		
		var bestExact = false;
		var displayed = 0;
		for (var i=0;i<showNum;i++) {
			var dep = new Date(Date.parse(f_sel[i].dep_takeoff));
			var ret = new Date(Date.parse(f_sel[i].ret_takeoff));
			var spec_class = (i==0 && f_sel[0] == flights[0]) ? "best" : "";
			if (!bestExact && Math.abs(dep.diff(depDate)) == 0 && Math.abs(ret.diff(retDate)) == 0) {
				spec_class = "bestExact";
				bestExact = true;
			}
			result = dom.addFlight(f_sel[i], elm.flight, elm.descr, spec_class, options.onClick);
			if ( result ) displayed += 1;
		}
		
		dom.flights_summary.html(displayed+" "+config.LANGTEXT.cheapest+" "+config.LANGTEXT.of+" "+f_sel.length+" "+config.LANGTEXT.prices);
	}
}


/* Menu / Filters update */
var updatefilters = {
	price: function (values) {
		if (values.from > 0) filters.price.from = values.from;
		if (values.to > 0 && values.to > values.from) filters.price.to = values.to;
		filters.price.edited = true;
	},
	timedep: function (values) {
		updatetime("timedep", values);
	},
	timeret: function (values) {
		updatetime("timeret", values);
	},
	ranges: function (values) {
		if (values.dep >= 0) filters.ranges.dep = values.dep;
		if (values.ret >= 0) filters.ranges.ret = values.ret;		
	}
	
};
function updatetime (_type, values) {
	if (values !== null && typeof values.type == "object") {
		
		filters[_type] = [];
		var _from;
		var oldtime = null;
		for (i in values.type) {
			if (i != "anytime" && values.type[i]) {
				for (j in values.hours) {
					if (values.hours[j] > 0) {
						var time = (values.hours[j] == 12) ? values.hours[j]-1 : values.hours[j];
						time = (i == "pm") ? time+12 : time;
						
						if (oldtime !== null && oldtime+1 == time) {
							oldtime = time;
						} else if (oldtime !== null) {
							filters[_type].push({from: _from, to: time});
							oldtime = null;
						} else {
							_from = time;
							oldtime = time;
						}
					}
					
				}
				
			}
		}
		if (oldtime !== null) {
			filters[_type].push({from: _from, to: time});
		}
		
		if (values.type.anytime !== null && values.type.anytime) {
			filters[_type] = null;
			//return;
		}

	}
}

function updatemenu () {
	// Update price menu
	$("#"+menu_info.price).slider('option', 'min', filters.price.min); // was getPriceMin(flights)
	$("#"+menu_info.price).slider('option', 'max', filters.price.max); // was getPriceMax(flights, true)
	
	if (filters.price.edited == null || !filters.price.edited) { // only update the slider's values if the user didn't touch them, otherwise it keeps the user value!
		$("#"+menu_info.price).slider('values', 0, filters.price.from);
		$("#"+menu_info.price).slider('values', 1, filters.price.to);
		$("#"+menu_info.price).slider('enable');
		$("#"+menu_info.priceInput).val(options.currency_symbol + $("#"+menu_info.price).slider("values", 0) + ' - '+ options.currency_symbol + $("#"+menu_info.price).slider("values", 1));
		filters.price.edited = false;
	} else {
		updatefilters.price({from: $("#"+menu_info.price).slider("values", 0), to: $("#"+menu_info.price).slider("values", 1)});
	}
		$("#"+menu_info.price).slider('values', 0, $("#"+menu_info.price).slider('values', 0));
		$("#"+menu_info.price).slider('values', 1, $("#"+menu_info.price).slider('values', 1));
		$("#"+menu_info.priceInput).val(options.currency_symbol + $("#"+menu_info.price).slider("values", 0) + ' - ' +options.currency_symbol + $("#"+menu_info.price).slider("values", 1));

}

/* Output function */
function outputState (text, div) {
	var el;
	if (div == null) {
		el = loadingEl;
	} else {
		el = $(".loading_status", div);
	}
	if (text != "") {
		el.html(text).show(); // +" <img src='"+config.loading_img+"' alt='Loading' style='vertical-align:bottom;' />"
		if (div != null) div.removeClass("editing");
	} else {
		el.html("").hide();
		if (div != null) div.addClass("editing");
	}
}
function outputTotalFlights (idSource, tot) {
	var el = $("#suppliers_sel-"+idSource+" span.numFlights");
	if (tot > 0) el.html("("+tot+")");
	else el.html("");
	
}
function updateStatus() {
	var priority = 99;
	for (i in sources) {
		if (status_priority[sources[i].status] !== null && status_priority[sources[i].status] < priority) priority = status_priority[sources[i].status];
	}
	outputState(status_text[priority]);
}

// Max, min functions
function getPriceMin (f) {
	var tmp = f.slice(0);
	tmp.sort(sortByPrice);
	return tmp[0].price;
}
function getPriceMax (f, max_num) {
	var tmp = f.slice(0);
	tmp.sort(sortByPrice);
	return (max_num==null || max_num<=0) ? tmp[tmp.length-1].price : tmp[max_num-1].price;
}
function getTimeMin (f) {
	var tmp = f.slice(0);
	tmp.sort(sortByFlighttime);
	return tmp[0].flightTime;
}
function getTimeMax (f, absolute) {
	var tmp = f.slice(0);
	tmp.sort(sortByFlighttime);
	return (absolute) ? tmp[tmp.length-1].flightTime : tmp[showNum-1].flightTime;
}

// Sort functions
function sortByPrice(a, b) {
    var x = a.price;
    var y = b.price;
    return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}
function sortFlighttime(a, b) {
    var x = a.flightTime;
    var y = b.flightTime;
    return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

// Unique comparisons
function compareUnique_str (original, newelement) {
	if (original.unique_str != newelement.unique_str) return false;
	original.others.push({supplier: newelement.supplier, price: newelement.price, CabinClass: newelement.CabinClass, BookingClass: newelement.BookingClass});
	for (i in newelement.others) {
		original.others.push(newelement.others[i]);
	}
	return true;
}


// Public functions
this.startLoading = function () {
	outputState(config.LANGTEXT.loading+" "+config.LANGTEXT.graphics);
	loadDOMtpl();
	outputState("");
	loadFlights();

}
this.setMenu = function (settings) {
	$.extend(menu_info, settings);
}

this.syncMenu = function (changes) {
	if (changes == null) {
		updatemenu();
	} else {
		for (i in changes) {
			updatefilters[i](changes[i]);
		}
		if (flights.length > 0) drawFlights();
	}
}

this.setOptions = function (settings) {
	$.extend(options, settings);
};


// Class constructor
init();
}


