// Callsign always has focus on load
$("#callsign").focus();

var sessiondata={};
$(document).ready(async function () {
	sessiondata=await getSession();			// save sessiondata global (we need it later, when adding qso)
	await restoreContestSession(sessiondata);	// wait for restoring until finished
	setRst($("#mode").val());
	$('#contestname').val($('#contestname_select').val());

	// Clear the localStorage for the qrg units
	localStorage.clear();
	set_qrg();
	qrg_inputtype();

	// Storing the contestid in contest session
	$('#contestname, #copyexchangeto, #exchangesequence_select, #band, #mode, #frequency, #radio').change(function () {
		var formdata = new FormData(document.getElementById("qso_input"));
		setSession(formdata);
	});

	// Storing the exchange type in contest session
	$('#exchangetype').change(function () {
		var exchangetype = $("#exchangetype").val();
		setExchangetype(exchangetype);
		var formdata = new FormData(document.getElementById("qso_input"));
		setSession(formdata);
	});
});

// Always update the contestname
$('#contestname_select').change(function () {
	$('#contestname').val($('#contestname_select').val());
});

function disabledContestnameSelect(disabled) {
	if (disabled) {
		$("#contestname_select")
			.prop('disabled', true)
			.attr({
				'title': lang_contestname_warning,
				'data-bs-toggle': 'tooltip',
				'data-bs-html': 'true',
				'data-bs-placement': 'top'
			})
			.tooltip();
	} else {
		$("#contestname_select")
			.prop('disabled', false)
			.removeAttr('title data-bs-toggle data-bs-html data-bs-placement')
			.tooltip('dispose');
	}
}

function reset_dialog() {
	BootstrapDialog.confirm({
			title: lang_general_word_danger,
			message: lang_contest_reset_session,
			type: BootstrapDialog.TYPE_DANGER,
			closable: true,
			draggable: true,
			btnOKClass: 'btn-danger',
			callback: function(result) {
				if(result) {
					reset_contest_session();
				}
			}
	});
}

// Resets the logging form and deletes session from database
async function reset_contest_session() {
	await $.ajax({
		url: base_url + 'index.php/contesting/deleteSession',
		type: 'post',
		success: function (data) {

		}
	});
	// the user is now allowed again to change the contest name
	disabledContestnameSelect(false);
	// reset the form
	$('#name').val("");
	$('.callsign-suggestions').text("");
	$('#callsign').val("");
	$('#comment').val("");

	$("#exch_serial_s").val("1");
	$("#exch_serial_r").val("");
	$('#exch_sent').val("");
	$('#exch_rcvd').val("");
	$("#exch_gridsquare_r").val("");

	$("#callsign").focus();
	setRst($("#mode").val());
	$("#exchangetype").val("None");
	setExchangetype("None");
	$("#contestname_select").val("Other").change();
	$(".contest_qso_table_contents").empty();
 	$('#copyexchangeto').val("None");

	if (!$.fn.DataTable.isDataTable('.qsotable')) {
		$.fn.dataTable.moment('DD-MM-YYYY HH:mm:ss');
		$('.qsotable').DataTable({
			"stateSave": true,
			"pageLength": 25,
			responsive: false,
			"scrollY": "400px",
			"scrollCollapse": true,
			"paging": false,
			"scrollX": true,
			"language": {
				url: getDataTablesLanguageUrl(),
			},
			order: [0, 'desc'],
			"columnDefs": [
				{
					"render": function ( data, type, row ) {
						return row[8] !== null && row[8] !== '' ? pad(row[8], 3) : '';
					},
					"targets" : 8
				},
				{
					"render": function ( data, type, row ) {
						return row[9] !== null && row[9] !== '' ? pad(row[9], 3) : '';
					},
					"targets" : 9
				}
			]
		});
	}
	var table = $('.qsotable').DataTable();
	table.clear();

}

