/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /*eslint no-undef: "warn"*/ import WidgetCommonProperties = JQueryUI.WidgetCommonProperties; import {EMPTY_LAYOUT, Layout} from './domain/layout'; import {CookieHandler} from './cookie-handler'; import {Globals} from './domain/globals'; import {LayoutRenderer} from './layout-renderer'; import {UhrRenderer} from './uhr-renderer'; import {WidgetPrototype} from './widget/widget-prototype'; declare var $: JQueryStatic; export class Uhr { private timer: number = null; private currentMinute: number = null; private renderer: UhrRenderer; private cookieHandler: CookieHandler; public constructor(private readonly widgetInstance: WidgetPrototype & WidgetCommonProperties) { const userTime = this.widgetInstance.options.time; if (this.widgetInstance.options.time === undefined) { this.widgetInstance.options.time = new Date(); } this.cookieHandler = new CookieHandler(this.widgetInstance.uuid, this.widgetInstance.options.cookiePath); this.parseHash(); this.renderer = new UhrRenderer(this, this.widgetInstance.element, this.widgetInstance.options, this.widgetInstance.uuid); this.renderer.render(); if (userTime !== undefined) { this.setTime(userTime); } } public destroy(): void { if (this.timer) { window.clearInterval(this.timer); this.timer = null; } this.widgetInstance.element .removeAttr('style') .removeAttr('class') .empty(); $(`#uhr-configlink${this.widgetInstance.uuid}`).remove(); $(`#uhr-controlpanel${this.widgetInstance.uuid}`).remove(); } public start(): void { if (!this.isOn()) { this.timer = window.setInterval((): void => { this.widgetInstance.options.time = new Date(); this.update(); }, 1000); this.update(); this.cookieHandler.setStatus('on'); } } public stop(): void { if (this.isOn()) { window.clearInterval(this.timer); this.timer = null; this.update(); this.cookieHandler.setStatus('off'); } } public toggle(): void { if (this.isOn()) { this.stop(); } else { this.start(); } } public setLayout(key: string): void { if (key !== this.widgetInstance.options.language) { this.widgetInstance.options.language = key; const renderer = new LayoutRenderer(this.getCurrentLayout(), this.widgetInstance.element.find('.letterarea')); renderer.render((): void => { this.currentMinute = -1; this.update(); }); this.cookieHandler.setLayout(key); this.update(); } } public setTheme(styleClass: string): void { if (styleClass !== this.widgetInstance.options.theme) { this.widgetInstance.element.removeClass(this.widgetInstance.options.theme).addClass(styleClass); $(`#uhr-onoffswitch${this.widgetInstance.uuid}`).removeClass(this.widgetInstance.options.theme).addClass(styleClass); this.widgetInstance.options.theme = styleClass; this.cookieHandler.setTheme(styleClass); } } public setTime(time: Date): void { this.currentMinute = null; if (time === null) { this.widgetInstance.options.time = new Date(); } else { if (this.timer !== null) { window.clearInterval(this.timer); } this.widgetInstance.options.time = time; } this.update(); } public setMode(mode: string): void { this.widgetInstance.options.mode = mode; this.currentMinute = null; this.update(); this.cookieHandler.setMode(mode); } public setWidth(width: string): void { this.renderer.setWidth(width); } private isOn(): boolean { return this.timer !== null; } private update(): void { if (this.isOn()) { const time = this.widgetInstance.options.time; if (!this.getCurrentLayout().hasOwnProperty('seconds') && this.widgetInstance.options.mode !== 'seconds') { if (time.getMinutes() === this.currentMinute) { return; } this.currentMinute = time.getMinutes(); } this.show(time); } else { this.clear(); this.currentMinute = -1; } } private show(time: Date): void { const second = this.getSecond(time); const dotMinute = this.getDotMinute(time); const hour = this.getHour(time); const coarseMinute = this.getCoarseMinute(time); this.clear(); if (this.widgetInstance.options.mode === 'seconds') { this.highlight(`second${second}`); } else { this.highlight('on'); for (let i = 1; i <= dotMinute; i++) { this.highlight(`dot${i}`); } this.highlight(`minute${coarseMinute}`); this.highlight(`hour${hour}`); } } private clear(): void { this.widgetInstance.element.find('.item').removeClass('active'); } private highlight(itemClass: string): void { this.widgetInstance.element.find(`.item.${itemClass}`).addClass('active'); } private getSecond(time: Date): number { if (typeof this.getCurrentLayout().getSeconds === 'function') { return this.getCurrentLayout().getSeconds(time); } return time.getSeconds(); } private getDotMinute(date: Date): number { if (typeof this.getCurrentLayout().getDotMinute === 'function') { return this.getCurrentLayout().getDotMinute(date); } return date.getMinutes() % 5; } private getCoarseMinute(date: Date): number { if (typeof this.getCurrentLayout().getCoarseMinute === 'function') { return this.getCurrentLayout().getCoarseMinute(date); } return date.getMinutes(); } private getHour(date: Date): number { if (typeof this.getCurrentLayout().getHour === 'function') { return this.getCurrentLayout().getHour(date); } const hour = date.getHours(); if (date.getMinutes() >= 25) { return (hour + 1) % 24; } return hour; } private parseHash(): void { let hash: string = window.location.hash; if (hash !== undefined && hash.charAt(0) === '#') { hash = hash.substring(1); hash = decodeURIComponent(hash); const params: string[] = hash.split('&'); params.forEach((element: string): void => { const pair: string[] = element.split('='); const key = pair[0]; const value = pair[1]; switch (key) { case 'l': case 'language': this.widgetInstance.options.language = value; this.widgetInstance.options.force = true; break; case 't': case 'theme': this.widgetInstance.options.theme = value; this.widgetInstance.options.force = true; break; case 'm': case 'mode': this.widgetInstance.options.mode = value; this.widgetInstance.options.force = true; break; case 's': case 'status': this.widgetInstance.options.status = value; this.widgetInstance.options.force = true; break; } }); } } private getCurrentLayout(): Layout { const matchingLanguages: Layout[] = Globals.getLayouts().filter((element: Layout): boolean => element.code === this.widgetInstance.options.language, this); if (matchingLanguages.length > 0) { return matchingLanguages[0]; } // fallback: return empty object return EMPTY_LAYOUT; } }