// Global variables --
var athFullTimes = new Array(7), iqFullTimes = new Array(7);
var millisTillIq = new Array(7), millisTillAth = new Array(7);
var minDx;
var ddfs = -1, ats = [], dremain, ciq = [], loctn, CLCLT = 0;
var sliderTicker, nextTicker;
var Lng, Lat, Elev, timeZone, julianDate;
var fajrAng, ishaAng, ishaTime, asrFactor;
var ServerDay;
function getPageParms() {
"use strict";
// Set page-specific parameters here
// Get location
loctn = document.getElementById("dateBox").innerHTML;
Lat = Number(document.getElementById("parms").innerHTML.split(',')[0]);
Lng = Number(document.getElementById("parms").innerHTML.split(',')[1]);
Elev = Number(document.getElementById("parms").innerHTML.split(',')[2]);
fajrAng = Number(document.getElementById("parms").innerHTML.split(',')[3]);
ishaAng = Number(document.getElementById("parms").innerHTML.split(',')[4]);
ishaTime = Number(document.getElementById("parms").innerHTML.split(',')[5]);
asrFactor = Number(document.getElementById("parms").innerHTML.split(',')[6]);
CLCLT = Number(document.getElementById("parms").innerHTML.split(',')[7]);
ServerDay = Number(document.getElementById("parms").innerHTML.split(',')[8]); // included 10/10/2019
document.getElementById("parms").innerHTML = "";
// if(Lat != "" && Lng != "") { CLCLT = true; ddfs = 0; }
// if(CLCLT === 1) { CLCLT = 1; ddfs = 0; } else CLCLT = 0;
if(CLCLT === 1) ddfs = 0;
// var today = new Date();
// julianDate = jd(today.getFullYear(), today.getMonth()+1, today.getDate());
// // goes from the westernmost -12:00 to the easternmost +14:00
// // javascript defines timezone as the difference b/n UTC and local
// // time. Offset is positive if local time is behind UTC. For prayer
// // time calculations, we need to invert that, ie, local - UTC.
// timeZone = -today.getTimezoneOffset()/60;
}
function set12Hrs(h) {
"use strict";
h = ((h + 11) % 12 + 1);
return h;
}
function checkZero(i) {
"use strict";
if (i < 10) { i = "0" + i; }
return i;
}
// To be called at 12:00 midnight
function setNewDate() {
"use strict";
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], mos = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], today = new Date(), day = days[today.getDay()], mo = mos[today.getMonth()], dateElement;
dateElement = document.getElementById("dateBox");
dateElement.innerHTML = day + " " + mo + " " + today.getDate() + "<br>" + loctn;
julianDate = jd(today.getFullYear(), today.getMonth()+1, today.getDate());
// goes from the westernmost -12:00 to the easternmost +14:00
// javascript defines timezone as the difference b/n UTC and local
// time. Offset is positive if local time is behind UTC. For prayer
// time calculations, we need to invert that, ie, local - UTC.
timeZone = -today.getTimezoneOffset()/60;
}
// Prayer Time Calculations Functions:
function fix(a, b) {
a = a - b * Math.floor(a/b);
return (a < 0) ? a+b : a;
}
// Degrees to Radians
function dtr(x) {
return x*Math.PI/180;
}
function rtd(x){
return x*180/Math.PI;
}
function Sin(x) { return Math.sin(dtr(x)); }
function Asin(x) { return rtd(Math.asin(x)); }
function Cos(x) { return Math.cos(dtr(x)); }
function Acos(x) { return rtd(Math.acos(x)); }
function Atan2(x, y) { return rtd(Math.atan2(x, y)); }
function Acot(x) { return rtd(Math.atan(1/x)); }
function Tan(x) { return Math.tan(dtr(x)); }
// Get julian day
function jd(year, month, day) {
if (month <= 2) {
year -= 1;
month += 12;
}
var A = Math.floor(year/ 100);
var B = 2- A+ Math.floor(A/ 4);
var JD = Math.floor(365.25* (year+ 4716))+ Math.floor(30.6001* (month+ 1))+ day+ B- 1524.5;
return JD;
}
function sunAng(jd) {
var D = jd - 2451545.0;
var g = fix((357.529 + 0.98560028 * D), 360)
var q = fix((280.459 + 0.98564736 * D), 360)
var L = fix((q + 1.915 * Sin(g) + 0.020 * Sin(2 * g)), 360)
var e = 23.439 - 0.00000036 * D
var RA = Atan2((Cos(e) * Sin(L)), Cos(L)) / 15;
var d = Asin((Sin(e) * Sin(L))) // declination of the Sun
var EqT = q/15 - fix(RA, 24); // equation of time
return {EqT: EqT, decl: d};
}
// Mid-day
function zenith(approxtime) {
var noon = fix((12 - sunAng(julianDate + approxtime/24).EqT), 24);
return noon;
}
// To be called at 12:00 midnight and at first load
function getPrayerTimes() {
"use strict";
var i, iqIds = ['fajIq', 'dummy', 'dhuIq', 'asrIq', 'magIq', 'ishIq'], athIds = ['fajAth', 'sunAth', 'dhuAth', 'asrAth', 'magAth', 'ishAth'], iqHrs = new Array(6), iqMns = new Array(6), athHrs = new Array(6), athMns = new Array(6), x, a;
// Read Athan and Iqama times from the DOM
// Those were inserted by PHP at first load or JS after 24 hrs --
for (i = 0; i < 6; i += 1) {
a = document.getElementById(athIds[i]).innerHTML;
x = a.split(' ')[0];
athHrs[i] = parseInt(x.split(':')[0], 10); // radix = 10, default!
if (a.search("PM") > -1 && athHrs[i] < 12) { athHrs[i] += 12; }
athMns[i] = parseInt(x.split(':')[1], 10);
if (i !== 1) {
a = document.getElementById(iqIds[i]).innerHTML;
x = a.split(' ')[0];
iqHrs[i] = parseInt(x.split(':')[0], 10);
if (a.search("PM") > -1 && iqHrs[i] < 12) { iqHrs[i] += 12; }
iqMns[i] = parseInt(x.split(':')[1], 10);
} else { iqHrs[1] = athHrs[1]; iqMns[1] = athMns[1]; }
}
for (i = 0; i < 6; i += 1) {
athFullTimes[i] = new Date();
athFullTimes[i].setHours(athHrs[i], athMns[i], 0, 0);
iqFullTimes[i] = new Date();
iqFullTimes[i].setHours(iqHrs[i], iqMns[i], 0, 0);
}
// Set pseudo athan and iqama at midnight
athFullTimes[6] = new Date();
athFullTimes[6].setDate(athFullTimes[6].getDate() + 1);
athFullTimes[6].setHours(0, 0, 0, 0);
iqFullTimes[6] = new Date();
iqFullTimes[6].setDate(iqFullTimes[6].getDate() + 1);
iqFullTimes[6].setHours(0, 0, 0, 0);
/*document.getElementById("debug").innerHTML = "iqHrs[0] = " + iqHrs[0] + "<br>iqHrs[1] = " + iqHrs[1] + "<br>iqHrs[2] = " + iqHrs[2] + "<br>iqHrs[3] = " + iqHrs[3] + "<br>iqHrs[4] = " + iqHrs[4] + "<br>iqHrs[5] = " + iqHrs[5];*/
// Check for correctness of iqama as always > athan except for Friday.
for (i = 0; i < 6; i += 1) {
if(i == 1) continue;
if(athFullTimes[i].getTime() > iqFullTimes[i].getTime())
document.getElementById(iqIds[i]).setAttribute("class", "lateIq");
else document.getElementById(iqIds[i]).setAttribute("class", "");
}
//document.getElementById("debug").innerHTML = "To athan: " + getTimeTo(athFullTimes[5])/3600 + "<br>To Iqama: " + getTimeTo(iqFullTimes[5])/3600 + "</br>";
}
// Future athan times
function getFAT() {
"use strict";
var ihtml = (document.getElementById("fat").innerHTML).split(';'),
i,
x;
CLCLT = Number(ihtml[0]); // added Oct 21, 2019
dremain = Number(ihtml[1]); // chnaged from Number(ihtml[0]) on Oct 21, 2019
//document.getElementById("debug").innerHTML = "CLCLT = " + CLCLT + " dremain = " + dremain + "</br>";
// the following is the only way the display gets php CLCLT value
// note that CLCLT never permanently changes on server! Even when dremain
// counts down to 0. This may result in conflicting times b/n devices at yearend
if(CLCLT === 1) {
ddfs = 0;
ciq = (ihtml[2]).split(',');
}
else {
//document.getElementById("debug").innerHTML = "CLCLT = " + CLCLT + " dremain = " + dremain + "</br>";
//if(dremain == 0) dremain +=1; // on Dec 31, next day prayer times (Jan 01) are also sent here, count forward by 1
//for (i = 0; i < dremain; i += 1) {
for (i = 0; i <= dremain+1; i += 1) {
x = (ihtml[i + 2]).split(',');
ats[i] = [x[1], x[2], x[3], x[4], x[5], x[6]];
}
ciq = (ihtml[dremain + 4]).split(',');
}
document.getElementById("fat").innerHTML = "";
}
function update_iq(hma, im) {
"use strict";
var x, a, h, m, d = new Date();
x = hma.split(" ")[0];
h = parseInt(x.split(":")[0], 10);
if (hma.search("PM") > -1 && h < 12) { h += 12; }
m = parseInt(x.split(":")[1], 10);
d.setHours(h, (m + parseInt(im, 10)), 0, 0);
a = "PM";
h = d.getHours();
if (h < 12) { a = "AM"; }
h = set12Hrs(h);
m = checkZero(d.getMinutes());
return (h + ":" + m + " " + a);
}
// reformate decimal time to string time
// rnd: floor, round, ceil
// adj: adjustment in minutes or parts of minutes
function boardTime(time, rnd_type, adj) {
var mins, hrs, a;
time = time + adj/60
hrs = Math.floor(time);
switch(rnd_type) {
case 'ceil': mins = Math.ceil((time - hrs)*60); break;
case 'round': mins = Math.round((time - hrs)*60); break;
case 'floor': mins = Math.floor((time - hrs)*60); break;
default: mins = Math.round((time - hrs)*60); break;
}
if(mins == 60) { mins = 0; hrs++; }
if(hrs >= 12) a = "PM"; else a = "AM";
return set12Hrs(hrs) + ":" + checkZero(mins) + " " + a;
}
function Talpha(angle, d) {
return Acos((-Sin(angle) - Sin(d) * Sin(Lat))/(Cos(d) * Cos(Lat)))/15;
}
function timeAtSunAng(time, angle, isup) {
var talpha = Talpha(angle, sunAng(julianDate + time/24).decl);
if(isup == 'up') talpha = -talpha;
return zenith(time) + talpha;
}
// Calculate time of Asr athan
function asrTime(time) {
var decl = sunAng(julianDate + time/24).decl;
var angle = -Acot(asrFactor + Tan(Math.abs(Lat - decl)));
return timeAtSunAng(time, angle);
}
// calculate prayer times of today and place in ats[0]
// with CLCLT, ddfs = 0
function calculateAthTimes() {
var i, times = [5.00, 7.00, 12.00, 15.00, 17.00, 19.00];
for(i=0; i<3; i++) {
// Dhuhr
times[2] = zenith(times[2]) + timeZone - Lng/15;
// Sunrise/set
var angle = 0.833 + 0.0347*Math.sqrt(Elev);
times[1] = timeAtSunAng(times[1], angle, 'up') + timeZone - Lng/15;
times[4] = timeAtSunAng(times[4], angle) + timeZone - Lng/15;
// Fajr
times[0] = timeAtSunAng(times[0], fajrAng, 'up') + timeZone - Lng/15;
// Isha
if(ishaAng > 0) times[5] = timeAtSunAng(times[5], ishaAng) + timeZone - Lng/15;
if(ishaTime > 0) times[5] = times[4] + ishaTime/60;
// Asr
times[3] = asrTime(times[3]) + timeZone - Lng/15;
} // for loop
ats[ddfs] = times;
ats[ddfs][0] = boardTime(times[0], 'floor', 0);
ats[ddfs][1] = boardTime(times[1], 'floor', 0);
ats[ddfs][2] = boardTime(times[2], 'ceil', 0);
ats[ddfs][3] = boardTime(times[3], 'ceil', 0);
ats[ddfs][4] = boardTime(times[4], 'ceil', 0);
ats[ddfs][5] = boardTime(times[5], 'ceil', 0);
}
// Set athan and iqama times
function setAT() {
"use strict";
var i, j, athIds = ['fajAth', 'sunAth', 'dhuAth', 'asrAth', 'magAth', 'ishAth'], iqIds = ['fajIq', 'dhuIq', 'asrIq', 'magIq', 'ishIq'];
// in case you run out of uploaded data - in case of no reload for a long time
if(dremain == 0) { CLCLT = 1; ddfs = 0; }
// Calculate prayer times of today
if(CLCLT === 1) calculateAthTimes();
// Set athan and iqama times in table
for (i = 0; i < 6; i += 1) {
document.getElementById(athIds[i]).innerHTML = ats[ddfs][i];
if (i != 1) {
if (i > 1) { j = i - 1; } else { j = i; }
if (parseInt(ciq[j], 10) > 0) {
document.getElementById(iqIds[j]).innerHTML = update_iq(ats[ddfs][i], ciq[j]);
}
}
}
// Set Friday athan (can be negative minutes before dhuhr)
if (parseInt(ciq[5], 10) != 0) {
document.getElementById('fdp').innerHTML = update_iq(ats[ddfs][2], ciq[5]);
}
}
// Highlight Friday row on Friday and turn it off the rest of the week
function fridayOnOff() {
"use strict";
var today = new Date();
if (today.getDay() === 5) {
document.getElementsByTagName("tr")[7].setAttribute("class", "next");
} else {
document.getElementsByTagName("tr")[7].setAttribute("class", "");
}
}
// Return milliseconds untill 'untill'
function getTimeTo(untill) {
"use strict";
var rightnow = new Date(), ms = new Date(rightnow.getFullYear(), rightnow.getMonth(), rightnow.getDate(), untill.getHours(), untill.getMinutes(), 0, 0) - rightnow;
if (ms < 0) {
ms += 86400000; // add a day
}
return ms;
}
// Return milliseconds untill 'untill' -- Don't add next day
// Return negatives
function getTimeToNND(untill) {
"use strict";
var rightnow = new Date(), ms = new Date(rightnow.getFullYear(), rightnow.getMonth(), rightnow.getDate(), untill.getHours(), untill.getMinutes(), 0, 0) - rightnow;
return ms;
}
String.prototype.toHHMMSS = function () {
"use strict";
var sec_num = parseInt(this, 10), hours = Math.floor(sec_num / 3600), minutes = Math.floor((sec_num - (hours * 3600)) / 60), seconds = sec_num - (hours * 3600) - (minutes * 60);
if (hours < 10) { hours = "0" + hours; }
if (minutes < 10) { minutes = "0" + minutes; }
if (seconds < 10) { seconds = "0" + seconds; }
return hours + ':' + minutes + ':' + seconds;
};
function tickToPrayer(time, pn) { // pn = prayer name
"use strict";
document.getElementsByTagName("h2")[0].innerHTML = "Remaining to </br>" + pn + " :";
clearInterval(nextTicker);
nextTicker = setInterval(function () {
var x = getTimeTo(time) / 1000;
if (x > 1) {
document.getElementById("timerBox").innerHTML = x.toString().toHHMMSS();
} else {
clearInterval(nextTicker);
document.getElementById("timerBox").innerHTML = "";
}
}, 500);
}
function getMin(ar) {
"use strict";
var i, x = ar[0], dx = 0;
for (i = 1; i < 7; i += 1) {
if (ar[i] < x) { x = ar[i]; dx = i; }
}
return dx;
}
// To count down to following athan or iqama, then call itself back
// at the next athan or iqama
function countDownToIqama() {
"use strict";
var i, setDx, rmDx, prayerName = ['', 'FAJR', 'DHUHR', 'ASR', 'MAGHRIB', 'ISHA', 'SUNRISE', 'MIDNIGHT'], nextIq, nextAth, oneoclock = new Date(), a, xx, fdpHrs, fdpMns;
a = document.getElementById("fdp").innerHTML;
xx = a.split(' ')[0];
fdpHrs = parseInt(xx.split(':')[0], 10);
if (a.search("PM") > -1 && fdpHrs < 12) { fdpHrs += 12; }
fdpMns = parseInt(xx.split(':')[1], 10);
oneoclock.setHours(fdpHrs, fdpMns, 0, 0);
for (i = 0; i < 7; i += 1) {
millisTillAth[i] = getTimeTo(athFullTimes[i]);
millisTillIq[i] = getTimeTo(iqFullTimes[i]);
}
// Delay
millisTillAth[6] += 2000;
millisTillIq[6] += 2000;
nextIq = getMin(millisTillIq);
nextAth = getMin(millisTillAth);
if (oneoclock.getDay() === 5 && getTimeToNND(oneoclock) < 0) {
// If Dhuhr Athan or Iqama comes after Jumuah move that to Asr
if (nextIq === 2) { nextIq = 3; }
if (nextAth === 2) { nextAth = 3; }
}
// Highlight next prayer after page open
if (nextIq === 0) {
setDx = 1;
rmDx = 5;
} else if (nextIq === 1) {
setDx = 6;
rmDx = 1;
} else if (nextIq === 2) {
setDx = nextIq;
rmDx = 6;
} else if (nextIq === 6) {
setDx = 7;
rmDx = 5;
} else {
setDx = nextIq;
rmDx = nextIq - 1;
}
if (setDx !== 7) {
document.getElementsByTagName("tr")[setDx].setAttribute("class", "next");
}
document.getElementsByTagName("tr")[rmDx].setAttribute("class", "");
if (oneoclock.getDay() === 5 && nextAth > 1 && getTimeToNND(oneoclock) >= 0) {
tickToPrayer(oneoclock, "JUMUAH");
setTimeout(countDownToIqama, getTimeTo(oneoclock) + 500);
} else {
// If between athan and iqama, start ticking to iqama right away
// April 2018: subtracted 1000 ms to fix iqama/midnight issue
if (millisTillIq[nextIq] < (millisTillAth[nextAth]-1000)) {
tickToPrayer(iqFullTimes[nextIq], "IQAMA");
setTimeout(countDownToIqama, millisTillIq[nextIq] + 500);
} else { // otherwise, count down to athan
tickToPrayer(athFullTimes[nextAth], prayerName[setDx]);
setTimeout(countDownToIqama, millisTillAth[nextAth] + 500);
}
}
}
// Run slider section
function runSlider() {
clearInterval(sliderTicker);
sliderTicker = setInterval(function() {
$("#slider").slideUp(3000, function () {
if($(this).html().indexOf("Fajr") != -1) {
$("#slider").html("Dhuhr " + ats[ddfs][2].split(' ')[0]);
} else if($(this).html().indexOf("Dhuhr") != -1) {
$("#slider").html("Asr " + ats[ddfs][3].split(' ')[0]);
} else if($(this).html().indexOf("Asr") != -1) {
$("#slider").html("Maghrib " + ats[ddfs][4].split(' ')[0]);
} else if($(this).html().indexOf("Maghrib") != -1) {
$("#slider").html("Isha " + ats[ddfs][5].split(' ')[0]);
} else if($(this).html().indexOf("Isha") != -1) {
$("#slider").html("Fajr " + ats[ddfs][0].split(' ')[0]);
} else {
$("#slider").html("Fajr " + ats[ddfs][0].split(' ')[0]);
}
});
$("#slider").slideDown(4000);
}, 8000);
}
function jsreload() {
"use strict";
setNewDate();
if(CLCLT === 0) ddfs += 1;
if(dremain > 0) dremain -= 1; // avoid falling below 0 with CLCLT
setAT();
getPrayerTimes();
fridayOnOff();
runSlider();
setTimeout(jsreload, (24 * 60 * 60 * 1000));
//document.getElementById("debug").innerHTML = "jsreload </br>";
}
function ClientVsServerDate(i, j) {
// return 0 for i == j
// 1 for i > j
// -1 for i < j
if(i == j) return 0;
else { // if beginning of a new month
if((i >= 30 && j == 1) || (i == 1 && j >= 30)) {
if(i == 1) i += 31;
else j += 31;
}
if(i > j) return 1; else return -1;
}
}
function jsreload_once() {
"use strict";
var ClientDay = new Date().getDate();
if(ClientVsServerDate(ClientDay, ServerDay) == -1) {
if(CLCLT === 0) ddfs += 1;
if(dremain > 0) dremain -= 1;
setAT();
getPrayerTimes();
}
if(ClientVsServerDate(ClientDay, ServerDay) == 0) {
if(CLCLT === 0) ddfs += 2;
if(dremain > 0) dremain -= 2;
}
if(ClientVsServerDate(ClientDay, ServerDay) == 1) {
if(CLCLT === 0) ddfs += 3;
if(dremain > 0) dremain -= 3;
setAT();
getPrayerTimes();
}
runSlider();
//document.getElementById("debug").innerHTML = "Client Date: " + ClientDay + " - ServerDate: " + ServerDay + "</br>";
}
function refresh_MN() {
"use strict";
var MN = new Date();
MN.setDate(MN.getDate() + 1);
MN.setHours(0, 0, 0, 0);
MN = getTimeTo(MN);
setTimeout(jsreload, MN);
// setTimeout(function () {
// if(navigator.onLine) window.location.reload(true);
// }, MN+(60*60*1000));
}
refresh_MN();
getPageParms();
setNewDate();
getFAT();
if(CLCLT === 1) setAT();
getPrayerTimes();
fridayOnOff();
//if(CLCLT === 1) runSlider();
jsreload_once();
var lastCheck = 0;
function sleepCheck() {
var now = new Date().getTime();
var diff = now - lastCheck;
if (Math.abs(diff) > 30000) { // a min diff of half a minute is required before a reload
// alert('took ' + diff + 'ms');
if(window.navigator.onLine) window.location.reload(true);
}
lastCheck = now;
}
window.onload = function () {
"use strict";
setTimeout(countDownToIqama, 300);
setInterval(function () {
document.getElementById('clockBox').innerHTML = new Date().toTimeString();
}, 500);
lastCheck = new Date().getTime();
setInterval(sleepCheck, 5000); // Check every 5 seconds
// document.getElementById('debug').innerHTML = " Browser online: " + navigator.onLine;
};