function sort_exchange() {

	// Get the selected sequence
	let exchangeSelect = $('#exchangesequence_select');

	// If the sequence is not set, we need to set one to prevent errors
	if (!exchangeSelect.val()) {
		exchangeSelect.val('s-g-e');
	}

	// Split the squence into an array
	let selectedOrder = exchangeSelect.val().split('-');

	// Map sequence to corresponding SENT elements
	let mapping = {
		"g": ".gridsquares",
		"s": ".serials",
		"e": ".exchanges",
	};

	// Reorder the elements in the DOM
	selectedOrder.forEach(function(item) {
		$('#sent_exchange').append($(mapping[item]));
	});

	// Map sequence to corresponding RECEIVED elements
	mapping = {
		"g": ".gridsquarer",
		"s": ".serialr",
		"e": ".exchanger",
	};

	// Reorder the elements in the DOM
	selectedOrder.forEach(function(item) {
		$('#rcvd_exchange').append($(mapping[item]));
	});
}

// Change the sequence of the exchange fields
$('#exchangesequence_select').change(function () {
	sort_exchange();
});

// Show Settings modal on click
$('#moreSettingsButton').click(function () {
	$('#moreSettingsModal').modal('show');
});

async function setSession(formdata) {
    formdata.set('copyexchangeto',$("#copyexchangeto option:selected").index());
	await $.ajax({
		url: base_url + 'index.php/contesting/setSession',
		type: 'post',
		data: formdata,
		processData: false,
		contentType: false,
		success: function (data) {
			sessiondata=data;
		}
	});
}

// realtime clock
if ( ! manual ) {
	$(function ($) {
		handleStart = setInterval(function() { getUTCTimeStamp($('.input_time')); }, 500);
	});

	$(function ($) {
		handleDate = setInterval(function() { getUTCDateStamp($('.input_date')); }, 1000);
	});
} else {
	getUTCDateStamp($('.input_date'));
	getUTCTimeStamp($('.input_time'));
}

// We don't want spaces to be written in callsign
// We don't want spaces to be written in exchange
// We don't want spaces to be written in gridsquare
// We don't want spaces to be written in time :)
$(function () {
	$('#callsign, #exch_rcvd, #exch_gridsquare_r, #start_time').on('keypress', function (e) {
		if (e.which == 32) {
			return false;
		}
	});
});

// We don't want spaces to be written in serial
$(function () {
	$('#exch_serial_r').on('keypress', function (e) {
		if (e.which == 32) {
			return false;
		}
	});
});

// Some Browsers (Firefox...) allow Chars in Serial Input. We don't want that.
// reference: https://stackoverflow.com/questions/49923588/input-type-number-with-pattern-0-9-allows-letters-in-firefox
$(function () {
    $('#exch_serial_s, #exch_serial_r').on('keypress', function (e) {
        var charCode = e.which || e.keyCode;
        var charStr = String.fromCharCode(charCode);

        if (!/^[0-9]+$/.test(charStr)) {
            e.preventDefault();
        }
    });
});


