'use strict'; var App = {}; App.init = function(){ App.name = 'Flip.io'; $('.title').text(App.name); App.touch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; if(window['Audio']){ var audio = new Audio(); var ext = '.wav'; if(audio.canPlayType('audio/mp3')){ ext = '.mp3'; } App.sounds = {}; var ding = new Audio(); ding.src = './media/ding' + ext; ding.volume = 0.5; var sweep = new Audio(); sweep.src = './media/sweep' + ext; sweep.volume = 0.3; App.sounds['sweep'] = sweep; App.sounds['ding'] = ding; } $('body').on('touchmove', function(e){ if(e.target.style = 'clues'){ } else { e.preventDefault(); } }); this.homeView = new App.HomeView(); this.puzzleView = new App.PuzzleView(); this.router = new App.Router(); Backbone.history.start(); } App.play = function(sound){ if(App.sounds){ var snd = App.sounds[sound]; try{ snd.pause(); snd.currentTime = 0; } catch (err){} snd.play(); } } App.addWin = function(puzNum){ if(window['localStorage']){ var wins = localStorage.setItem['wins']; if(!wins){ wins = []; } wins.push(puzNum); localStorage.setItem['wins'] = wins; } } App.getWins = function(){ if(window['localStorage']){ var wins = localStorage.setItem['wins']; if(!wins){ wins = []; } return wins; } else { return []; } } App.Router = Backbone.Router.extend({ currentView: null, routes: { '': 'showHome', ':number': 'showPuzzle', }, clearCurrent: function(){ if(this.currentView){ this.currentView.$el.html(''); this.currentView.remove(); } }, showHome: function() { $('.content').fadeOut(function(){ App.router.clearCurrent(); document.title = App.name; $('.titlenum').text(''); App.homeView.render(); $('.content').html(App.homeView.$el); App.router.currentView = App.homeView; $('.puznum').focus(); $('.content').fadeIn(); }); }, showPuzzle: function(puzNum) { $('.content').fadeOut(function(){ App.router.clearCurrent(); document.title = App.name + ' / Puzzle ' + puzNum; $('.titlenum').text('#' + puzNum); App.puzzleView.render(puzNum); $('.content').html(App.puzzleView.$el); App.router.currentView = App.puzzleView; $('.content').fadeIn(); }); } }); App.HomeView = Backbone.View.extend({ tagName: 'div', className: 'home', events: function() { var events; if(App.touch){ events = { 'keypress .puznum': 'checkField', 'update .puznum': 'checkField', 'submit .puz-form': 'loadPuzzle', 'touchend .go-btn': 'loadPuzzle', 'touchend .random-btn': 'randomPuzzle' } } else { events = { 'keypress .puznum': 'checkField', 'submit .puz-form': 'loadPuzzle', 'click .go-btn': 'loadPuzzle', 'click .random-btn': 'randomPuzzle' } } return events; }, render: function() { this.delegateEvents(); var tpl = $('.homeTemplate').text(); var html = _.template(tpl, {}); this.$el.html(html); $('.puznum').focus(); }, checkField: function(e){ var keyCode = e.keyCode || e.charCode; //console.log(keyCode); if(keyCode == 13 || keyCode == 8 || keyCode == 46 || keyCode == 92 || keyCode == 39 || keyCode == 37){ return true; } if(keyCode < 48 || keyCode > 57){ return false; } var val = $('.puznum').val(); if(val.length >= 3){ return false; } }, loadPuzzle: function(e){ if(e){ e.preventDefault(); } var puzNum = parseInt($('.puznum').val()); if(isNaN(puzNum) || puzNum < 1 || puzNum > 1000){ $('.puznum').val(''); } else { App.router.navigate(puzNum+'', {trigger: true}); } }, randomPuzzle: function(){ var puzNum = Math.floor( Math.random() * ( 1001) ); $('.puznum').val(puzNum); // App.router.navigate(puzNum + "", {trigger: true}); } }); App.PuzzleView = Backbone.View.extend({ tagName: 'div', className: 'puzzle', secs: 0, stop: false, intervalID: null, guessing: false, count: 0, total: 7, puzNum: 0, data: null, events: function(){ var events; if(App.touch){ events = { 'touchend .shuffle' : 'doShuffle', 'touchend .hint' : 'doHint', 'touchend .square' : 'doSquare', 'touchend .reset': 'doReset', 'touchend .restart': 'doRestart', 'touchend .gohome': 'doHome', 'touchend .next': 'doNext' } } else { events = { 'click .shuffle' : 'doShuffle', 'click .hint' : 'doHint', 'click .square' : 'doSquare', 'click .reset': 'doReset', 'click .restart': 'doRestart', 'click .gohome': 'doHome', 'click .next': 'doNext' } } return events; }, render: function(puzNum) { this.delegateEvents(); this.guessing = false; this.count = 0; this.puzNum = parseInt(puzNum); if(isNaN(puzNum) || puzNum < 1 || puzNum > 1000){ App.router.navigate('', {trigger: true}); } this.start = new Date(); this.secs = 0; this.data = puzzles[puzNum]; var tpl = $('.puzzleTemplate').text(); var html = _.template(tpl, this.data); this.$el.html(html); this.startTimer(); }, doHome: function(e){ this.stopTimer(); App.router.navigate('', {trigger: true}); }, doNext: function(e){ App.router.navigate((App.puzzleView.puzNum +1)+'', {trigger: true}); }, doShuffle: function(e){ shuffleItems('tr'); shuffleItems('tbody'); }, doHint: function(e){ var active = []; $('.clues li').each(function(index){ if($(this).data('answer') !== ''){ active.push($(this)); } }); var rand = Math.floor(Math.random() * active.length); var $clue = active[rand]; var b = rot13($clue.data('answer')); b = b.substr(0,3); $('.square').each(function(index){ if($(this).data('guessed') !== 'true'){ var s = $(this).text(); if(b.indexOf(s) == 0){ $clue.fadeOut('slow', function(){ $clue.fadeIn(); }); $(this).fadeOut('slow', function(){ $(this).fadeIn(); }); } } }); }, doSquare: function(e){ if(App.puzzleView.guessing == false){ var sq = e.target; $(sq).data('guessed','true'); $(sq).hide(); var a = $('.answertext').text(); a = a + $(sq).text(); $('.answertext').html(a); if(a.length > 9){ App.puzzleView.doReset(e); } else { App.puzzleView.doGuess(a); } } }, doGuess: function(a){ if(a == ''){ return; } var $clues = $('.clues li'); App.puzzleView.guessing = true; for(var i = 0; i < $clues.length; i++){ var $clue = $clues.eq(i); var b = rot13($clue.data('answer')); if( a.toLowerCase() == b.toLowerCase()){ App.play('ding'); $clue.data('answer',''); $('.answertext').fadeOut('fast',function(){ $('.answertext').html(''); $('.answertext').show(); }); $clue.find('.word').fadeOut(function(){ $(this).html(b).addClass('correct'); $(this).fadeIn(); }); $clue.find('.def').fadeOut(function(){ $(this).css({'text-decoration':'line-through','font-style':'italic'}); $(this).fadeIn(); }); $('.square').each(function(index){ $(this).data('guessed',''); }); App.puzzleView.count++; if(App.puzzleView.count == App.puzzleView.total){ App.puzzleView.doWin(); return; } break; } } App.puzzleView.guessing = false; }, doWin: function(){ App.puzzleView.stopTimer(); App.addWin(App.puzzleView.puzNum); App.play('sweep'); setTimeout(function() { $('.squares table').fadeOut(); $('.hint').hide(); $('.shuffle').hide(); var tpl = $('.winTemplate').text(); var html = _.template(tpl, {}); $('.squares').html(html); }, 1000); }, doRestart: function(e){ App.puzzleView.secs = 0; App.puzzleView.render(App.puzzleView.puzNum); }, doReset: function(e){ $('.answertext').html(''); //$('.answertext').css('color',''); $('.square').each(function(index){ if($(this).data('guessed') == 'true'){ $(this).data('guessed',''); $(this).fadeIn(); } }); }, stopTimer: function(){ clearInterval(App.puzzleView.intervalID); App.puzzleView.intervalID = null; }, startTimer: function(){ if(App.puzzleView.intervalID == null){ App.puzzleView.intervalID = setInterval('App.puzzleView.timer()', 1000); } }, timer: function(){ App.puzzleView.secs = Math.floor(((new Date()) - App.puzzleView.start)/1000) ; $('.timer').text(formatTime(App.puzzleView.secs)); } }); // ----- misc functions function formatTime(sec){ var hr = Math.floor(sec / 3600); var min = Math.floor((sec - (hr * 3600))/60); sec -= ((hr * 3600) + (min * 60)); sec += ''; min += ''; while (min.length < 2) {min = '0' + min;} while (sec.length < 2) {sec = '0' + sec;} hr = (hr)?':'+hr:''; return hr + min + ':' + sec; } function rot13(str) { return str.replace(/[a-zA-Z]/g, function(c) { return String.fromCharCode((c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26); }); } function shuffleItems(sel) { var $el = $(sel); $el.each(function(){ var items = $(this).children().clone(true); var ret = (items.length) ? $(this).html(shuffle(items)) : this; $el.replaceWith(ret); }); } function shuffle(arr) { for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x); return arr; }