Changes:
[enigma2-plugins.git] / webinterface / src / web-data / tools.js
1 //$Header$
2 var templates = {};
3 var loadedChannellist = {};
4
5 var epgListData = {};
6 var signalPanelData = {};
7
8 var mediaPlayerStarted = false; 
9 var popUpBlockerHinted = false;
10
11 var settings = null;
12 var parentControlList = null;
13
14 var requestcounter = 0;
15
16 var debugWin = '';
17 var signalWin = '';
18 var webRemoteWin = '';
19 var EPGListWin = '';
20
21 var currentBouquet = bouquetsTv;
22
23 var updateBouquetItemsPoller = '';
24 var updateCurrentPoller = '';
25 var signalPanelUpdatePoller = '';
26
27 var hideNotifierTimeout = '';
28
29 var isActive = {};
30 isActive.getCurrent = false;
31
32 var currentLocation = "/hdd/movie";
33 var locationsList = [];
34 var tagsList = [];
35
36 var boxtype = "";
37
38 function startUpdateCurrentPoller(){
39         updateCurrentPoller = setInterval(updateItems, 10000);
40 }
41
42 function stopUpdateCurrentPoller(){
43         clearInterval(updateCurrentPoller);
44 }
45
46 function getXML(request){
47         var xmlDoc = "";
48
49         if(window.ActiveXObject){ // we're on IE
50                 xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
51                 xmlDoc.async="false";
52                 xmlDoc.loadXML(request.responseText);
53         } else { //we're not on IE
54                 if (!window.google || !google.gears){
55                         xmlDoc = request.responseXML;
56                 } else { //no responseXML on gears
57                         xmlDoc = (new DOMParser()).parseFromString(request.responseText, "text/xml");
58                 }
59         }
60
61         return xmlDoc;
62 }
63 /*
64 * Set boxtype Variable for being able of determining model specific stuff correctly (like WebRemote)
65 */
66 function incomingDeviceInfoBoxtype(request){
67         debug("[incomingAboutBoxtype] returned");
68         boxtype = getXML(request).getElementsByTagName("e2devicename").item(0).firstChild.data;
69
70         debug("[incomingAboutBoxtype] Boxtype: " + boxtype);
71 }
72
73
74 function getBoxtype(){
75         doRequest(URL.deviceinfo, incomingDeviceInfoBoxtype, false);
76 }
77
78 function toggleStandby(){
79         sendPowerState(0);
80 }
81
82 function incomingPowerState(request){
83         var standby = getXML(request).getElementsByTagName("e2instandby").item(0).firstChild.data;
84         
85         var signal = $('openSignalPanel');
86         var signalImg = $('openSignalPanelImg');
87         
88         if(standby.strip() == "false"){
89                 signal.stopObserving('click', openSignalPanel);
90                 signal.observe('click', openSignalPanel);
91                 
92                 signalImg.src = "/web-data/img/signal.png";
93                 signalImg.title = "Show Signal Panel";
94                 
95         } else {
96                 signal.stopObserving('click', openSignalPanel);         
97                 
98                 signalImg.src = "/web-data/img/signal_off.png";
99                 signalImg.title = "Please disable standby first";
100         }
101 }
102
103 function getPowerState(){
104         doRequest(URL.powerstate, incomingPowerState);  
105 }
106
107 function set(element, value){
108         element = parent.$(element);
109         if (element){
110                 element.innerHTML = value;
111         }
112 }
113
114 function hideNotifier(){
115         $('notification').fade({duration : 0.5 });
116 }
117
118 function notify(text, state){
119         notif = $('notification');
120
121         if(notif !== null){
122                 //clear possibly existing hideNotifier timeout of a previous notfication
123                 clearTimeout(hideNotifierTimeout);
124                 if(state === false){
125                         notif.style.background = "#C00";
126                 } else {
127                         notif.style.background = "#85C247";
128                 }                               
129
130                 set('notification', "<div>"+text+"</div>");
131                 notif.appear({duration : 0.5, to: 0.9 });
132                 hideNotifierTimeout = setTimeout(hideNotifier, 7500);
133         }
134 }
135
136
137 function simpleResultHandler(simpleResult){
138         notify(simpleResult.statetext, simpleResult.state);
139 }
140
141
142 function startUpdateBouquetItemsPoller(){
143         debug("[startUpdateBouquetItemsPoller] called");
144         updateBouquetItemsPoller = setInterval(updateItemsLazy, 60000);
145 }
146
147
148 function stopUpdateBouquetItemsPoller(){
149         debug("[stopUpdateBouquetItemsPoller] called");
150         clearInterval(updateBouquetItemsPoller);
151 }
152
153
154 //General Helpers
155 function parseNr(num) {
156         if(isNaN(num)){
157                 return 0;
158         } else {
159                 return Number(num);
160         }
161 }
162
163
164 function dec2hex(nr, len){
165
166         var hex = parseInt(nr, 10).toString(16).toUpperCase();
167         if(len > 0){
168                 try{
169                         while(hex.length < len){
170                                 hex = "0"+hex;
171                         }
172                 } 
173                 catch(e){
174                         //something went wrong, return -1
175                         hex = -1;
176                 }
177         } 
178         return hex;
179 }
180
181
182 function quotes2html(txt) {
183         if(typeof(txt) != "undefined"){
184                 return txt.escapeHTML().replace('\n', '<br>');
185         } else {
186                 return "";
187         }
188 }
189
190 function addLeadingZero(nr){
191         if(nr < 10){
192                 return '0' + nr;
193         }
194         return nr;
195 }
196
197 function dateToString(date){
198
199         var dateString = "";
200
201         dateString += date.getFullYear();
202         dateString += "-" + addLeadingZero(date.getMonth()+1);
203         dateString += "-" + addLeadingZero(date.getDate());
204         dateString += " " + addLeadingZero(date.getHours());
205         dateString += ":" + addLeadingZero(date.getMinutes());
206
207         return dateString;
208 }
209
210
211 function showhide(id){
212         var s = $(id).style;
213         s.display = (s.display!="none")? "none":"";
214 }
215
216
217 function show(id){
218         try{
219                 $(id).style.display = "";
220         } catch(e) {
221                 debug("[show] Could not show element with id: " + id);
222         }
223 }
224
225
226 function hide(id){
227         try{
228                 $(id).style.display = "none";
229         } catch(e) {
230                 debug("[hide] Could not hide element with id: " + id);
231         }
232 }
233
234
235 /*
236 * Sets the Loading Notification to the given HTML Element
237 * @param targetElement - The element the Ajax-Loader should be set in
238 */
239 function setAjaxLoad(targetElement){
240         $(targetElement).innerHTML = getAjaxLoad();
241 }
242
243
244 //Ajax Request Helpers
245 //requestindikator
246
247 function requestIndicatorUpdate(){
248         /*debug(requestcounter+" open requests");
249         if(requestcounter>=1){
250                 $('RequestIndicator').style.display = "inline";
251         }else{
252                 $('RequestIndicator').style.display = "none";
253         }*/
254 }
255
256 function requestStarted(){
257         requestcounter +=1;
258         requestIndicatorUpdate();
259 }
260
261 function requestFinished(){
262         requestcounter -= 1;
263         requestIndicatorUpdate();
264 }
265
266 //Popup And Messagebox Helpers
267 function messageBox(m){
268         alert(m);
269 }
270
271
272 function popUpBlockerHint(){
273         if(!popUpBlockerHinted){
274                 popUpBlockerHinted = true;
275                 messageBox("Please disable your Popup-Blocker for enigma2 WebControl to work flawlessly!");
276
277         }
278 }
279
280 function setWindowContent(window, html){
281         window.document.write(html);
282         window.document.close();
283 }
284
285 function openPopup(title, html, width, height, x, y){
286         try {
287                 var popup = window.open('about:blank',title,'scrollbars=yes, width='+width+',height='+height);          
288                 setWindowContent(popup, html);
289                 return popup;
290         } catch(e){
291                 popUpBlockerHint();
292                 return "";
293         }
294 }
295
296 function openPopupPage(title, uri, width, height, x, y){
297         try {
298                 var popup = window.open(uri,title,'scrollbars=yes, width='+width+',height='+height);
299                 return popup;
300         } catch(e){
301                 popUpBlockerHint();
302                 return "";
303         }
304 }
305
306 function debug(text){
307         var DBG = userprefs.data.debug || false;
308         
309         if(DBG){
310                 try{
311                         if(!debugWin.closed && debugWin.location){
312                                 var inner = debugWin.document.getElementById('debugContent').innerHTML;
313                                 debugWin.document.getElementById('debugContent').innerHTML = new Date().toLocaleString() + ": "+text+"<br>" + inner;
314                         } else {                        
315                                 openDebug();
316                                 
317                                 setTimeout(     function(){
318                                                                         var inner = debugWin.document.getElementById('debugContent').innerHTML;
319                                                                         debugWin.document.getElementById('debugContent').innerHTML = new Date().toLocaleString() + ": "+text+"<br>" + inner;
320                                                                 }, 
321                                                                 1000
322                                                         );
323                         }
324                 } catch (Exception) {}
325         }
326 }
327
328 function saveSettings(){
329         userprefs.load();
330         
331         var debug = $('enableDebug').checked;
332         if(typeof(debug) != undefined){
333                 if( userprefs.data.debug != debug ){
334                         userprefs.data.debug = debug;
335                         userprefs.save();
336                         
337                         if(debug){
338                                 openDebug();
339                         }
340                 }
341                 
342                 
343         }
344         
345 }
346
347 //Template Helpers
348 function saveTpl(request, tplName){
349         debug("[saveTpl] saving template: " + tplName);
350         templates[tplName] = request.responseText;
351 }
352
353
354 function renderTpl(tpl, data, domElement) {     
355         var result = tpl.process(data);
356
357         try{
358                 $(domElement).innerHTML = result;
359         }catch(ex){
360                 //              debug("[renderTpl] exception: " + ex);
361         }
362 }
363
364
365 function fetchTpl(tplName, callback){
366         if(typeof(templates[tplName]) == "undefined") {
367                 var url = URL.tpl+tplName+".htm";
368
369                 doRequest(
370                                 url, 
371                                 function(transport){
372                                         saveTpl(transport, tplName);
373                                         if(typeof(callback) == 'function'){
374                                                 callback();
375                                         }
376                                 }
377                 );
378         } else {
379                 if(typeof(callback) == 'function'){
380                         callback();
381                 }
382         }
383 }
384
385 function incomingProcessTpl(request, data, domElement, callback){
386         if(request.readyState == 4){
387                 renderTpl(request.responseText, data, domElement);
388                 if(typeof(callback) == 'function') {
389                         callback();
390                 }
391         }
392 }
393
394 function processTpl(tplName, data, domElement, callback){
395         var url = URL.tpl+tplName+".htm";
396
397         doRequest(url, 
398                         function(transport){
399                 incomingProcessTpl(transport, data, domElement, callback);
400         }
401         );
402 }
403
404 //Debugging Window
405
406
407 function openDebug(){
408         var uri = URL.tpl+'tplDebug.htm';
409         debugWin = openPopupPage("Debug", uri, 500, 300);
410 }
411
412 function doRequest(url, readyFunction){
413         requestStarted();
414         var request = '';
415         // gears or not that's the question here
416         if (!window.google || !google.gears){ //no gears, how sad
417 //              debug("NO GEARS!!");            
418                 try{
419                         request = new Ajax.Request(url,
420                                         {
421                                 asynchronous: true,
422                                 method: 'GET',
423                                 requestHeaders: ['Pragma', 'no-cache', 'Cache-Control', 'no-cache', 'Cache-Control', 'no-store', 'Expires', '0'],
424                                 onException: function(o,e){ throw(e); },                                
425                                 onSuccess: function (transport, json) {                                         
426                                         if(typeof(readyFunction) != "undefined"){
427                                                 readyFunction(transport);
428                                         }
429                                 },
430                                 onComplete: requestFinished 
431                                         });
432                 } catch(e) {}
433         } else { //we're on gears!
434                 try{
435                         request = google.gears.factory.create('beta.httprequest');
436                         request.open('GET', url);
437
438                         if( typeof(readyFunction) != "undefined" ){
439                                 request.onreadystatechange = function(){                                
440                                         if(request.readyState == 4){
441                                                 if(request.status == 200){                      
442                                                         readyFunction(request);
443                                                 } else {
444                                                         //we COULD do some error handling here
445                                                 }
446                                         }
447                                 };
448                         }
449                         request.send();
450                 } catch(e) {}
451         }
452 }
453
454 //Parental Control
455 function incomingParentControl(request) {
456         if(request.readyState == 4){
457                 parentControlList = new ServiceList(getXML(request)).getArray();
458                 debug("[incomingParentControl] Got "+parentControlList.length + " services");
459         }
460 }
461
462 function getParentControl() {
463         doRequest(URL.parentcontrol, incomingParentControl, false);
464 }
465
466
467 function getParentControlByRef(txt) {
468         debug("[getParentControlByRef] ("+txt+")");
469         for(var i = 0; i < parentControlList.length; i++) {
470                 debug( "[getParentControlByRef] "+parentControlList[i].getClearServiceReference() );
471                 if(String(parentControlList[i].getClearServiceReference()) == String(txt)) {
472                         return parentControlList[i].getClearServiceReference();
473                 } 
474         }
475         return "";
476 }
477
478
479 //Settings
480 function getSettingByName(txt) {
481         debug("[getSettingByName] (" + txt + ")");
482         for(var i = 0; i < settings.length; i++) {
483                 debug("("+settings[i].getSettingName()+") (" +settings[i].getSettingValue()+")");
484                 if(String(settings[i].getSettingName()) == String(txt)) {
485                         return settings[i].getSettingValue().toLowerCase();
486                 } 
487         }
488         return "";
489 }
490
491 function parentPin(servicereference) {
492         debug("[parentPin] parentControlList");
493         servicereference = decodeURIComponent(servicereference);
494         if(parentControlList === null || String(getSettingByName("config.ParentalControl.configured")) != "true") {
495                 return true;
496         }
497         //debug("parentPin " + parentControlList.length);
498         if(getParentControlByRef(servicereference) == servicereference) {
499                 if(String(getSettingByName("config.ParentalControl.type.value")) == "whitelist") {
500                         debug("[parentPin] Channel in whitelist");
501                         return true;
502                 }
503         } else {
504                 debug("[parentPin] sRef differs ");
505                 return true;
506         }
507         debug("[parentPin] Asking for PIN");
508
509         var userInput = prompt('Parental Control is enabled!<br> Please enter the Parental Control PIN','PIN');
510         if (userInput !== '' && userInput !== null) {
511                 if(String(userInput) == String(getSettingByName("config.ParentalControl.servicepin.0")) ) {
512                         return true;
513                 } else {
514                         return parentPin(servicereference);
515                 }
516         } else {
517                 return false;
518         }
519 }
520
521
522 function incomingGetDreamboxSettings(request){
523         if(request.readyState == 4){
524                 settings = new Settings(getXML(request)).getArray();
525
526                 debug("[incomingGetDreamboxSettings] config.ParentalControl.configured="+ getSettingByName("config.ParentalControl.configured"));
527
528                 if(String(getSettingByName("config.ParentalControl.configured")) == "true") {
529                         getParentControl();
530                 }
531         }
532 }
533
534
535 function getDreamboxSettings(){
536         doRequest(URL.settings, incomingGetDreamboxSettings, false);
537 }
538
539
540 //Subservices
541 function incomingSubServiceRequest(request){
542         if(request.readyState == 4){
543                 var services = new ServiceList(getXML(request)).getArray();
544                 debug("[incomingSubServiceRequest] Got " + services.length + " SubServices");
545
546                 if(services.length > 1) {
547
548                         var first = services[0];
549
550                         // we already have the main service in our servicelist so we'll
551                         // start with the second element                        
552                         services.shift();
553                         
554                         var data = { subservices : services };
555                         
556
557                         var id = 'SUB'+first.servicereference;
558                         show('tr' + id);
559                         processTpl('tplSubServices', data, id);
560                 }
561         }
562 }
563
564
565 function getSubServices(bouquet) {
566         doRequest(URL.subservices, incomingSubServiceRequest, false);
567 }
568
569
570 function delayedGetSubservices(){
571         setTimeout(getSubServices, 5000);
572 }
573
574 //zap zap
575 function zap(servicereference){
576         doRequest("/web/zap?sRef=" + servicereference); 
577         setTimeout(updateItemsLazy, 7000); //reload epg and subservices
578         setTimeout(updateItems, 3000);
579 }
580
581 //SignalPanel
582
583 function updateSignalPanel(){   
584         var html = templates.tplSignalPanel.process(signalPanelData);
585
586         if (!signalWin.closed && signalWin.location) {
587                 setWindowContent(signalWin, html);
588         } else {
589                 clearInterval(signalPanelUpdatePoller);
590                 signalPanelUpdatePoller = '';
591         }
592 }
593
594 function incomingSignalPanel(request){
595         var namespace = {};
596
597         if (request.readyState == 4){
598                 var xml = getXML(request).getElementsByTagName("e2frontendstatus").item(0);
599                 namespace = {
600                                 snrdb : xml.getElementsByTagName('e2snrdb').item(0).firstChild.data,
601                                 snr : xml.getElementsByTagName('e2snr').item(0).firstChild.data,
602                                 ber : xml.getElementsByTagName('e2ber').item(0).firstChild.data,
603                                 acg : xml.getElementsByTagName('e2acg').item(0).firstChild.data
604                 };
605         }
606
607         signalPanelData = { signal : namespace };
608         fetchTpl('tplSignalPanel', updateSignalPanel);  
609 }
610
611 function reloadSignalPanel(){
612         doRequest(URL.signal, incomingSignalPanel, false);
613 }
614
615 function openSignalPanel(){
616         if (!(!signalWin.closed && signalWin.location)){
617                 signalWin = openPopup('SignalPanel', '', 220, 120);
618                 if(signalPanelUpdatePoller === ''){
619                         signalPanelUpdatePoller = setInterval(reloadSignalPanel, 5000);
620                 }
621         }
622         reloadSignalPanel();
623 }
624
625 //EPG functions
626
627
628 function showEpgList(){
629         var html = templates.tplEpgList.process(epgListData);
630
631         if (!EPGListWin.closed && EPGListWin.location) {
632                 setWindowContent(EPGListWin, html);
633         } else {
634                 EPGListWin = openPopup("EPG", html, 900, 500);
635         }
636 }
637
638 function incomingEPGrequest(request){
639         debug("[incomingEPGrequest] readyState" +request.readyState);           
640         if (request.readyState == 4){
641                 var EPGItems = new EPGList(getXML(request)).getArray(true);
642                 debug("[incomingEPGrequest] got "+EPGItems.length+" e2events");
643
644                 if( EPGItems.length > 0){
645                         epgListData = {epg : EPGItems};
646                         fetchTpl('tplEpgList', showEpgList);
647                 } else {
648                         messageBox('No Items found!', 'Sorry but I could not find any EPG Content containing your search value');
649                 }
650         }
651 }
652
653 function loadEPGBySearchString(string){
654         doRequest(URL.epgsearch+escape(string),incomingEPGrequest, false);
655 }
656
657 function loadEPGByServiceReference(servicereference){
658         doRequest(URL.epgservice+servicereference,incomingEPGrequest, false);
659 }
660
661 function buildServiceListEPGItem(epgevent, type){
662         var data = { epg : epgevent,
663                                  nownext: type
664                                 };
665         // e.innerHTML = RND(tplServiceListEPGItem, namespace);
666
667         var id = type + epgevent.servicereference;
668
669         show('tr' + id);
670
671         if(typeof(templates.tplServiceListEPGItem) != "undefined"){
672                 renderTpl(templates.tplServiceListEPGItem, data, id, true);
673         } else {
674                 debug("[buildServiceListEPGItem] tplServiceListEPGItem N/A");
675         }
676 }
677
678 function incomingServiceEPGNowNext(request, type){
679         if(request.readyState == 4){
680                 var epgevents = getXML(request).getElementsByTagName("e2eventlist").item(0).getElementsByTagName("e2event");
681                 for (var c = 0; c < epgevents.length; c++){
682                         try{
683                                 var epgEvt = new EPGEvent(epgevents.item(c), c).toJSON();
684                         } catch (e){
685                                 debug("[incomingServiceEPGNowNext]" + e);
686                         }
687
688                         if (epgEvt.eventid != ''){
689                                 buildServiceListEPGItem(epgEvt, type);
690                         }
691                 }
692         }
693 }
694
695 function incomingServiceEPGNow(request){
696         incomingServiceEPGNowNext(request, 'NOW');
697 }
698
699 function incomingServiceEPGNext(request){
700         incomingServiceEPGNowNext(request, 'NEXT');
701 }
702
703 function loadServiceEPGNowNext(servicereference, next){
704         var url = URL.epgnow+servicereference;
705
706         if(typeof(next) == 'undefined'){
707                 doRequest(url, incomingServiceEPGNow, false);
708         } else {
709                 url = URL.epgnext+servicereference;
710                 doRequest(url, incomingServiceEPGNext, false);
711         }
712 }
713
714
715 function getBouquetEpg(){
716         loadServiceEPGNowNext(currentBouquet);
717         loadServiceEPGNowNext(currentBouquet, true);
718 }
719
720
721 function recordNowPopup(){
722         var result = confirm(   
723                         "OK: Record current event\n" +
724                         "Cancel: Start infinite recording"
725         );
726
727         if( result === true || result === false){
728                 recordNowDecision(result);
729         }
730 }
731
732
733 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
734 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
735 //++++ volume functions ++++
736 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
737 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
738 function handleVolumeRequest(request){
739         if (request.readyState == 4) {
740                 var b = getXML(request).getElementsByTagName("e2volume");
741                 var newvalue = b.item(0).getElementsByTagName('e2current').item(0).firstChild.data;
742                 var mute = b.item(0).getElementsByTagName('e2ismuted').item(0).firstChild.data;
743                 debug("[handleVolumeRequest] Volume " + newvalue + " | Mute: " + mute);
744
745                 for (var i = 1; i <= 10; i++)           {
746                         if ( (newvalue/10)>=i){
747                                 $("volume"+i).src = "/web-data/img/led_on.png";
748                         }else{
749                                 $("volume"+i).src = "/web-data/img/led_off.png";
750                         }
751                 }
752                 if (mute == "False"){
753                         $("speaker").src = "/web-data/img/speak_on.png";
754                 }else{
755                         $("speaker").src = "/web-data/img/speak_off.png";
756                 }
757         }       
758 }
759
760
761 function getVolume(){
762         doRequest(URL.getvolume, handleVolumeRequest, false);
763 }
764
765 function volumeSet(val){
766         doRequest(URL.setvolume+val, handleVolumeRequest, false);
767 }
768
769 function volumeUp(){
770         doRequest(URL.volumeup, handleVolumeRequest, false);
771 }
772
773 function volumeDown(){
774         doRequest(URL.volumedown, handleVolumeRequest, false);
775 }
776
777 function volumeMute(){
778         doRequest(URL.volumemute, handleVolumeRequest, false);
779 }
780
781 function initVolumePanel(){
782         getVolume(); 
783 }
784
785
786
787 //Channels and Bouquets
788
789 function incomingChannellist(request){
790         var serviceList = null;
791         if(typeof(loadedChannellist[currentBouquet]) != "undefined"){
792                 serviceList = loadedChannellist[currentBouquet];
793         } else if(request.readyState == 4) {
794                 serviceList = new ServiceList(getXML(request)).getArray();
795                 debug("[incomingChannellist] got "+serviceList.length+" Services");
796         }
797         if(serviceList !== null) {              
798                 var data = { services : serviceList };
799
800                 processTpl('tplServiceList', data, 'contentServices', getBouquetEpg);
801                 delayedGetSubservices();
802         } else {
803                 debug("[incomingChannellist] services is null");
804         }
805 }
806
807
808 function loadBouquet(servicereference, name){ 
809         debug("[loadBouquet] called");
810
811         currentBouquet = servicereference;
812
813         setContentHd(name);
814         setAjaxLoad('contentServices');
815
816         startUpdateBouquetItemsPoller();
817         doRequest(URL.getservices+servicereference, incomingChannellist, true);
818
819 }
820
821
822 function incomingBouquetListInitial(request){
823         if (request.readyState == 4) {
824                 var bouquetList = new ServiceList(getXML(request)).getArray();
825                 debug("[incomingBouquetListInitial] Got " + bouquetList.length + " TV Bouquets!");      
826         
827                 // loading first entry of TV Favorites as default for ServiceList
828                 incomingBouquetList(
829                                 request, 
830                                 function(){
831                                         loadBouquet(bouquetList[0].servicereference, bouquetList[0].servicename);;
832                                 }
833                         );
834         }
835 }
836
837
838 function incomingBouquetList(request, callback){
839         if (request.readyState == 4) {
840                 var bouquetList = new ServiceList(getXML(request)).getArray();
841                 debug("[incomingBouquetList] got " + bouquetList.length + " TV Bouquets!");     
842                 var data = { bouquets : bouquetList };
843                 
844                 if( $('contentBouquets') != undefined ){
845                         processTpl('tplBouquetList', data, 'contentBouquets');
846                         if(typeof(callback) == 'function')
847                                 callback();
848                 } else {
849                         processTpl(                                     
850                                         'tplBouquetsAndServices', 
851                                         null, 
852                                         'contentMain',
853                                         function(){
854                                                 processTpl('tplBouquetList', data, 'contentBouquets');
855                                                 if(typeof(callback) == 'function')
856                                                         callback();
857                                         }
858                         );
859                 }
860         }
861 }
862
863
864 function initChannelList(){
865         var url = URL.getservices+encodeURIComponent(bouquetsTv);
866         currentBouquet = bouquetsTv;
867
868         doRequest(url, incomingBouquetListInitial, true);
869 }
870
871
872
873 //Movies
874 function initMovieList(){
875         // get videodirs, last_videodir, and all tags
876         doRequest(URL.getcurrlocation, incomingMovieListCurrentLocation, false);
877 }
878
879 function incomingMovieListCurrentLocation(request){
880         if(request.readyState == 4){
881                 result  = new SimpleXMLList(getXML(request), "e2location");
882                 currentLocation = result.getList()[0];
883                 debug("[incomingMovieListCurrentLocation].currentLocation" + currentLocation);
884                 doRequest(URL.getlocations, incomingMovieListLocations, false);
885         }
886 }
887
888 function incomingMovieListLocations(request){
889         if(request.readyState == 4){
890                 result  = new SimpleXMLList(getXML(request), "e2location");
891                 locationsList = result.getList();
892
893                 if (locationsList.length === 0) {
894                         locationsList = ["/hdd/movie"];
895                 }
896                 doRequest(URL.gettags, incomingMovieListTags, false);
897         }
898 }
899
900 function incomingMovieListTags(request){
901         if(request.readyState == 4){
902                 result  = new SimpleXMLList(getXML(request), "e2tag");
903                 tagsList = result.getList();
904         }
905 }
906
907 function createOptionListSimple(lst, selected) {
908         var namespace = Array();
909         var i = 0;
910         var found = false;
911
912         for (i = 0; i < lst.length; i++) {
913                 if (lst[i] == selected) {
914                         found = true;
915                 }
916         }
917
918         if (!found) {
919                 lst = [ selected ].concat(lst);
920         }
921
922         for (i = 0; i < lst.length; i++) {
923                 namespace[i] = {
924                                 'value': lst[i],
925                                 'txt': lst[i],
926                                 'selected': (lst[i] == selected ? "selected" : " ")};
927         }
928
929         return namespace;
930 }
931
932 function loadMovieNav(){
933         // fill in menus
934         var data = {
935                         dirname: createOptionListSimple(locationsList, currentLocation),
936                         tags: createOptionListSimple(tagsList, "")
937         };
938
939         processTpl('tplNavMovies', data, 'navContent');
940 }
941
942 function incomingMovieList(request){
943         if(request.readyState == 4){
944
945                 var movieList = new MovieList(getXML(request)).getArray();
946                 debug("[incomingMovieList] Got "+movieList.length+" movies");
947
948                 var data = { movies : movieList };
949                 processTpl('tplMovieList', data, 'contentMain');
950         }               
951 }
952
953 function loadMovieList(loc, tag){
954         if(typeof(loc) == 'undefined'){
955                 loc = currentLocation;
956         }
957         if(typeof(tag) == 'undefined'){
958                 tag = '';
959         }
960         debug("[loadMovieList] Loading movies in location '"+loc+"' with tag '"+tag+"'");
961         doRequest(URL.movielist+"?dirname="+loc+"&tag="+tag, incomingMovieList, false);
962 }
963
964
965 function incomingDelMovieResult(request) {
966         debug("[incomingDelMovieResult] called");
967         if(request.readyState == 4){
968                 var result = new SimpleXMLResult(getXML(request));
969                 if(result.getState()){                  
970                         loadMovieList();
971                 }
972                 simpleResultHandler(result);
973         }               
974 }
975
976
977 function delMovie(sref ,servicename, title, description) {
978         debug("[delMovie] File(" + unescape(sref) + "), servicename(" + servicename + ")," +
979                         "title(" + unescape(title) + "), description(" + description + ")");
980
981         result = confirm( "Are you sure want to delete the Movie?\n" +
982                         "Servicename: " + servicename + "\n" +
983                         "Title: " + unescape(title) + "\n" + 
984                         "Description: " + description + "\n");
985
986         if(result){
987                 debug("[delMovie] ok confirm panel"); 
988                 doRequest(URL.moviedelete+"?sRef="+unescape(sref), incomingDelMovieResult, false); 
989                 return true;
990         }
991         else{
992                 debug("[delMovie] cancel confirm panel");
993                 return false;
994         }
995 }
996
997 //Send Messages and Receive the Answer
998
999
1000 function incomingMessageResult(request){
1001         if(request.readyState== 4){
1002                 var result = new SimpleXMLResult(getXML(request));
1003                 simpleResultHandler(result);
1004         }
1005 }
1006
1007 function getMessageAnswer() {
1008         doRequest(URL.messageanswer, incomingMessageResult, false);
1009 }
1010
1011 function sendMessage(messagetext, messagetype, messagetimeout){
1012         if(!messagetext){
1013                 messagetext = $('MessageSendFormText').value;
1014         }       
1015         if(!messagetimeout){
1016                 messagetimeout = $('MessageSendFormTimeout').value;
1017         }       
1018         if(!messagetype){
1019                 var index = $('MessageSendFormType').selectedIndex;
1020                 messagetype = $('MessageSendFormType').options[index].value;
1021         }       
1022         if(parseNr(messagetype) === 0){
1023                 doRequest(URL.message+'?text='+messagetext+'&type='+messagetype+'&timeout='+messagetimeout);
1024                 setTimeout(getMessageAnswer, parseNr(messagetimeout)*1000);
1025         } else {
1026                 doRequest(URL.message+'?text='+messagetext+'&type='+messagetype+'&timeout='+messagetimeout, incomingMessageResult, false);
1027         }
1028 }
1029
1030
1031 //Screenshots
1032 function getScreenShot(what) {
1033         debug("[getScreenShot] called");
1034
1035         var buffer = new Image();
1036         var downloadStart;
1037         var data = {};
1038
1039         buffer.onload = function () { 
1040                 debug("[getScreenShot] image assigned");
1041
1042                 data = { img : { src : buffer.src } };  
1043                 processTpl('tplGrab', data, 'contentMain');
1044
1045                 return true;
1046         };
1047
1048         buffer.onerror = function (meldung) { 
1049                 debug("[getScreenShot] Loading image failed"); 
1050                 return true;
1051         };
1052
1053         switch(what){
1054         case "o":
1055                 what = "&o=&n=";
1056                 break;
1057         case "v":
1058                 what = "&v=";
1059                 break;
1060         default:
1061                 what = "";
1062         break;
1063         }
1064
1065         downloadStart = new Date().getTime();
1066         buffer.src = '/grab?format=jpg&r=720&' + what + '&filename=/tmp/' + downloadStart;
1067 }
1068
1069 function getVideoShot() {
1070         getScreenShot("v");
1071 }
1072
1073 function getOsdShot(){
1074         getScreenShot("o");
1075 }
1076
1077 //RemoteControl Code
1078
1079 function incomingRemoteControlResult(request){
1080 //      if(request.readyState == 4){
1081 //              var b = getXML(request).getElementsByTagName("e2remotecontrol");
1082 //              var result = b.item(0).getElementsByTagName('e2result').item(0).firstChild.data;
1083 //              var resulttext = b.item(0).getElementsByTagName('e2resulttext').item(0).firstChild.data;
1084 //      }
1085 }
1086
1087 function openWebRemote(){
1088         var template = templates.tplWebRemoteOld;
1089
1090         if(boxtype == "dm8000"){
1091                 template = templates.tplWebRemote;
1092         }
1093
1094
1095         if (!webRemoteWin.closed && webRemoteWin.location) {
1096                 setWindowContent(webRemoteWin, template);
1097         } else {
1098                 webRemoteWin = openPopup('WebRemote', template, 250, 600);
1099         }
1100
1101 }
1102
1103
1104 function loadAndOpenWebRemote(){
1105         if(boxtype == "dm8000"){
1106                 fetchTpl('tplWebRemote', openWebRemote);
1107                 
1108         } else {
1109                 fetchTpl('tplWebRemoteOld', openWebRemote);
1110         }
1111 }
1112
1113
1114 function sendRemoteControlRequest(command){
1115         doRequest(URL.remotecontrol+'?command='+command, incomingRemoteControlResult, false);
1116         if(webRemoteWin.document.getElementById('getScreen').checked) {
1117                 if(webRemoteWin.document.getElementById('getVideo').checked){
1118                         getScreenShot();
1119                 } else {
1120                         getScreenShot("o");
1121                 }
1122         }
1123 }
1124
1125
1126 // Array.insert( index, value ) - Insert value at index, without overwriting existing keys
1127 Array.prototype.insert = function( j, v ) {
1128         if( j>=0 ) {
1129                 var a = this.slice(), b = a.splice( j );
1130                 a[j] = v;
1131                 return a.concat( b );
1132         }
1133 };
1134
1135 //Array.splice() - Remove or replace several elements and return any deleted
1136 //elements
1137 if( typeof Array.prototype.splice==='undefined' ) {
1138         Array.prototype.splice = function( a, c ) {
1139                 var e = arguments, d = this.copy(), f = a, l = this.length;
1140
1141                 if( !c ) { 
1142                         c = l - a; 
1143                 }
1144
1145                 for( var i = 0; i < e.length - 2; i++ ) { 
1146                         this[a + i] = e[i + 2]; 
1147                 }
1148
1149
1150                 for( var j = a; j < l - c; j++ ) { 
1151                         this[j + e.length - 2] = d[j - c]; 
1152                 }
1153                 this.length -= c - e.length + 2;
1154
1155                 return d.slice( f, f + c );
1156         };
1157 }
1158
1159 function ifChecked(rObj) {
1160         if(rObj.checked) {
1161                 return rObj.value;
1162         } else {
1163                 return "";
1164         }
1165 }
1166
1167 //Device Info
1168 /*
1169  * Handles an incoming request for /web/deviceinfo Parses the Data, and calls
1170  * everything needed to render the Template using the parsed data and set the
1171  * result into contentMain @param request - the XHR
1172  */
1173 function incomingDeviceInfo(request) {
1174         if(request.readyState == 4){
1175                 debug("[incomingDeviceInfo] called");
1176                 var deviceInfo = new DeviceInfo(getXML(request));
1177
1178                 processTpl('tplDeviceInfo', deviceInfo, 'contentMain');
1179         }
1180 }
1181
1182
1183 /*
1184  * Show Device Info Information in contentMain
1185  */
1186 function showDeviceInfo() {
1187         doRequest(URL.deviceinfo, incomingDeviceInfo, false);
1188 }
1189
1190 function showGears(){
1191         var enabled = false;
1192         
1193         if (window.google && google.gears){
1194                 enabled = gearsEnabled();
1195         }
1196         
1197         data = { 'useGears' : enabled };
1198         processTpl('tplGears', data, 'contentMain');
1199 }
1200
1201 function showSettings(){
1202         var debug = userprefs.data.debug;
1203         var debugChecked = "";
1204         if(debug){
1205                 debugChecked = 'checked';
1206         }
1207
1208         data = { 'debug' : debugChecked };
1209         processTpl('tplSettings', data, 'contentMain');
1210 }
1211
1212  
1213 // Spezial functions, mostly for testing purpose
1214 function openHiddenFunctions(){
1215         openPopup("Extra Hidden Functions",tplExtraHiddenFunctions,300,100,920,0);
1216 }
1217
1218
1219 function startDebugWindow() {
1220         DBG = true;
1221         debugWin = openPopup("DEBUG", "", 300, 300,920,140, "debugWindow");
1222 }
1223
1224
1225 function restartTwisted() {
1226         doRequest( "/web/restarttwisted" );
1227 }
1228
1229
1230 //MediaPlayer
1231 function sendMediaPlayer(command) {
1232         debug("[sendMediaPlayer] called");
1233         doRequest( URL.mediaplayercmd+command );
1234 }
1235
1236
1237 function incomingMediaPlayer(request){
1238         if(request.readyState == 4){
1239                 var files = new FileList(getXML(request)).getArray();
1240
1241                 debug("[loadMediaPlayer] Got "+files.length+" entries in mediaplayer filelist");
1242                 // listerHtml = tplMediaPlayerHeader;
1243
1244                 var namespace = {};
1245
1246                 var root = files[0].getRoot();
1247                 if (root != "playlist") {
1248                         namespace = {'root': root};
1249                         if(root != '/') {
1250                                 var re = new RegExp(/(.*)\/(.*)\/$/);
1251                                 re.exec(root);
1252                                 var newroot = RegExp.$1+'/';
1253                                 if(newroot == '//') {
1254                                         newroot = '/';
1255                                 }
1256                                 namespace = {
1257                                                 'root': root,
1258                                                 'servicereference': newroot,
1259                                                 'exec': 'loadMediaPlayer',
1260                                                 'exec_description': 'Change to directory ../',
1261                                                 'color': '000000',
1262                                                 'newroot': newroot,
1263                                                 'name': '..'
1264                                 };      
1265                         }
1266                 }
1267
1268                 var itemnamespace = Array();
1269                 for ( var i = 0; i <files.length; i++){
1270                         var file = files[i];
1271                         if(file.getNameOnly() == '') {
1272                                 continue;
1273                         }
1274                         var exec = 'loadMediaPlayer';
1275                         var exec_description = 'Change to directory' + file.getServiceReference();
1276                         var color = '000000';                   
1277                         var isdir = 'true';
1278
1279                         if (file.getIsDirectory() == "False") {
1280                                 exec = 'playFile';
1281                                 exec_description = 'play file';
1282                                 color = '00BCBC';
1283                                 isdir = 'false';
1284                         }
1285
1286                         itemnamespace[i] = {
1287                                         'isdir' : isdir,
1288                                         'servicereference': file.getServiceReference(),
1289                                         'exec': exec,
1290                                         'exec_description': exec_description,
1291                                         'color': color,                                                 
1292                                         'root': file.getRoot(),
1293                                         'name': file.getNameOnly()
1294                         };
1295
1296                 }
1297                 /*
1298                 if (root == "playlist") {
1299                         listerHtml += tplMediaPlayerFooterPlaylist;
1300                 }
1301                  */
1302
1303                 var data = { mp : namespace,
1304                                 items: itemnamespace
1305                 };
1306
1307                 processTpl('tplMediaPlayer', data, 'contentMain');
1308                 var sendMediaPlayerTMP = sendMediaPlayer;
1309                 sendMediaPlayer = false;
1310                 // setBodyMainContent('BodyContent');
1311                 sendMediaPlayer = sendMediaPlayerTMP;
1312         }               
1313 }
1314
1315
1316 function loadMediaPlayer(directory){
1317         debug("[loadMediaPlayer] called");
1318         if(typeof(directory) == 'undefined') directory = 'Filesystems';
1319         doRequest(URL.mediaplayerlist+directory, incomingMediaPlayer, false);
1320 }
1321
1322
1323 function playFile(file,root) {
1324         debug("[playFile] called");
1325         mediaPlayerStarted = true;
1326         doRequest( URL.mediaplayerplay+file+"&root="+root );
1327 }
1328
1329
1330 function deleteFile(sref) {
1331         debug("[deleteFile] called");
1332         mediaPlayerStarted = true;
1333         doRequest( URL.mediaplayerremove+sref );
1334 }
1335
1336
1337 function openMediaPlayerPlaylist() {
1338         debug("[openMediaPlayerPlaylist] called");
1339         doRequest(URL.mediaplayerlist+"playlist", incomingMediaPlayer, false);
1340 }
1341
1342
1343 function writePlaylist() {
1344         debug("[writePlaylist] called");
1345         var filename = '';
1346         filename = prompt("Please enter a name for the playlist", "");
1347
1348         if(filename !== "") {
1349                 doRequest( URL.mediaplayerwrite+filename );
1350         }
1351 }
1352
1353 //Powerstate
1354 /*
1355  * Sets the Powerstate @param newState - the new Powerstate Possible Values
1356  * (also see WebComponents/Sources/PowerState.py) #-1: get current state # 0:
1357  * toggle standby # 1: poweroff/deepstandby # 2: rebootdreambox # 3:
1358  * rebootenigma
1359  */
1360 function sendPowerState(newState){
1361         doRequest( URL.powerstate+'?newstate='+newState, incomingPowerState);
1362 }
1363
1364
1365 //Currently Running Service
1366 function incomingCurrent(request){
1367         //      debug("[incomingCurrent called]");
1368         if(request.readyState == 4){
1369                 try{
1370                         var epg = new EPGList(getXML(request)).getArray();
1371                         epg = epg[0];
1372
1373                         var data = { current : epg };
1374
1375                         if(typeof(templates.tplCurrent) != "undefined"){
1376                                 var display = 'none';
1377                                 try{
1378                                         var display = $('trExtCurrent').style.display;
1379                                 } catch(e){}
1380                                 
1381                                 renderTpl(templates.tplCurrent, data, "currentContent");
1382                                 $('trExtCurrent').style.display = display;
1383                         } else {
1384                                 debug("[incomingCurrent] tplCurrent N/A");
1385                         }
1386
1387                 } catch (e){}
1388                 
1389                 isActive.getCurrent = false;
1390         }
1391 }
1392
1393
1394 function getCurrent(){
1395         if(!isActive.getCurrent){
1396                 isActive.getCurrent = true;
1397                 doRequest(URL.getcurrent, incomingCurrent, false);
1398         }
1399 }
1400
1401
1402 //Navigation and Content Helper Functions
1403
1404 /*
1405  * Loads all Bouquets for the given enigma2 servicereference and sets the
1406  * according contentHeader @param sRef - the Servicereference for the bouquet to
1407  * load
1408  */
1409 function getBouquets(sRef){     
1410         var url = URL.getservices+encodeURIComponent(sRef);
1411         
1412         doRequest(url, incomingBouquetList, true);              
1413 }
1414
1415 /*
1416  * Loads another navigation template and sets the navigation header
1417  * @param template - The name of the template
1418  * @param title - The title to set for the navigation
1419  */
1420 function reloadNav(template, title){
1421         setAjaxLoad('navContent');
1422         processTpl(template, null, 'navContent');
1423         setNavHd(title);
1424 }
1425
1426 function reloadNavDynamic(fnc, title){
1427         setAjaxLoad('navContent');
1428         setNavHd(title);
1429         fnc();
1430 }
1431
1432 function getBouquetsTv(){
1433         getBouquets(bouquetsTv);
1434 }
1435
1436 function getProviderTv(){
1437         getBouquets(providerTv);
1438 }
1439
1440 function getSatellitesTv(){
1441         getBouquets(satellitesTv);
1442 }
1443
1444 function getAllTv(){
1445         loadBouquet(allTv, "All (TV)");
1446 }
1447
1448
1449 function getBouquetsRadio(){
1450         getBouquets(bouquetsRadio);
1451 }
1452
1453 function getProviderRadio(){
1454         getBouquets(providerRadio);
1455 }
1456
1457 function getSatellitesRadio(){
1458         getBouquets(satellitesRadio);
1459 }
1460
1461 function getAllRadio(){
1462         loadBouquet(allRadio, "All (Radio)");
1463 }
1464
1465 /*
1466  * Loads dynamic content to $(contentMain) by calling a execution function
1467  * @param fnc - The function used to load the content
1468  * @param title - The Title to set on the contentpanel
1469  */
1470 function loadContentDynamic(fnc, title, domid){
1471         if(typeof(domid) != undefined){
1472                 setAjaxLoad(domid);
1473         } else {
1474                 setAjaxLoad('contentMain');
1475         }
1476         setContentHd(title);
1477         stopUpdateBouquetItemsPoller();
1478
1479         fnc();
1480 }
1481
1482 /*
1483  * like loadContentDynamic but without the AjaxLoaderAnimation being shown
1484  */
1485 function reloadContentDynamic(fnc, title){
1486         setContentHd(title);
1487         fnc();
1488 }
1489
1490 /*
1491  * Loads a static template to $(contentMain)
1492  * @param template - Name of the Template
1493  * @param title - The Title to set on the Content-Panel
1494  */
1495 function loadContentStatic(template, title){
1496         setAjaxLoad('contentMain');
1497         setContentHd(title);
1498         stopUpdateBouquetItemsPoller();
1499         processTpl(template, null, 'contentMain');
1500 }
1501
1502
1503 /*
1504  * Opens the given Control
1505  * @param control - Control Page as String
1506  * Possible Values: power, extras, message, screenshot, videoshot, osdshot
1507  */
1508 function loadControl(control){
1509         switch(control){
1510         case "power":
1511                 loadContentStatic('tplPower', 'PowerControl');
1512                 break;
1513
1514         case "message":
1515                 loadContentStatic('tplSendMessage', 'Send a Message');
1516                 break;
1517
1518         case "remote":
1519                 loadAndOpenWebRemote();
1520                 break;
1521
1522         case "screenshot":
1523                 loadContentDynamic(getScreenShot, 'Screenshot');
1524                 break;
1525
1526         case "videoshot":
1527                 loadContentDynamic(getVideoShot, 'Videoshot');
1528                 break;
1529
1530         case "osdshot":
1531                 loadContentDynamic(getOsdShot, 'OSDshot');
1532                 break;
1533
1534         default:
1535                 break;
1536         }
1537 }
1538
1539
1540 function loadDeviceInfo(){
1541         loadContentDynamic(showDeviceInfo, 'Device Information');
1542 }
1543
1544 function loadAbout(){
1545         loadContentStatic('tplAbout', 'About');
1546 }
1547
1548 function loadSettings(){
1549         loadContentDynamic(showSettings, 'Settings');
1550 }
1551
1552 function loadGearsInfo(){
1553         loadContentDynamic(showGears, 'Google Gears');
1554 }
1555
1556 function reloadGearsInfo(){
1557         loadContentDynamic(showGears, 'Google Gears');
1558 }
1559
1560
1561 /*
1562  * Switches Navigation Modes
1563  * @param mode - The Navigation Mode you want to switch to
1564  * Possible Values: TV, Radio, Movies, Timer, Extras
1565  */
1566 function switchMode(mode){
1567         switch(mode){
1568         case "TV":
1569                 reloadNav('tplNavTv', 'TeleVision');
1570                 break;
1571
1572         case "Radio":
1573                 reloadNav('tplNavRadio', 'Radio');
1574                 break;
1575
1576         case "Movies":
1577                 //The Navigation
1578                 reloadNavDynamic(loadMovieNav, 'Movies');
1579
1580                 // The Movie list
1581                 loadContentDynamic(loadMovieList, 'Movies');
1582                 break;
1583
1584         case "Timer":
1585                 //The Navigation
1586                 reloadNav('tplNavTimer', 'Timer');
1587
1588                 // The Timerlist
1589                 loadContentDynamic(loadTimerList, 'Timer');
1590                 break;
1591
1592         case "MediaPlayer":
1593                 loadContentDynamic(loadMediaPlayer, 'MediaPlayer');
1594                 break;
1595
1596         case "BoxControl":
1597                 reloadNav('tplNavBoxControl', 'BoxControl');
1598                 break;
1599
1600         case "Extras":
1601                 reloadNav('tplNavExtras', 'Extras');
1602                 break;
1603                 
1604         default:
1605                 break;
1606         }
1607 }
1608
1609 function openWebTV(){
1610         window.open('/web-data/streaminterface.html', 'WebTV', 'scrollbars=no, width=800, height=730');
1611 }
1612
1613
1614
1615 function updateItems(){
1616         getCurrent();
1617         getPowerState();
1618 }
1619
1620 function updateItemsLazy(bouquet){
1621         getSubServices();
1622         getBouquetEpg();
1623 }
1624
1625 /*
1626  * Does the everything required on initial pageload
1627  */
1628
1629 function init(){
1630         var DBG = userprefs.data.debug || false;
1631         if(DBG){
1632                 openDebug();
1633         }
1634
1635         if (typeof document.body.style.maxHeight == "undefined") {
1636                 alert("Due to the tremendous amount of work needed to get everthing to " +
1637                 "work properly, there is (for now) no support for Internet Explorer Versions below 7");
1638         }
1639         
1640         getBoxtype();
1641
1642         setAjaxLoad('navContent');
1643         setAjaxLoad('contentMain');
1644
1645         fetchTpl('tplServiceListEPGItem');
1646         fetchTpl('tplBouquetsAndServices');
1647         fetchTpl('tplCurrent'); 
1648         reloadNav('tplNavTv', 'TeleVision');
1649
1650         initChannelList();
1651         initVolumePanel();
1652         initMovieList();
1653
1654         updateItems();
1655         startUpdateCurrentPoller();
1656 }