// Here we capture keystrokes to execute functions
document.onkeyup = function (e) {
	// ALT-W wipe
	if (e.altKey && e.key == "w") {
		reset_log_fields();
		// CTRL-Enter logs QSO
	} else if ((e.key === "Enter") && (e.ctrlKey || e.metaKey)) {
		$("#callsign").blur();
		logQso();
		// Enter in received exchange logs QSO
	} else if ((e.key == "Enter") && (
		($(document.activeElement).attr("id") == "exch_rcvd")
		|| ($(document.activeElement).attr("id") == "exch_gridsquare_r")
		|| ($(document.activeElement).attr("id") == "exch_serial_r")
		|| (($(document.activeElement).attr("id") == "callsign") && ($("#exchangetype").val() == "None"))
	)) {
		logQso();
	} else if (e.key == "Escape") {
		reset_log_fields();
		// Space to jump to either callsign or the various exchanges
	} else if (e.key == " ") {
		let exchangetype = $("#exchangetype").val();
		let sequence = $('#exchangesequence_select').val().split('-');

		let mapping = {
			"g": "exch_gridsquare_r",
			"s": "exch_serial_r",
			"e": "exch_rcvd",
		};

		if (manual && $(document.activeElement).attr("id") == "start_time") {
			$("#callsign").focus();
			return false;
		}

		if (exchangetype == 'Exchange') {
			if ($(document.activeElement).attr("id") == "callsign") {
				$("#exch_rcvd").focus();
				return false;
			} else if ($(document.activeElement).attr("id") == "exch_rcvd") {
				$("#callsign").focus();
				return false;
			}
		}
		else if (exchangetype == 'Serial') {
			if ($(document.activeElement).attr("id") == "callsign") {
				$("#exch_serial_r").focus();
				return false;
			} else if ($(document.activeElement).attr("id") == "exch_serial_r") {
				$("#callsign").focus();
				return false;
			}
		}
		else if (exchangetype == 'Gridsquare') {
			if ($(document.activeElement).attr("id") == "callsign") {
				$("#exch_gridsquare_r").focus();
				return false;
			} else if ($(document.activeElement).attr("id") == "exch_gridsquare_r") {
				$("#callsign").focus();
				return false;
			}
		}
		else if (exchangetype == 'Serialexchange') {
			let filteredSequence = sequence.filter(key => key !== 'g');

			if ($(document.activeElement).attr("id") == "callsign") {
				$(`#${mapping[filteredSequence[0]]}`).focus();
				return false;
			} else if ($(document.activeElement).attr("id") == mapping[filteredSequence[0]]) {
				$(`#${mapping[filteredSequence[1]]}`).focus();
				return false;
			} else if ($(document.activeElement).attr("id") == mapping[filteredSequence[1]]) {
				$("#callsign").focus();
				return false;
			}
		}
		else if (exchangetype == 'Serialgridsquare') {
			let filteredSequence = sequence.filter(key => key !== 'e');

			if ($(document.activeElement).attr("id") == "callsign") {
				$(`#${mapping[filteredSequence[0]]}`).focus();
				return false;
			} else if ($(document.activeElement).attr("id") == mapping[filteredSequence[0]]) {
				$(`#${mapping[filteredSequence[1]]}`).focus();
				return false;
			} else if ($(document.activeElement).attr("id") == mapping[filteredSequence[1]]) {
				$("#callsign").focus();
				return false;
			}
		}
		else if (exchangetype == 'SerialGridExchange') {
			if ($(document.activeElement).attr("id") == "callsign") {
				$(`#${mapping[sequence[0]]}`).focus();
				return false;
			} else if ($(document.activeElement).attr("id") == mapping[sequence[0]]) {
				$(`#${mapping[sequence[1]]}`).focus();
				return false;
			} else if ($(document.activeElement).attr("id") == mapping[sequence[1]]) {
				$(`#${mapping[sequence[2]]}`).focus();
				return false;
			} else if ($(document.activeElement).attr("id") == mapping[sequence[2]]) {
				$("#callsign").focus();
				return false;
			}
		}
	}

};

/* time input shortcut */
$('#start_time').change(function() {
	var raw_time = $(this).val();
	if(raw_time.match(/^\d\[0-6]d$/)) {
		raw_time = "0"+raw_time;
	}
	if(raw_time.match(/^[012]\d[0-5]\d$/)) {
		raw_time = raw_time.substring(0,2)+":"+raw_time.substring(2,4);
		$('#start_time').val(raw_time);
	}
});

/* date input shortcut */
$('#start_date').change(function() {
	 raw_date = $(this).val();
	if(raw_date.match(/^[12]\d{3}[01]\d[0123]\d$/)) {
		raw_date = raw_date.substring(0,4)+"-"+raw_date.substring(4,6)+"-"+raw_date.substring(6,8);
		$('#start_date').val(raw_date);
	}
});


$("#callsign").on( "blur", function() {
	var call = $(this).val();
	if ((call.length>=3) && ($("#bearing_info").html().length == 0)) {
		getCallbook();
	}
});

var scps=[];

$("#callsign").on("compositionstart", function(){ this.isComposing = true; });
$("#callsign").on("compositionend", function(e){
	this.isComposing = false;
	$(this).trigger("keyup");
});

// On Key up check and suggest callsigns
$("#callsign").keyup(async function (e) {
	// Prevent checking when the user's composing in IME
	if (this.isComposing || e.isComposing) return;

	var call = $(this).val();
	if ((!((e.keyCode == 10 || e.keyCode == 13) && (e.ctrlKey || e.metaKey))) && (call.length >= 3)) {	// prevent checking again when pressing CTRL-Enter

		if ($(this).val().length >= 3) {
			$callsign = $(this).val().replace('Ø', '0');
			if (scps.filter((call => call.includes($(this).val().toUpperCase()))).length <= 0) {
				$.ajax({
					url: 'lookup/scp',
					method: 'POST',
					data: {
						callsign: $callsign.toUpperCase()
					},
					success: function(result) {
						$('.callsign-suggestions').text(result);
						scps=result.split(" ");
						highlight(call.toUpperCase());
					}
				});
			} else {
				$('.callsign-suggestions').text(scps.filter((call) => call.includes($(this).val().toUpperCase())).join(' '));
				highlight(call.toUpperCase());
			}
		}

		await checkIfWorkedBefore();
		var qTable = $('.qsotable').DataTable();
		qTable.search(call).draw();
	}
	else if (call.length <= 2) {
		$('.callsign-suggestions').text("");
		$('#bearing_info').html("");
	}
});

