3 var theTimeoutSecs
= null;
4 var theTimeoutEntry
= null;
6 var theCurrentTimeoutSecs
= null;
7 var theCurrentEndTimeSecs
= null;
8 var theCurrentTimerId
= null;
10 var elBody
= $("body");
11 var elDisplay
= $("#display");
12 var elCountdownControls
= $("#countdown-controls");
13 var elConfigureControls
= $("#configure-controls");
14 var audio
= $("#alarm audio").get(0);
17 var flashElement = function(el
) {
18 el
.css("opacity", "0.5");
19 el
.animate({"opacity": "1.0"}, {"duration": 200, "queue": false});
22 var setState = function(state
) {
23 elBody
.removeClass().addClass(state
);
26 var addState = function(state
) {
27 elBody
.addClass(state
);
30 var removeState = function(state
) {
31 elBody
.removeClass(state
);
34 var padTwoDigits = function(x
) {
42 var formatTimeHMS = function(seconds
, minutes
, hours
) {
46 padTwoDigits(minutes
) +
52 var getNowSecs = function() {
53 return Math
.round(new Date().getTime() / 1000);
56 var updateTimeoutSecs = function() {
57 var seconds
= theTimeoutEntry
% 100;
58 var minutes
= Math
.floor(theTimeoutEntry
/ 100) % 100;
59 var hours
= Math
.floor(theTimeoutEntry
/ 10000) % 10000;
60 theTimeoutSecs
= seconds
+ minutes
*60 + hours
*3600;
62 var text
= formatTimeHMS(seconds
, minutes
, hours
);
66 var fillDisplay = function(s
) {
67 elDisplay
.children().remove();
68 for (var i
= 0; i
< s
.length
; ++i
) {
69 $("<span/>").text(s
[i
]).appendTo(elDisplay
);
73 var formatTimeSecs = function(tsec
) {
74 var seconds
= tsec
% 60;
75 var minutes
= Math
.floor(tsec
/ 60) % 60;
76 var hours
= Math
.floor(tsec
/ 3600);
77 return formatTimeHMS(seconds
, minutes
, hours
);
80 var beginCountdownMode = function() {
81 if (theTimeoutSecs
<= 0) {
85 setState("countdown");
87 flashElement(elConfigureControls
);
90 var beginConfigureMode = function() {
93 setState("configure");
95 flashElement(elCountdownControls
);
98 var resetConfigureMode = function() {
102 flashElement(elBody
);
105 var processDigitInput = function(newDigit
) {
106 if (theTimeoutEntry
>= 100000) {
107 // ignore too much input
110 var newDigit
= parseInt(newDigit
);
111 theTimeoutEntry
= theTimeoutEntry
* 10 + newDigit
;
115 var resetCountdown = function() {
117 theCurrentTimeoutSecs
= theTimeoutSecs
;
118 fillDisplay(formatTimeSecs(theCurrentTimeoutSecs
));
119 flashElement(elDisplay
);
122 var refreshCountdown = function() {
123 var remainingSecs
= theCurrentEndTimeSecs
- getNowSecs();
124 if (remainingSecs
<= 0) {
129 fillDisplay(formatTimeSecs(remainingSecs
));
132 var runAlarm = function() {
137 var stopAlarm = function() {
138 if (audio
.duration
> 0 && !audio
.paused
) {
140 audio
.currentTime
= 0;
142 removeState("alarm");
146 var runCountdown = function() {
147 if (theCurrentTimerId
!= null) {
150 theCurrentTimerId
= setInterval(refreshCountdown
, 100);
151 theCurrentEndTimeSecs
= getNowSecs() + theCurrentTimeoutSecs
;
152 addState("counting");
155 var stopCountdown = function() {
156 if (theCurrentTimerId
== null) {
159 clearInterval(theCurrentTimerId
);
160 theCurrentTimerId
= null;
161 removeState("counting");
164 var pauseCountdown = function() {
166 theCurrentTimeoutSecs
= theCurrentEndTimeSecs
- getNowSecs();
174 var handleConfigureKey = function(e
) {
175 // Return/Enter/Space
176 if (e
.which
== 13 || e
.which
== 32) {
178 beginCountdownMode();
182 // Backspace/Delete/Escape
183 if (e
.which
== 8 || e
.which
== 46 || e
.which
== 27) {
185 resetConfigureMode();
189 var c
= String
.fromCharCode(e
.which
);
190 if ("0123456789".indexOf(c
) >= 0) {
192 processDigitInput(c
);
197 var handleNumberButton = function(e
) {
199 processDigitInput($(this).text());
202 var handleConfigureReset = function(e
) {
204 resetConfigureMode();
207 var handleConfigureSet = function(e
) {
209 beginCountdownMode();
212 var handleCountdownKey = function(e
) {
213 if (e
.which
== 8 || e
.which
== 46) { // Backspace/Delete
218 if (e
.which
== 27) { // Escape
220 beginConfigureMode();
224 var handleAlarmKey = function(e
) {
225 // Return/Enter/Space
226 if (e
.which
== 13 || e
.which
== 32) {
233 var handleCountdownPlayKey = function(e
) {
234 // Return/Enter/Space
235 if (e
.which
== 13 || e
.which
== 32) {
242 var handleCountdownPauseKey = function(e
) {
243 // Return/Enter/Space
244 if (e
.which
== 13 || e
.which
== 32) {
251 var handleCountdownStart = function(e
) {
256 var handleCountdownPause = function(e
) {
261 var handleCountdownReset = function(e
) {
266 var handleCountdownReconfigure = function(e
) {
268 beginConfigureMode();
272 var init = function() {
273 $(document
).on("keydown", ".configure", handleConfigureKey
);
274 $("#number-buttons button").on("click", handleNumberButton
);
275 $("#configure-reset").on("click", handleConfigureReset
);
276 $("#configure-set").on("click", handleConfigureSet
);
278 $(document
).on("keydown", ".countdown", handleCountdownKey
);
279 $(document
).on("keydown", ".alarm", handleAlarmKey
);
280 $(document
).on("keydown", ".countdown:not(.counting):not(.alarm)", handleCountdownPlayKey
);
281 $(document
).on("keydown", ".counting", handleCountdownPauseKey
);
282 $("#countdown-start").on("click", handleCountdownStart
);
283 $("#countdown-pause").on("click", handleCountdownPause
);
284 $("#countdown-reset").on("click", handleCountdownReset
);
285 $("#countdown-reconfigure").on("click", handleCountdownReconfigure
);
287 $("#alarm-stop").on("click", stopAlarm
);
288 $(audio
).on("ended", stopAlarm
);
290 beginConfigureMode();