/**
* Load message bank data into selection dropdowns
* @param {Function || null} cbOK callback when complete
*/
function load_messagebank(cbOK = null) {
$("#input_GOP").empty();
$("#input_GBD").empty();
$("#input_GFC").empty();
$("#input_FLD").empty();
// get messagebank data from server, which contains [FLIGHT_NUMBER]
let messageData = [...new Set(window.messagebankdata.filter(mb => mb.message_Detail.includes('[FLIGHT_NUMBER]')).map(mb => `${mb.description} [${mb.aNN_ID}]`))];
messageData.forEach((item) => {
$("#input_GOP").append($("").attr("value", item).text(item));
$("#input_GBD").append($("").attr("value", item).text(item));
$("#input_GFC").append($("").attr("value", item).text(item));
$("#input_FLD").append($("").attr("value", item).text(item));
});
if (window.messagebankdata.length > 0) {
if (cbOK) cbOK();
}
}
function load_remark_selection() {
fetchAPI("Settings/FISCode", "GET", {}, null, (okdata) => {
$("#input_GOP").val(okdata.gop)
$("#input_GBD").val(okdata.gbd);
$("#input_GFC").val(okdata.gfc);
$("#input_FLD").val(okdata.fld);
$("#input_defaultvoice").val(okdata.defaultvoice);
}, (errdata) => {
alert("Error getting FIS codes : " + errdata.message);
});
}
function Get_OldResultDays(){
fetchAPI("Settings/OldResultDays", "GET", {}, null, (okdata) => {
let days = parseInt(okdata.message);
if(isNaN(days) || days < 0){
days = 3;
}
$("#oldresultdays").val(days);
}, (errdata) => {
alert("Error getting Old Result Days : " + errdata.message);
});
}
function Set_OldResultDays(){
let days = parseInt($("#oldresultdays").val());
if(isNaN(days) || days < 0){
alert("Please enter a valid number of days (0 or more).");
return;
}
fetchAPI("Settings/OldResultDays", "POST", {}, { days: days }, (okdata) => {
alert("Old Result Days updated successfully.");
}, (errdata) => {
alert("Error updating Old Result Days : " + errdata.message);
});
}
function load_default_voice(){
$("#input_defaultvoice").empty();
window.voiceTypes.forEach((voice) => {
$("#input_defaultvoice").append($("").attr("value", voice).text(voice));
});
}
function ValidLatitude(lat){
const num = parseFloat(lat);
return !isNaN(num) && num >= -90 && num <= 90;
}
function ValidLongitude(lon){
const num = parseFloat(lon);
return !isNaN(num) && num >= -180 && num <= 180;
}
function ValidTimezone(tz){
try{
Intl.DateTimeFormat(undefined, { timeZone: tz });
return true;
} catch(e){
return false;
}
}
function ValidHHMM(time){
const regex = /^([01]\d|2[0-3]):([0-5]\d)$/;
return regex.test(time);
}
/**
* Check if a date string is valid in DD/MM/YYYY format
* @param {string} dateStr date to check in DD/MM/YYYY format
* @returns {boolean} true if valid date in DD/MM/YYYY format, false otherwise
*/
function ValidDateDDMMYYYY(dateStr){
const regex = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/;
if (!regex.test(dateStr)) return false;
const [day, month, year] = dateStr.split('/').map(Number);
const date = new Date(year, month - 1, day);
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
}
function ValidFilePath(path){
if (typeof path !== 'string' || path.trim() === '') return false;
// test if ends with .wav or .mp3
const regex = /\.(wav|mp3)$/i;
return regex.test(path);
}
function IsEnabled(value){
// accept "true", "false", true, false, 1, 0
// detect if value is null or undefined
if (value === null || value === undefined) return false;
if (typeof value === 'boolean') return value;
if (typeof value === 'number') return value === 1;
if (typeof value === 'string') return value.toLowerCase() === "true" || value === "1";
return false;
}
/**
* @typedef {Object} AdzanSetting
* @property {string} latitude
* @property {string} longitude
* @property {string} timezone
* @property {string} fajar_sound
* @property {string} dzuhur_sound
* @property {string} ashar_sound
* @property {string} maghrib_sound
* @property {string} isya_sound
* @property {string} fajar_time
* @property {string} dzuhur_time
* @property {string} ashar_time
* @property {string} maghrib_time
* @property {string} isya_time
* @property {boolean} fajar_enable
* @property {boolean} dzuhur_enable
* @property {boolean} ashar_enable
* @property {boolean} maghrib_enable
* @property {boolean} isya_enable
*/
function Get_AdzanSetting(){
fetchAPI("Settings/AdzanSetting", "GET", {}, null,
/**
* returned AdzanSetting data
* @param {AdzanSetting} okdata
*/
(okdata) => {
// text input for latitude, longitude, timezone
if (ValidLatitude(okdata.latitude)) {
$('#adzanlatitude').val(okdata.latitude);
} else {
$('#adzanlatitude').val("N/A");
}
if (ValidLongitude(okdata.longitude)) {
$('#adzanlongitude').val(okdata.longitude);
} else {
$('#adzanlongitude').val("N/A");
}
if (ValidTimezone(okdata.timezone)) {
$('#adzantimezone').val(okdata.timezone);
} else {
$('#adzantimezone').val("N/A");
}
// text input for adzan sound file for each prayer time
if (ValidFilePath(okdata.fajar_sound)) {
$('#fajar .adzanfile').val(okdata.fajar_sound);
} else {
$('#fajar .adzanfile').val("N/A");
}
if (ValidFilePath(okdata.dzuhur_sound)) {
$('#dzuhur .adzanfile').val(okdata.dzuhur_sound);
} else {
$('#dzuhur .adzanfile').val("N/A");
}
if (ValidFilePath(okdata.ashar_sound)) {
$('#ashar .adzanfile').val(okdata.ashar_sound);
} else {
$('#ashar .adzanfile').val("N/A");
}
if (ValidFilePath(okdata.maghrib_sound)) {
$('#maghrib .adzanfile').val(okdata.maghrib_sound);
} else {
$('#maghrib .adzanfile').val("N/A");
}
if (ValidFilePath(okdata.isya_sound)) {
$('#isya .adzanfile').val(okdata.isya_sound);
} else {
$('#isya .adzanfile').val("N/A");
}
// checkbox adzanenable for each prayer time
$('#fajar .adzanenable').prop('checked', IsEnabled(okdata.fajar_enable));
$('#dzuhur .adzanenable').prop('checked', IsEnabled(okdata.dzuhur_enable));
$('#ashar .adzanenable').prop('checked', IsEnabled(okdata.ashar_enable));
$('#maghrib .adzanenable').prop('checked', IsEnabled(okdata.maghrib_enable));
$('#isya .adzanenable').prop('checked', IsEnabled(okdata.isya_enable));
// adzantime for each prayer time
// if valid HH:MM will set value, else set to undefined
if (ValidHHMM(okdata.fajar_time)) {
$('#fajar .adzantime').val(okdata.fajar_time);
} else {
$('#fajar .adzantime').val("");
}
if (ValidHHMM(okdata.dzuhur_time)) {
$('#dzuhur .adzantime').val(okdata.dzuhur_time);
} else {
$('#dzuhur .adzantime').val("");
}
if (ValidHHMM(okdata.ashar_time)) {
$('#ashar .adzantime').val(okdata.ashar_time);
} else {
$('#ashar .adzantime').val("");
}
if (ValidHHMM(okdata.maghrib_time)) {
$('#maghrib .adzantime').val(okdata.maghrib_time);
} else {
$('#maghrib .adzantime').val("");
}
if (ValidHHMM(okdata.isya_time)) {
$('#isya .adzantime').val(okdata.isya_time);
} else {
$('#isya .adzantime').val("");
}
}, (errdata) => {
alert("Error getting Adzan settings : " + errdata.message);
});
}
function Set_AdzanSetting(){
let latitude = $('#adzanlatitude').val();
if (!ValidLatitude(latitude)){
alert("Please enter a valid latitude between -90 and 90.");
return;
}
let longitude = $('#adzanlongitude').val();
if (!ValidLongitude(longitude)){
alert("Please enter a valid longitude between -180 and 180.");
return;
}
let timezone = $('#adzantimezone').val();
if (!ValidTimezone(timezone)){
alert("Please enter a valid timezone.");
return;
}
let fajar_sound = $('#fajar .adzanfile').val();
if (!ValidFilePath(fajar_sound)){
alert("Please enter a valid file path for Fajar adzan sound (must end with .wav or .mp3).");
return;
}
let dzuhur_sound = $('#dzuhur .adzanfile').val();
if (!ValidFilePath(dzuhur_sound)){
alert("Please enter a valid file path for Dzuhur adzan sound (must end with .wav or .mp3).");
return;
}
let ashar_sound = $('#ashar .adzanfile').val();
if (!ValidFilePath(ashar_sound)){
alert("Please enter a valid file path for Ashar adzan sound (must end with .wav or .mp3).");
return;
}
let maghrib_sound = $('#maghrib .adzanfile').val();
if (!ValidFilePath(maghrib_sound)){
alert("Please enter a valid file path for Maghrib adzan sound (must end with .wav or .mp3).");
return;
}
let isya_sound = $('#isya .adzanfile').val();
if (!ValidFilePath(isya_sound)){
alert("Please enter a valid file path for Isya adzan sound (must end with .wav or .mp3).");
return;
}
let fajar_enable = $('#fajar .adzanenable').prop('checked');
let dzuhur_enable = $('#dzuhur .adzanenable').prop('checked');
let ashar_enable = $('#ashar .adzanenable').prop('checked');
let maghrib_enable = $('#maghrib .adzanenable').prop('checked');
let isya_enable = $('#isya .adzanenable').prop('checked');
let fajar_time = $('#fajar .adzantime').val();
if (!ValidHHMM(fajar_time)){
alert("Please enter a valid time for Fajar adzan (HH:MM).");
return;
}
let dzuhur_time = $('#dzuhur .adzantime').val();
if (!ValidHHMM(dzuhur_time)){
alert("Please enter a valid time for Dzuhur adzan (HH:MM).");
return;
}
let ashar_time = $('#ashar .adzantime').val();
if (!ValidHHMM(ashar_time)){
alert("Please enter a valid time for Ashar adzan (HH:MM).");
return;
}
let maghrib_time = $('#maghrib .adzantime').val();
if (!ValidHHMM(maghrib_time)){
alert("Please enter a valid time for Maghrib adzan (HH:MM).");
return;
}
let isya_time = $('#isya .adzantime').val();
if (!ValidHHMM(isya_time)){
alert("Please enter a valid time for Isya adzan (HH:MM).");
return;
}
/**
* @type {AdzanSetting}
*/
let data = {
latitude: latitude,
longitude: longitude,
timezone: timezone,
fajar_sound: fajar_sound,
dzuhur_sound: dzuhur_sound,
ashar_sound: ashar_sound,
maghrib_sound: maghrib_sound,
isya_sound: isya_sound,
fajar_enable: fajar_enable,
dzuhur_enable: dzuhur_enable,
ashar_enable: ashar_enable,
maghrib_enable: maghrib_enable,
isya_enable: isya_enable,
fajar_time: fajar_time,
dzuhur_time: dzuhur_time,
ashar_time: ashar_time,
maghrib_time: maghrib_time,
isya_time: isya_time
};
fetchAPI("Settings/AdzanSetting", "POST", {}, data, (okdata) => {
alert("Adzan settings updated successfully.");
}, (errdata) => {
alert("Error updating Adzan settings : " + errdata.message);
});
}
function Get_WebAccessSetting(){
fetchAPI("Settings/WebAccess", "GET", {}, null, (okdata) => {
let adminpass = okdata.adminpass || "password";
let viewerpass = okdata.userpass || "password";
$("#adminpassword1").val(adminpass);
$("#adminpassword2").val(adminpass);
$("#viewerpassword1").val(viewerpass);
$("#viewerpassword2").val(viewerpass);
}, (errdata) => {
alert("Error getting Web Access settings : " + errdata.message);
});
}
function Set_WebAccessSetting(){
let adminpass1 = $("#adminpassword1").val();
let adminpass2 = $("#adminpassword2").val();
let viewerpass1 = $("#viewerpassword1").val();
let viewerpass2 = $("#viewerpassword2").val();
if(adminpass1 !== adminpass2){
alert("Admin passwords do not match.");
return;
}
if(viewerpass1 !== viewerpass2){
alert("Viewer passwords do not match.");
return;
}
let data = {
adminpass: adminpass1,
viewerpass: viewerpass1
};
fetchAPI("Settings/WebAccess", "POST", {}, data, (okdata) => {
alert("Web Access settings updated successfully.");
}, (errdata) => {
alert("Error updating Web Access settings : " + errdata.message);
});
}
$(document).ready(function () {
console.log("setting.js loaded");
load_default_voice();
Get_OldResultDays();
Get_WebAccessSetting();
Get_AdzanSetting();
load_messagebank(() => load_remark_selection());
$('#fiscodesave').click(function () {
Set_OldResultDays();
let gop = $("#input_GOP").val();
let gbd = $("#input_GBD").val();
let gfc = $("#input_GFC").val();
let fld = $("#input_FLD").val();
let voice = $("#input_defaultvoice").val();
if (gop && gbd && gfc && fld && voice) {
let data = {
GOP: gop,
GBD: gbd,
GFC: gfc,
FLD: fld,
defaultvoice: voice
};
fetchAPI("Settings/FISCode", "POST", {}, data, (okdata) => {
alert("FIS codes saved successfully.");
}, (errdata) => {
alert("Error saving FIS codes : " + errdata.message);
});
} else {
alert("Please select all FIS codes (GOP, GBD, GFC, FLD) and Default Voice before saving.");
}
});
$('#webaccesssave').click(function () {
Set_WebAccessSetting();
});
$('#adzansave').click(function () {
Set_AdzanSetting();
});
});