(function() { // TODO add date parameter, because a train may one day have reservation, the other may not. Same for train type. One day local, the other suburban let _obj = new solapps.dataModule({ key : 'trena', type : 'data', label : 'Τρένα', orderBy : 'TRENO', requires : [], updateEvery : 86400, //secs db : { needed : false, createStatements : {}, }, listFormatter : function(obj, lang) { return ''; }, optionFormatter : function(obj, lang) { return ''; } }); let CONSTS = { TYPE_SUBURBAN : 12, TYPE_ICTY : 9, // long haul }; let makeInteger = function (ddro) { return `${ddro}`.replace(/-/g, '')*1; }; let fixDOW = function (dow) { if (dow*1 > 7) return solapps.util.date.dow(dow); return dow*1; } _obj.setUpdater(function(force) { $.ajax({ data: {c: 'dbsync', op: 'getData', item:'trena', assoc:true}, success: function (reply) { if (!reply) return; if (!reply.status && reply.message != null) {alert(reply.message);return;} _obj.DATA = reply.data; _obj.dataUpdated(); } }); }); _obj.updateIsRequired = function () { return false; // placeholder for when there are data structure changes between versions and things like that }; if (typeof(_obj.DATA) === 'undefined') _obj.DATA = {}; if (_obj.DATA === null || typeof(_obj.DATA.trena) === 'undefined') _obj.requestUpdate(true); let get = function (treno) { if (_obj.DATA !== null && typeof(_obj.DATA.trena[treno]) !== 'undefined') return _obj.DATA.trena[treno]; _obj.requestUpdate(true); return null; }; let correctRoute = function(data, ddro, index_by_stno=true) { // I choose to return the first populated route version, because we aren't going to be // changing route versions very often. If I rely on dates, I run the risk of not getting // the route of a non-regular train. // if (!ddro) { // console.log(data); let firstIndex = null; for (let e = 1; e < 8; e++) { let v = data[`VERSION_D${e}`]; if (v*1 === 0) continue; let r = data.versions[v].ROUTE; if (r*1 > 0) { firstIndex = r; break; } } if (firstIndex === null) { console.warn(`\n\n\nRoutes were blank for train ${data.TRENO}, attempting to update cache...\n\n\n`); _obj.requestUpdate(true); } return index_by_stno ? data.routes[firstIndex] : data.routes_by_stat[firstIndex]; // } else { // let dow = ddro < 8 ? ddro : solapps.util.date.dow(ddro); // let version = data[`VERSION_D${dow}`]; // let vdata = data.versions[version]; // // if (vdata === undefined) // // console.log({version:version, dow:dow, ddro:ddro, data:data}); // return data.routes[vdata.ROUTE]; // } }; let route_object = function(data) { if (data === null) return null; let by_stno = []; let _data = data; for (let e in data) { let s = data[e]; by_stno.push( {stat:s.stat, tafix : s.tafix, tanax : s.tanax, seq:e*1} ); } by_stno.sort(function(a,b) { if (a.seq > b.seq) return 1; else if (a.seq < b.seq) return -1; else return 0; }); let firstStop = by_stno[0]; let lastStop = by_stno[ by_stno.length - 1 ]; this.by_stno = by_stno; this.by_station = {}; for (let e in by_stno) { let x = by_stno[e]; this.by_station[x.stat] = x; } this.stopsAt = function(stat) { return typeof(this.by_station[stat]) !== 'undefined'; }; this.isFirstStop = function(stat) { return firstStop.stat === stat; }; this.isLastStop = function(stat) { return lastStop.stat === stat; }; this.getStartingStation = function() {return firstStop.stat;} this.getEndingStation = function() {return lastStop.stat;} this.arrivalTime = function(stat) { if (!this.stopsAt(stat)) return null; return this.by_station[stat].tafix*1; }; this.departureTime = function(stat) { if (!this.stopsAt(stat)) return null; return this.by_station[stat].tanax*1; } this.arrivalAddDays = function(stat) { let tanax0 = _data[0].tanax*1; let tafix = this.arrivalTime(stat); return (tafix < tanax0) ? 1 : 0; }; this.departureAddDays = function(stat) { let tanax0 = _data[0].tanax*1; let tanax1 = this.departureTime(stat); return (tanax1 < tanax0) ? 1 : 0; }; this.indexOf = function(stat) { if (!this.stopsAt(stat)) return -1; return this.by_station[stat].seq; }; }; _obj.getStartingStation = function (treno, ddro=null) { let data = get(treno); ddro = makeInteger(ddro); if (data == null) return null; return correctRoute(data, ddro)[0].stat; }; _obj.getEndingStation = function (treno, ddro=null) { let data = get(treno); if (data == null) return null; ddro = makeInteger(ddro); let route = correctRoute(data, ddro); return route[ route.length-1 ].stat; }; _obj.timeDepartureInitial = function (treno, ddro=null) { let data = get(treno); if (data == null) return null; ddro = makeInteger(ddro); return correctRoute(data, ddro)[0].tanax; }; _obj.timeArrivalFinal = function (treno, ddro=null) { let data = get(treno); if (data == null) return null; ddro = makeInteger(ddro); let route = correctRoute(data, ddro); return route[ route.length-1 ].tafix; }; _obj.timeDepartureAt = function (treno, stat, ddro=null) { let data = get(treno); if (data == null) return null; ddro = makeInteger(ddro); let index = _obj.indexOfStationInRoute(treno, stat, ddro); if (index === null) return null; return correctRoute(data, ddro)[index].tanax; }; _obj.timeArrivalAt = function (treno, stat, ddro=null) { let data = get(treno); if (data == null) return null; ddro = makeInteger(ddro); let index = _obj.indexOfStationInRoute(treno, stat, ddro); if (index == null) { // console.warn(`trena.timeArrivalAt(${treno}, ${stat}, ${ddro}) => station ${stat} seems not to be in route!`) return null; } let route = correctRoute(data, ddro); return route[index].tafix; }; _obj.changesDayAt = function (treno, stat, ddro=null) { if (treno == null || stat == null || !_obj.stopsAt(treno, stat)) return false; ddro = makeInteger(ddro); let start = _obj.timeDepartureInitial(treno, ddro) * 1; let end = _obj.timeArrivalAt(treno, stat, ddro) * 1; return end < start; }; _obj.dateArrivalFinal = function (treno, ddro=null) { let data = get(treno); if (data == null) return null; ddro = makeInteger(ddro); if (_obj.changesDayAt(treno, _obj.getEndingStation(treno))) return solapps.util.date.moveDate(ddro, 1); return ddro; }; _obj.dateArrivalAt = function (treno, ddro, stat) { let data = get(treno); ddro = makeInteger(ddro); let dow = solapps.util.date.dow(ddro); if (data == null || !_obj.stopsAt(treno, stat, dow)) return null; if (_obj.changesDayAt(treno, stat)) return solapps.util.date.moveDate(ddro, 1); return ddro; }; _obj.dateInitialDepartureFor = function (treno, dbrd, stat) { let data = get(treno); dbrd = makeInteger(dbrd); let dow = solapps.util.date.dow(dbrd); // minor danger here, but practically none for the Greek network // console.log({in_treno:treno, in_dbrd:dbrd, in_stat:stat, dow:dow, stops:_obj.stopsAt(treno, stat, dow)}); if (data == null || !_obj.stopsAt(treno, stat, dow)) return null; if (_obj.changesDayAt(treno, stat, dbrd)) return solapps.util.date.moveDate(dbrd, -1); return dbrd; }; _obj.getDBRDfor = _obj.dateArrivalAt; _obj.getDDROfor = _obj.dateInitialDepartureFor; _obj.exists = function (treno) { let data = get(treno); return data !== null; }; _obj.getVersionFor = function (treno, day_of_the_week) { let data = get(treno); if (data == null) return null; day_of_the_week = makeInteger(day_of_the_week); day_of_the_week = fixDOW(day_of_the_week); return data['VERSION_D'+day_of_the_week]; } _obj.runsOnDOW = function (treno, day_of_the_week) { let data = get(treno); if (data == null) return null; day_of_the_week = makeInteger(day_of_the_week); day_of_the_week = fixDOW(day_of_the_week); return _obj.getVersionFor(treno, day_of_the_week) != null; } _obj.hasReservation = function (treno, ddro=null) { let data = get(treno); if (data == null) return null; ddro = makeInteger(ddro); let version = _obj.getVersionFor(treno, fixDOW(ddro)); if (version === 0) return false; return data.versions[version].KRATHSH*1 === 1; }; _obj.getRoute = function(treno, ddro) { ddro = makeInteger(ddro); let data = get(treno); if (!data) return null; let stops = correctRoute(data, ddro); return new route_object(stops); }; _obj.stopsAt = function (treno, stat, dow) { let data = get(treno); if (data == null) return null; dow = makeInteger(dow); dow = fixDOW(dow); let route = correctRoute(data, dow, false); // console.log({at:'stopsAt', treno:treno, dow:dow, stat:stat, route:route, data:data}); return typeof(route[stat]) != 'undefined'; }; _obj.indexOfStationInRoute = function (treno, stat, ddro) { ddro = makeInteger(ddro); let data = get(treno); if (data == null) return null; let route = correctRoute(data, ddro, false); if (typeof(route[stat]) == 'undefined') return null; // console.log("treno:"+treno+", stat:"+stat+", version:"+version+", route_version:"+route_version); // console.log(data.routes_by_stat[route_version][stat]); return route[stat].stno*1 - 1; }; _obj.getType = function(treno, ddro=null) { let data = get(treno); if (data == null) return ''; return data.EMP_TYPE; }; _obj.getTypeNameFull = function(treno, ddro=null) { let typos = _obj.getType(treno); if (!typos || typeof(_obj.DATA.typoi[typos]) === 'undefined') return ''; return _obj.DATA.typoi[typos+''].LABEL_GR; }; _obj.getTypeNameShort = function(treno, ddro=null) { let typos = _obj.getType(treno); if (!typos || typeof(_obj.DATA.typoi[typos]) === 'undefined') return ''; return _obj.DATA.typoi[typos+''].SHORT_GR; }; _obj.getTypeNameShortFromOldCode = function(code, lang='gr') { if (!['gr', 'en'].includes(lang)) lang = 'gr'; lang = lang.toUpperCase(); for (let ty in _obj.DATA.typoi) { let data = _obj.DATA.typoi[ty]; if (data.OLD_CODES == null) continue; if (data.OLD_CODES.includes(`:${code}:`)) return data[`SHORT_${lang}`]; } return ''; }; _obj.isSuburban = function(treno, ddro=null) { let type = _obj.getType(treno); if (type === null) return false; return type*1 === CONSTS.TYPE_SUBURBAN; }; return _obj; })();