2013-11-27 11:12:50 +01:00
/ *
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/>.
* /
2014-07-03 16:53:07 +02:00
( function ( $ ) {
2014-06-28 16:40:24 +02:00
'use strict' ;
2014-07-03 18:36:43 +02:00
var uhrGlobals = {
"id" : 0 ,
"languages" : [ ] ,
"themes" : [ ] ,
2014-07-03 20:10:55 +02:00
registerLanguage : function registerLanguage ( code , language ) {
2014-07-03 20:33:26 +02:00
var alreadyExists = uhrGlobals . languages . reduce ( function ( exists , element ) {
2014-07-03 20:10:55 +02:00
if ( exists ) {
return true ;
}
2014-07-03 18:36:43 +02:00
if ( code === element . code ) {
console . error ( "Error: Language code '" + code + "' cannot be registered for language '" + language . language + "' because it is already registered for language '" + element . language + "'!" ) ;
2014-07-03 20:10:55 +02:00
return true ;
2014-07-03 18:36:43 +02:00
}
2014-07-03 20:10:55 +02:00
return false ;
} , false ) ;
if ( ! alreadyExists ) {
language . code = code ;
2014-07-03 20:33:26 +02:00
uhrGlobals . languages . push ( language ) ;
2014-07-03 20:10:55 +02:00
}
2014-07-03 18:36:43 +02:00
}
} ;
2014-01-11 03:26:53 +01:00
2014-06-28 02:00:34 +02:00
// auto-detect themes
2014-06-28 23:12:20 +02:00
var styleSheets = $ ( 'link[rel=stylesheet]' ) ;
2014-06-28 10:54:28 +02:00
for ( var i = 0 ; i < styleSheets . length ; i ++ ) {
var styleSheet = $ ( styleSheets [ i ] ) ;
var styleClass = styleSheet . attr ( 'data-class' ) ;
if ( styleClass !== undefined ) {
var name = styleSheet . attr ( 'data-name' ) ;
if ( name === undefined ) {
name = styleClass ;
}
2014-07-03 20:33:26 +02:00
uhrGlobals . themes . push ( { 'styleClass' : styleClass , 'name' : name } ) ;
2014-06-28 10:54:28 +02:00
}
2014-06-28 02:00:34 +02:00
}
2014-06-28 13:56:20 +02:00
// fall-back if no theme was included
2014-07-03 20:33:26 +02:00
if ( uhrGlobals . themes . length === 0 ) {
uhrGlobals . themes . push ( { } ) ;
2014-06-28 13:56:20 +02:00
}
2014-01-11 03:26:53 +01:00
2014-07-03 20:10:55 +02:00
// public interface methods (exported later)
var start = function start ( ) {
if ( ! isOn ( this ) ) {
var uhr = this ;
this . _timer = window . setInterval ( function uhrTimer ( ) {
uhr . options . time = new Date ( ) ;
update ( uhr ) ;
} , 1000 ) ;
update ( this ) ;
setCookie ( this , 'uhr-status' , 'on' ) ;
}
} ;
var stop = function stop ( ) {
if ( isOn ( this ) ) {
window . clearInterval ( this . _timer ) ;
this . _timer = null ;
update ( this ) ;
setCookie ( this , 'uhr-status' , 'off' ) ;
}
} ;
var toggle = function toggle ( ) {
if ( isOn ( this ) ) {
this . stop ( ) ;
} else {
this . start ( ) ;
}
} ;
var setLanguage = function setLanugage ( languageKey ) {
if ( languageKey !== this . options . language ) {
this . options . language = languageKey ;
var renderer = new UhrRenderer ( language ( this ) , this . element . find ( '.letterarea' ) ) ;
var uhr = this ;
renderer . render ( this , function ( ) {
uhr . _currentMinute = - 1 ;
update ( uhr ) ;
} ) ;
setCookie ( this , 'uhr-language' , languageKey ) ;
update ( this ) ;
}
} ;
var setTheme = function setTheme ( theme ) {
if ( theme !== this . options . theme ) {
this . element . removeClass ( this . options . theme ) . addClass ( theme ) ;
$ ( '#uhr-onoffswitch' + this . _id ) . removeClass ( this . options . theme ) . addClass ( theme ) ;
this . options . theme = theme ;
setCookie ( this , 'uhr-theme' , theme ) ;
}
} ;
var setTime = function setTime ( time ) {
this . _currentMinute = - 1 ;
if ( time === null ) {
this . options . time = new Date ( ) ;
} else {
if ( this . _timer !== null ) {
window . clearInterval ( this . _timer ) ;
}
this . options . time = time ;
}
update ( this ) ;
} ;
2014-01-11 03:26:53 +01:00
2014-07-03 20:10:55 +02:00
// private interface methods
var create = function create ( ) {
2014-07-03 20:33:26 +02:00
this . _id = uhrGlobals . id ++ ;
2014-07-03 20:10:55 +02:00
var userTime = this . options . time ;
if ( this . options . time === undefined ) {
this . options . time = new Date ( ) ;
}
setupHTML ( this ) ;
wireFunctionality ( this ) ;
if ( userTime !== undefined ) {
this . time ( userTime ) ;
}
} ;
// private helper methods (not exported)
// set up
var setupHTML = function setupHTML ( uhr ) {
var e = uhr . element ;
// Base clock area
e . addClass ( 'uhr' ) ;
e . empty ( ) ;
e . append ( '<span class="item dot dot1"></span>' ) ;
e . append ( '<span class="item dot dot2"></span>' ) ;
e . append ( '<span class="item dot dot3"></span>' ) ;
e . append ( '<span class="item dot dot4"></span>' ) ;
e . append ( '<div class="letterarea"></div>' ) ;
e . append ( '<div class="reflection"></div>' ) ;
e . css ( 'width' , uhr . options . width ) ;
var realWidth = e . width ( ) ;
e . width ( realWidth ) ;
e . height ( realWidth ) ;
e . css ( 'font-size' , ( realWidth / 40 ) + 'px' ) ;
2014-01-11 03:26:53 +01:00
2014-07-03 20:10:55 +02:00
if ( uhr . options . controls ) {
// on/off switch
var toggleSwitch = $ ( '<div class="onoffswitch" id="uhr-onoffswitch' + uhr . _id + '"></div>' ) ;
toggleSwitch . append ( '<input type="checkbox" class="onoffswitch-checkbox" id="uhr-onoffswitch-checkbox' + uhr . _id + '" checked="checked" />' ) ;
toggleSwitch . append ( '<label class="onoffswitch-label" for="uhr-onoffswitch-checkbox' + uhr . _id + '">'
+ '<div class="onoffswitch-inner"></div>'
+ '<div class="onoffswitch-switch"></div>'
+ '</label>' ) ;
e . after ( toggleSwitch ) ;
2014-01-11 03:26:53 +01:00
2014-07-03 20:10:55 +02:00
// language chooser
2014-07-03 20:33:26 +02:00
if ( uhrGlobals . languages . length > 1 ) {
2014-07-03 20:10:55 +02:00
var languageChooser = $ ( '<select id="uhr-languagechooser' + uhr . _id + '"></select>' ) ;
2014-07-03 20:33:26 +02:00
for ( var i = 0 ; i < uhrGlobals . languages . length ; i ++ ) {
var language = uhrGlobals . languages [ i ] ;
2014-07-03 20:10:55 +02:00
languageChooser . append ( '<option value="' + language . code + '">' + language . language + '</option>' ) ;
}
e . after ( languageChooser ) ;
}
2014-01-11 03:26:53 +01:00
2014-07-03 20:10:55 +02:00
// theme chooser
2014-07-03 20:33:26 +02:00
if ( uhrGlobals . themes . length > 1 ) {
2014-07-03 20:10:55 +02:00
var themeChooser = $ ( '<select id="uhr-themechooser' + uhr . _id + '"></select>' ) ;
2014-07-03 20:33:26 +02:00
for ( var i = 0 ; i < uhrGlobals . themes . length ; i ++ ) {
var theme = uhrGlobals . themes [ i ] ;
2014-07-03 20:10:55 +02:00
themeChooser . append ( '<option value="' + theme . styleClass + '">' + theme . name + '</option>' ) ;
}
e . after ( themeChooser ) ;
}
}
} ;
var wireFunctionality = function wireFunctionality ( uhr ) {
2014-01-11 03:26:53 +01:00
2014-07-03 20:10:55 +02:00
// on/off switch
var toggleSwitch = $ ( '#uhr-onoffswitch-checkbox' + uhr . _id ) ;
toggleSwitch . on ( 'click' , function ( ) {
uhr . toggle ( ) ;
} ) ;
var status = $ . cookie ( 'uhr-status' + uhr . _id ) ;
if ( status === undefined || uhr . options . force ) {
status = uhr . options . status ;
}
toggleSwitch . prop ( 'checked' , status === 'on' ) ;
if ( status === 'on' ) {
uhr . start ( ) ;
} else {
uhr . stop ( ) ;
}
// language chooser
var languageChooser = $ ( '#uhr-languagechooser' + uhr . _id ) ;
languageChooser . on ( 'change' , function ( ) {
uhr . language ( this . value ) ;
} ) ;
var selectedLanguage = $ . cookie ( 'uhr-language' + uhr . _id ) ;
if ( selectedLanguage === undefined || uhr . options . force ) {
selectedLanguage = uhr . options . language ;
}
var found = false ;
2014-07-03 20:33:26 +02:00
for ( var i = 0 ; i < uhrGlobals . languages . length ; i ++ ) {
var code = uhrGlobals . languages [ i ] . code ;
2014-07-03 20:10:55 +02:00
if ( selectedLanguage === code ) {
found = true ;
break ;
}
}
if ( ! found ) {
var fallback ;
2014-07-03 20:33:26 +02:00
if ( uhrGlobals . languages . length > 0 ) {
fallback = uhrGlobals . languages [ 0 ] . code ;
2014-07-03 20:10:55 +02:00
} else {
fallback = '' ;
}
console . warn ( "Language " + selectedLanguage + " not found! Using fallback: " + fallback ) ;
selectedLanguage = fallback ;
}
languageChooser . val ( selectedLanguage ) ;
uhr . options . language = "" ;
uhr . language ( selectedLanguage ) ;
// theme chooser
var themeChooser = $ ( '#uhr-themechooser' + uhr . _id ) ;
themeChooser . on ( 'change' , function ( ) {
uhr . theme ( this . value ) ;
} ) ;
var selectedTheme = $ . cookie ( 'uhr-theme' + uhr . _id ) ;
if ( selectedTheme === undefined || uhr . options . force ) {
selectedTheme = uhr . options . theme ;
}
found = false ;
2014-07-03 20:33:26 +02:00
for ( var i = 0 ; i < uhrGlobals . themes . length ; i ++ ) {
var styleClass = uhrGlobals . themes [ i ] . styleClass ;
2014-07-03 20:10:55 +02:00
if ( selectedTheme === styleClass ) {
found = true ;
break ;
}
}
if ( ! found ) {
2014-07-03 20:33:26 +02:00
var fallback = uhrGlobals . themes [ 0 ] . styleClass ;
2014-07-03 20:10:55 +02:00
console . warn ( "Theme " + selectedTheme + " not found! Using fallback: " + fallback ) ;
selectedTheme = fallback ;
}
themeChooser . val ( selectedTheme ) ;
uhr . options . theme = "" ;
uhr . theme ( selectedTheme ) ;
} ;
var setCookie = function setCookie ( uhr , cookieName , cookieValue ) {
var options = { } ;
if ( uhr . options . cookiePath !== undefined ) {
options = { expires : 365 , path : uhr . options . cookiePath } ;
} else {
options = { expires : 365 } ;
}
$ . cookie ( cookieName + uhr . _id , cookieValue , options ) ;
} ;
// business logic
var isOn = function isOn ( uhr ) {
return uhr . _timer !== null ;
} ;
var update = function update ( uhr ) {
if ( isOn ( uhr ) ) {
var time = uhr . options . time ;
if ( time . getMinutes ( ) === uhr . _currentMinute ) {
return ;
}
uhr . _currentMinute = time . getMinutes ( ) ;
show ( uhr , time ) ;
} else {
clear ( uhr ) ;
uhr . _currentMinute = - 1 ;
}
} ;
var show = function show ( uhr , time ) {
var dotMinute = getDotMinute ( uhr , time ) ;
var hour = getHour ( uhr , time ) ;
var coarseMinute = getCoarseMinute ( uhr , time ) ;
clear ( uhr ) ;
highlight ( uhr , 'on' ) ;
for ( var i = 1 ; i <= dotMinute ; i ++ ) {
highlight ( uhr , 'dot' + i ) ;
}
highlight ( uhr , 'minute' + coarseMinute ) ;
highlight ( uhr , 'hour' + hour ) ;
} ;
var highlight = function highlight ( uhr , itemClass ) {
uhr . element . find ( '.item.' + itemClass ) . addClass ( 'active' ) ;
} ;
var clear = function clear ( uhr ) {
uhr . element . find ( '.item' ) . removeClass ( 'active' ) ;
} ;
var getDotMinute = function getDotMinute ( uhr , date ) {
if ( typeof language ( uhr ) . getDotMinute === 'function' ) {
return language ( uhr ) . getDotMinute ( date ) ;
}
var minutes = date . getMinutes ( ) ;
return minutes % 5 ;
} ;
var getCoarseMinute = function getCoarseMinute ( uhr , date ) {
if ( typeof language ( uhr ) . getCoarseMinute === 'function' ) {
return language ( uhr ) . getCoarseMinute ( date ) ;
}
return date . getMinutes ( ) ;
} ;
var getHour = function getHour ( uhr , date ) {
if ( typeof language ( uhr ) . getHour === 'function' ) {
return language ( uhr ) . getHour ( date ) ;
}
var hour = date . getHours ( ) ;
if ( date . getMinutes ( ) >= 25 ) {
return ( hour + 1 ) % 24 ;
}
return hour ;
} ;
var language = function language ( uhr ) {
2014-07-03 20:33:26 +02:00
var matchingLanguages = uhrGlobals . languages . filter ( function ( element ) {
2014-07-03 20:10:55 +02:00
return ( element . code === this . options . language )
} , uhr ) ;
if ( matchingLanguages . length > 0 ) {
return matchingLanguages [ 0 ] ;
}
// fallback: return empty object
return { } ;
} ;
$ . widget ( "fritteli.uhr" , {
"options" : {
width : '100%' ,
status : 'on' ,
language : 'de_CH' ,
2014-07-03 20:33:26 +02:00
theme : uhrGlobals . themes [ 0 ] . styleClass ,
2014-07-03 20:10:55 +02:00
force : false ,
controls : true
} ,
"start" : start ,
"stop" : stop ,
"toggle" : toggle ,
"language" : setLanguage ,
"theme" : setTheme ,
"time" : setTime ,
// constructor method
"_create" : create ,
// private variables
"_id" : - 1 ,
"_timer" : null ,
"_currentMinute" : - 1
} ) ;
2014-07-03 20:33:26 +02:00
$ . fritteli . uhr . register = uhrGlobals . registerLanguage ;
2014-06-28 15:53:08 +02:00
/ * *
* Hilfsklasse zum Rendern der Uhr .
* @ param layout Layout - Objekt , das gerendert werden soll .
* @ param renderarea Das jQuery - gewrappte HTML - Element , auf dem gerendert werden soll .
* /
function UhrRenderer ( layout , renderarea ) {
this . layout = layout ;
this . renderarea = renderarea ;
2014-06-25 12:52:32 +02:00
}
2014-07-03 16:53:07 +02:00
UhrRenderer . prototype . render = function ( uhr , beforeshow ) {
2014-06-28 15:53:08 +02:00
var renderer = this ;
if ( this . layout . _parsed === undefined ) {
switch ( this . layout . version ) {
case 2 :
var delegate = new _UhrRendererV2Delegate ( this . layout ) ;
this . layout . _parsed = delegate . parse ( ) ;
break ;
default :
console . warn ( "Unknown layout version: '" + this . layout . version + "'" ) ;
return ;
2013-11-26 13:25:50 +01:00
}
}
2014-06-28 15:53:08 +02:00
var letters = this . layout . _parsed ;
2014-07-03 16:53:07 +02:00
this . renderarea . fadeOut ( 'fast' , function ( ) {
2014-06-28 15:53:08 +02:00
renderer . renderarea . empty ( ) ;
for ( var y = 0 ; y < letters . length ; y ++ ) {
for ( var x = 0 ; x < letters [ y ] . length ; x ++ ) {
var letter = letters [ y ] [ x ] ;
renderer . renderarea . append ( letter . toString ( ) ) ;
}
if ( y < letters . length - 1 ) {
renderer . renderarea . append ( '<br/>' ) ;
}
}
if ( typeof beforeshow === 'function' ) {
beforeshow ( ) ;
}
renderer . renderarea . fadeIn ( 'fast' ) ;
} ) ;
2014-06-19 23:09:58 +02:00
} ;
2014-06-28 15:53:08 +02:00
function _UhrRendererV2Delegate ( layout ) {
this . layout = layout ;
2014-07-03 16:53:07 +02:00
this . _parseArrayOrObject = function ( letters , styleClass , input ) {
2014-06-28 15:53:08 +02:00
if ( Array . isArray ( input ) ) {
for ( var i = 0 ; i < input . length ; i ++ ) {
this . _parseObject ( letters , styleClass , input [ i ] ) ;
}
} else {
this . _parseObject ( letters , styleClass , input ) ;
}
2014-06-26 15:52:08 +02:00
}
2014-06-28 15:53:08 +02:00
this . _parseObject = function ( letters , styleClass , object ) {
for ( var line in object ) {
if ( object . hasOwnProperty ( line ) ) {
var highlightLetters = object [ line ] ;
for ( var i = 0 ; i < highlightLetters . length ; i ++ ) {
var x = highlightLetters [ i ] - 1 ;
letters [ line - 1 ] [ x ] . addStyle ( styleClass ) ;
}
2014-06-26 15:52:08 +02:00
}
}
}
2014-06-28 15:53:08 +02:00
this . _parseTimeDefinition = function ( letters , styleClass , definition ) {
for ( var listString in definition ) {
if ( definition . hasOwnProperty ( listString ) ) {
var array = listString . split ( ',' ) ;
var highlightLetters = definition [ listString ] ;
for ( var index = 0 ; index < array . length ; index ++ ) {
this . _parseArrayOrObject ( letters , styleClass + array [ index ] , highlightLetters ) ;
}
2014-06-26 15:52:08 +02:00
}
}
}
2013-11-25 12:53:54 +01:00
}
2014-06-28 15:53:08 +02:00
_UhrRendererV2Delegate . prototype . parse = function ( ) {
var letters = [ ] ;
for ( var i = 0 ; i < this . layout . letters . length ; i ++ ) {
var line = [ ] ;
var string = this . layout . letters [ i ] ;
for ( var c = 0 ; c < string . length ; c ++ ) {
var character = new Letter ( string [ c ] ) ;
line . push ( character ) ;
}
letters . push ( line ) ;
2014-06-26 15:52:08 +02:00
}
2014-06-28 15:53:08 +02:00
this . _parseArrayOrObject ( letters , 'on' , this . layout . permanent ) ;
this . _parseTimeDefinition ( letters , 'minute' , this . layout . minutes ) ;
this . _parseTimeDefinition ( letters , 'hour' , this . layout . hours ) ;
return letters ;
2014-06-19 23:09:58 +02:00
} ;
2014-06-28 15:53:08 +02:00
/ * *
* Ein Buchstabe . Hilfsklasse für den Renderer und Inhalt der Layout - Arrays .
* @ param value Der Buchstabe , der Dargestellt werden soll .
* @ param style Die CSS - Styleklassen des Buchstabens .
* /
function Letter ( value , style ) {
2014-07-03 18:36:43 +02:00
var myValue = value ;
var myStyle = style || '' ;
2014-06-28 15:53:08 +02:00
this . addStyle = function ( style ) {
2014-07-03 18:36:43 +02:00
if ( myStyle == '' ) {
myStyle = style ;
2014-06-28 15:53:08 +02:00
} else {
2014-07-03 18:36:43 +02:00
myStyle += ' ' + style ;
2014-06-28 15:53:08 +02:00
}
2014-06-26 13:46:10 +02:00
}
2014-07-03 18:36:43 +02:00
this . toString = function ( ) {
return '<span class="item letter ' + myStyle + '">' + myValue + '</span>' ;
} ;
2013-11-25 10:57:30 +01:00
}
2014-07-03 20:37:34 +02:00
} ) ( jQuery ) ;