(function() {
'use strict';
/**
* Usage pattern
*
*/
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
angular.module('ds.clock', [])
.directive('dsWidgetClock', ['$interval', '$filter',
function($interval, $filter) {
return clock($interval, $filter);
}
]);
function clock($interval, $filter) {
return {
restrict: 'EA',
scope: {
gmtOffset: '=gmtOffset',
digitalFormat: '=digitalFormat',
showDigital: '=showDigital',
showAnalog: '=showAnalog',
startTime: '=startTime',
theme: '=theme',
majorsTotal: '=majorsTotal'
},
template: '
',
link: function(scope, element, attrs) {
var format, // date format
stopTime; // so that we can cancel the time updates
var o = {};
var gmtOffset = scope.gmtOffset;
var digitalFormat = scope.digitalFormat ? scope.digitalFormat : 'HH:mm:ss';
o.showDigital = scope.showDigital != null ? scope.showDigital : attrs.showDigital !== undefined ? true : false;
o.showAnalog = scope.showAnalog != null ? scope.showAnalog : attrs.showAnalog !== undefined ? true : false;
o.showGmtInfo = attrs.showGmtInfo !== undefined ? true : false;
o.startTime = parseInt(scope.startTime, 10); // ms
scope.themeClass = scope.theme ? scope.theme : attrs.theme ? attrs.theme : 'light';
if (!o.showDigital && !o.showAnalog) {
o.showAnalog = true;
o.showDigital = true;
}
scope.gmtInfo = false;
scope.date = getDate(o);
scope.digital = o.showDigital ? 'Loading..' : false;
scope.analog = o.showAnalog;
scope.majors = attrs.majorsTotal ? new Array(parseInt(attrs.majorsTotal)) : new Array(12);
scope.minors = new Array(60);
var date = null;
var tick = function() {
if (!isNaN(o.startTime)) {
o.startTime = o.startTime + 1000;
}
date = getDate(o);
scope.date = date;
if (o.showDigital) {
scope.digital = timeText(date, digitalFormat, $filter);
}
};
stopTime = $interval(tick, 1000);
// watch the expression, and update the UI on change.
scope.$watch('gmtOffset', function(value, old) {
gmtOffset = value;
o.gmtOffset = (gmtOffset != null) ? getGMTbase100(gmtOffset) : false;
if (o.showGmtInfo && o.gmtOffset !== false) {
scope.gmtInfo = getGMTText(o.gmtOffset);
}
tick();
});
scope.$watch('digitalFormat', function(value, old) {
if(value != old){
digitalFormat = value;
}
});
scope.$watch('startTime', function(value, old) {
if(value != old){
o.startTime = parseInt(value, 10);
}
});
scope.$watch('showDigital', function(value, old) {
if(value != old){
o.showDigital = value;
scope.digital = o.showDigital ? 'Loading..' : false;;
}
});
scope.$watch('showAnalog', function(value, old) {
if(value != old){
o.showAnalog = value;
scope.analog = value;
}
});
scope.$watch('theme', function(value, old) {
if(value != old){
scope.themeClass = value ? value : attrs.theme ? attrs.theme : 'light';
}
});
// listen on DOM destroy (removal) event, and cancel the next UI update
// to prevent updating time after the DOM element was removed.
element.on('$destroy', function() {
$interval.cancel(stopTime);
stopTime = null;
});
}
};
}
function getGMTbase100(offset) {
offset = parseFloat(offset);
var f = offset > 0 ? Math.floor(offset) : Math.ceil(offset),
s = (offset % 1) / 0.6;
return f + s;
}
function getGMTbase60(offset) {
var f = offset > 0 ? Math.floor(offset) : Math.ceil(offset),
s = ((offset > 0 ? offset : offset * -1) % 1) * 60;
return f + s;
}
function getGMTText(offset) {
var f = offset > 0 ? Math.floor(offset) : Math.ceil(offset),
s = Math.round(((offset > 0 ? offset : offset * -1) % 1) * 60);
return 'GMT' + (offset === 0 ? '' : ((offset > 0 ? ' +' : ' ') + lpad(f) + '.' + rpad(s).substring(0, 2)));
}
function lpad(num) {
if (num < 0) {
return (num > -10 ? '-0' : '-') + (num * -1);
} else {
return (num < 10 ? '0' : '') + num;
}
}
function rpad(num) {
return num + (num < 10 ? '0' : '');
}
// Checkfor offset and get correct time
function getDate(o) {
var now = (!isNaN(o.startTime)) ? new Date(o.startTime) : new Date();
if (o.gmtOffset !== null && o.gmtOffset !== false) {
/*Use GMT + gmtOffset
convert to msec
add local time zone offset
get UTC time in msec*/
var utc = now.getTime() + (now.getTimezoneOffset() * 60000);
// create new Date object for different city
// using supplied offset
var offsetNow = new Date(utc + (3600000 * o.gmtOffset));
return {
hrs: offsetNow.getHours(),
mins: offsetNow.getMinutes(),
secs: offsetNow.getSeconds(),
date: offsetNow
};
} else {
// Use local time
return {
hrs: now.getHours(),
mins: now.getMinutes(),
secs: now.getSeconds(),
date: now
};
}
}
function timeText(d, format, $filter) {
return $filter('date')(d.date, format);
}
})();