Merge pull request #473 from Montellese/onplaybackspeedchanged
[vuplus_xbmc] / addons / webinterface.default / js / MediaLibrary.js
1 /*
2  *      Copyright (C) 2005-2010 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 var MediaLibrary = function() {
23                 this.init();
24                 return true;
25         }
26
27 MediaLibrary.prototype = {
28     playlists: { },  
29   
30                 init: function() {
31                         this.bindControls();
32       this.getPlaylists();
33                 },
34                 
35                 bindControls: function() {
36                         $('#musicLibrary').click(jQuery.proxy(this.musicLibraryOpen, this));
37                         $('#movieLibrary').click(jQuery.proxy(this.movieLibraryOpen, this));
38                         $('#tvshowLibrary').click(jQuery.proxy(this.tvshowLibraryOpen, this));
39                         $('#pictureLibrary').click(jQuery.proxy(this.pictureLibraryOpen, this));
40                         $('#remoteControl').click(jQuery.proxy(this.remoteControlOpen, this));
41                         $('#overlay').click(jQuery.proxy(this.hideOverlay, this));
42                         $(window).resize(jQuery.proxy(this.updatePlayButtonLocation, this));
43                 },
44                 resetPage: function() {
45                         $('#musicLibrary').removeClass('selected');
46                         $('#movieLibrary').removeClass('selected');
47                         $('#tvshowLibrary').removeClass('selected');
48                         $('#remoteControl').removeClass('selected');
49                         $('#pictureLibrary').removeClass('selected');
50                         this.hideOverlay();
51                 },
52                 replaceAll: function(haystack, find, replace) {
53                         var parts = haystack.split(find);
54                         var result = "";
55                         var first = true;
56                         for (index in parts)
57                         {
58                                 if (!first)
59                                         result += replace;                              
60                                 else
61                                         first = false;
62                                 
63                                 result += parts[index];
64                         }
65                         
66                         return result;
67                 },
68
69     getPlaylists: function() {
70       jQuery.ajax({
71                                 type: 'POST', 
72                                 url: JSON_RPC + '?GetPlaylists', 
73                                 data: '{"jsonrpc": "2.0", "method": "Playlist.GetPlaylists", "id": 1}', 
74                                 timeout: 3000,
75                                 success: jQuery.proxy(function(data) {
76                                         if (data && data.result && data.result.length > 0) {
77             $.each($(data.result), jQuery.proxy(function(i, item) {
78               this.playlists[item.type] = item.playlistid;
79             }, this));
80           }
81                                 }, this),
82                                 error: jQuery.proxy(function(data, error) {
83                                         displayCommunicationError();
84                                         setTimeout(jQuery.proxy(this.updateState, this), 2000);
85                                 }, this), 
86                                 dataType: 'json'});
87     },
88                 remoteControlOpen: function(event) {
89                         this.resetPage();
90                         $('#remoteControl').addClass('selected');
91                         $('.contentContainer').hide();
92                         var libraryContainer = $('#remoteContainer');
93                         if (!libraryContainer || libraryContainer.length == 0) {
94                                 $('#spinner').show();
95                                 libraryContainer = $('<div>');
96                                 libraryContainer.attr('id', 'remoteContainer')
97                                                                 .addClass('contentContainer');
98                                 $('#content').append(libraryContainer);
99                                 var keys=[
100                                                 {name:'up',width:'40px',height:'30px',top:'28px',left:'58px'}
101                                                 ,{name:'down',width:'40px',height:'30px',top:'122px',left:'58px'}
102                                                 ,{name:'left',width:'40px',height:'30px',top:'74px',left:'15px'}
103                                                 ,{name:'right',width:'40px',height:'30px',top:'74px',left:'104px'}
104                                                 ,{name:'ok',width:'40px',height:'30px',top:'74px',left:'58px'}
105                                                 ,{name:'back',width:'40px',height:'30px',top:'13px',left:'161px'}
106                                                 ,{name:'home',width:'40px',height:'30px',top:'154px',left:'8px'}
107                                                 ,{name:'mute',width:'40px',height:'30px',top:'107px',left:'391px'}
108                                                 ,{name:'power',width:'30px',height:'30px',top:'-3px',left:'13px'}
109                                                 ,{name:'volumeup',width:'30px',height:'30px',top:'49px',left:'422px'}
110                                                 ,{name:'volumedown',width:'30px',height:'30px',top:'49px',left:'367px'}
111                                                 ,{name:'playpause',width:'32px',height:'23px',top:'62px',left:'260px'}
112                                                 ,{name:'stop',width:'32px',height:'23px',top:'62px',left:'211px'}
113                                                 ,{name:'next',width:'38px',height:'25px',top:'102px',left:'304px'}
114                                                 ,{name:'previous',width:'38px',height:'25px',top:'101px',left:'160px'}
115                                                 ,{name:'forward',width:'32px',height:'23px',top:'102px',left:'259px'}
116                                                 ,{name:'rewind',width:'32px',height:'23px',top:'101px',left:'211px'}
117                                                 ,{name:'cleanlib_a',width:'46px',height:'26px',top:'47px',left:'553px'}
118                                                 ,{name:'updatelib_a',width:'46px',height:'26px',top:'47px',left:'492px'}
119                                                 ,{name:'cleanlib_v',width:'46px',height:'26px',top:'111px',left:'553px'}
120                                                 ,{name:'updatelib_v',width:'46px',height:'26px',top:'111px',left:'492px'}
121                                          ];
122                                 for (var akey in keys) {
123                                         var aremotekey=$('<p>').attr('id',keys[akey]['name']);
124                                         aremotekey.addClass('remote_key')
125                                                 .css('height',keys[akey]['height'])
126                                                 .css('width',keys[akey]['width'])
127                                                 .css('top',keys[akey]['top'])
128                                                 .css('left',keys[akey]['left'])
129                                                 //.css('border','1px solid black')
130                                                 .bind('click',{key: keys[akey]['name']},jQuery.proxy(this.pressRemoteKey,this));
131                                                 libraryContainer.append(aremotekey);
132                                 }
133                                 
134         
135                         } else {
136                                 libraryContainer.show();
137                                 libraryContainer.trigger('scroll');
138                         }
139
140                         $('#spinner').hide();
141                 },
142
143                 pressRemoteKey: function(event) {
144                         var keyPressed=event.data.key;
145                         $('#spinner').show();
146                         var player = -1;
147       // TODO: Get active player
148                         if($('#videoDescription').is(':visible'))
149                           player = this.playlists["video"];
150                         else if($('#audioDescription').is(':visible'))
151         player = this.playlists["audio"];
152         
153                         //common part
154                         switch(keyPressed) {
155                                 case 'cleanlib_a':
156                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "AudioLibrary.Clean", "id": 1}', function(data){$('#spinner').hide();}, 'json');
157                                         return; 
158                                 case 'updatelib_a':
159                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "AudioLibrary.Scan", "id": 1}', function(data){$('#spinner').hide();}, 'json');
160                                         return; 
161                                 case 'cleanlib_v':
162                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "VideoLibrary.Clean", "id": 1}', function(data){$('#spinner').hide();}, 'json');
163                                         return; 
164                                 case 'updatelib_v':
165                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "VideoLibrary.Scan", "id": 1}', function(data){$('#spinner').hide();}, 'json');
166                                         return; 
167                                 case 'back':
168                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Back", "id": 1}', function(data){$('#spinner').hide();}, 'json');
169                                         return; 
170                                 case 'home':
171                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Home", "id": 1}', function(data){$('#spinner').hide();}, 'json');
172                                         return;
173                                 case 'mute':
174                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.SetMute", "params": { "mute": "toggle" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
175                                         return;
176                                 case 'power':
177                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "System.Shutdown", "id": 1}', function(data){$('#spinner').hide();}, 'json');
178                                         return;
179                                 case 'volumeup':
180         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": { "properties": [ "volume" ] }, "id": 1}', function(data){
181                                                 var volume = data.result.volume + 1;
182                                                 jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": { "volume": '+volume+' }, "id": 1}', function(data){
183                                         
184                                                 $('#spinner').hide();
185                                                  }, 'json');
186                            }, 'json');
187                                         return;
188                                 case 'volumedown':
189                                         jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": { "properties": [ "volume" ] }, "id": 1}', function(data){
190                                                 var volume = data.result.volume - 1;
191                                                 jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Application.SetVolume", "params": { "volume": '+volume+' }, "id": 1}', function(data){
192                                         
193                                                 $('#spinner').hide();
194                                                  }, 'json');
195                            }, 'json');
196                                         return;
197                         }
198                         //menus or other sections
199                         if (player == -1)
200                         {       
201                                 switch(keyPressed) {
202                                         case 'up':
203                                                 jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Up", "id": 1}', function(data){$('#spinner').hide();}, 'json');
204                                                 return;
205                                         case 'down':
206                                                 jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Down", "id": 1}', function(data){$('#spinner').hide();}, 'json');
207                                                 return;
208                                         case 'left':
209                                                 jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Left", "id": 1}', function(data){$('#spinner').hide();}, 'json'); 
210                                                 return;
211                                         case 'right':
212                                                 jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Right", "id": 1}', function(data){$('#spinner').hide();}, 'json');
213                                                 return;
214                                         case 'ok':
215                                                 jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Input.Select", "id": 1}', function(data){$('#spinner').hide();}, 'json');
216                                                 return;                         
217                                 }
218                         }
219       
220       if (player >= 0)
221       {
222         switch(keyPressed) {
223           case 'up':
224             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.Seek", "params": { "playerid": ' + player + ', "value": "bigforward" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
225             return;
226           case 'down':
227             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.Seek", "params": { "playerid": ' + player + ', "value": "bigbackward" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
228             return;
229           case 'left':
230             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.Seek", "params": { "playerid": ' + player + ', "value": "smallbackward" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');        
231             return;
232           case 'right':
233             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.Seek", "params": { "playerid": ' + player + ', "value": "smallforward" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
234             return;
235           case 'playpause':
236             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.PlayPause", "params": { "playerid": ' + player + ' }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
237             return;
238           case 'stop':
239             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": ' + player + ' }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
240             return;
241           case 'next':
242             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.GoNext", "params": { "playerid": ' + player + ' }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
243             return;
244           case 'previous':
245             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.GoPrevious", "params": { "playerid": ' + player + ' }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
246             return;
247           case 'forward':
248             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.SetSpeed", "params": { "playerid": ' + player + ', "speed": "increment" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
249             return;
250           case 'rewind':
251             jQuery.post(JSON_RPC + '?SendRemoteKey', '{"jsonrpc": "2.0", "method": "Player.SetSpeed", "params": { "playerid": ' + player + ', "speed": "decrement" }, "id": 1}', function(data){$('#spinner').hide();}, 'json');
252             return;
253         }
254       }
255                 },
256
257                 musicLibraryOpen: function(event) {
258                         this.resetPage();
259                         $('#musicLibrary').addClass('selected');
260                         $('.contentContainer').hide();
261                         var libraryContainer = $('#libraryContainer');
262                         if (!libraryContainer || libraryContainer.length == 0) {
263                                 $('#spinner').show();
264                                 libraryContainer = $('<div>');
265                                 libraryContainer.attr('id', 'libraryContainer')
266                                                                 .addClass('contentContainer');
267                                 $('#content').append(libraryContainer);
268                                 jQuery.post(JSON_RPC + '?GetAlbums', '{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "limits": { "start": 0 }, "properties": ["description", "theme", "mood", "style", "type", "albumlabel", "artist", "genre", "rating", "title", "year", "thumbnail"], "sort": { "method": "artist" } }, "id": 1}', jQuery.proxy(function(data) {
269                                         if (data && data.result && data.result.albums) {
270                                                 this.albumList = data.result.albums;
271                                                 $.each($(this.albumList), jQuery.proxy(function(i, item) {
272                                                         var floatableAlbum = this.generateThumb('album', item.thumbnail, item.title, item.artist);
273                                                         floatableAlbum.bind('click', { album: item }, jQuery.proxy(this.displayAlbumDetails, this));
274                                                         libraryContainer.append(floatableAlbum);
275                                                 }, this));
276                                                 libraryContainer.append($('<div>').addClass('footerPadding'));
277                                                 $('#spinner').hide();
278                                                 libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
279                                                 libraryContainer.trigger('scroll');
280                                                 myScroll = new iScroll('libraryContainer');
281                                         } else {
282                                                 libraryContainer.html('');
283                                         }
284                                 }, this), 'json');
285                         } else {
286                                 libraryContainer.show();
287                                 libraryContainer.trigger('scroll');
288                         }
289                 },
290                 getThumbnailPath: function(thumbnail) {
291                         return thumbnail ? ('/vfs/' + thumbnail) : DEFAULT_ALBUM_COVER;
292                 },
293                 generateThumb: function(type, thumbnail, title, artist) {
294                         var floatableAlbum = $('<div>');
295                         var path = this.getThumbnailPath(thumbnail);
296                         title = title || '';
297                         artist = artist ||'';
298                         if (title.length > 18 && !(title.length <= 21)) {
299                                 title = title.substring(0, 18) + '...';
300                         }
301                         if (artist.length > 20 && !(artist.length <= 22)) {
302                                 artist = artist.substring(0, 20) + '...';
303                         }
304                         var className = '';
305                         var code = '';
306                         switch(type) {
307                                 case 'album':
308                                         className = 'floatableAlbum';
309                                         code = '<p class="album" title="' + title + '">' + title + '</p><p class="artist" title="' + artist + '">' + artist + '</p>';
310                                         break;
311                                 case 'movie':
312                                         className = 'floatableMovieCover';
313                                         code = '<p class="album" title="' + title + '">' + title + '</p>';
314                                         break;
315                                 case 'tvshow':
316                                         className = 'floatableTVShowCover';
317                                         break;
318                                 case 'tvshowseason':
319                                         className = 'floatableTVShowCoverSeason';
320                                         break;
321                                 case 'image':
322                                 case 'directory':
323                                         className = 'floatableAlbum';
324                                         code = '<p class="album" title="' + title + '">' + title + '</p>';
325                                         break;
326                         }
327                         return floatableAlbum.addClass(className).html('<div class="imgWrapper"><div class="inner"><img src="' + path + '" alt="' + title + '" /></div></div>' + code);
328                 },
329                 showAlbumSelectorBlock: function(album) {
330                         if (album) {
331                                 //Find album in stored array
332                                 var prevAlbum = null,
333                                         nextAlbum = null;
334                                 $.each($(this.albumList), jQuery.proxy(function(i, item) {
335                                         if (item.albumid == album.albumid) {
336                                                 if (this.albumList.length > 1) {
337                                                         prevAlbum = this.albumList[i <= 0 ? this.albumList.length-1 : i-1];
338                                                         nextAlbum = this.albumList[i >= this.albumList.length ? 0 : i+1];
339                                                 }
340                                                 return false; /* .each break */
341                                         }
342                                 }, this));
343                                 var albumSelectorBlock = $('#albumSelector');
344                                 if (!albumSelectorBlock || albumSelectorBlock.length == 0) {
345                                         albumSelectorBlock = $('<div>');
346                                         albumSelectorBlock.attr('id', 'albumSelector')
347                                                                           .html('<table><tr><td class="allAlbums">All Albums</td><td class="activeAlbumTitle"></td><td class="prevAlbum">&nbsp;</td><td class="nextAlbum">&nbsp;</td></tr></table>');
348                                         $('#content').prepend(albumSelectorBlock);
349                                         $('#albumSelector .allAlbums').bind('click', jQuery.proxy(this.hideAlbumDetails, this));
350                                 }
351                                 $('#albumSelector .prevAlbum').unbind();
352                                 $('#albumSelector .nextAlbum').unbind();
353                                 if (prevAlbum) {
354                                         $('#albumSelector .prevAlbum').bind('click', {album: prevAlbum}, jQuery.proxy(this.displayAlbumDetails, this));
355                                 }
356                                 if (nextAlbum) {
357                                         $('#albumSelector .nextAlbum').bind('click', {album: nextAlbum}, jQuery.proxy(this.displayAlbumDetails, this));
358                                 }
359                                 $('#albumSelector .activeAlbumTitle').html(album.title||'Unknown Album');
360                                 albumSelectorBlock.show();
361                         }
362                 },
363                 hideAlbumDetails: function() {
364                         $('.contentContainer').hide();
365                         this.musicLibraryOpen();
366                 },
367                 displayAlbumDetails: function(event) {
368                         this.showAlbumSelectorBlock(event.data.album);
369                         var albumDetailsContainer = $('#albumDetails' + event.data.album.albumid);
370                         $('#topScrollFade').hide();
371                         if (!albumDetailsContainer || albumDetailsContainer.length == 0) {
372                                 $('#spinner').show();
373                                 jQuery.post(JSON_RPC + '?GetSongs', '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": { "properties": ["title", "artist", "genre", "track", "duration", "year", "rating", "playcount"], "albumid" : ' + event.data.album.albumid + ' }, "id": 1}', jQuery.proxy(function(data) {
374                                         albumDetailsContainer = $('<div>');
375                                         albumDetailsContainer.attr('id', 'albumDetails' + event.data.album.albumid)
376                                                                                  .addClass('contentContainer')
377                                                                                  .addClass('albumContainer')
378                                                                                  .html('<table class="albumView"><thead><tr class="headerRow"><th>Artwork</th><th>&nbsp;</th><th>Name</th><th class="time">Time</th><th>Artist</th><th>Genre</th></tr></thead><tbody class="resultSet"></tbody></table>');
379                                         $('.contentContainer').hide();
380                                         $('#content').append(albumDetailsContainer);
381                                         var albumThumbnail = event.data.album.thumbnail;
382                                         var albumTitle = event.data.album.title||'Unknown Album';
383                                         var albumArtist = event.data.album.artist||'Unknown Artist';
384                                         var trackCount = data.result.limits.total;
385                                         $.each($(data.result.songs), jQuery.proxy(function(i, item) {
386                                                 if (i == 0) {
387                                                         var trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2);
388                                                         trackRow.append($('<td>').attr('rowspan', ++trackCount + 1).addClass('albumThumb'));
389                                                         for (var a = 0; a < 5; a++) {
390                                                                 trackRow.append($('<td>').html('&nbsp').attr('style', 'display: none'));
391                                                         }
392                                                         $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
393                                                 }
394                                                 var trackRow = $('<tr>').addClass('trackRow').addClass('tr' + i % 2).bind('click', { album: event.data.album, itmnbr: i }, jQuery.proxy(this.playTrack,this));
395                                                 var trackNumberTD = $('<td>')
396                                                         .html(item.track)
397                                                         
398                                                 trackRow.append(trackNumberTD);
399                                                 var trackTitleTD = $('<td>')
400                                                         .html(item.title);
401                                                         
402                                                 trackRow.append(trackTitleTD);
403                                                 var trackDurationTD = $('<td>')
404                                                         .addClass('time')
405                                                         .html(durationToString(item.duration));
406                                                         
407                                                 trackRow.append(trackDurationTD);
408                                                 var trackArtistTD = $('<td>')
409                                                         .html(item.artist);
410                                                         
411                                                 trackRow.append(trackArtistTD);
412                                                 var trackGenreTD = $('<td>')
413                                                         .html(item.genre);
414                                                         
415                                                 trackRow.append(trackGenreTD);
416                                                 $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
417                                         }, this));
418                                         if (trackCount > 0) {
419                                                 var trackRow = $('<tr>').addClass('fillerTrackRow');
420                                                 for (var i = 0; i < 5; i++) {
421                                                         trackRow.append($('<td>').html('&nbsp'));
422                                                 }
423                                                 $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow);
424
425                                                 var trackRow2 = $('<tr>').addClass('fillerTrackRow2');
426                                                 trackRow2.append($('<td>').addClass('albumBG').html('&nbsp'));
427                                                 for (var i = 0; i < 5; i++) {
428                                                         trackRow2.append($('<td>').html('&nbsp'));
429                                                 }
430                                                 $('#albumDetails' + event.data.album.albumid + ' .resultSet').append(trackRow2);
431                                         }
432                                         $('#albumDetails' + event.data.album.albumid + ' .albumThumb')
433                                                 .append(this.generateThumb('album', albumThumbnail, albumTitle, albumArtist))
434                                                 .append($('<div>').addClass('footerPadding'));
435                                         $('#spinner').hide();
436                                         myScroll = new iScroll('albumDetails' + event.data.album.albumid);
437                                 }, this), 'json');
438                         } else {
439                                 $('.contentContainer').hide();
440                                 $('#albumDetails' + event.data.album.albumid).show();
441                         }
442                 },
443                 
444                 togglePosterView: function(event){
445                         var view=event.data.mode;
446                         var wthumblist,hthumblist,hthumbdetails;
447                         $("#toggleBanner").removeClass('activeMode');
448                         $("#togglePoster").removeClass('activeMode');
449                         $("#toggleLandscape").removeClass('activeMode');
450                         switch(view) {
451                                 case 'poster':
452                                         setCookie('TVView','poster');
453                                         wthumblist='135px';
454                                         hthumblist='199px';
455                                         hthumbdetails='559px';
456                                         $("#togglePoster").addClass('activeMode');
457                                         break;
458                                 case 'landscape':
459                                         setCookie('TVView','landscape');
460                                         wthumblist='210px';
461                                         hthumblist='118px';
462                                         hthumbdetails='213px';
463                                         $("#toggleLandscape").addClass('activeMode');
464                                         break;
465                                 default: //set banner view as default
466                                         setCookie('TVView','banner');
467                                         wthumblist='379px';
468                                         hthumblist='70px';
469                                         hthumbdetails='70px';
470                                         $("#toggleBanner").addClass('activeMode');
471                                         break;
472                         }
473                         $(".floatableTVShowCover, .floatableTVShowCover div.imgWrapper, .floatableTVShowCover img, .floatableTVShowCover div.imgWrapper div.inner").css('width',wthumblist).css('height',hthumblist);
474                         $(".floatableTVShowCoverSeason div.imgWrapper, .floatableTVShowCoverSeason div.imgWrapper div.inner,.floatableTVShowCoverSeason img, .floatableTVShowCoverSeason").css('height',hthumbdetails);                 
475                 },
476                 
477                 displayTVShowDetails: function(event) {
478                         var tvshowDetailsContainer = $('#tvShowDetails' + event.data.tvshow.tvshowid);
479                         $('#topScrollFade').hide();
480                         toggle=this.toggle.detach();    
481                         if (!tvshowDetailsContainer || tvshowDetailsContainer.length == 0) {
482                                 $('#spinner').show();
483                                 jQuery.post(JSON_RPC + '?GetTVShowSeasons', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetSeasons", "params": { "properties": [ "season", "showtitle", "playcount", "episode", "thumbnail","fanart" ], "tvshowid" : ' + event.data.tvshow.tvshowid + ' }, "id": 1}', jQuery.proxy(function(data) {
484                                         tvshowDetailsContainer = $('<div>');
485                                         tvshowDetailsContainer.attr('id', 'tvShowDetails' + event.data.tvshow.tvshowid)
486                                                                                   .css('display', 'none')
487                                                                                   .addClass('contentContainer')
488                                                                                   .addClass('tvshowContainer');
489                                         var showThumb = this.generateThumb('tvshowseason', event.data.tvshow.thumbnail, event.data.tvshow.title);
490                                         if (data && data.result && data.result.seasons && data.result.seasons.length > 0) {
491                                                 var showDetails = $('<div>').addClass('showDetails');
492                                                 showDetails.append(toggle);
493                                                 showDetails.append($('<p>').html(data.result.seasons[0].showtitle).addClass('showTitle'));
494                                                 var seasonSelectionSelect = $('<select>').addClass('seasonPicker');
495                                                 //var episodeCount = 0;
496                                                 this.tvActiveShowContainer = tvshowDetailsContainer;
497                                                 //var fanart;
498                                                 $.each($(data.result.seasons), jQuery.proxy(function(i, item) {
499 //                                                      if(fanart==null && item.fanart!=null){
500 //                                                              fanart=item.fanart;
501 //                                                      }
502 //                                                      //episodeCount += item.episode;
503                                                         var season = $('<option>').attr('value',i);
504                                                         season.text(item.label);
505                                                         seasonSelectionSelect.append(season);
506                                                         
507                                                 }, this));
508 //                                              if(fanart!=null)
509 //                                              {
510 //                                                      $('.contentContainer').css('background','url("'+this.getThumbnailPath(fanart)+'")').css('background-size','cover');     
511 //                                              }
512                                                 seasonSelectionSelect.bind('change', {tvshow: event.data.tvshow.tvshowid, seasons: data.result.seasons, element: seasonSelectionSelect}, jQuery.proxy(this.displaySeasonListings, this));
513                                                 //showDetails.append($('<p>').html('<span class="heading">Episodes:</span> ' + episodeCount));
514                                                 showDetails.append(seasonSelectionSelect);
515                                                 tvshowDetailsContainer.append(showDetails);
516                                                 tvshowDetailsContainer.append(showThumb);
517                                                 seasonSelectionSelect.trigger('change');
518                                                 $('#content').append(tvshowDetailsContainer);
519                                                 if(getCookie('TVView')!=null && getCookie('TVView')!='banner'){
520                                                 var view=getCookie('TVView');
521                                                 switch(view) {
522                                                         case 'poster':
523                                                                 togglePoster.trigger('click');
524                                                                 break;
525                                                         case 'landscape':
526                                                                 toggleLandscape.trigger('click')
527                                                                 break;                                          
528                                                 }
529                                         }
530                                                 tvshowDetailsContainer.fadeIn();
531                                         }
532                                         $('#spinner').hide();
533                                 }, this), 'json');
534                         } else {
535                                 $('.contentContainer').hide();
536                                 $('#tvShowDetails' + event.data.tvshow.tvshowid).show();
537                                 $('#tvShowDetails' + event.data.tvshow.tvshowid +' select').trigger('change');
538                         }
539                 },
540                 displaySeasonListings: function(event) {
541                         //retrieve selected season
542                         var selectedVal=event.data.element.val();
543                         var seasons=event.data.seasons;
544                         $('#topScrollFade').hide();
545                         //Hide old listings
546                         var oldListings = $('.episodeListingsContainer', this.tvActiveShowContainer).fadeOut();
547                         //Update ActiveSeason
548                         this.tvActiveSeason = selectedVal;                      
549                         //Populate new listings
550                         jQuery.post(JSON_RPC + '?GetTVSeasonEpisodes', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "properties": [ "title", "thumbnail","episode","plot","season"], "season" : ' + seasons[selectedVal].season + ', "tvshowid" : ' + event.data.tvshow + ' }, "id": 1}', jQuery.proxy(function(data) {
551                                 var episodeListingsContainer = $('<div>').addClass('episodeListingsContainer');
552                                 var episodeTable= $('<table>').addClass('seasonView').html('<thead><tr class="headerRow"><th class="thumbHeader">N&deg;</th><th>Title</th><th class="thumbHeader">Thumb</th><th class="thumbHeader">Details</th></tr></thead><tbody class="resultSet"></tbody>');       
553                                 $.each($(data.result.episodes), jQuery.proxy(function(i, item) {
554                                         var episodeRow = $('<tr>').addClass('episodeRow').addClass('tr' + i % 2);
555                                         var episodePictureImg = $('<img>').bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this)).css('cursor','pointer');
556                                         episodePictureImg.attr('src', this.getThumbnailPath(item.thumbnail));
557                                         var episodePicture=$('<td>').addClass('episodeThumb').append(episodePictureImg).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
558                                         var episodeNumber = $('<td>').addClass('episodeNumber').html(item.episode).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
559                                         var episodeTitle = $('<td>').html(item.title).bind('click', { episode: item }, jQuery.proxy(this.playTVShow, this));
560                                         var episodeDetails = $('<td class="info">').html('').bind('click',{episode:item}, jQuery.proxy(this.displayEpisodeDetails, this)).css('cursor','pointer');
561                                         episodeRow.append(episodeNumber).append(episodeTitle).append(episodePicture).append(episodeDetails);
562                                         episodeTable.append(episodeRow);
563                                 }, this));
564                                 episodeListingsContainer.append(episodeTable);
565                                 $(this.tvActiveShowContainer).append(episodeListingsContainer);
566                         }, this), 'json');
567                         
568                 },
569                 
570                 displayEpisodeDetails: function(event) {
571                         var episodeDetails = $('<div>').attr('id', 'episode-' + event.data.episode.episodeid).addClass('episodePopoverContainer');
572                         episodeDetails.append($('<img>').attr('src', '/images/close-button.png').addClass('closeButton').bind('click', jQuery.proxy(this.hideOverlay, this)));
573                         episodeDetails.append($('<img>').attr('src', this.getThumbnailPath(event.data.episode.thumbnail)).addClass('episodeCover'));
574                         episodeDetails.append($('<div>').addClass('playIcon').bind('click', {episode: event.data.episode}, jQuery.proxy(this.playTVShow, this)));
575                         var episodeTitle = $('<p>').addClass('episodeTitle');
576                         var yearText = event.data.episode.year ? ' <span class="year">(' + event.data.episode.year + ')</span>' : '';
577                         episodeTitle.html(event.data.episode.title + yearText);
578                         episodeDetails.append(episodeTitle);
579                         if (event.data.episode.runtime) {
580                                 episodeDetails.append($('<p>').addClass('runtime').html('<strong>Runtime:</strong> ' + event.data.epispde.runtime + ' minutes'));
581                         }
582                         if (event.data.episode.season) {
583                                 episodeDetails.append($('<p>').addClass('season').html('<strong>Season:</strong> ' + event.data.episode.season));
584                         }
585                         if (event.data.episode.episode) {
586                                 episodeDetails.append($('<p>').addClass('episode').html('<strong>Episode:</strong> ' + event.data.episode.episode));
587                         }
588                         if (event.data.episode.plot) {
589                                 episodeDetails.append($('<p>').addClass('plot').html('<strong>Plot:</strong> <br/><br/>' +event.data.episode.plot));
590                         }
591                         if (event.data.episode.genre) {
592                                 episodeDetails.append($('<p>').addClass('genre').html('<strong>Genre:</strong> ' + event.data.episode.genre));
593                         }
594                         if (event.data.episode.rating) {
595                                 //Todo
596                         }
597                         if (event.data.episode.director) {
598                                 episodeDetails.append($('<p>').addClass('director').html('<strong>Directed By:</strong> ' + event.data.episode.director));
599                         }
600                         this.activeCover = episodeDetails;
601                         $('body').append(episodeDetails);
602                         $('#overlay').show();
603                         this.updatePlayButtonLocation();
604                 },
605                 
606                 playTVShow: function(event) {
607       jQuery.post(JSON_RPC + '?AddTvShowToPlaylist', '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "episodeid": ' + event.data.episode.episodeid + ' } }, "id": 1}', jQuery.proxy(function(data) {
608         this.hideOverlay();
609       }, this), 'json');
610                 },
611                 hideOverlay: function(event) {
612                         if (this.activeCover) {
613                                 $(this.activeCover).remove();
614                                 this.activeCover = null;
615                         }
616                         $('#overlay').hide();
617                 },
618                 updatePlayButtonLocation: function(event) {
619                         var movieContainer = $('.movieCover');
620                         if (movieContainer.length > 0) {
621                                 var playIcon = $('.playIcon');
622                                 if (playIcon.length > 0) {
623                                         var heightpi=$(movieContainer[0]).height();
624                                         playIcon.width(Math.floor(0.65*heightpi));
625                                         playIcon.height(heightpi);
626                                 }
627                         }
628                         var episodeContainer = $('.episodeCover');
629                         if (episodeContainer.length > 0) {
630                                 var playIcon = $('.playIcon');
631                                 if (playIcon.length > 0) {
632                                         var widthpi=$(episodeContainer[0]).width();
633                                         playIcon.width(widthpi);
634                                         //assume 16/9 thumb
635                                         playIcon.height(Math.floor(widthpi*9/16));
636                                 }
637                         }
638                 },
639                 playMovie: function(event) {
640                         jQuery.post(JSON_RPC + '?PlayMovie', '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "movieid": ' + event.data.movie.movieid + ' } }, "id": 1}', jQuery.proxy(function(data) {
641                                 this.hideOverlay();
642                         }, this), 'json');
643                 },
644                 displayMovieDetails: function(event) {
645                         var movieDetails = $('<div>').attr('id', 'movie-' + event.data.movie.movieid).addClass('moviePopoverContainer');
646                         movieDetails.append($('<img>').attr('src', '/images/close-button.png').addClass('closeButton').bind('click', jQuery.proxy(this.hideOverlay, this)));
647                         movieDetails.append($('<img>').attr('src', this.getThumbnailPath(event.data.movie.thumbnail)).addClass('movieCover'));
648                         movieDetails.append($('<div>').addClass('playIcon').bind('click', {movie: event.data.movie}, jQuery.proxy(this.playMovie, this)));
649                         var movieTitle = $('<p>').addClass('movieTitle');
650                         var yearText = event.data.movie.year ? ' <span class="year">(' + event.data.movie.year + ')</span>' : '';
651                         movieTitle.html(event.data.movie.title + yearText);
652                         movieDetails.append(movieTitle);
653                         if (event.data.movie.runtime) {
654                                 movieDetails.append($('<p>').addClass('runtime').html('<strong>Runtime:</strong> ' + event.data.movie.runtime + ' minutes'));
655                         }
656                         if (event.data.movie.plot) {
657                                 movieDetails.append($('<p>').addClass('plot').html(event.data.movie.plot));
658                         }
659                         if (event.data.movie.genre) {
660                                 movieDetails.append($('<p>').addClass('genre').html('<strong>Genre:</strong> ' + event.data.movie.genre));
661                         }
662                         if (event.data.movie.rating) {
663                                 //Todo
664                         }
665                         if (event.data.movie.director) {
666                                 movieDetails.append($('<p>').addClass('director').html('<strong>Directed By:</strong> ' + event.data.movie.director));
667                         }
668                         this.activeCover = movieDetails;
669                         $('body').append(movieDetails);
670                         $('#overlay').show();
671                         this.updatePlayButtonLocation();
672                 },
673                 playTrack: function(event) {
674                         jQuery.post(JSON_RPC + '?ClearPlaylist', '{"jsonrpc": "2.0", "method": "Playlist.Clear", "params": { "playlistid": ' + this.playlists["audio"] + ' }, "id": 1}', jQuery.proxy(function(data) {
675                                 //check that clear worked.
676                                 jQuery.post(JSON_RPC + '?AddAlbumToPlaylist', '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "playlistid": ' + this.playlists["audio"] + ', "item": { "albumid": ' + event.data.album.albumid + ' } }, "id": 1}', jQuery.proxy(function(data) {
677                                         //play specific song in playlist
678                                         jQuery.post(JSON_RPC + '?PlaylistItemPlay', '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "playlistid": ' + this.playlists["audio"] + ', "position": '+ event.data.itmnbr + ' } }, "id": 1}', function() {}, 'json');
679                                 }, this), 'json');
680                         }, this), 'json');
681                 },
682                 movieLibraryOpen: function() {
683                         this.resetPage();
684                         $('#movieLibrary').addClass('selected');
685                         $('.contentContainer').hide();
686                         var libraryContainer = $('#movieLibraryContainer');
687                         if (!libraryContainer || libraryContainer.length == 0) {
688                                 $('#spinner').show();
689                                 jQuery.post(JSON_RPC + '?GetMovies', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "limits": { "start": 0 }, "properties": [ "genre", "director", "trailer", "tagline", "plot", "plotoutline", "title", "originaltitle", "lastplayed", "runtime", "year", "playcount", "rating", "thumbnail", "file" ], "sort": { "method": "sorttitle", "ignorearticle": true } }, "id": 1}', jQuery.proxy(function(data) {
690                                         if (data && data.result && data.result.movies) {
691                                                         libraryContainer = $('<div>');
692                                                         libraryContainer.attr('id', 'movieLibraryContainer')
693                                                                                         .addClass('contentContainer');
694                                                         $('#content').append(libraryContainer);
695                                         } else {
696                                                 libraryContainer.html('');
697                                         }
698                                         //data.result.movies.sort(jQuery.proxy(this.movieTitleSorter, this));
699                                         $.each($(data.result.movies), jQuery.proxy(function(i, item) {
700                                                 var floatableMovieCover = this.generateThumb('movie', item.thumbnail, item.title);
701                                                 floatableMovieCover.bind('click', { movie: item }, jQuery.proxy(this.displayMovieDetails, this));
702                                                 libraryContainer.append(floatableMovieCover);
703                                         }, this));
704                                         libraryContainer.append($('<div>').addClass('footerPadding'));
705                                         $('#spinner').hide();
706                                         libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
707                                         libraryContainer.trigger('scroll');
708                                         //$('#libraryContainer img').lazyload();
709                                         myScroll = new iScroll('movieLibraryContainer');
710                                 }, this), 'json');
711                         } else {
712                                 libraryContainer.show();
713                                 libraryContainer.trigger('scroll');
714                         }
715                 },
716                 tvshowLibraryOpen: function() {
717                         this.resetPage();
718                         $('#tvshowLibrary').addClass('selected');
719                         $('.contentContainer').hide();
720                         var libraryContainer = $('#tvshowLibraryContainer');
721                         if (!libraryContainer || libraryContainer.length == 0) {
722                                 $('#spinner').show();
723                                 toggle=$('<p>').addClass('toggle');
724                                 togglePoster= $('<span>Poster</span>');
725                                 togglePoster.attr('id', 'togglePoster')
726                                                         .css('cursor','pointer')
727                                                         .bind('click',{mode: 'poster'},jQuery.proxy(this.togglePosterView,this));
728                                 toggleBanner= $('<span>Banner</span>');
729                                 toggleBanner.attr('id', 'toggleBanner')
730                                                         .css('cursor','pointer')
731                                                         .addClass('activeMode')
732                                                         .bind('click',{mode: 'banner'},jQuery.proxy(this.togglePosterView,this));
733                                 toggleLandscape= $('<span>Landscape</span>');
734                                 toggleLandscape.attr('id', 'toggleLandscape')
735                                                         .css('cursor','pointer')
736                                                         .bind('click',{mode: 'landscape'},jQuery.proxy(this.togglePosterView,this));
737                                 toggle.append(toggleBanner).append(' | ').append(togglePoster).append(' | ').append(toggleLandscape);
738                                 this.toggle=toggle;                             
739                                 jQuery.post(JSON_RPC + '?GetTVShows', '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": ["genre", "plot", "title", "lastplayed", "episode", "year", "playcount", "rating", "thumbnail", "studio", "mpaa", "premiered"] }, "id": 1}', jQuery.proxy(function(data) {
740                                         if (data && data.result && data.result.tvshows) {
741                                                         libraryContainer = $('<div>');                                                                  
742                                                         libraryContainer.append(toggle);
743                                                         libraryContainer.attr('id', 'tvshowLibraryContainer')
744                                                                                         .addClass('contentContainer');
745                                                         $('#content').append(libraryContainer);
746                                         } else {
747                                                 libraryContainer.html('');
748                                         }
749                                         $.each($(data.result.tvshows), jQuery.proxy(function(i, item) {
750                                                 var floatableTVShowCover = this.generateThumb('tvshow', item.thumbnail, item.title);
751                                                 floatableTVShowCover.bind('click', { tvshow: item }, jQuery.proxy(this.displayTVShowDetails, this));
752                                                 libraryContainer.append(floatableTVShowCover);
753                                         }, this));
754                                         libraryContainer.append($('<div>').addClass('footerPadding'));
755                                         $('#spinner').hide();
756                                         libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
757                                         libraryContainer.trigger('scroll');
758                                         myScroll = new iScroll('tvshowLibraryContainer');
759                                         if(getCookie('TVView')!=null && getCookie('TVView')!='banner'){
760                                                 var view=getCookie('TVView');
761                                                 switch(view) {
762                                                         case 'poster':
763                                                                 togglePoster.trigger('click');
764                                                                 break;
765                                                         case 'landscape':
766                                                                 toggleLandscape.trigger('click')
767                                                                 break;                                          
768                                                 }
769                                         }
770                                 }, this), 'json');                                      
771                         } else {
772                                 libraryContainer.prepend($(".toggle").detach()).show();
773                                 libraryContainer.trigger('scroll');
774                         }
775                         
776                 },
777                 updateScrollEffects: function(event) {
778                         if (event.data.activeLibrary && $(event.data.activeLibrary).scrollTop() > 0) {
779                                 $('#topScrollFade').fadeIn();
780                         } else {
781                                 $('#topScrollFade').fadeOut();
782                         }
783                 },
784                 startSlideshow: function(event) {
785                         jQuery.post(JSON_RPC + '?StartSlideshow', '{"jsonrpc": "2.0", "method": "Player.Open", "params": { "item": { "recursive" : "true", "random":"true", "path" : "' + this.replaceAll(event.data.directory.file, "\\", "\\\\") + '" } }, "id": 1}', null, 'json');
786                 },
787                 showDirectory: function(event) {
788                         var directory = event.data.directory.file;
789                         var jsonDirectory = this.replaceAll(directory, "\\", "\\\\");                   
790                         this.resetPage();
791                         $('#pictureLibrary').addClass('selected');
792                         $('.contentContainer').hide();
793                         var libraryContainer = $('#pictureLibraryDirContainer' + directory);
794                         if (!libraryContainer || libraryContainer.length == 0) {
795                                 $('#spinner').show();                           
796                                 jQuery.post(JSON_RPC + '?GetDirectory', '{"jsonrpc": "2.0", "method": "Files.GetDirectory", "params": { "media" : "pictures", "directory": "' + jsonDirectory + '" }, "id": 1}', jQuery.proxy(function(data) {
797                                         if (data && data.result && ( data.result.directories || data.result.files )) {
798                                                 libraryContainer = $('<div>');
799                                                 libraryContainer.attr('id', 'pictureLibraryDirContainer' + directory)
800                                                                                 .addClass('contentContainer');
801                                                 $('#content').append(libraryContainer);
802                                                 var breadcrumb = $('<div>');
803                                                 var seperator = '/';
804                                                 var item = '';
805                                                 var directoryArray = directory.split(seperator);
806                                                 jQuery.each(directoryArray, function(i,v) {
807                                                         if(v != '') {
808                                                                 item += v + seperator;
809                                                                 //tmp.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));               
810                                                                 breadcrumb.append($('<div>').text(' > ' + v).css('float','left').addClass('breadcrumb'));                                                 
811                                                         }
812                                                 });
813                                                 libraryContainer.append(breadcrumb);
814                                                 libraryContainer.append($('<div>').css('clear','both'));
815                                                 if (data.result.files) {
816                                                         $.each($(data.result.files), jQuery.proxy(function(i, item) {
817                                                                 if (item.filetype == "file")
818                                                                 {
819                                                                         var floatableImage = this.generateThumb('image', item.file, item.label);
820                                                                         libraryContainer.append(floatableImage);
821                                                                 }
822                                                                 else if (item.filetype == "directory")
823                                                                 {
824                                                                         var floatableShare = this.generateThumb('directory', item.thumbnail, item.label);
825                                                                         floatableShare.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));              
826                                                                         //var slideshow = $('<div">');
827                                                                         //slideshow.html('<div>Slideshow</div>');
828                                                                         //slideshow.bind('click', { directory: item }, jQuery.proxy(this.startSlideshow, this));        
829                                                                         //floatableShare.append(slideshow);
830                                                                         libraryContainer.append(floatableShare);
831                                                                 }
832                                                         }, this));
833                                                 }
834                                                 libraryContainer.append($('<div>').addClass('footerPadding'));
835                                         } else {
836                                                 libraryContainer.html('');
837                                         }
838                                         $('#spinner').hide();
839                                         libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
840                                         libraryContainer.trigger('scroll');
841                                         myScroll = new iScroll('#pictureLibraryDirContainer' + directory);
842                                 }, this), 'json');
843                         } else {
844                                 libraryContainer.show();
845                                 libraryContainer.trigger('scroll');
846                         }
847                 },
848                 pictureLibraryOpen: function() {
849                         this.resetPage();
850                         $('#pictureLibrary').addClass('selected');
851                         $('.contentContainer').hide();
852                         var libraryContainer = $('#pictureLibraryContainer');
853                         if (!libraryContainer || libraryContainer.length == 0) {
854                                 $('#spinner').show();
855                                 jQuery.post(JSON_RPC + '?GetSources', '{"jsonrpc": "2.0", "method": "Files.GetSources", "params": { "media" : "pictures" }, "id": 1}',                                  jQuery.proxy(function(data) {
856                                         if (data && data.result && data.result.shares) {
857                                                 libraryContainer = $('<div>');
858                                                 libraryContainer.attr('id', 'pictureLibraryContainer')
859                                                                                 .addClass('contentContainer');
860                                                 $('#content').append(libraryContainer);
861                                         } else {
862                                                 libraryContainer.html('');
863                                         }
864                                         $.each($(data.result.shares), jQuery.proxy(function(i, item) {
865                                                 var floatableShare = this.generateThumb('directory', item.thumbnail, item.label);
866                                                 floatableShare.bind('click', { directory: item }, jQuery.proxy(this.showDirectory, this));                                      
867                                                 libraryContainer.append(floatableShare);
868                                         }, this));
869                                         libraryContainer.append($('<div>').addClass('footerPadding'));
870                                         $('#spinner').hide();
871                                         libraryContainer.bind('scroll', { activeLibrary: libraryContainer }, jQuery.proxy(this.updateScrollEffects, this));
872                                         libraryContainer.trigger('scroll');
873                                         myScroll = new iScroll('#pictureLibraryContainer');
874                                 }, this), 'json');
875                         } else {
876                                 libraryContainer.show();
877                                 libraryContainer.trigger('scroll');
878                         }
879                 }
880         }