/*
Copyright (c) 2023-forever Douglas Malnati. All rights reserved.
See the /faq/tos page for details.
(If this generated header is stamped on a file which is a 3rd party file or under a different license or copyright, then ignore this copyright statement and use that file's terms.)
*/
import * as utl from '/js/Utl.js';
import { Base } from './Base.js';
import { TabularData } from '../../../../js/TabularData.js';
export class WsprSearchUiFlightStatsController
extends Base
{
constructor(cfg)
{
super();
this.cfg = cfg;
this.ok = this.cfg.container;
if (this.ok)
{
this.ui = this.#MakeUI();
this.cfg.container.appendChild(this.ui);
}
}
SetDebug(tf)
{
super.SetDebug(tf);
this.t.SetCcGlobal(tf);
}
OnEvent(evt)
{
if (this.ok)
{
switch (evt.type) {
case "DATA_TABLE_RAW_READY": this.#OnDataTableRawReady(evt); break;
}
}
}
#OnDataTableRawReady(evt)
{
this.t.Reset();
this.t.Event(`WsprSearchUiFlightStatsController::OnDataTableRawReady Start`);
// clear existing child nodes
this.cfg.container.innerHTML = "";
// get handle to data
let td = evt.tabularDataReadOnly;
// calculate distance stats
let distKm = 0;
let distMi = 0;
td.ForEach((row) => {
distKm += td.Get(row, "DistKm");
distMi += td.Get(row, "DistMi");
});
// calculate spot stats
let spotCount = td.GetDataTable().length - 1;
// calculate duration stats
let durationStr = "";
if (td.Length() > 1)
{
let dtFirst = td.Get(td.Length() - 1, "DateTimeLocal");
let dtLast = td.Get(0, "DateTimeLocal");
let msFirst = utl.ParseTimeToMs(dtFirst);
let msLast = utl.ParseTimeToMs(dtLast);
let msDiff = msLast - msFirst;
durationStr = utl.MsToDurationStrDaysHoursMinutes(msDiff);
}
// calculate eastward laps around world using resolved location
let lapCount = this.#CalculateEastwardLapCount(td);
// create summary
let status =
`
Flight duration: ${durationStr}
Laps around world: ${utl.Commas(lapCount)}
Distance Traveled Km: ${utl.Commas(Math.round(distKm))}
Distance Traveled Mi: ${utl.Commas(Math.round(distMi))}
Spots: ${utl.Commas(spotCount)}
`;
// update UI
this.ui.innerHTML = status;
// replace with new
this.cfg.container.appendChild(this.ui);
this.t.Event(`WsprSearchUiFlightStatsController::OnDataTableRawReady End`);
}
#MakeUI()
{
this.ui = document.createElement('div');
return this.ui;
}
#CalculateEastwardLapCount(td)
{
let lonList = [];
// Table is newest-first, so iterate oldest -> newest.
for (let idx = td.Length() - 1; idx >= 0; --idx)
{
let lon = td.Get(idx, "Lng");
if (lon == undefined || lon == null || lon === "")
{
continue;
}
lon = Number(lon);
if (Number.isFinite(lon))
{
lonList.push(lon);
}
}
if (lonList.length < 2)
{
return 0;
}
// Unwrap longitude so east/west movement is continuous across +/-180.
let unwrappedLonList = [lonList[0]];
for (let i = 1; i < lonList.length; ++i)
{
let prevRaw = lonList[i - 1];
let curRaw = lonList[i];
let delta = curRaw - prevRaw;
if (delta > 180) { delta -= 360; }
if (delta < -180) { delta += 360; }
let nextUnwrapped = unwrappedLonList[unwrappedLonList.length - 1] + delta;
unwrappedLonList.push(nextUnwrapped);
}
let startLon = unwrappedLonList[0];
let lapCount = 0;
// Count only eastward full wraps past start + 360n.
for (let i = 1; i < unwrappedLonList.length; ++i)
{
let prevRel = unwrappedLonList[i - 1] - startLon;
let curRel = unwrappedLonList[i] - startLon;
while (prevRel < (lapCount + 1) * 360 && curRel >= (lapCount + 1) * 360)
{
++lapCount;
}
}
return lapCount;
}
}