Adding a listener for DriverMode. If it receives a value > 0 it will pause playing...
[profile/ivi/MediaPlayer.git] / js / main.js
1 /*
2  * Copyright (c) 2013, 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 var currentMenu = "main";
11 var mouseDownEvent;
12 var resizeCB = resizeMainMenu;
13 var screenWidth;
14 var screenHeight;
15 var screenOrientation;
16 var iconWidth;
17 var padding;
18 var contentType = "AUDIO";
19 var audioContent;
20 var videoContent;
21 var imageContent;
22 var currentContent;
23 var currentPlayer;
24 var currentPlayerType = "AUDIO";
25 var currentPlayerControls;
26 var audioPlayer;
27 var videoPlayer;
28 var listIndex = 0;
29 var videoIndex = 0;
30 var imageIndex = 0;
31 var vidIcon = new Image();
32 var imgIcon = new Image();
33 var musicIcon = new Image();
34 var imagesLoaded = false;
35 var mediaListItemW;
36 var mediaListItemH;
37 var imageControls;
38 var loadAndPlay = false;
39 var loadTimer;
40 var currentFileLoaded = false;
41 var mediaNameCanvas;
42 var mediaNameCTX;
43 var speechObj;
44 var nightMode = false;
45 var waitingToResumeVideo = false;               //Media has been paused by exterior forces.  If set to true, resume previous media when given the signal.
46
47 var mainMenuTitleTemplateLandscape = {"font" : "oblique bolder 30pt arial", "lineWidth" : 9.5, "fillStyle" : "black", "strokeStyle" : "white", "textAlign" : "left",
48                 "largeShadow" : 8, "shadowOffsetX" : 0, "shadowOffsetY" : 0, "shadowBlur" : 45, "shadowColor" : "rgba(255, 187, 0, 0.4)"};
49
50 var mainMenuTitleTemplate = {"font" : "oblique bolder 40pt arial", "lineWidth" : 9.5, "fillStyle" : "black", "strokeStyle" : "white", "textAlign" : "left",
51                 "largeShadow" : 8, "shadowOffsetX" : 0, "shadowOffsetY" : 0, "shadowBlur" : 45, "shadowColor" : "rgba(255, 187, 0, 0.4)"};
52
53 var mainTrackTemplateLandscape = {"font" : "bold 20pt Arial", "lineWidth" : 7.5, "fillStyle" : "black", "strokeStyle" : "white", "textAlign" : "left",
54                 "largeShadow" : 8, "shadowOffsetX" : 0, "shadowOffsetY" : 0, "shadowBlur" : 45, "shadowColor" : "rgba(255, 187, 0, 0.5))"};
55
56 var mainTrackTemplate = {"font" : "bold 30pt Arial", "lineWidth" : 7.5, "fillStyle" : "black", "strokeStyle" : "white", "textAlign" : "left",
57                 "largeShadow" : 8, "shadowOffsetX" : 0, "shadowOffsetY" : 0, "shadowBlur" : 45, "shadowColor" : "rgba(255, 187, 0, 0.5))"};
58
59 var mediaTextTemplate2 = {"font" : "bold 20pt Arial", "lineWidth" : 10.0, "fillStyle" : "white", "strokeStyle" : "rgba(0, 0, 0, 1.0)", "textAlign" : "left",
60                 "shadowOffsetX" : 0, "shadowOffsetY" : 0, "shadowBlur" : 0, "shadowColor" : "rgba(0, 0, 0, 1.0)"};
61
62 var mediaTextTemplate3 = {"font" : "bold 20pt Arial", "lineWidth" : 3.0, "fillStyle" : "white", "strokeStyle" : "rgba(100, 0, 0, 1.0)", "textAlign" : "left"};
63
64 var trackTextTemplate  = {"font" : "bold 16pt Arial", "lineWidth" : 3.0, "fillStyle" : "white", "strokeStyle" : "black", "textAlign" : "left"};
65
66 var mediaTextTemplate2Landscape = {"font" : "bold 15pt Arial", "lineWidth" : 10.0, "fillStyle" : "white", "strokeStyle" : "rgba(0, 0, 0, 1.0)", "textAlign" : "left",
67                 "shadowOffsetX" : 0, "shadowOffsetY" : 0, "shadowBlur" : 0, "shadowColor" : "rgba(0, 0, 0, 1.0)"};
68
69 var mediaTextTemplate3Landscape = {"font" : "bold 15pt Arial", "lineWidth" : 3.0, "fillStyle" : "white", "strokeStyle" : "rgba(100, 0, 0, 1.0)", "textAlign" : "left"};
70
71 var trackTextTemplateLandscape  = {"font" : "bold 11pt Arial", "lineWidth" : 3.0, "fillStyle" : "white", "strokeStyle" : "black", "textAlign" : "left"};
72
73
74 var mediaTextTemplate = {"font" : "bold 20pt Arial", "fillStyle" : "", "textAlign" : "left",
75                 "shadowOffsetX" : 0, "shadowOffsetY" : 0, "shadowBlur" : 12, "shadowColor" : "red"};
76
77 function onError()
78 {
79         console.log("Content discovery failed");
80 }
81
82 function setupSpeech()
83 {
84         console.log("MediaPlayer in setupSpeech");
85
86         speechObj = tizen.speech;
87         speechObj.vocalizeString(" ");
88
89         try
90         {
91                 var speechEventListener = {
92                         onaudiostart: function(){console.log("MediaPlayer: onaudiostart received");},
93                         onsoundstart: function(){console.log("MediaPlayer: onsoundstart received");},
94                         onspeechstart: function(){console.log("MediaPlayer: onspeechstart received");},
95                         onspeechend: function(){console.log("MediaPlayer: onspeechend received");},
96                         onsoundend: function(){console.log("MediaPlayer: onsoundend received");},
97                         onaudioend: function(){console.log("MediaPlayer: onaudioend received");},
98                         onresult: function(result){
99
100                                 console.log("MediaPlayer: onresult received");
101
102                                 for (var i = 0; i < result.length; i++)
103                                 {
104                                         console.log("MediaPlayer: forloop, command = " + result[i]);
105                                         var commandFound = false;
106
107                                         switch(result[i])
108                                         {
109                                                 case "play":
110                                                         playButtonClick();
111                                                         commandFound = true;
112                                                 break;
113                                                 case "next":
114                                                         nextButtonClick();
115                                                         commandFound = true;
116                                                 break;
117                                                 case "previous":
118                                                         backButtonClick();
119                                                         commandFound = true;
120                                                 break;
121                                                 case "stop":
122                                                 case "pause":
123                                                         pauseButtonClick();
124                                                         commandFound = true;
125                                                 break;
126                                                 default:
127                                                 break;
128                                         }
129
130                                         if (commandFound)
131                                                 break;
132                                 }
133                         },
134                         onnomatch: function(result){console.log("MediaPlayer: onnomatch received ");},
135                         onerror: function(error){console.log("MediaPlayer: onerror received");},
136                         onstart: function(){console.log("MediaPlayer: onstart received");},
137                         onend: function(){console.log("MediaPlayer: onend received");}
138                 }
139
140                 speechObj.setCBListener(speechEventListener);
141
142         }
143         catch(err)
144         {
145                 console.log("MediaPlayer setupSpeech FAILED + " + err.message);
146         }
147
148 }
149
150 function loadImages(callback)
151 {
152         console.log("MediaPlayer in loadImages");
153
154         var loadedImages = 0;
155         var numImages = 0;
156
157         for (var src in audioContent)
158         {
159                 numImages++;
160         }
161         for (var src in audioContent)
162         {
163                 try
164                 {
165                 audioContent[src].coverArt = new Image();
166                 audioContent[src].coverArt.onload = function(){
167
168                         if (++loadedImages >= numImages) {
169                                 imagesLoaded = true;
170                                 callback(audioContent);
171                         }
172                 };
173
174                 audioContent[src].coverArt.onerror = function(e){
175                         audioContent[src].coverArt.src = "images/musicIcon.png";
176                 };
177
178                 audioContent[src].coverArt.src = (audioContent[src].coverArtURI !== undefined && audioContent[src].coverArtURI !== "") ? audioContent[src].coverArtURI : "images/musicIcon.png";
179                 }
180                 catch(err)
181                 {
182                         console.log("Failed to load audio cover image");
183                 }
184         }
185 }
186
187 function updateMediaName(newArtist, newTitle, newCover)
188 {
189         console.log("MediaPlayer in updateMediaName");
190
191         var playBarHeight = mediaNameCanvas.height;
192         var boxWidth = playBarHeight * 0.75;
193         mediaNameCTX.clearRect(0,0,mediaNameCanvas.width, mediaNameCanvas.height);
194
195         if (currentPlayerType === "AUDIO")
196         {
197                 var shadeJump = 10;
198                 var alphaJump = 0.01;
199                 var currColor = 255;
200                 var currAlpha = 1.0;
201
202                 mediaNameCTX.fillStyle="rgba(30,30,30,0.5)";
203                 mediaNameCTX.strokeStyle="rgba(130,130,130,1)";
204                 mediaNameCTX.lineWidth = 5;
205                 mediaNameCTX.fillRect(0,0,mediaNameCanvas.width, playBarHeight);
206                 mediaNameCTX.strokeRect(-20,0,mediaNameCanvas.width + 40, playBarHeight);
207
208                 if (newCover === undefined || newCover.naturalWidth === undefined || newCover.naturalWidth <= 0)
209                 {
210                         newCover = musicIcon;
211                 }
212
213                 mediaNameCTX.drawImage(newCover, 20, (playBarHeight - boxWidth) / 2, boxWidth, boxWidth);
214
215                 if (screenOrientation === "portrait")
216                 {
217                         var textStartX = boxWidth + 50;
218                         var trackText = new TextObject(mediaNameCTX,{"text" : newTitle, "xLoc" : textStartX, "yLoc" : 70 , "zLoc" : 0,
219                                                                         "width" : mediaNameCanvas.width - textStartX, "height" : 50, "lineHeight" : 50, "wordWrap" : true});
220                         trackText.applyTemplate(mainMenuTitleTemplate);
221                         var artistText = new TextObject(mediaNameCTX,{"text" : newArtist, "xLoc" : textStartX, "yLoc" : 70 + trackText.height, "zLoc" : 0,
222                                                                         "width" : mediaNameCanvas.width - textStartX, "height" : 50, "lineHeight" : 50, "wordWrap" : true});
223                         artistText.applyTemplate(mainTrackTemplate);
224                         artistText.yLoc = 70 + trackText.height;
225                 }
226                 else
227                 {
228                         var textStartX = boxWidth + 50;
229                         var trackText = new TextObject(mediaNameCTX,{"text" : newTitle, "xLoc" : textStartX, "yLoc" : 50 , "zLoc" : 0,
230                                                                         "width" : mediaNameCanvas.width - textStartX, "height" : 30, "lineHeight" : 30, "wordWrap" : true});
231                         trackText.applyTemplate(mainMenuTitleTemplateLandscape);
232                         var artistText = new TextObject(mediaNameCTX,{"text" : newArtist, "xLoc" : textStartX, "yLoc" : 50, "zLoc" : 0,
233                                                                         "width" : mediaNameCanvas.width - textStartX, "height" : 30, "lineHeight" : 30, "wordWrap" : true});
234                         artistText.applyTemplate(mainTrackTemplateLandscape);
235                         artistText.yLoc = 50 + trackText.height;
236                 }
237
238                 trackText.drawObj();
239                 trackText.drawLargeShadow();
240                 artistText.drawObj();
241
242         }
243 }
244
245 function fillMediaList(contentList)
246 {
247         console.log("MediaPlayer in fillMediaList");
248         //Don't try and fill an empty content list or an audio list that hasn't finished loading the thumbnails
249         if (contentList === undefined || contentList === null || contentList.length <=0 || (contentList === audioContent && !imagesLoaded))
250                 return false;
251
252         var iconURI;
253         var currentCanvas;
254         var iconImg = new Image();
255         var canvasW = mediaListItemW;
256         var canvasH = mediaListItemH * 0.95 ;
257
258         $("#mediaListItems").empty();
259         var lightColor = false;
260         for (var i=0; i < contentList.length; i++)
261         {
262                 if (!lightColor)
263                 {
264                         if (nightMode)
265                         {
266                                 $("#mediaListItems").append("<li><a href='#' class='night'>" +
267                                                 "<canvas id=canvasNum" + i + " width=" + canvasW + " height=" + canvasH + "> </canvas>" +
268                                                 "</a></li>"
269                                 );
270                         }
271                         else
272                         {
273                                 $("#mediaListItems").append("<li><a href='#'>" +
274                                                 "<canvas id=canvasNum" + i + " width=" + canvasW + " height=" + canvasH + "> </canvas>" +
275                                                 "</a></li>"
276                                 );
277                         }
278                 }
279                 else
280                 {
281                         if (nightMode)
282                         {
283                                 $("#mediaListItems").append("<li><a href='#' class='lightColor night'>" +
284                                         "<canvas id=canvasNum" + i + " width=" + canvasW + " height=" + canvasH + "> </canvas>" +
285                                         "</a></li>"
286                                 );
287                         }
288                         else
289                         {
290                                 $("#mediaListItems").append("<li><a href='#' class='lightColor'>" +
291                                         "<canvas id=canvasNum" + i + " width=" + canvasW + " height=" + canvasH + "> </canvas>" +
292                                         "</a></li>"
293                                 );
294                         }
295
296                 }
297
298                 lightColor = !lightColor;
299
300                 currentCanvas = document.getElementById("canvasNum"+ i);
301                 currentCTX = currentCanvas.getContext("2d");
302
303                 // Set callback function for the new list item
304                 $("#canvasNum"+i).click(function () {
305                         listIndex = $(this).parent().parent().index();
306
307                         switch (currentPlayerType)
308                         {
309                         case "AUDIO":
310                                 try
311                                 {
312                                         $("#playButton").toggleClass('playing', false);
313                                         loadAndPlay = true;
314                                         updateMediaName(audioContent[listIndex].artists[0], audioContent[listIndex].title, audioContent[listIndex].coverArt);
315                                         $("#audioSrc").attr("src", audioContent[listIndex].contentURI);
316                                         audioPlayer.load();
317                                         startLoadTimer();
318                                 }
319                                 catch(err)
320                                 {
321                                         console.log("updateMediaName error: " + err.message);
322                                 }
323                                 break;
324
325                         case "VIDEO":
326                                 try
327                                 {
328                                         $("#playButton").toggleClass('playing', false);
329                                         updateMediaName(videoContent[listIndex].artists[0], audioContent[listIndex].title, vidIcon);
330                                         $("#videoSrc").attr("src", videoContent[listIndex].contentURI);
331                                         videoPlayer.load();
332                                         $("#mediaList").fadeOut(300);
333                                 }
334                                 catch(err)
335                                 {
336                                         console.log("updateMediaName error: " + err.message);
337                                 }
338                                 break;
339
340                         case "IMAGE":
341                                 try
342                                 {
343                                         $("#playButton").toggleClass('playing', false);
344                                         $("#imagePlayer").css("background", "url(" + imageContent[listIndex].contentURI + ") no-repeat center");
345                                         $("#imagePlayer").css("background-size", "contain");
346                                         $("#mediaList").fadeOut(300);
347                                 }
348                                 catch(err)
349                                 {
350                                         console.log("updateMediaName error: " + err.message);
351                                 }
352                                 break;
353
354                         default:
355                                 break;
356                         }
357                 });
358
359                 switch (currentPlayerType)
360                 {
361                 case "AUDIO":
362                         currentCTX.drawImage(audioContent[i].coverArt, 0, 0, canvasH, canvasH );
363                         var trackText = new TextObject(currentCTX,{"text" : contentList[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0});
364                         var artistText = new TextObject(currentCTX,{"text" : contentList[i].artists[0], "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0});
365
366                         break;
367                 case "VIDEO":
368                         currentCTX.drawImage(vidIcon, 0, 0, canvasH, canvasH );
369                         var artistText = new TextObject(currentCTX,{"text" : contentList[i].artists[0], "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0});
370                         var trackText = new TextObject(currentCTX,{"text" : contentList[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0});
371
372                         break;
373                 case "IMAGE":
374                         currentCTX.drawImage(imgIcon, 0, 0, canvasH, canvasH );
375                         var artistText = new TextObject(currentCTX,{"text" : contentList[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0});
376                         var trackText = new TextObject(currentCTX,{"text" : " ", "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0});
377                         break;
378
379                 default:
380                         break;
381                 }
382
383                 var mediaTextTemp1 = screenOrientation === "portrait" ? mediaTextTemplate2 : mediaTextTemplate2Landscape;
384                 var mediaTextTemp2 = screenOrientation === "portrait" ? mediaTextTemplate3 : mediaTextTemplate3Landscape;
385                 var trackTextTemp = screenOrientation === "portrait" ? trackTextTemplate : trackTextTemplateLandscape;
386
387                 trackText.applyTemplate(mediaTextTemp1);
388                 trackText.drawObj();
389                 trackText.applyTemplate(mediaTextTemp2);
390                 trackText.drawObj();
391
392                 artistText.applyTemplate(trackTextTemp);
393                 artistText.drawObj();
394         }
395
396         $("#mediaListItems li").css({"width" : mediaListItemW + "px", "height" : mediaListItemH + "px", "margin-bottom" : "10px"});
397 }
398
399 function onContentItemArraySuccess(content)
400 {
401         console.log("MediaPlayer in onContentItemArraySuccess");
402         var emptyContent = true;
403
404         if (!content || content === undefined || content.length <= 0)
405                 console.log("Invalid content for " + contentType);
406         else
407         {
408                 emptyContent = false;
409         }
410
411         switch (contentType)
412         {
413         case "AUDIO":
414
415                         if (!emptyContent)
416                         {
417                                 try
418                                 {
419                                         audioContent = content;
420                                         sortByAlpha(audioContent);
421
422                                         $("#audioSrc").attr("src", audioContent[0].contentURI);
423                                         audioPlayer.load();
424                                         startLoadTimer();
425
426                                         var imgSources = [];
427                                         for (var i = 0; i < audioContent.length; i++)
428                                         {
429                                                 var iconURI = (audioContent[i].thumbnailURIs !== undefined && audioContent[i].thumbnailURIs !== null) ? audioContent[i].thumbnailURIs[0] : "images/musicIcon.png";
430                                                 audioContent[i].coverArtURI = iconURI;
431                                         }
432
433                                         loadImages(fillMediaList);
434                                 }
435
436                                 catch (err)
437                                 {
438                                         console.log("Error when parsing audioContent");
439                                 }
440                         }
441
442                 contentType = "VIDEO";
443                 break;
444
445         case "VIDEO":
446                 if (!emptyContent)
447                 {
448                         videoContent = content;
449                         $("#videoSrc").attr("src", videoContent[0].contentURI);
450                 }
451                 contentType = "IMAGE";
452                 break;
453
454         case "IMAGE":
455                 if (!emptyContent)
456                 {
457                         imageContent = content;
458                         $("#imagePlayer").css("background", "url(" + imageContent[0].contentURI + ") no-repeat center");
459                         $("#imagePlayer").css("background-size", "contain");
460                 }
461                 contentType = undefined;
462                 break;
463
464         default:
465                 console.log("Undefined content search type");
466         nextContentType = undefined;
467         break;
468         }
469
470         if (contentType !== undefined)
471                 getMedia(contentType);
472 }
473
474 function getMedia(mediaType)
475 {
476         console.log("MediaPlayer in getMedia");
477         var manager = tizen.content;
478
479         var filter = new tizen.AttributeFilter("type", "EXACTLY", mediaType);
480         manager.find(onContentItemArraySuccess, onError, null, filter);
481 }
482
483 function showMediaMenu()
484 {
485         console.log("MediaPlayer in showMediaMenu");
486         $(".navButton").fadeIn(800);
487
488         switch(currentPlayerType)
489         {
490         case "AUDIO":
491                 //show audio player
492                 try
493                 {
494                         updateMediaName(audioContent[listIndex].artists[0], audioContent[listIndex].title, audioContent[listIndex].coverArt);
495                 }
496                 catch(err)
497                 {
498                         console.log("updateMediaName failed for showMediaMenu (audio) : " + err.message);
499                 }
500
501                 $("#mediaName").fadeIn(800);
502                 $(".sortButton").fadeIn(800);
503                 currentPlayer.fadeIn(800);
504
505                 $("#mediaList").addClass("mediaListAudioList");
506
507                 if (screenOrientation === "landscape" )
508                         $("#mediaList").addClass("landscape");
509                 else
510                         $("#mediaList").removeClass("landscape");
511
512                 $("#mediaList").fadeIn(800);
513                 break;
514
515         case "VIDEO":
516                 //show video
517                 setTimeout(function(){currentPlayer.show()}, 800);              //The video element can't be faded, so wait a moment before showing
518                 break;
519
520         case "IMAGE":
521                 //show image
522                 currentPlayer.fadeIn(800);
523                 break;
524
525         default:
526                 console.log("Invalid player type");
527         break;
528         }
529 }
530
531 function showMediaList()
532 {
533         console.log("MediaPlayer in showMediaList");
534         if ($("#mediaList").is(":visible"))
535                 $("#mediaList").fadeOut(300);
536         else
537         {
538                 fillMediaList(currentContent);
539                 $("#mediaList").fadeIn(300);
540         }
541 }
542
543 function changeMenu(menuButtonId)
544 {
545         console.log("MediaPlayer in changeMenu");
546         var clickedButton  = $("#" + menuButtonId);
547         var buttonWidth  = clickedButton.width();
548         var buttonHeight = clickedButton.height();
549         var buttonBottom = clickedButton.css("bottom");
550         var buttonRight  = clickedButton.css("right");
551
552         //Animate the clicked button slightly
553         clickedButton.animate({
554                 bottom: screenOrientation === "portrait" ? "+=0" : "+=50",
555                                 right: screenOrientation === "portrait" ? "+=50" : "+=0",
556                                                 opacity: "0"
557         }, 300 ,
558
559         //Reset the size once done
560         function() {
561                 clickedButton.width(buttonWidth);
562                 clickedButton.height(buttonHeight);
563
564                 if (screenOrientation === "portrait")
565                         clickedButton.css({"right": buttonRight});
566                 else
567                         clickedButton.css({"bottom": buttonBottom});
568         }
569         );
570
571         $(".mainButton").fadeOut(300);
572
573         switch(menuButtonId)
574         {
575         case ("mainMusicButton"):
576                 speechObj.vocalizeString("Music player");
577                 currentMenu = "audio";
578                 currentPlayer = $("#audioPlayer");
579                 currentPlayerControls = document.getElementById("audioPlayer");
580                 currentPlayerType = "AUDIO";
581                 currentContent = audioContent;
582                 showMediaMenu();
583         break;
584
585         case ("mainVideoButton"):
586                 speechObj.vocalizeString("Video player");
587                 currentMenu = "video";
588                 currentPlayer = $("#videoPlayer");
589                 currentPlayerControls = document.getElementById("videoPlayer");
590                 currentPlayerType = "VIDEO";
591                 currentContent = videoContent;
592                 showMediaMenu();
593         break;
594
595         case ("mainImageButton"):
596                 speechObj.vocalizeString("Picture viewer");
597                 currentMenu = "image";
598                 currentPlayer = $("#imagePlayer");
599                 currentPlayerControls = imageControls;
600                 currentPlayerType = "IMAGE";
601                 currentContent = imageContent;
602                 showMediaMenu();
603         break;
604         default:
605                 console.log("Error: No menu by that name");
606         break;
607         }
608 }
609
610 function showMainMenu()
611 {
612         console.log("MediaPlayer in showMainMenu");
613         currentMenu = "main";
614         currentPlayerControls.pause();
615
616         $("#playButton").toggleClass('playing', false);
617
618         //If the media list is showing, hide it.  Remove the mediaListAudioList class if it exists so that it will resize properly
619         if ($("#mediaList").is(":visible"))
620                 $("#mediaList").fadeOut(300, function(){$("#mediaList").removeClass("mediaListAudioList");});
621
622         $(".navButton").fadeOut(300);
623         $(".sortButton").fadeOut(300);
624         $("#mediaName").fadeOut(300);
625
626         if (currentPlayerType !== "VIDEO")
627                 currentPlayer.fadeOut(300);
628         else
629                 currentPlayer.hide();
630
631
632         $(".mainButton").css({"opacity": "100"});
633         $(".mainButton").fadeIn(800);
634 }
635
636 function sortByAlpha(contentToSort)
637 {
638         console.log("MediaPlayer in sortByAlpha");
639         //If contentToSort is undefined it's because the request came from the sortBy buttons
640         if (contentToSort === undefined)
641                 contentToSort = audioContent;
642
643         contentToSort.sort(function (a,b) {
644                 var first = a.title.toLowerCase();
645                 var second = b.title.toLowerCase();
646
647                 if (first < second)
648                         return -1;
649                 if (first > second)
650                         return 1;
651
652                 return 0;
653         });
654
655         fillMediaList(contentToSort);
656 }
657
658 function sortByArtist(contentToSort)
659 {
660         console.log("MediaPlayer in sortByArtist");
661         if (contentToSort === undefined)
662                 contentToSort = audioContent;
663
664         contentToSort.sort(function (a,b) {
665                 var first = a.artists[0].toLowerCase();
666                 var second = b.artists[0].toLowerCase();
667
668                 if (first < second)
669                         return -1;
670                 if (first > second)
671                         return 1;
672
673                 return 0;
674         });
675
676         fillMediaList(contentToSort);
677 }
678
679 function sortByAlbum(contentToSort)
680 {
681         console.log("MediaPlayer in sortByAlbum");
682         if (contentToSort === undefined)
683                 contentToSort = audioContent;
684
685         contentToSort.sort(function (a,b) {
686                 var first = a.album.toLowerCase();
687                 var second = b.album.toLowerCase();
688
689                 if (first < second)
690                         return -1;
691                 if (first > second)
692                         return 1;
693
694                 return 0;
695         });
696
697         fillMediaList(contentToSort);
698 }
699
700 /**************************************** NAVIGATION FUNCTIONS *******************************************/
701
702
703 // A timer that will produce an error if a file can't be loaded.
704 function startLoadTimer()
705 {
706         console.log("MediaPlayer in startLoadTimer");
707         if (loadTimer !== undefined)
708                 clearTimeout(loadTimer);
709
710         loadTimer = setTimeout(
711                 function(){
712                 if (currentMenu != "main")
713
714                         $("#playButton").toggleClass('playing', false);
715                         alert("File failed to load! - " + audioContent[listIndex].artists[0] + " : " + audioContent[listIndex].title);
716                         currentFileLoaded = false;
717                 }, 5000);
718 }
719
720 // This function is called once a file being loaded is ready to play
721 function playLoadedMedia()
722 {
723         console.log("MediaPlayer in playLoadedMedia");
724         currentFileLoaded = true;
725
726         if (loadTimer !== undefined)
727                 clearTimeout(loadTimer);
728
729         if (loadAndPlay)
730         {
731                 currentPlayerControls.play();
732
733                 $("#playButton").toggleClass('playing', true);
734                 loadAndPlay = false;
735         }
736 }
737
738 function playButtonClick()
739 {
740         console.log("MediaPlayer in playButtonClick");
741         if (currentFileLoaded)
742         {
743                 if (currentPlayerControls.paused)
744                 {
745                         $("#playButton").toggleClass('playing', true);
746                         currentPlayerControls.play();
747                 }
748                 else
749                 {
750                         $("#playButton").toggleClass('playing', false);
751                         currentPlayerControls.pause();
752                 }
753         }
754         else
755                 alert(audioContent[listIndex].artists[0] + " : " + audioContent[listIndex].title + " failed to load, please select another file");
756 }
757
758 function pauseButtonClick()
759 {
760         console.log("MediaPlayer in pauseButtonClick");
761         if (!currentPlayerControls.paused)
762         {
763                 currentPlayerControls.pause();
764                 $("#playButton").toggleClass('playing', false);
765         }
766 }
767
768 function backButtonClick()
769 {
770         console.log("MediaPlayer in backButtonClick");
771         switch (currentPlayerType)
772         {
773         case "AUDIO":
774                 if (audioContent)
775                 {
776                         if (listIndex > 0 )
777                                 listIndex--;
778                         else
779                                 listIndex = imageContent.length - 1;
780
781                         loadAndPlay = true;
782                         audioPlayer.pause();
783
784                         $("#audioSrc").attr("src", audioContent[listIndex].contentURI);
785                         updateMediaName(audioContent[listIndex].artists[0], audioContent[listIndex].title, audioContent[listIndex].coverArt);
786                         audioPlayer.load();
787                         startLoadTimer();
788                 }
789                 break;
790
791         case "VIDEO":
792                 if (videoContent)
793                 {
794                         if (videoIndex > 0 )
795                                 videoIndex--;
796                         else
797                                 videoIndex = imageContent.length - 1;
798
799                         if ($("#mediaList").is(":visible"))
800                                 videoPlayer.pause();
801
802                         $("#playButton").toggleClass('playing', true);
803                         $("#videoSrc").attr("src", videoContent[videoIndex].contentURI);
804                         videoPlayer.load();
805                 }
806                 break;
807
808         case "IMAGE":
809                 if (imageContent)
810                 {
811                         if (imageIndex > 0 )
812                                 imageIndex--;
813                         else
814                                 imageIndex = imageContent.length - 1;
815
816                         $("#imagePlayer").css("background", "url(" + imageContent[imageIndex].contentURI + ") no-repeat center");
817                         $("#imagePlayer").css("background-size", "contain");
818                 }
819                 break;
820
821         default:
822                 console.log("Content failure");
823         break;
824         }
825 }
826
827
828 function nextButtonClick()
829 {
830         console.log("MediaPlayer in nextButtonClick");
831         switch (currentPlayerType)
832         {
833         case "AUDIO":
834                 if (audioContent)
835                 {
836                         if (audioContent.length > (listIndex + 1))
837                                 listIndex++;
838                         else
839                                 listIndex = 0;
840
841                         loadAndPlay = true;
842                         audioPlayer.pause();
843
844                         $("#audioSrc").attr("src", audioContent[listIndex].contentURI);
845                         updateMediaName(audioContent[listIndex].artists[0], audioContent[listIndex].title, audioContent[listIndex].coverArt);
846                         audioPlayer.load();
847                         startLoadTimer();
848                 }
849                 break;
850
851         case "VIDEO":
852                 if (videoContent)
853                 {
854                         if (videoContent.length > (videoIndex + 1))
855                                 videoIndex++;
856                         else
857                                 videoIndex = 0;
858
859                         videoPlayer.pause();
860                         $("#playButton").toggleClass('playing', true);
861                         $("#videoSrc").attr("src", videoContent[videoIndex].contentURI);
862                         videoPlayer.load();
863                 }
864                 break;
865
866         case "IMAGE":
867                 if (imageContent)
868                 {
869                         if (imageContent.length > (imageIndex + 1))
870                                 imageIndex++;
871                         else
872                                 imageIndex = 0;
873
874                         $("#imagePlayer").css("background", "url(" + imageContent[imageIndex].contentURI + ") no-repeat center");
875                         $("#imagePlayer").css("background-size", "contain");
876                 }
877                 break;
878
879         default:
880                 console.log("Content failure");
881         break;
882         }
883 }
884
885 /**************************************** END NAVIGATION FUNCTIONS *******************************************/
886
887 function resizeMainMenu()
888 {
889         console.log("MediaPlayer in resizeMainMenu");
890
891         $("#mediaList").fadeOut(0);
892         screenWidth = window.innerWidth;
893         screenHeight = window.innerHeight;
894         screenOrientation = screenWidth < screenHeight ? "portrait" : "landscape";
895         iconWidth = screenOrientation === "portrait" ? screenHeight / 4 : screenWidth / 4;
896         var padding = 20;
897
898         $(".mainButton").width(iconWidth + "px");
899         $(".mainButton").height(iconWidth + "px");
900
901         var iconsTop  = screenOrientation === "portrait" ? ((screenHeight - (iconWidth * 3)) / 2) - (padding * 3) : (screenHeight - iconWidth) / 2;
902
903         if (screenOrientation === "portrait")
904                 $("#mainMenuButtons").css({"top": iconsTop + "px", "left" : (screenWidth / 2) - (iconWidth /2) - padding + "px", "width" : "50%"});
905         else
906         {
907                 $("#mainMenuButtons").css({"top": iconsTop + "px", "left" : ((iconWidth / 2) - (padding * 3)) + "px", "width" : "100%"});
908                 $("#sortButtons").addClass("landscape");
909         }
910 }
911
912 function resizePlayerPage()
913 {
914         console.log("MediaPlayer in resizePlayerPage");
915
916         audioPlayer = document.getElementById("audioPlayer");
917         videoPlayer = document.getElementById("videoPlayer");
918         screenWidth = window.innerWidth;
919         screenHeight = window.innerHeight;
920
921         var padding = 15;
922         var buttonWidth = screenOrientation === "portrait" ? screenHeight * 0.05 : screenWidth * 0.05;
923
924         $("#backButton").css({"width": buttonWidth + "px", "height": buttonWidth + "px", "top": padding + "px", "left": ((screenWidth / 2) - (buttonWidth *3)) + "px"});
925         $("#nextButton").css({"width": buttonWidth + "px", "height": buttonWidth + "px", "top": padding + "px", "left": ((screenWidth / 2) + (buttonWidth *2)) + "px"});
926         $("#returnButton").css({"width": buttonWidth + "px", "height": buttonWidth + "px", "top": padding + "px", "left": padding + "px"});
927         $("#listButton").css({"width": buttonWidth + "px", "height": buttonWidth + "px", "top": padding + "px", "left": (screenWidth - buttonWidth - padding * 2) + "px"});
928         $("#playButton").css({"width": buttonWidth * 1.3 + "px", "height": buttonWidth * 1.3 + "px", "top": padding * 0.3 + "px", "left": (screenWidth / 2) - (buttonWidth / 2) + "px"});
929
930         mediaNameCanvas.width = (screenWidth);
931         mediaNameCanvas.height = (screenHeight * 0.34) - (buttonWidth + (2 * padding));
932         mediaNameCanvas.style.top = (buttonWidth + (2 * padding) ) + "px";
933         mediaNameCanvas.style.left = "0px";
934
935         var sortButtonTop = (buttonWidth + (2 * padding) ) + mediaNameCanvas.height - (buttonWidth * 1.3);
936         var sortButtonWidth = buttonWidth * 2.5;
937         var buttonSpacing = screenWidth / 5;
938
939         mediaListItemW = $("#mediaList").width() * 0.92;
940         mediaListItemH = $("#mediaList").height() / 10;
941 }
942
943 function resizeAll()
944 {
945         console.log("MediaPlayer in resizeAll");
946         resizeMainMenu();
947         resizePlayerPage();
948 }
949
950 /*
951  * swipe - Handles swipe events.  Currently it just acts as another way to hit the next / back buttons, but
952  * it could be expanded to other things in the future.
953  */
954
955 function swipe(direction, object)
956 {
957         console.log("MediaPlayer in swipe");
958         switch (object)
959         {
960         case "mediaName":
961                 if (direction === "right")
962                         nextButtonClick();
963                 else if (direction === "left")
964                         backButtonClick();
965                 break;
966
967         default:
968                 break;
969         }
970 }
971
972 function init()
973 {
974         console.log("MediaPlayer in init");
975          var vehicle = tizen.vehicle;
976
977
978         /* Subscribe to AMB NightMode signal, and switch colors
979          * upon receipt of the signal
980          */
981
982         vehicle.subscribe("NightMode",function(value) {
983                 console.log("MediaPlayer: Day / Night mode changed to " + value.nightmode);
984
985                 if (nightMode !== value.nightmode)
986                 {
987                         Array.prototype.forEach.call (document.querySelectorAll ('*'), function (el) {el.classList.toggle('night');});
988                         nightMode = value.nightmode
989                 }
990         });
991
992         /* Subscribe to AMB DrivingMode signal, and pause video
993          * upon receipt of the signal
994          */
995
996
997         vehicle.subscribe("DrivingMode",function(value) {
998                 console.log("MediaPlayer: DrivingMode changed to " + value.drivingMode);
999
1000                 if (value.vehicleSpeed > 0 && currentPlayerType === "VIDEO" && !currentPlayerControls.paused)
1001                 {
1002                         console.log("MediaPlayer: pausing video due to vehicle motion");
1003                         currentPlayerControls.pause();
1004                          waitingToResumeVideo = true;
1005                 }
1006                 else if (value.vehicleSpeed === 0 && currentPlayerType === "VIDEO" && waitingToResumeVideo)
1007                 {
1008                         console.log("MediaPlayer: vehicle has stopped, resuming video");
1009                         currentPlayerControls.play();
1010                         waitingToResumeVideo = false;
1011                 }
1012
1013         });
1014
1015
1016         musicIcon.src = "images/musicIcon.png";
1017         vidIcon.src = "images/videoIcon.png";
1018         imgIcon.src = "images/imageIcon.png";
1019         imageControls = new ImageControls();
1020
1021         mediaNameCanvas = document.getElementById("mediaName");
1022         mediaNameCTX = mediaNameCanvas.getContext("2d");
1023
1024         //Resize all items and search for local media
1025         resizeAll();
1026
1027         //Check if DLNA plugin is installed.  If so, scan for media.
1028         if (tizen.mediaserver)
1029         {
1030                 tizen.mediaserver.scanNetwork(foundMediaServer);
1031         }
1032         else
1033                 console.log("MediaPlayer: No DLNA server running, using local media only...");
1034
1035         //Setup voice control
1036         if (tizen.speech)
1037                 setupSpeech();
1038         else
1039                 console.log("MediaPlayer: Speech Recognition not running, voice control will be unavailable");
1040
1041         //Get local media
1042         getMedia(contentType);
1043
1044         //Prevent highlighting
1045         window.ondragstart = function() { return false; }
1046
1047         $(window).bind('resize', resizeAll);
1048
1049         //Simple swipe detection
1050         $("#mediaName").mousedown(function(e){mouseDownEvent = e;});
1051         $("#mediaName").mouseup(function(e){
1052                 if (Math.abs(mouseDownEvent.clientY - e.clientY) < 100)
1053                 {
1054                         if (Math.abs(mouseDownEvent.clientX - e.clientX) > 100)
1055                         {
1056                                 if (mouseDownEvent.clientX > e.clientX)
1057                                         swipe("left", "mediaName");
1058                                 else
1059                                         swipe("right", "mediaName");
1060                         }
1061                 }
1062         });
1063
1064     document.getElementById('videoPlayer').addEventListener("playing", function() {
1065         $("#navigationButtons").hide();
1066     }, false);
1067     document.getElementById('videoPlayer').addEventListener("pause", function() {
1068         $("#navigationButtons").show();
1069     }, false);
1070 }
1071
1072 $(document).ready(function () {
1073         init();
1074 });