async function getCallbook() {
	var call = $("#callsign").val();
	if (call.length >= 3) {
		$.getJSON(base_url + 'index.php/logbook/json/' + call + '/'+$("#band").val()+'/'+$("#band").val() + '/' + current_active_location, function(result) {
			try {
				$('#bearing_info').html(result.bearing);
			} catch {}
		});
	}
}

async function checkIfWorkedBefore() {
	var call = $("#callsign").val();
	if (call.length >= 3) {
		$('#callsign_info').text("");
		$.ajax({
			url: base_url + 'index.php/contesting/checkIfWorkedBefore',
			type: 'post',
			data: {
				'call': call,
				'mode': $("#mode").val(),
				'band': $("#band").val(),
				'contest': $("#contestname").val()
			},
			success: function (result) {
				if (result.message.substr(0,6) == 'Worked') {
					$('#callsign_info').text(result.message);
				}
			}
		});
	}
}

async function reset_log_fields() {
	$('#name').val("");
	$('.callsign-suggestions').text("");
	$('#callsign').val("");
	$('#comment').val("");
	$('#exch_rcvd').val("");
	$('#exch_serial_r').val("");
	$('#exch_gridsquare_r').val("");
	$("#callsign").focus();
	setRst($("#mode").val());
	$('#callsign_info').text("");
	$('#bearing_info').text("");

	await refresh_qso_table(sessiondata);
	var qTable = $('.qsotable').DataTable();
	qTable.search('').draw();
}

RegExp.escape = function (text) {
	return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}

function highlight(term, base) {
	if (!term) return;
	base = base || document.body;
	var re = new RegExp("(" + RegExp.escape(term) + ")", "gi");
	var replacement = "<span class=\"text-primary\">" + term + "</span>";
	$(".callsign-suggestions", base).contents().each(function (i, el) {
		if (el.nodeType === 3) {
			var data = el.data;
			if (data = data.replace(re, replacement)) {
				var wrapper = $("<span>").html(data);
				$(el).before(wrapper.contents()).remove();
			}
		}
	});
}

// Only set the frequency when not set by userdata/PHP.
if ($('#frequency').val() == "") {
	$.get('qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function (result) {
		$('#frequency').val(result).trigger("change");
		$('#frequency_rx').val("");
		set_qrg();
	});
}

/* on mode change */
$('#mode').change(function () {
		if ($('#radio').val() == '0') {
	$.get('qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function (result) {
		$('#frequency').val(result).trigger("change");
		$('#frequency_rx').val("");
	});
	}
	setRst($("#mode").val());
	checkIfWorkedBefore();
});

/* Calculate Frequency */
/* on band change */
$('#band').change(function () {
	if ($('#radio').val() == '0') {
		$.get('qso/band_to_freq/' + $(this).val() + '/' + $('.mode').val(), function (result) {
			$('#frequency').val(result).trigger("change");
			$('#frequency_rx').val("");
		});
	}
	set_qrg();
	checkIfWorkedBefore();
});

/* on radio change */
// in the footer is defined that we want to clear the frequency when changing the radio
// this may fit for QSOs, but not for the contesting module
// so we want atleast to set the frequency to the default frequency of the band
$('#radio').change(function () {
	if ($('#radio').val() == '0') {
		$.get('qso/band_to_freq/' + $('#band').val() + '/' + $('.mode').val(), function (result) {
			$('#frequency').val(result).trigger("change");
			$('#frequency_rx').val("");
		});
	}
});

// Handle manual frequency entry - sync visible field to hidden field
$('#freq_calculated').on('change', function() {
	// set_new_qrg() is defined in qrg_handler.js and will:
	// 1. Parse the frequency value and convert to Hz
	// 2. Update #frequency (hidden field)
	// 3. Update #band selector to match the frequency
	if (typeof set_new_qrg === 'function') {
		set_new_qrg();
	}
});

