(function() {
/**
* @typedef {Help4.engine.StateEngine.Params} Help4.engine.ConditionEngine.Params
* @property {Help4.controller.ControllerBase} controller
* @property {Help4.service.ConditionService} conditionService
* @property {Help4.engine.DomRefreshEngine} domRefreshEngine
* @property {Help4.engine.hotspotManager.HotspotManagerEngine} hotspotManager
*/
/**
* ConditionEngine class.
* @augments Help4.engine.StateEngine
*/
Help4.engine.ConditionEngine = class extends Help4.engine.StateEngine {
/**
* @override
* @param {Help4.engine.ConditionEngine.Params} params
*/
constructor(params) {
super(params, {
controller: null,
hotspotManager: null,
domRefreshEngine: null,
conditionService: null
});
this.onChange = new Help4.EmbeddedEvent();
this._execJob = () => this.execJob.call(this);
}
/** @override */
destroy() {
this.stop();
delete this._status;
delete this._execJob;
this.onChange?.destroy();
delete this.onChange;
super.destroy();
}
/** @override */
start() {
if (this._started) return;
super.start();
const {_execJob} = this;
this._status = {};
this._params.domRefreshEngine.addExecutor(_execJob); // watch DOM UI Elements
window.addEventListener('popstate', _execJob); // watch URL changes
}
/** @override */
stop() {
if (!this._started) return;
super.stop();
const {_execJob} = this;
this._params.domRefreshEngine.removeExecutor(_execJob);
window.removeEventListener('popstate', _execJob);
this._status = {};
}
/** @override */
clean() {
this._status = {};
}
/**
* @param {string} tileId
* @return {boolean}
*/
getStatus(tileId) {
return this._status?.[tileId] ?? true;
}
execJob() {
if (!this._started) return;
const {_params: {controller, conditionService}, _status} = this;
const {isEditMode = true, isTourMode = true} = controller?.getConfiguration() || {};
if (isEditMode || isTourMode) return;
const model = controller.getService('model');
const carousel = controller.getHandler()?.getCarousel();
const tiles = [];
const promises = [];
for (const carouselTile of carousel?.getTile() || []) {
const tileId = carouselTile.getMetadata('tileId');
const tourId = carouselTile.getMetadata('tourId');
const tile = tileId
? model.getTile(tileId)
: (tourId ? model.getProject({id: tourId}) : null);
if (tile?.conditions?.length) {
const {id, conditions, hotspotAnchor} = tile;
tiles.push(id);
promises.push(conditionService.checkConditions({conditions, hotspotAnchor}));
}
}
Help4.Promise.all(promises)
.then(result => {
/**
* @param {boolean|null} fulfilled
* @param {number} index
*/
result.forEach((fulfilled, index) => {
const id = tiles[index];
if (typeof fulfilled === 'boolean' && _status[id] !== fulfilled) {
_status[id] = fulfilled;
this.onChange.onEvent({id, fulfilled});
}
});
});
}
}
})();