Tizen 2.0 Release
[samples/web/MemoryMatch.git] / js / main.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 Game = {};
11
12 (function () {
13     var infocus = true;
14     var fliptime = 400;
15     var ignore = false;
16     var matchcard = undefined;
17     var win_level = 0;
18     var game_level = -1;
19     var lvl_bg_sound;
20     var flip_sound;
21     var match_sound;
22     var mismatch_sound;
23     var click_sound;
24     var win_sound;
25
26     function gamesound(file) {
27         this.file = file;
28         this.soundobj = new Array();
29         this.soundobj.push(new Audio(file));
30         this.soundobj.push(new Audio(file));
31         this.idx = 0;
32         this.play = function play() {
33             if(!infocus)
34                 return;
35
36             /* create two instances of the file to play sequentially if calls */
37             /* come too fast, otherwise the second call will be ignored */
38             this.soundobj[this.idx].play();
39             this.idx = (this.idx + 1)%2;
40         };
41     }
42
43     function stop_bg_sounds() {
44         for(var i = 0; i < 3; i++)
45         {
46             lvl_bg_sound[i].pause();
47             if(lvl_bg_sound[i].currentTime > 0)
48                 lvl_bg_sound[i].currentTime = 0;
49         }
50     }
51
52     var gamedata = [
53         {
54             cardcount : 8
55         },
56         {
57             cardcount : 12
58         },
59         {
60             cardcount : 16
61         }
62     ];
63
64     function input_on() {
65         ignore = false;
66     }
67
68     function input_off() {
69         ignore = true;
70     }
71
72     function cardEntry(classname) {
73         this.classname = classname;
74         this.flipped = false;
75     }
76
77     function win_dlg(lvl) {
78         win_level = lvl;
79
80         if (window.chrome&&window.chrome.i18n)
81         {
82             if(lvl < 3)
83                 $("#win_btn2").text(chrome.i18n.getMessage("win_nextlevel"));
84             else
85                 $("#win_btn2").text(chrome.i18n.getMessage("win_backtostart"));
86             $("#win_btn1").text(chrome.i18n.getMessage("win_replay"));
87             $("#win_btn3").text(chrome.i18n.getMessage("win_quit"));
88             $("#win_dlg_text").html(chrome.i18n.getMessage("win_text"));
89         }
90         else
91         {
92             if(lvl < 3)
93                 $("#win_btn2").text("NEXT LEVEL");
94             else
95                 $("#win_btn2").text("BACK TO START");
96         }
97
98         win_sound.play();
99         $("#win_dlg_page").show();
100     }
101
102     function update_matches(lvl) {
103         var flipcount = 0;
104         var cardcount = gamedata[lvl-1].cardcount;
105         $(".flip").each(function() { flipcount++; });
106         var matches = (flipcount/2)|0;
107         var possible_matches = (cardcount/2)|0;
108
109         /* set the match text */
110         if (window.chrome&&window.chrome.i18n)
111         {
112             $("#lvl"+lvl+"_matches").text(chrome.i18n.getMessage("matches")+" "+
113              chrome.i18n.getMessage("num"+matches)+"/"+
114              chrome.i18n.getMessage("num"+possible_matches));
115         }
116         else
117         {
118             $("#lvl"+lvl+"_matches").text("Matches "+matches+"/"+possible_matches);
119         }
120
121         return (flipcount >= cardcount);
122     }
123
124     function card_flipped(elem) {
125         var newcard = $(elem).attr("id");
126         var lvl = parseInt(newcard.substring(3, 4));
127
128         if(matchcard != undefined)
129         {
130             var newclass = $("#"+newcard+" .front").attr("class");
131             var matchclass = $("#"+matchcard+" .front").attr("class");
132
133             if(newclass == matchclass)
134             {
135                 /* good match */
136                 if(update_matches(lvl))
137                 {
138                     win_dlg(lvl);
139                 }
140                 else
141                 {
142                     match_sound.play();
143                     input_on();
144                 }
145             }
146             else
147             {
148                 /* bad match */
149                 mismatch_sound.play();
150                 $("#"+newcard).removeClass('flip');
151                 $("#"+matchcard).removeClass('flip');
152
153                 /* keep ignoring input til the cards are flipped back */
154                 window.setTimeout("Game.input_on()", fliptime);
155             }
156
157             /* reset the match card */
158             matchcard = undefined;
159         }
160         else
161         {
162             /* first card in match attempt, set it and wait */
163             matchcard = newcard;
164             input_on();
165         }
166     }
167
168     function generate_hint(lvl) {
169         if(matchcard != undefined)
170         {
171             var matchclass = $("#"+matchcard+" .front").attr("class");
172             $(".lvl"+lvl+"_card").each(function() {
173                 var newcard = $(this).attr("id");
174                 var newclass = $("#"+newcard+" .front").attr("class");
175                 if((matchclass == newclass)&&(matchcard != newcard))
176                 {
177                     /* ignore clicks while hint is generated */
178                     input_off();
179
180                     /* flip the card's match for the poor child */
181                     flip_sound.play();
182                     $("#"+newcard).addClass('flip');
183
184                     if(update_matches(lvl))
185                     {
186                         match_sound.play();
187                         window.setTimeout("Game.win_dlg("+lvl+")", fliptime);
188                     }
189                     else
190                     {
191                         match_sound.play();
192                         window.setTimeout("Game.input_on()", fliptime);
193                     }
194                 }
195             });
196             matchcard = undefined;
197         }
198         else
199         {
200             var cardlist = new Array();
201             $(".lvl"+lvl+"_card").each(function() {
202                 if(!$(this).hasClass('flip'))
203                     cardlist.push($(this).attr("id"));
204             });
205
206             /* if all cards are flipped, return */
207             if(cardlist.length <= 0)
208                 return;
209
210             var target = (Math.random() * cardlist.length)|0;
211             var tgtcard = cardlist[target];
212             var tgtclass = $("#"+tgtcard+" .front").attr("class");
213
214             $(".lvl"+lvl+"_card").each(function() {
215                 var newcard = $(this).attr("id");
216                 var newclass = $("#"+newcard+" .front").attr("class");
217                 if((tgtclass == newclass)&&(tgtcard != newcard))
218                 {
219                     /* ignore clicks while hint is generated */
220                     input_off();
221
222                     /* flip two cards for the poor child */
223                     flip_sound.play();
224                     $("#"+tgtcard).addClass('flip');
225                     $("#"+newcard).addClass('flip');
226
227                     if(update_matches(lvl))
228                     {
229                         match_sound.play();
230                         window.setTimeout("Game.win_dlg("+lvl+")", fliptime);
231                     }
232                     else
233                     {
234                         match_sound.play();
235                         window.setTimeout("Game.input_on()", fliptime);
236                     }
237                 }
238             });
239         }
240     }
241
242     function start_game(lvl) {
243         game_level = lvl;
244
245         /* reset all the cards */
246         $(".card").removeClass('flip');
247
248         var types = new Array();
249         var cardcount = gamedata[lvl].cardcount;
250         var cardtypes = gamedata[lvl].cardcount/2;
251         var i, j;
252
253         if (window.chrome&&window.chrome.i18n)
254         {
255             $("#lvl"+(lvl+1)+"_matches").text(chrome.i18n.getMessage("matches")+" "+
256                 chrome.i18n.getMessage("num0")+"/"+
257                 chrome.i18n.getMessage("num"+cardtypes));
258         }
259         else
260         {
261             $("#lvl"+(lvl+1)+"_matches").text("Matches 0/"+cardtypes);
262         }
263
264         /* create a list of cards by index */
265         for(i = 0; i < cardcount; i++)
266             types.push((i%cardtypes)+1);
267
268         /* randomly fill out the deck */
269         for(i = 0; i < cardcount; i++)
270         {
271             var card_id = "#lvl"+(lvl+1)+"_card"+(i+1)+" .front";
272             var target = (Math.random() * types.length)|0;
273             var idx = types.splice(target, 1);
274             var card_class = "front lvl"+(lvl+1)+"_card_type"+idx;
275             $(card_id).attr('class', card_class);
276         }
277
278         input_on();
279     }
280
281     $(document).ready(function()
282     {
283         license_init("license", "main_page");
284         help_init("main_help", "help_");
285         help_init("lvl1_help", "help_");
286         help_init("lvl2_help", "help_");
287         help_init("lvl3_help", "help_");
288         if (window.chrome&&window.chrome.i18n)
289         {
290             $("#lvl1_quit").html("&nbsp;&nbsp;&nbsp;"+chrome.i18n.getMessage("quit"));
291             $("#lvl2_quit").html("&nbsp;&nbsp;&nbsp;"+chrome.i18n.getMessage("quit"));
292             $("#lvl3_quit").html("&nbsp;&nbsp;&nbsp;"+chrome.i18n.getMessage("quit"));
293             $("#lvl1_hint").text(chrome.i18n.getMessage("hint"));
294             $("#lvl2_hint").text(chrome.i18n.getMessage("hint"));
295             $("#lvl3_hint").text(chrome.i18n.getMessage("hint"));
296             $("#main_lvl1btn").text(chrome.i18n.getMessage("level1"));
297             $("#main_lvl2btn").text(chrome.i18n.getMessage("level2"));
298             $("#main_lvl3btn").text(chrome.i18n.getMessage("level3"));
299             $("#help_contents").html(chrome.i18n.getMessage("help_text"));
300         }
301
302         Game.card_flipped = card_flipped;
303         Game.input_on = input_on;
304         Game.input_off = input_off;
305         Game.win_dlg = win_dlg;
306         Game.start_game = start_game;
307
308         lvl_bg_sound = new Array();
309         lvl_bg_sound.push(document.querySelector("audio.lvl1_bg_sound"));
310         lvl_bg_sound.push(document.querySelector("audio.lvl2_bg_sound"));
311         lvl_bg_sound.push(document.querySelector("audio.lvl3_bg_sound"));
312         flip_sound = new gamesound("audio/FlipCard.wav");
313         match_sound = new gamesound("audio/GetMatch.wav");
314         mismatch_sound = new gamesound("audio/WrongLose.wav");
315         click_sound = new gamesound("audio/NavClick.wav");
316         win_sound = new gamesound("audio/WinLevel.wav");
317
318
319         /* if a mouseup happens reset the buttons, this is to maintain */
320         /* the original page state if a button is only half clicked */
321         $("body").mouseup(function() {
322             $('#main_lvl1btn').removeClass("main_lvl1btn_on");
323             $('#main_lvl1btn').addClass("main_lvl1btn_off");
324             $('#main_lvl2btn').removeClass("main_lvl2btn_on");
325             $('#main_lvl2btn').addClass("main_lvl2btn_off");
326             $('#main_lvl3btn').removeClass("main_lvl3btn_on");
327             $('#main_lvl3btn').addClass("main_lvl3btn_off");
328         });
329
330         $('#win_dlg_page').mouseup(function() {
331             $('#win_btn1').removeClass("win_btn1_on");
332             $('#win_btn1').addClass("win_btn1_off");
333             $('#win_btn2').removeClass("win_btn2_on");
334             $('#win_btn2').addClass("win_btn2_off");
335             $('#win_btn3').removeClass("win_btn3_on");
336             $('#win_btn3').addClass("win_btn3_off");
337         });
338
339         /* game launch buttons */
340         $('#main_lvl1btn').click(function() {
341             click_sound.play();
342             $("#main_page").hide();
343             $("#lvl1_page").show();
344             lvl_bg_sound[0].play();
345             start_game(0);
346         });
347
348         $('#main_lvl2btn').click(function() {
349             click_sound.play();
350             $("#main_page").hide();
351             $("#lvl2_page").show();
352             lvl_bg_sound[1].play();
353             start_game(1);
354         });
355
356         $('#main_lvl3btn').click(function() {
357             click_sound.play();
358             $("#main_page").hide();
359             $("#lvl3_page").show();
360             lvl_bg_sound[2].play();
361             start_game(2);
362         });
363
364         /* setup for game pages */
365         $('.quit').click(function() {
366             if(!ignore)
367             {
368                 stop_bg_sounds();
369                 click_sound.play();
370                 $("#lvl1_page").hide();
371                 $("#lvl2_page").hide();
372                 $("#lvl3_page").hide();
373                 $("#main_page").show();
374                 game_level = -1;
375             }
376         });
377
378         $('.hintrays').click(function() {
379             if(!ignore)
380             {
381                 var id = $(this).attr("id");
382                 generate_hint(parseInt(id.substring(3, 4)));
383             }
384         });
385
386         $('.card').click(function(){
387             if(!ignore&&!($(this).hasClass('flip')))
388             {
389                 /* start the flip animation */
390                 flip_sound.play();
391                 $(this).addClass('flip');
392
393                 /* ignore clicks during flip */
394                 input_off();
395
396                 /* set the function to be called after the animation has done */
397                 window.setTimeout("Game.card_flipped("+($(this).attr("id"))+")", fliptime);
398             }
399         });
400
401         $("#win_btn1").click(function() {
402             click_sound.play();
403             $("#win_dlg_page").hide();
404             $(".card").removeClass('flip');
405             window.setTimeout("Game.start_game("+(win_level-1)+")", fliptime);
406         });
407
408         $("#win_btn2").click(function() {
409             click_sound.play();
410             var next_level = ((win_level)%3)+1;
411             $("#win_dlg_page").hide();
412             $("#lvl"+win_level+"_page").hide();
413             $("#lvl"+next_level+"_page").fadeIn("fast");
414             stop_bg_sounds();
415             lvl_bg_sound[next_level-1].play();
416             start_game(next_level-1);
417         });
418
419         $("#win_btn3").click(function() {
420             stop_bg_sounds();
421             click_sound.play();
422             $("#win_dlg_page").hide();
423             $("#lvl1_page").hide();
424             $("#lvl2_page").hide();
425             $("#lvl3_page").hide();
426             $("#main_page").show();
427             game_level = -1;
428         });
429
430         window.onblur = function() {
431             if(infocus)
432             {
433                 infocus = false;
434                 if(game_level >= 0)
435                     lvl_bg_sound[game_level].pause();
436             }
437         };
438
439         window.onfocus = function() {
440             if(!infocus)
441             {
442                 infocus = true;
443                 if(game_level >= 0)
444                     lvl_bg_sound[game_level].play();
445             }
446         };
447     });
448 })()