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