function setSerial(data) {
	var serialsent = 1;
	if (data.serialsent != "") {
		serialsent = parseInt(data.serialsent);
	}
	$("#exch_serial_s").val(serialsent);
}

function setExchangetype(exchangetype) {
	// Perhaps a better approach is to hide everything, then just enable the things you need
	$('#sent_exchange').hide().removeClass();
	$('#rcvd_exchange').hide().removeClass();
	$(".exchanger").hide();
	$(".exchanges").hide();
	$(".serials").hide();
	$(".serialr").hide();
	$(".gridsquarer").hide();
	$(".gridsquares").hide();

    // To track the transition, the code for the exchangecopy is kept
    // separate.
	switch(exchangetype) {
      case 'None':
		$('#sent_exchange').hide().removeClass();
		$('#rcvd_exchange').hide().removeClass();
		break;

      case 'Serial':
		$('#sent_exchange').show().addClass('d-flex gap-2 col-md-2');
		$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-2');
		$(".serials").show();
		$(".serialr").show();
		break;

      case 'Serialgridsquare':
		$('#sent_exchange').show().addClass('d-flex gap-2 col-md-3');
		$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-3');
		$(".serials").show();
		$(".serialr").show();
		$(".gridsquarer").show();
		$(".gridsquares").show();
		break;

      case 'Gridsquare':
		$('#sent_exchange').show().addClass('d-flex gap-2 col-md-2');
		$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-2');
		$(".gridsquarer").show();
		$(".gridsquares").show();
        if ($("#copyexchangeto").prop('disabled') == false) {
          $("#copyexchangeto").prop('disabled','disabled');
          $("#copyexchangeto").data('oldValue',$("#copyexchangeto").val());
          $("#copyexchangeto").val('None');
        } else {
          // Do nothing
        }
        break;

      case 'Exchange':
		$('#sent_exchange').show().addClass('d-flex gap-2 col-md-2');
		$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-2');
		$(".exchanger").show();
		$(".exchanges").show();
		break;

      case 'Serialexchange':
		$('#sent_exchange').show().addClass('d-flex gap-2 col-md-3');
		$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-3');
		$(".exchanger").show();
		$(".exchanges").show();
		$(".serials").show();
		$(".serialr").show();
        if ($("#copyexchangeto").prop('disabled') == false) {
          // Do nothing
        } else {
          $("#copyexchangeto").val($("#copyexchangeto").data('oldValue') ?? 'None');
          $("#copyexchangeto").prop('disabled',false);
        }
        break;

	  case 'SerialGridExchange':
		$('#sent_exchange').show().addClass('d-flex gap-2 col-md-4');
		$('#rcvd_exchange').show().addClass('d-flex gap-2 col-md-4');
		$(".serials").show();
		$(".serialr").show();
		$(".gridsquarer").show();
		$(".gridsquares").show();
		$(".exchanger").show();
		$(".exchanges").show();
		if ($("#copyexchangeto").prop('disabled') == false) {
			// Do nothing
		} else {
			$("#copyexchangeto").val($("#copyexchangeto").data('oldValue') ?? 'None');
			$("#copyexchangeto").prop('disabled',false);
		}
		break;

      default:
    }
}

/*
	Function: logQso
	Job: this handles the logging done in the contesting module.
 */
