[Flashcards]update Flashcards(tizen_2.1)
[samples/web/Flashcards.git] / js / flashcards.js
1 /*
2  * Copyright (c) 2012, Intel Corporation.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9
10 /**
11  * globals
12  */
13 var getMessage,
14     license_init,
15     GameSound,
16     window,
17     document;
18
19 (function () {
20     "use strict";
21
22     /**
23      * FlashCards() class contains all the variables and functions needed to run the flash card game
24      *  @constructor
25      */
26     function FlashCards() {
27         this.cardDecks = {
28             COLORDECK: "ColorDeck",
29             SHAPEDECK: "ShapeDeck",
30             SPANISHDECK: "SpanishDeck",
31             COUNTINGDECK: "CountingDeck"
32         };
33         this.cardCount = 0; //current game wrong answers
34         this.rightCount = 0; //current game right answers
35         this.cardSet = this.cardDecks.SHAPEDECK; //name of card set and file prefix
36         this.endGameFlag = false; //endGame flag
37         this.deckAnswer = []; //the array of answers for this deck
38     };
39
40     /**
41      *  FlashCards.helpClicked() plays audio and makes the help card dialog visible when help icon is clicked
42      *  @private
43      */
44     FlashCards.prototype.helpClicked = function () {
45         this.buttonClickSound.play();
46         document.getElementById("help-dialog").style.display = "inline";
47     };
48
49     /*
50      * FlashCards.helpCloseClicked() plays audio and makes the help card dialog invisible when help X icon is clicked
51      * @private
52      */
53     FlashCards.prototype.helpCloseClicked = function () {
54         this.buttonClickSound.play();
55         document.getElementById("help-dialog").style.display = "none";
56     };
57
58     /**
59      * FlashCards.hideAnswer() will hide the wrong and right buttons and answer text reseting the cursor style
60      * @private
61      */
62     FlashCards.prototype.hideAnswer = function () {
63             document.getElementById("answer").style.display = "none";
64     };
65
66     /**
67      * FlashCards.clear() will reset game counters, hide stars, replay button, answers, and reset the score
68      * @private
69      */
70     FlashCards.prototype.clear = function () {
71         var parent = document.getElementById("game-screen"),
72             count,
73             children;
74
75         //reset properties
76         this.endGameFlag = false;
77         this.rightCount = 0;
78         this.cardCount = 0;
79
80         //remove all stars from dom
81         children = document.getElementsByClassName("star");
82         for (count = children.length - 1; count >= 0; count = count - 1) {
83             parent.removeChild(document.getElementsByClassName("star")[count]);
84         }
85
86         document.getElementById("score-number").innerHTML = "0";
87         document.getElementById("replay-button").style.display = "none";
88         document.getElementById("endgame-prompt").style.display = "none";
89         this.hideAnswer();
90     };
91
92     /**
93      *  FlashCards.navPaneClose()  closes nav pane and plays nav pane sound effect
94      * @private
95      */
96     FlashCards.prototype.navPaneClose = function () {
97         this.swooshSound.play();
98         if (document.getElementsByClassName("animation-open")[0]) {
99             document.getElementsByClassName("animation-open")[0].setAttribute("class", "animation-close");
100         }
101     };
102
103     /**
104      *  FlashCards.navPaneToggle() opens or closes nav pane and plays nav pane sound effect
105      * @private
106      */
107     FlashCards.prototype.navPaneToggle = function () {
108         this.swooshSound.play();
109         if (document.getElementsByClassName("animation-open")[0]) {
110             document.getElementsByClassName("animation-open")[0].setAttribute("class", "animation-close");
111         } else {
112             document.getElementsByClassName("animation-close")[0].setAttribute("class", "animation-open");
113         }
114     };
115
116     /**
117      *  FlashCards.navPaneClicked() plays button click audio, opens or closes nav pane and plays nav pane sound effect
118      * @private
119      */
120     FlashCards.prototype.navPaneClicked = function () {
121         this.buttonClickSound.play();
122         this.navPaneToggle();
123     };
124
125     /**
126      *  FlashCards.getShapeDeckAnswers() will call getMessage to get the localized answers for this deck
127      *  @private
128      */
129     FlashCards.prototype.getShapeDeckAnswers = function () {
130         this.shapeAnswer = [];
131         this.shapeAnswer[0] = getMessage("circle");
132         this.shapeAnswer[1] = getMessage("square");
133         this.shapeAnswer[2] = getMessage("triangle");
134         this.shapeAnswer[3] = getMessage("oval");
135         this.shapeAnswer[4] = getMessage("star");
136         this.shapeAnswer[5] = getMessage("octagon");
137         this.shapeAnswer[6] = getMessage("rectangle");
138         this.shapeAnswer[7] = getMessage("trapezoid");
139     };
140
141     /**
142      *  FlashCards.setCardContent() sets the image centered horizontally in the card
143      * @private
144      */
145     FlashCards.prototype.setCardContent = function () {
146         var img = new Image();
147         img.src = 'images/' + this.cardSet + this.cardCount + '.png';
148         document.getElementById("card").style.display = "none";
149         img.onload = function(){
150             document.getElementById("card-graphic").style.width = img.width+"px";
151             document.getElementById("card-graphic").style.height = img.height+"px";
152             document.getElementById("card-graphic").style.top = (160-(img.height/2))+"px";
153             document.getElementById("card-graphic").style.backgroundImage = 'url('+ img.src +')';
154             document.getElementById("card").style.display = "inline";
155         };
156     }
157
158     /**
159      *  FlashCards.shapeDeckClicked() set the game to play through the this deck
160      * @private
161      */
162     FlashCards.prototype.setShapeDeck = function () {
163         this.whipCrackSound.play();
164         this.clear();
165         this.cardSet = this.cardDecks.SHAPEDECK;
166         this.deckAnswer = this.shapeAnswer;
167         this.setCardContent();
168         document.getElementById("nav-flag").innerHTML = getMessage("shapes");
169         document.getElementById("card-answer").style.color = "#499aff";
170         document.getElementById("card-answer").innerHTML = this.deckAnswer[this.cardCount];
171     };
172
173     /**
174      * FlashCards.shapeDeckClicked() plays the button click audio, navPane animation, and calls the setter for this deck
175      * @private
176      */
177     FlashCards.prototype.shapeDeckClicked = function () {
178         this.buttonClickSound.play();
179         this.navPaneClicked();
180         this.setShapeDeck();
181     };
182
183     /**
184      *  FlashCards.getCountingDeckAnswers() will call getMessage to get the localized answers for this deck
185      *  @private
186      */
187     FlashCards.prototype.getCountingDeckAnswers = function () {
188         this.countingAnswer = [];
189         this.countingAnswer[0] = getMessage("one");
190         this.countingAnswer[1] = getMessage("two");
191         this.countingAnswer[2] = getMessage("three");
192         this.countingAnswer[3] = getMessage("four");
193         this.countingAnswer[4] = getMessage("five");
194         this.countingAnswer[5] = getMessage("six");
195         this.countingAnswer[6] = getMessage("seven");
196         this.countingAnswer[7] = getMessage("eight");
197         this.countingAnswer[8] = getMessage("nine");
198         this.countingAnswer[9] = getMessage("ten");
199     };
200
201     /**
202      *  FlashCards.setCountingDeck() set the game to play through the this deck
203      *  @private
204      */
205     FlashCards.prototype.setCountingDeck = function () {
206         this.whipCrackSound.play();
207         this.clear();
208         this.cardSet = this.cardDecks.COUNTINGDECK;
209         this.deckAnswer = this.countingAnswer;
210         this.setCardContent();
211         document.getElementById("nav-flag").innerHTML = getMessage("counting");
212         document.getElementById("card-answer").style.color = "navy";
213         document.getElementById("card-answer").innerHTML = this.deckAnswer[this.cardCount];
214     };
215
216     /**
217      * FlashCards.countingDeckClicked() plays the button click audio, navPane animation, and calls the setter for this deck
218      * @private
219      */
220     FlashCards.prototype.countingDeckClicked = function () {
221         this.buttonClickSound.play();
222         this.navPaneClicked();
223         this.setCountingDeck();
224     };
225
226     /**
227      *  FlashCards.getSpanishDeckAnswers() will call getMessage to get the localized answers for this deck
228      *  @private
229      */
230     FlashCards.prototype.getSpanishDeckAnswers = function () {
231         this.spanishAnswer = [];
232         this.spanishAnswer[0] = getMessage("sun");
233         this.spanishAnswer[1] = getMessage("cloud");
234         this.spanishAnswer[2] = getMessage("cat");
235         this.spanishAnswer[3] = getMessage("dog");
236         this.spanishAnswer[4] = getMessage("tree");
237         this.spanishAnswer[5] = getMessage("fish");
238         this.spanishAnswer[6] = getMessage("fruit");
239         this.spanishAnswer[7] = getMessage("worm");
240         this.spanishAnswer[8] = getMessage("bird");
241         this.spanishAnswer[9] = getMessage("crocodile");
242         this.spanishAnswer[10] = getMessage("book");
243         this.spanishAnswer[11] = getMessage("socks");
244         this.spanishAnswer[12] = getMessage("cup");
245         this.spanishAnswer[13] = getMessage("chair");
246     };
247
248     /**
249      * FlashCards.setSpanishDeck() set the game to play through the this deck
250      * @private
251      */
252     FlashCards.prototype.setSpanishDeck = function () {
253         this.whipCrackSound.play();
254         this.clear();
255         this.cardSet = this.cardDecks.SPANISHDECK;
256         this.deckAnswer = this.spanishAnswer;
257         this.setCardContent();
258         document.getElementById("nav-flag").innerHTML = getMessage("spanish");
259         document.getElementById("card-answer").style.color = "#000000";
260         document.getElementById("card-answer").innerHTML = this.deckAnswer[this.cardCount];
261     };
262
263     /**
264      *  FlashCards.spanishDeckClicked() plays the button click audio, navPane animation, and calls the setter for this deck
265      *  @private
266      */
267     FlashCards.prototype.spanishDeckClicked = function () {
268         this.buttonClickSound.play();
269         this.navPaneClicked();
270         this.setSpanishDeck();
271     };
272
273     /**
274      *  FlashCards.getColorDeckAnswers() will call getMessage to get the localized answers for this deck
275      *  @private
276      */
277     FlashCards.prototype.getColorDeckAnswers = function () {
278         this.colorAnswer = [];
279         this.colorAnswer[0] = getMessage("red");
280         this.colorAnswer[1] = getMessage("purple");
281         this.colorAnswer[2] = getMessage("blue");
282         this.colorAnswer[3] = getMessage("green");
283         this.colorAnswer[4] = getMessage("orange");
284         this.colorAnswer[5] = getMessage("yellow");
285         this.colorAnswer[6] = getMessage("black");
286         this.colorAnswer[7] = getMessage("pink");
287         this.colorAnswer[8] = getMessage("white");
288         this.colorAnswer[9] = getMessage("brown");
289         this.colorAnswer[10] = getMessage("grey");
290     };
291
292     /**
293      *  FlashCards.getColorDeckColors() will set the text colors for each card in this deck
294      * @private
295      */
296     FlashCards.prototype.getColorDeckColors = function () {
297         this.colorHex = [];
298         this.colorHex[0] = "#DD0000"; //red
299         this.colorHex[1] = "#7E0B80"; //purple
300         this.colorHex[2] = "#0000ff"; //blue
301         this.colorHex[3] = "#00BC00"; //green
302         this.colorHex[4] = "#DA8D00"; //orange
303         this.colorHex[5] = "#FEF600"; //yellow
304         this.colorHex[6] = "#000000"; //black
305         this.colorHex[7] = "#FF00FF"; //pink
306         this.colorHex[8] = "#FFFFFF"; //white
307         this.colorHex[9] = "#996600"; //brown
308         this.colorHex[10] = "#C0C0C0"; //grey
309     };
310
311     /**
312      * FlashCards.setColorDeck set the game to play through the this deck
313      * @private
314      */
315     FlashCards.prototype.setColorDeck = function () {
316         this.whipCrackSound.play();
317         this.clear();
318         this.cardSet = this.cardDecks.COLORDECK;
319         this.deckAnswer = this.colorAnswer;
320         this.setCardContent();
321         document.getElementById("nav-flag").innerHTML = getMessage("colors");
322         document.getElementById("card-answer").innerHTML = this.colorAnswer[this.cardCount];
323         document.getElementById("card-answer").style.color = this.colorHex[this.cardCount];
324     };
325
326     /**
327      *  FlashCards.colorDeckClicked() plays the button click audio, navPane animation, and calls the setter for this deck
328      * @private
329      */
330     FlashCards.prototype.colorDeckClicked = function () {
331         this.buttonClickSound.play();
332         this.navPaneClicked();
333         this.setColorDeck();
334     };
335
336     /**
337      * FlashCards.initGame() gets the localized strings for the game play screen, sets the default deck to Shapes
338      * @private
339      */
340     FlashCards.prototype.initGame = function () {
341         this.initSound();
342         this.backgroundSound.play();
343
344         document.getElementById("score-text").innerHTML = getMessage("scoreText");
345         document.getElementById("help-text").innerHTML = getMessage("helpText");
346
347         this.setGameEventListeners();
348
349         this.getColorDeckAnswers();
350         this.getColorDeckColors();
351         this.getShapeDeckAnswers();
352         this.getCountingDeckAnswers();
353         this.getSpanishDeckAnswers();
354
355         this.setShapeDeck();
356     };
357
358     /**
359      *  FlashCards.playNowClicked() will initialize the game screen when Play Now button is clicked and hide the splash screen
360      * @private
361      */
362     FlashCards.prototype.playNowClicked = function () {
363         this.initGame();
364         document.getElementById("splash-screen").style.display = "none";
365         document.getElementById("game-screen").style.display = "inline";
366     };
367
368     /**
369      * FlashCards.isLastCard()
370      * @private
371      * @return true if card count is equal to the number of cards in the deck, else return false
372      */
373     FlashCards.prototype.isLastCard = function () {
374         if ((this.deckAnswer.length) === this.cardCount) {
375             return true;
376         }
377         return false;
378     };
379
380     /**
381      * FlashCards.drawStars() draws the stars for right and wrong answers
382      * @private
383      */
384     FlashCards.prototype.drawStars = function () {
385         var star,
386         count,
387         container;
388
389         //paint correct stars equal to rightCount
390         for (count = 1; count <= this.rightCount; count = count + 1) {
391             star = document.createElement("img");
392             star.setAttribute('src', 'images/StarFilled.png');
393             star.setAttribute('id', ('star' + count));
394             star.setAttribute('class', ('star'));
395             container = document.getElementById("game-screen");
396             container.appendChild(star);
397         }
398
399         //paint remaining stars as empty stars
400         for (count = (this.rightCount + 1); count <= (this.deckAnswer.length); count = count + 1) {
401             star = document.createElement("img");
402             star.setAttribute('src', 'images/StarEmpty.png');
403             star.setAttribute('id', ('star' + count));
404             star.setAttribute('class', ('star'));
405             container = document.getElementById("game-screen");
406             container.appendChild(star);
407         }
408     };
409
410     /**
411      * FlashCards.endGame() opens nav pane, plays audio sound for end of game, shows correct star score and replay button
412      * @private
413      */
414     FlashCards.prototype.endGame = function () {
415         this.trumpetFanfareSound.play();
416         this.endGameFlag = true;
417         this.navPaneClose();
418         document.getElementById("card").style.display = "none";
419         document.getElementById("card-flip").setAttribute("id", "card-graphic");
420
421         this.drawStars();
422
423         //if user got more right than wrong then show localized strings for "good job" else show localized strings for "try again"
424         if (((this.deckAnswer.length) - this.rightCount) < this.rightCount) {
425             document.getElementById("endgame-prompt").innerHTML = getMessage("goodJob");
426         } else {
427             document.getElementById("endgame-prompt").innerHTML = getMessage("tryAgain");
428         }
429
430         //set card answer color and display replay button
431         document.getElementById("endgame-prompt").style.display = "inline";
432         document.getElementById("replay-button").style.display = "inline";
433     };
434
435     /**
436      * FlashCards.flipCard() hide answers and moves to next card in the deck, increments counters and checks for end game state
437      * @private
438      */
439     FlashCards.prototype.flipCard = function () {
440         this.hideAnswer();
441         document.getElementById("card-graphic").setAttribute("id", "card-flip");
442         this.cardCount = this.cardCount + 1;
443         if (!this.isLastCard()) {
444             this.cardFlipSound.play();
445             this.setCardContent();
446             document.getElementById("card-answer").innerHTML = this.deckAnswer[this.cardCount];
447             if (this.cardSet === this.cardDecks.COLORDECK) {
448                 document.getElementById("card-answer").style.color = this.colorHex[this.cardCount];
449             }
450             document.getElementById("card-flip").setAttribute("id", "card-graphic");
451         } else {
452             this.endGame();
453         }
454     };
455
456     /**
457      * FlashCards.wrongButtonClicked() plays audio sounds, increments wrongCount and calls flipCard()
458      * @private
459      */
460     FlashCards.prototype.wrongButtonClicked = function () {
461         this.wrongAnswerSound.play();
462         this.buttonClickSound.play();
463         this.flipCard();
464     };
465
466     /**
467      * FlashCards.rightButtonClicked() plays audio sounds, increments rightCount and calls flipCard()
468      * @private
469      */
470     FlashCards.prototype.rightButtonClicked = function () {
471         this.rightAnswerSound.play();
472         this.buttonClickSound.play();
473         this.rightCount = this.rightCount + 1;
474         this.flipCard();
475         document.getElementById("score-number").innerHTML = this.rightCount;
476     };
477
478     /**
479      * FlashCards.replayButtonClicked() restarts current game and calls clear()
480      * @private
481      */
482     FlashCards.prototype.replayButtonClicked = function () {
483         if (this.cardSet === this.cardDecks.COLORDECK) {
484             this.colorDeckClicked();
485         } else if (this.cardSet === this.cardDecks.SHAPEDECK) {
486             this.shapeDeckClicked();
487         } else if (this.cardSet === this.cardDecks.SPANISHDECK) {
488             this.spanishDeckClicked();
489         } else if (this.cardSet === this.cardDecks.COUNTINGDECK) {
490             this.countingDeckClicked();
491         }
492         this.clear();
493     };
494
495     /**
496      * FlashCards.showAnswer() will show right and wrong buttons, answer and set cursor type
497      * @private
498      */
499     FlashCards.prototype.showAnswer = function () {
500         document.getElementById("answer").style.display = "inline";
501     };
502
503     /**
504      * FlashCards.cardClicked() plays button click sound, makes sure the nav pane is closed, and if not end game state will call showAnswer()
505      * @private
506      */
507     FlashCards.prototype.cardClicked = function () {
508         this.buttonClickSound.play();
509         this.navPaneClose();
510         if (!this.endGameFlag) {
511             this.showAnswer();
512         }
513     };
514
515     /**
516      * FlashCards.scrollNavPane will scroll the navigation Pane the direction the user moves the mouse
517      * @private
518      */
519     FlashCards.prototype.scrollNavPane = function (delta) {
520         document.getElementById("scroll-items").style.webkitTransform = "translateY("+delta+"px)";
521     };
522
523     /**
524      * FlashCards.setGameEventListeners sets event handlers for the game
525      * @private
526      */
527     FlashCards.prototype.setGameEventListeners = function () {
528         var self = this,
529         starty = 0, //starting y coordinate of drag
530         isDrag = -1; //flag for qualifying drag event
531
532         document.getElementById("nav-pane").addEventListener('click', function () {
533             self.navPaneClicked();
534         }, false);
535         document.getElementById("scroll-overlay").addEventListener('mousedown', function (e) {
536             starty = e.clientY;
537             isDrag = 0; //mouse down
538         }, false);
539         document.getElementById("scroll-overlay").addEventListener('mousemove', function (e) {
540             isDrag = 1; //mouse move
541         }, false);
542         document.getElementById("scroll-overlay").addEventListener('mouseup', function (e) {
543             if(isDrag === 1) { //if equals 1 is drag event
544                 self.scrollNavPane((-1)*(starty-e.clientY));
545             }
546             isDrag = -1; //regardless reset endy
547         }, false);
548         document.getElementById("shape-deck").addEventListener('click', function () {
549             self.shapeDeckClicked();
550         }, false);
551         document.getElementById("color-deck").addEventListener('click', function () {
552             self.colorDeckClicked();
553         }, false);
554         document.getElementById("counting-deck").addEventListener('click', function () {
555             self.countingDeckClicked();
556         }, false);
557         document.getElementById("spanish-deck").addEventListener('click', function () {
558             self.spanishDeckClicked();
559         }, false);
560         document.getElementById("card").addEventListener('click', function () {
561             self.cardClicked();
562         }, false);
563         document.getElementById("card-answer").addEventListener('click', function () {
564             self.cardClicked();
565         }, false);
566         document.getElementById("wrong-button").addEventListener('click', function () {
567             self.wrongButtonClicked();
568         }, false);
569         document.getElementById("right-button").addEventListener('click', function () {
570             self.rightButtonClicked();
571         }, false);
572         document.getElementById("replay-button").addEventListener('click', function () {
573             self.replayButtonClicked();
574         }, false);
575         document.getElementById("help-icon").addEventListener('click', function () {
576             self.helpClicked();
577         }, false);
578         document.getElementById("help-close").addEventListener('click', function () {
579             self.helpCloseClicked();
580         }, false);
581     };
582
583     /**
584      * FlashCards.setSplashScreenEventListeners sets event handlers for the splash screen
585      * @private
586      */
587     FlashCards.prototype.setSplashScreenEventListeners = function () {
588         var self = this;
589         this.buttonClickSound = new GameSound("sound-buttonclick", "audio/GeneralButtonClick_wav.ogg", "none");
590         document.getElementById("play-button").addEventListener('click', function () {
591             self.buttonClickSound.play();
592             self.playNowClicked();
593         }, false);
594     };
595
596     /**
597      * FlashCards.initSound will initialize all the sound id's for each sound file
598      * @private
599      */
600     FlashCards.prototype.initSound = function () {
601         this.cardFlipSound = new GameSound("sound-cardflip", "audio/CardFlip.ogg", "none");
602         this.backgroundSound = new GameSound("sound-background", "audio/GameplayBackgroundAtmospheric_Loop.ogg", "none", true);
603         this.swooshSound = new GameSound("sound-navpane", "audio/NavPaneSwoosh.ogg", "none");
604         this.trumpetFanfareSound = new GameSound("sound-end", "audio/Replay.ogg", "none");
605         this.rightAnswerSound = new GameSound("sound-starbutton", "audio/StarButton.ogg", "none");
606         this.wrongAnswerSound = new GameSound("sound-thumbbutton", "audio/ThumbsDown.ogg", "none");
607         this.whipCrackSound = new GameSound("sound-begin", "audio/WhipCrackBegin.ogg", "none");
608     };
609
610     /**
611      * FlashCards.init() will set the license, play intro sound, and set splash screen text
612      * @private
613      */
614     FlashCards.prototype.init = function () {
615         document.getElementById("app-name").innerHTML = getMessage("appName");
616         document.getElementById("adventure-ribbon").innerHTML = getMessage("adventureText");
617         document.getElementById("cards-ribbon").innerHTML = getMessage("cardsText");
618         document.getElementById("play-button").innerHTML = getMessage("playButtonText");
619         this.adventureThemeSound = new GameSound("sound-intro", "audio/Theme_Loop.ogg", "auto", true);
620         this.adventureThemeSound.play();
621         this.setSplashScreenEventListeners();
622         license_init("license", "splash-screen");
623     };
624
625     window.addEventListener('load', function () {
626         var App = new FlashCards();
627         App.init();
628         //hack to get active state to work on webkit
629         this.touchstart = function (e) {};
630     }, false);
631
632 }());