function logQso() {
	if ($("#callsign").val().length > 0) {

		// To prevent changing the contest name while logging we disable the select
		// Only "Start a new contest session" will enable it again
		disabledContestnameSelect(true);

		// Avoid resubmission by disabling the button
		var saveQsoButtonText = $("#saveQso").html();
		$("#saveQso").html('<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span> ' + saveQsoButtonText + '...').prop('disabled', true);

		$('.callsign-suggestions').text("");
		$('#callsign_info').text("");

		var table = $('.qsotable').DataTable();
		var exchangetype = $("#exchangetype").val();

		var gridsquare = $("#exch_gridsquare_r").val();
		var vucc = '';

		if (gridsquare.indexOf(',') != -1) {
			vucc = gridsquare;
			gridsquare = '';
		}

		var gridr = '';
		var vuccr = '';
		var exchsent = '';
		var exchrcvd = '';
		var serials = '';
		var serialr = '';

		switch (exchangetype) {
			case 'Exchange':
				exchsent = $("#exch_sent").val();
				exchrcvd = $("#exch_rcvd").val();
			break;

			case 'Gridsquare':
				gridr = gridsquare;
				vuccr = vucc;
			break;

			case 'Serial':
				serials = $("#exch_serial_s").val();
				serialr = $("#exch_serial_r").val();
			break;

			case 'Serialexchange':
				exchsent = $("#exch_sent").val();
				exchrcvd = $("#exch_rcvd").val();
				serials = $("#exch_serial_s").val();
				serialr = $("#exch_serial_r").val();
			break;

			case 'Serialgridsquare':
				gridr = gridsquare;
				vuccr = vucc;
				serials = $("#exch_serial_s").val();
				serialr = $("#exch_serial_r").val();
			break;

			case 'SerialGridExchange':
				gridr = gridsquare;
				vuccr = vucc;
				exchsent = $("#exch_sent").val();
				exchrcvd = $("#exch_rcvd").val();
				serials = $("#exch_serial_s").val();
				serialr = $("#exch_serial_r").val();
			break;
		}

		var formdata = new FormData(document.getElementById("qso_input"));

		let manual_addon = '?manual=' + qso_manual;

		$.ajax({
			url: base_url + 'index.php/qso/saveqso' + manual_addon,
			type: 'post',
			data: formdata,
			processData: false,
			contentType: false,
			enctype: 'multipart/form-data',
			success: async function (html) {
				var exchangetype = $("#exchangetype").val();
				if (exchangetype == "Serial" || exchangetype == 'Serialexchange' || exchangetype == 'Serialgridsquare' || exchangetype == 'SerialGridExchange') {
					$("#exch_serial_s").val(+$("#exch_serial_s").val() + 1);
					formdata.set('exch_serial_s', $("#exch_serial_s").val());
				}

				$('#name').val("");
				$('#bearing_info').html("");
				$('#callsign').val("");
				$('#comment').val("");
				$('#exch_rcvd').val("");
				$('#exch_gridsquare_r').val("");
				$('#exch_serial_r').val("");
				if (manual) {
					$("#start_time").focus().select();
				} else {
					$("#callsign").focus();
				}
				await setSession(formdata);

				await refresh_qso_table(sessiondata);
				var qTable = $('.qsotable').DataTable();
				qTable.search('').order([0, 'desc']).draw();

				// Re-enable the previously disabled button for resubmission avoidance
				$("#saveQso").html(saveQsoButtonText).prop("disabled", false);
			}
		});
	}
}

async function getSession() {
	return await $.ajax({
		url: base_url + 'index.php/contesting/getSession',
		type: 'post',
	});
}

async function restoreContestSession(data) {
	if (data) {
		let settings = JSON.parse(data.settings);

		if (settings.copyexchangeto != "") {
			$('#copyexchangeto option')[settings.copyexchangeto].selected = true;
		}

		if (data.contestid != "") {
			$("#contestname_select").val(data.contestid);
		}

		if (settings.exchangetype != "") {
			$("#exchangetype").val(settings.exchangetype);
			setExchangetype(settings.exchangetype);
			setSerial(data);
		}

		if (settings.exchangesequence != "") {
			$("#exchangesequence_select").val(settings.exchangesequence);
			sort_exchange();
		}

		if (data.exchangesent != "") {
			$("#exch_sent").val(data.exchangesent);
		}

		if (settings.radio != "0") {
			$("#radio").val(settings.radio);
		} else {
			$("#radio").val(settings.radio);
			$("#band").val(settings.band);
			$("#mode").val(settings.mode);
			if (settings.freq_display != "") {
				$("#frequency").val(settings.freq_display);
			} else {
				$.get('qso/band_to_freq/' + settings.band + '/' + settings.mode, function (result) {
					$('#frequency').val(result).trigger("change");
				});
			}
		}

		if (data.qso != "") {
			disabledContestnameSelect(true);
			await refresh_qso_table(data);
		} else {
			disabledContestnameSelect(false);
			$("#contestname_select").val("Other").change();
		}
	} else {
		$("#exch_serial_s").val("1");
	}
}

async function refresh_qso_table(data) {
	if (data !== null) {
		$.ajax({
			url: base_url + 'index.php/contesting/getSessionQsos',
			type: 'post',
			data: { 'qso': data.qso, },
			success: function (html) {
				if (!$.fn.DataTable.isDataTable('.qsotable')) {
					$.fn.dataTable.moment('DD-MM-YYYY HH:mm:ss');
					$('.qsotable').DataTable({
						"stateSave": true,
						"pageLength": 25,
						responsive: false,
						"scrollY": "400px",
						"scrollCollapse": true,
						"paging": false,
						"scrollX": true,
						"language": {
							url: getDataTablesLanguageUrl(),
						},
						order: [0, 'desc'],
						"columnDefs": [
							{
								"render": function ( data, type, row ) {
									return row[8] !== null && row[8] !== '' ? pad(row[8], 3) : '';
								},
								"targets" : 8
							},
							{
								"render": function ( data, type, row ) {
									return row[9] !== null && row[9] !== '' ? pad(row[9], 3) : '';
								},
								"targets" : 9
							}
						]
					});
				}
				var table = $('.qsotable').DataTable();
				table.clear();

				var mode = '';
				var data = [];
                $.each(html, function () {
                    if (this.col_submode == null || this.col_submode == '') {
                        mode = this.col_mode;
                    } else {
                        mode = this.col_submode;
                    }

                    data.push([
						this.col_time_on,
						'<a href="javascript:displayQso(' + this.col_primary_key + ');">'+this.col_call + '</a>',
                        this.col_band,
                        mode,
                        this.col_rst_sent,
                        this.col_rst_rcvd,
                        this.col_stx_string,
                        this.col_srx_string,
                        this.col_stx,
                        this.col_srx,
                        this.col_gridsquare,
                        this.col_vucc_grids
                    ]);
                });

                if (data.length > 0) {
                    table.rows.add(data).draw();
                }

			}
		});
	}
}

function pad (str, max) {
	str = str.toString();
	return str.length < max ? pad("0" + str, max) : str;
}

function getUTCTimeStamp(el) {
	var now = new Date();
	var localTime = now.getTime();
	var utc = localTime + (now.getTimezoneOffset() * 60000);
	if (manual) {
		$(el).attr('value', ("0" + now.getUTCHours()).slice(-2)+':'+("0" + now.getUTCMinutes()).slice(-2));
	} else {
		$(el).attr('value', ("0" + now.getUTCHours()).slice(-2)+':'+("0" + now.getUTCMinutes()).slice(-2)+':'+("0" + now.getUTCSeconds()).slice(-2));
	}
}

function getUTCDateStamp(el) {
	var now = new Date();
	var day = ("0" + now.getUTCDate()).slice(-2);
	var month = ("0" + (now.getUTCMonth() + 1)).slice(-2);
	var year = now.getUTCFullYear();
	var short_year = year.toString().slice(-2);

	// Format the date based on user_date_format passed from PHP
	var formatted_date;
	switch (user_date_format) {
		case "d/m/y":
			formatted_date = day + "/" + month + "/" + short_year;
			break;
		case "d/m/Y":
			formatted_date = day + "/" + month + "/" + year;
			break;
		case "m/d/y":
			formatted_date = month + "/" + day + "/" + short_year;
			break;
		case "m/d/Y":
			formatted_date = month + "/" + day + "/" + year;
			break;
		case "d.m.Y":
			formatted_date = day + "." + month + "." + year;
			break;
		case "y/m/d":
			formatted_date = short_year + "/" + month + "/" + day;
			break;
		case "Y-m-d":
			formatted_date = year + "-" + month + "-" + day;
			break;
		case "M d, Y":
			// Need to get the month name abbreviation
			var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
			formatted_date = monthNames[now.getUTCMonth()] + " " + parseInt(day) + ", " + year;
			break;
		case "M d, y":
			var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
			formatted_date = monthNames[now.getUTCMonth()] + " " + parseInt(day) + ", " + short_year;
			break;
		case "d M y":
			var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
			formatted_date = parseInt(day) + " " + monthNames[now.getUTCMonth()] + " " + short_year;
			break;
		default:
			// Default to d-m-Y format as shown in the PHP code
			formatted_date = day + "-" + month + "-" + year;
	}

	$(el).attr('value', formatted_date);
}
