[WebIf] * Fix certificates validity dates by setting fixed validFrom and validTo...
[enigma2-plugins.git] / webinterface / src / web-data / core.js
1 var Controller = Class.create({
2         initialize: function(handler){
3                 this.handler = handler;
4                 this.handler.onFinished.push(this.registerEvents.bind(this));
5                 this.handler.onFinished.push(this.onFinished.bind(this));
6                 this.eventsregistered = false;
7         },
8
9         registerEvents: function(){
10                 this.eventsregistered = true;
11         },
12
13         onFinished: function(){}
14 });
15
16 var Bouquets = Class.create(Controller, {
17         initialize: function($super, targetBouquets, targetMain){
18                 $super(new BouquetListHandler(targetBouquets, targetMain));
19                 this.loadFirstOnFinished = false;
20         },
21
22         load: function(sRef, loadFirstOnFinished){
23                 if(loadFirstOnFinished)
24                         this.loadFirstOnFinished = true;
25                 this.handler.load( {'sRef' : sRef} );
26                 var services = $('contentServices');
27                 if(services){
28                         services.update('Please select a bouquet');
29                 }
30         },
31
32         loadBouquetsTv: function(){
33                 setContentHd('Bouquets (TV)');
34                 this.load(bouquetsTv);
35         },
36
37         loadProviderTv: function(){
38                 setContentHd('Providers (TV)');
39                 this.load(providerTv);
40         },
41
42         loadSatellitesTv: function(){
43                 setContentHd('Satellites (TV)');
44                 this.load(satellitesTv);
45         },
46
47         loadBouquetsRadio: function(){
48                 setContentHd('Bouquets (Radio)');
49                 this.load(bouquetsRadio);
50         },
51
52         loadProviderRadio: function(){
53                 setContentHd('Providers (Radio)');
54                 this.load(providerRadio);
55         },
56
57         loadSatellitesRadio: function(){
58                 setContentHd('Satellites (Radio)');
59                 this.load(satellitesRadio);
60         },
61
62         onFinished: function(){
63                 var bouquets = this.handler.data.services;
64                 if(bouquets){
65                         if(this.loadFirstOnFinished || bouquets.length == 1){
66                                 var bouquet = bouquets[0];
67                                 setContentHd(bouquet.servicename);
68                                 this.loadFirstOnFinished = false;
69                                 hash = core.getBaseHash() + '/' + bouquet.servicereference;
70                                 hashListener.setHash(hash);
71                         } else {
72                                 var currentBouquet = hashListener.getHash().split('/')[3];
73                                 if(currentBouquet){
74                                         bouquets.each(function(bouquet){
75                                                 if(bouquet.servicereference == currentBouquet){
76                                                         setContentHd(bouquet.servicename);
77                                                 }
78                                         });
79                                 }
80                         }
81                 }
82         }
83 });
84
85 var Current = Class.create(Controller, {
86         initialize: function($super, curTarget, volTarget){
87                 $super(new CurrentHandler(curTarget, volTarget));
88                 this.handler.onFinished[this.handler.onFinished.length] = this.onFinished.bind(this);
89                 this.display = 'none';
90         },
91
92         load: function(){
93                 this.handler.load({});
94         },
95
96         toggleVisibility: function(element){
97                 var ext = $('trExtCurrent');
98                 if(ext){
99                         var bullet = element.down('.currentBulletToggle');
100                         if(ext.visible()){
101                                 bullet.src = '/web-data/img/toggle_expand.png';
102                                 bullet.alt = "+";
103                                 ext.hide();
104                         }else{
105                                 bullet.src = '/web-data/img/toggle_collapse.png';
106                                 bullet.alt = "-";
107                                 ext.show();
108                         }
109                         this.display = ext.style.display;
110                         setMaxHeight('contentMain');
111                 }
112         },
113
114         onFinished: function(){
115                 setMaxHeight('contentMain');
116                 var ext = $('trExtCurrent');
117                 if(ext){
118                         ext.style.display = this.display;
119                         var bullet = $('currentName').down('.currentBulletToggle');
120                         if(ext.visible()){
121                                 bullet.src = '/web-data/img/toggle_collapse.png';
122                                 bullet.alt = "-";
123                         }else{
124                                 bullet.src = '/web-data/img/toggle_expand.png';
125                                 bullet.alt = "+";
126                         }
127                 }
128                 core.currentData = this.handler.data;
129         }
130 });
131
132 var Externals = Class.create(Controller, {
133         initialize: function($super, target){
134                 $super(new ExternalsHandler(target));
135                 this.loaded = false;
136         },
137
138         load: function(){
139                 if(!this.loaded)
140                         this.handler.load({});
141                 else
142                         this.handler.show(this.handler.data);
143         },
144
145         onFinished: function(){
146                 this.loaded = true;
147         }
148 });
149
150 var EPG = Class.create(Controller, {
151         initialize: function($super){
152                 $super(new EpgListHandler(this.show.bind(this)));
153                 this.window = '';
154         },
155
156         show:function(html){
157                 var win = core.popup("EPG" + new Date().getTime(), html, 900, 500);
158                 this.doRegisterEvents(win);
159         },
160
161         load: function(sRef){
162                 this.handler.load({'sRef' : sRef});
163         },
164
165         search: function(needle){
166                 this.handler.search({'search' : needle});
167         },
168
169         doRegisterEvents: function(win){
170                 var elem = win.document;
171                 var onload = function(event){
172                         elem.on(
173                                 'click',
174                                 '.eListAddTimer',
175                                 function(event, element){
176                                         core.timers.addByEventId(element, 0);
177                                         return false;
178                                 }
179                         );
180                         elem.on(
181                                 'click',
182                                 '.eListZapTimer',
183                                 function(event, element){
184                                         core.timers.addByEventId(element, 1);
185                                         return false;
186                                 }
187                         );
188                         elem.on(
189                                 'click',
190                                 '.eListEditTimer',
191                                 function(event, element){
192                                         var hash = ["#!/timer", "edit"].join("/");
193                                         hashListener.setHash(hash);
194                                         core.timers.editFromEvent(element);
195                                         //return false;
196                                 }
197                         );
198                 };
199                 if(elem.on){
200                         onload();
201                 } else {
202                         win.onload = onload;
203                 }
204         }
205 });
206
207 var MultiEpg = Class.create(Controller, {
208         initialize: function($super){
209                 $super(new MultiEpgHandler(this.show.bind(this)));
210                 this.tplDetails = "";
211         },
212
213         load: function(bRef){
214                 templateEngine.fetch(
215                         'tplMultiEpgDetail',
216                         function(tpl){
217                                 this.tplDetails = tpl;
218                                 this.doLoad(bRef);
219                         }.bind(this));
220         },
221
222         doLoad: function(bRef){
223                 this.handler.load({'bRef' : bRef});
224         },
225
226         show:function(html){
227                 var win = core.popup("MultiEpg" + new Date().getTime(), html, 900, 570);
228                 this.doRegisterEvents(win);
229         },
230
231         doRegisterEvents: function(win){
232                 var elem = win.document;
233                 var _this = this;
234                 var onload = function(event){
235 //                      elem.on(
236 //                              'resize',
237 //                              function(event, element){
238 //                                      var tbody = $('mEpgTBody');
239 //                                      var top = tbody.cumulativeOffset().top;
240 //                                      var height = elem.viewport.height - top;
241 //                                      tbody.style.height = height;
242 //                                      console.log(offset);
243 //                              }
244 //                      );
245                         elem.on(
246                                 'click',
247                                 '.mEpgItem',
248                                 function(event, element){
249                                         var detail = elem.getElementById('mEpgDetail');
250                                         if(detail){
251                                                 var e = {};
252                                                 e.servicereference = element.readAttribute('data-servicereference');
253                                                 e.servicename = element.readAttribute('data-servicename');
254                                                 e.eventid = element.readAttribute('data-eventid');
255                                                 e.date = element.readAttribute('data-date');
256                                                 e.start = element.readAttribute('data-start');
257                                                 e.starttime = element.readAttribute('data-starttime');
258                                                 e.end = element.readAttribute('data-end');
259                                                 e.endtime = element.readAttribute('data-endtime');
260                                                 e.duration = element.readAttribute('data-duration');
261                                                 e.title = element.readAttribute('data-title');
262                                                 e.description = element.readAttribute('data-description');
263                                                 e.extdescription = element.readAttribute('data-extdescription');
264                                                 var data = {'e' : e};
265                                                 detail.update(_this.tplDetails.process(data));
266                                                 detail.fadeIn({'delay' : 300, 'to' : 95});
267                                         }
268                                         event.stop();
269                                 }
270                         );
271                         elem.on(
272                                 'click',
273                                 '.close',
274                                 function(event, element){
275                                         var detail = elem.getElementById('mEpgDetail');
276                                         if(detail)
277                                                 detail.fadeOut({'delay' : 300});
278                                         event.stop();
279                                 }
280                         );
281
282                         elem.on(
283                                 'click',
284                                 '.eListAddTimer',
285                                 function(event, element){
286                                         core.timers.addByEventId(element, 0);
287                                         event.stop();
288                                 }
289                         );
290                         elem.on(
291                                 'click',
292                                 '.eListZapTimer',
293                                 function(event, element){
294                                         core.timers.addByEventId(element, 1);
295                                         event.stop();
296                                 }
297                         );
298                         elem.on(
299                                 'click',
300                                 '.eListEditTimer',
301                                 function(event, element){
302                                         var hash = ["#!/timer", "edit"].join("/");
303                                         hashListener.setHash(hash);
304                                         core.timers.editFromEvent(element);
305                                         event.stop();
306                                 }
307                         );
308                 };
309                 if(elem.on){
310                         onload();
311                 } else {
312                         win.onload = onload;
313                 }
314         }
315 });
316
317 var Power = Class.create({
318         STATES: {'toggle' : 0, 'deep' : 1, 'reboot' : 2, 'gui' : 3},
319
320         initialize: function(){
321                 //As we do not have an real templates here, there is no handler for powerstate.
322                 //The Handling is up to the caller of this class
323                 this.provider = new PowerstateProvider(this.onLoadFinished.bind(this));
324                 this.callbacks = [];
325                 this.isLoading = false;
326                 this.isStandby = false;
327         },
328
329         load: function(params){
330                 this.isLoading = true;
331                 this.provider.load(params);
332         },
333
334         onLoadFinished:function (isStandby){
335                 this.isStandby = isStandby;
336                 this.isLoading = false;
337                 var len = this.callbacks.length;
338                 for(var i = 0; i < len; i++){
339                         callback = this.callbacks.pop();
340                         callback(this.isStandby);
341                 }
342         },
343
344         inStandby: function(callback){
345                 this.callbacks.push(callback);
346                 if(!this.isLoading){
347                         this.load({});
348                 }
349         },
350
351         set: function(newstate, callback){
352                 this.callbacks.push(callback);
353                 this.load({'newstate' : this.STATES[newstate]});
354         }
355 });
356
357 var LocationsAndTags = Class.create({
358         initialize: function(){
359                 this.currentLocation = '';
360                 this.locations = [];
361                 this.tags = [];
362                 this.isCurrentLocationsLoading = false;
363                 this.isCurrentLocationReady = false;
364                 this.isLocationsLoading = false;
365                 this.isLocationsReady = false;
366                 this.isTagsLoading = false;
367                 this.isTagsReady = false;
368                 this.curLocCallbacks = [];
369                 this.locCallbacks = [];
370                 this.tagCallbacks = [];
371                 this.locTagCallbacks = [];
372
373                 this.curlocprovider = new CurrentLocationProvider(this.onCurrentLocationAvailable.bind(this));
374                 this.locprovider = new LocationProvider(this.onLocationsAvailable.bind(this));
375                 this.tagprovider = new TagProvider(this.onTagsAvailable.bind(this));
376         },
377
378         getCurrentLocation: function(callback){
379                 if(this.isCurrentLocationReady){
380                         callback(this.currentLocation);
381                 } else {
382                         this.curLocCallbacks[this.curLocCallbacks.length] = callback;
383                         if(!this.isCurrentLocationLoading){
384                                 this.curlocprovider.load({});
385                                 this.isCurrentLocationLoading = true;
386                         }
387                 }
388         },
389
390         onCurrentLocationAvailable: function(currentLocation){
391                 debug("[LocationsAndTags].onCurrentLocationAvailable");
392                 this.isCurrentLocationReady = true;
393                 this.isCurrentLocationLoading = false;
394                 this.currentLocation = currentLocation;
395                 var len = this.curLocCallbacks.length;
396                 for(var i = 0; i < len; i++){
397                         callback = this.curLocCallbacks.pop();
398                         callback(this.currentLocation);
399                 }
400                 this.onLocationsOrTagsAvailable();
401         },
402
403         getLocations: function(callback){
404                 if(this.isLocationsReady){
405                         callback(this.locations);
406                 } else {
407                         this.locCallbacks[this.locCallbacks.length] = callback;
408                         if(!this.isLocationsLoading){
409                                 this.locprovider.load({});
410                                 this.isLocationsLoading = true;
411                         }
412                 }
413         },
414
415         onLocationsAvailable: function(locations){
416                 debug("[LocationsAndTags].onLocationsAvailable");
417                 this.isLocationsReady = true;
418                 this.isLocationsLoading = false;
419                 this.locations = locations.getList();
420                 var len = this.locCallbacks.length;
421                 for(var i = 0; i < len; i++){
422                         callback = this.locCallbacks.pop();
423                         callback(this.locations);
424                 }
425                 this.onLocationsOrTagsAvailable();
426         },
427
428         getTags: function(callback){
429                 if(this.isTagsReady){
430                         callback(this.tags);
431                 } else {
432                         this.tagCallbacks[this.tagCallbacks.length] = callback;
433                         if(!this.isTagsLoading){
434                                 this.tagprovider.load({});
435                                 this.isTagsLoading = true;
436                         }
437                 }
438         },
439
440         onTagsAvailable: function(tags){
441                 debug("[LocationsAndTags].onTagsAvailable");
442                 this.isTagsReady = true;
443                 this.isTagsLoading = false;
444                 this.tags = tags.getList();
445                 var len = this.tagCallbacks.length;
446                 for(var i = 0; i < len; i++){
447                         callback = this.tagCallbacks.pop();
448                         callback(this.tags);
449                 }
450                 this.onLocationsOrTagsAvailable();
451         },
452
453         getLocationsAndTags: function(callback){
454                 if(this.isCurrentLocationReady && this.isLocationsReady && this.isTagsReady){
455                         callback(this.currentLocation, this.locations, this.tags);
456                 } else {
457                         this.locTagCallbacks[this.locTagCallbacks.length] = callback;
458                         if(!this.isCurrentLocationLoading)
459                                 this.curlocprovider.load({});
460                         if(!this.isLocationsLoading)
461                                 this.locprovider.load({});
462                         if(!this.isTagsLoading)
463                                 this.tagprovider.load({});
464                 }
465         },
466
467         onLocationsOrTagsAvailable: function(){
468                 if(this.isCurrentLocationReady && this.isLocationsReady && this.isTagsReady){
469                         var len = this.locTagCallbacks.length;
470                         for(var i = 0; i < len; i++){
471                                 callback = this.locTagCallbacks.pop();
472                                 callback(this.currentLocation, this.locations, this.tags);
473                         }
474                 }
475         }
476 });
477
478 var MediaPlayer = Class.create(Controller, {
479         initialize: function($super, target){
480                 $super(new MediaPlayerHandler(target));
481         },
482
483         load: function(path){
484                 if(!path){
485                         path = 'Filesystems';
486                 }
487                 var parms = {'path' : path};
488                 this.handler.load(parms);
489         },
490
491         playFile: function(file){
492                 this.handler.playFile(file);
493         },
494
495         addFile: function(file){
496                 this.handler.addFile(file);
497         },
498
499         removeFile: function(file){
500                 this.handler.removeFile(file);
501         },
502
503         savePlaylist: function(filename){
504                 this.handler.savePlaylist(filename);
505         },
506
507         command: function(cmd){
508                 this.handler.command(cmd);
509         }
510 });
511
512 var Messages = Class.create({
513         initialize: function(){
514                 this.handler = new SimpleRequestHandler();
515         },
516
517         send: function(text, type, timeout){
518                 this.handler.load(URL.message, {'text' : text, 'type' : type, 'timeout' : timeout});
519         }
520 });
521
522 var Movies = Class.create(Controller, {
523         initialize: function($super, listTarget, navTarget){
524                 $super(new MovieListHandler(listTarget));
525                 this.navHandler = new MovieNavHandler(navTarget);
526         },
527
528         load: function(location, tags){
529                 if(!location){
530                         var sethash = function(location){
531                                 var hash = [core.getBaseHash(), "filter", encodeURIComponent(location), encodeURIComponent(tags)].join("/");
532                                 hashListener.setHash(hash);
533                         };
534                         if(core.currentLocation == ""){ //wait for currentLocation to be set;
535                                 core.lt.getCurrentLocation(sethash);
536                         } else {
537                                 sethash(core.currentLocation);
538                         }
539                         return;
540                 }
541
542                 this.handler.load({'dirname' : location, 'tag' : tags});
543         },
544
545         loadNav: function(){
546                 core.lt.getLocationsAndTags(this.showNav.bind(this));
547         },
548
549         showNav: function(currentLocation, locations, tags){
550                 this.navHandler.load(toOptionList(locations, currentLocation), toOptionList(tags, core.currentTag));
551         },
552
553         del: function(element){
554                 this.handler.del(element);
555         }
556 });
557
558 var RemoteControl = Class.create({
559         initialize: function(){
560                 this.handler = new RemoteControlHandler();
561                 this.window = '';
562         },
563
564         open: function(){
565                 if(!this.window)
566                         this.window = '';
567                 if (this.window.closed || !this.window.location){
568                         var tpl;
569                         switch(core.deviceInfo.info.devicename){
570                         case 'dm8000':
571                         case 'dm7020hd':
572                                 tpl = 'tplWebRemote';
573                                 break;
574                         default:
575                                 tpl = 'tplWebRemoteOld';
576                         }
577
578                         templateEngine.fetch(tpl, function(template){
579                                 this.eventsregistered = false;
580                                 this.window = core.popup('WebRemote', template, 250, 600);
581                                 this.registerEvents();
582                         }.bind(this));
583                 }
584         },
585
586         sendKey: function(cmd, type, shotType){
587                 debug("[RemoteControl].sendKey: " + cmd);
588                 this.handler.sendKey({'command' : cmd, 'type': type});
589
590                 var hash = '!/control'; //FIXME
591                 switch(shotType){
592                 case undefined:
593                 case '':
594                         return;
595                 case 'osd':
596                         hash = [hash, 'osdshot'].join("/");
597                         break;
598                 case 'all':
599                         hash = [hash, 'screenshot'].join("/");
600                         break;
601                 }
602                 //the box needs at least a little bit of time to actually draw the window
603                 //wait 250ms before fetching a new screenshot
604                 setTimeout(
605                         function(){
606                                 hashListener.setHash(hash);
607                                 if(hash == hashListener.getHash()){
608                                         core.onHashChanged(true);
609                                 }
610                         },
611                         250);
612         },
613
614         registerEvents:function(){
615                 var _this = this;
616                 var win = this.window;
617                 var elem = win.document;
618
619                 var onload = function(event){
620                         elem.on(
621                                 'click',
622                                 '.remoteKey',
623                                 function(event, element){
624                                         var id = element.readAttribute('data-keyid');
625                                         var long = _this.window.document.getElementById('long').checked;
626                                         var screenshot = _this.window.document.getElementById('screenshot').checked;
627                                         var video = _this.window.document.getElementById('video').checked;
628                                         var type = '';
629                                         if(long){
630                                                 type = 'long';
631                                         }
632                                         var shotType = 'none';
633                                         if(screenshot && video){
634                                                 shotType = 'all';
635                                         } else if (screenshot && !video) {
636                                                 shotType = 'osd';
637                                         }
638                                         _this.sendKey(id, type, shotType);
639                                 }
640                         );
641                 };
642                 if(elem.on){
643                         onload();
644                 } else {
645                         win.onload = onload;
646                 }
647         }
648 });
649
650 var Screenshots = Class.create(Controller, {
651         TYPE_OSD : 'o',
652         TYPE_VIDEO : 'v',
653         TYPE_ALL : '',
654
655         initialize: function($super, target){
656                 $super(new ScreenshotHandler(target));
657         },
658
659         load: function(type){
660                 var filename = '/tmp/' + new Date().getTime();
661                 var params = {'format' : 'jpg', 'r': '720', 'filename' : filename};
662
663                 switch(type){
664                         case this.TYPE_OSD:
665                                 params['o'] = '';
666                                 params['n'] = '';
667                                 params['format'] = 'png';
668                                 break;
669                         case this.TYPE_VIDEO:
670                                 params['v'] = '';
671                                 break;
672                         default:
673                                 break;
674                 }
675                 this.handler.load(params);
676         },
677
678         shootOsd: function(){
679                 setContentHd('Screenshot (OSD)');
680                 this.load(this.TYPE_OSD);
681         },
682
683         shootVideo: function(){
684                 setContentHd('Screenshot (Video)');
685                 this.load(this.TYPE_VIDEO);
686         },
687
688         shootAll: function(){
689                 setContentHd('Screenshot (All)');
690                 this.load(this.TYPE_ALL);
691         }
692 });
693
694 var Services = Class.create(Controller, {
695         initialize: function($super, target, epg){
696                 $super(new ServiceListHandler(target));
697                 this.epg = epg;
698                 this.cachedServiceElements = null;
699         },
700
701         zap: function(sRef, callback){
702                 this.handler.zap({'sRef' : sRef}, callback);
703         },
704
705         load: function(sRef){
706                 this.handler.load({'bRef' : sRef});
707         },
708
709         getNowNext: function(){
710                 this.handler.getNowNext();
711         },
712
713         getSubservices: function(){
714                 this.handler.getSubservices();
715         },
716
717         loadAll: function(ref){
718                 var tpl = 'tplBouquetsAndServices';
719                 var fnc = function(){
720                         $('contentBouquets').update('All Services');
721                         this.load(ref);
722                 }.bind(this);
723
724                 if($('contentBouquets')){
725                         fnc();
726                 } else {
727                         templateEngine.process(
728                                 tpl,
729                                 null,
730                                 'contentMain',
731                                 fnc
732                         );
733                         }
734         },
735
736         loadAllTv: function(){
737                 this.loadAll(allTv);
738                 setContentHd("All (Tv)");
739         },
740
741         loadAllRadio: function(){
742                 this.loadAll(allRadio);
743                 setContentHd("All (Radio)");
744         },
745
746         onFilterFocus: function(event){
747                 event.element().value = '';
748                 this.cachedServiceElements = null;
749                 this.filter(event);
750         },
751
752         filter: function(event){
753                 var needle = event.element().value.toLowerCase();
754
755                 if(this.cachedServiceElements == null){
756                         this.cachedServiceElements = $$('.sListRow');
757                 }
758
759                 for(var i = 0; i < this.cachedServiceElements.length; i++){
760                         var row = this.cachedServiceElements[i];
761                         var serviceName = row.readAttribute('data-servicename').toLowerCase();
762
763                         if(serviceName.match(needle) != needle && serviceName != ""){
764                                 row.hide();
765                         } else {
766                                 row.show();
767                         }
768                 }
769         },
770
771         addFilterInput: function(){
772                 var input = new Element('input');
773                 input.id = 'serviceFilter';
774                 input.value = 'Filter Services';
775                 $('contentHdExt').update(input);
776                 input.on('focus', this.onFilterFocus.bind(this));
777                 input.on('keyup', this.filter.bind(this));
778         },
779
780         onFinished: function(){
781                 this.addFilterInput();
782                 core.startUpdateBouquetItemsPoller();
783         }
784 });
785
786 var SignalWindow = Class.create(Controller, {
787         initialize: function($super, seconds){
788                 $super(new SignalHandler(this.show.bind(this)));
789                 this.window = '';
790                 if(!isNaN(Number(seconds))){
791                         this.seconds = seconds * 1000;
792                 } else {
793                         this.seconds = 5000;
794                 }
795                 this.interval = '';
796         },
797
798         load: function(){
799                 this.handler.load({});
800         },
801
802         reload: function(){
803                 debug('[SignalWindow].reload');
804                 if (!this.window.closed && this.window.location){
805                         this.load();
806                 } else {
807                         clearInterval(this.interval);
808                 }
809         },
810
811         show: function(html){
812                 debug('[SignalWindow].show');
813                 if (this.window.closed || !this.window.location){
814                         this.window = core.popup("SignalPanel", html, 220, 120);
815                         this.window.onbeforeunload = function(){
816                                 clearInterval(this.interval);
817                         };
818
819                         var _this = this;
820                         clearInterval(_this.interval);
821                         this.interval = setInterval(_this.reload.bind(this), _this.seconds);
822                 } else if(!this.window.closed && this.window.location) {
823                         this.window.document.write(html);
824                         this.window.document.close();
825                 }
826         }
827 });
828
829 var SimplePages = Class.create({
830         PAGE_ABOUT : 'tplAbout',
831         PAGE_MESSAGE : 'tplSendMessage',
832         PAGE_POWER : 'tplPower',
833         PAGE_SETTINGS: 'tplSettings',
834         PAGE_TOOLS: 'tplTools',
835
836         initialize: function(target){
837                 this.simpleHandler = new SimplePageHandler(target);
838                 this.deviceInfoHandler = new DeviceInfoHandler(target);
839         },
840
841         show: function(tpl, data){
842                 if(!data)
843                         data = {};
844                 this.simpleHandler.show(tpl, data);
845         },
846
847         loadAbout: function(){
848                 setContentHd('About');
849                 this.show(this.PAGE_ABOUT);
850         },
851
852         loadMessage: function(){
853                 setContentHd('Message');
854                 this.show(this.PAGE_MESSAGE);
855         },
856
857         loadPower: function(){
858                 setContentHd('PowerControl');
859                 this.show(this.PAGE_POWER);
860         },
861
862         loadSettings: function(){
863                 setContentHd('Settings');
864                 var debug = userprefs.data.debug;
865                 var debugChecked = "";
866                 if(debug){
867                         debugChecked = 'checked';
868                 }
869
870                 var updateCurrentInterval = userprefs.data.updateCurrentInterval / 1000;
871                 var updateBouquetInterval = userprefs.data.updateBouquetInterval / 1000;
872
873                 data = {'debug' : debugChecked,
874                                 'updateCurrentInterval' : updateCurrentInterval,
875                                 'updateBouquetInterval' : updateBouquetInterval
876                 };
877                 this.show(this.PAGE_SETTINGS, data);
878         },
879
880         loadTools: function(){
881                 setContentHd('Tools');
882                 this.show(this.PAGE_TOOLS);
883         },
884
885         loadDeviceInfo: function(){
886                 setContentHd('Device Info');
887                 this.deviceInfoHandler.load({});
888         },
889
890         getDeviceInfo: function(callback){
891                 this.deviceInfoHandler.get({}, callback);
892         }
893 });
894
895 var Timers = Class.create({
896         initialize: function(target){
897                 this.listHandler = new TimerListHandler(target);
898                 this.timerHandler = new TimerHandler(target, this.loadList.bind(this), [this.onTimerEditLoadFinished.bind(this)]);
899         },
900
901         loadList: function(){
902                 this.listHandler.load({});
903         },
904
905         cleanupList: function(){
906                 this.listHandler.cleanup();
907         },
908
909         create: function(){
910                 this.timerHandler.load({}, false, true);
911         },
912
913         edit: function(element){
914                 this.timerHandler.load(element, true);
915         },
916
917         editFromEvent: function(element){
918                 this.timerHandler.load(element, false, false, true);
919         },
920
921         save: function(element){
922                 this.timerHandler.commitForm(element);
923         },
924
925         onBouquetChanged: function(bRef){
926                 this.timerHandler.onBouquetChanged(bRef, this.onUpdatedServiceListReady.bind(this));
927         },
928
929         onUpdatedServiceListReady: function(data, timer){
930                 var serviceSel = $('service');
931                 var options = serviceSel.options;
932                 options.length = 0;
933
934                 var i = 0;
935                 data.services.each(function(s){
936                         var selected = false;
937                         if(timer.servicereference == unescape(s.servicereference)){
938                                 selected = true;
939                         }
940                         options.add ( new Option(s.servicename, s.servicereference, false, selected) );
941                         i++;
942                 });
943         },
944
945         recordNow: function(type, callback){
946                 this.timerHandler.recordNow(type, callback);
947         },
948
949         addByEventId: function(element, justplay){
950                 var parent = element.up('.epgListItem');
951                 var sRef = unescape(parent.readAttribute('data-servicereference'));
952                 var eventId = unescape(parent.readAttribute('data-eventid'));
953                 this.timerHandler.addByEventId(sRef, eventId, justplay);
954         },
955
956         toggleDisabled: function(element){
957                 this.timerHandler.toggleDisabled(element);
958         },
959
960         del: function(element){
961                 this.timerHandler.del(element);
962         },
963
964         onTimerEditLoadFinished: function(){
965                 debug("[Timers].onTimerEditLoadFinished");
966                 datePickerController.destroyDatePicker('sdate');
967                 datePickerController.destroyDatePicker('edate');
968                 var today = new Date();
969                 var pad = function(value, length) {
970                         length = length || 2;
971                         return "0000".substr(0,length - Math.min(String(value).length, length)) + value;
972                 };
973                 var opts = {
974                                 showWeeks: true,
975                                 noFadeEffect: true,
976                                 rangeLow: today.getFullYear() + "" + pad(today.getMonth()+1) + pad(today.getDate())
977                         };
978
979
980                 opts['formElements'] = { 'sdate' : 'Y-ds-m-ds-d'};
981                 datePickerController.createDatePicker(opts);
982
983                 opts['formElements'] = { 'edate' : 'Y-ds-m-ds-d'};
984                 datePickerController.createDatePicker(opts);
985
986         }
987 });
988
989 var Volume = Class.create(Controller, {
990         initialize: function($super, target){
991                 $super(new VolumeHandler(target));
992         },
993
994         load: function(){
995                 this.handler.load({});
996         },
997
998         set: function(value){
999                 this.handler.load({'set' : value});
1000         }
1001 });
1002
1003 var E2WebCore = Class.create({
1004         initialize: function(){
1005                 this.mediaPlayerStarted = false;
1006                 this.popUpBlockerHinted = false;
1007                 this.settings = null;
1008                 this.parentControlList = null;
1009
1010                 this.debugWin = '';
1011                 this.signalWin = '';
1012                 this.webRemoteWin = '';
1013                 this.EPGListWin = '';
1014
1015                 this.currentBouquet = bouquetsTv;
1016
1017                 this.updateBouquetItemsPoller = '';
1018                 this.updateCurrentPoller = '';
1019                 this.signalPanelUpdatePoller = '';
1020
1021                 this.hideNotifierTimeout = '';
1022
1023                 this.isActive = {};
1024                 this.isActive.getCurrent = false;
1025
1026                 this.mode = "";
1027                 this.subMode = "";
1028
1029                 //create required Instances
1030                 this.bouquets = new Bouquets('contentBouquets', 'contentMain');
1031                 this.current = new Current('currentContent', 'volContent');
1032                 this.externals = new Externals('navExternalsContainer');
1033                 this.epg = new EPG(new EpgListHandler());
1034                 this.lt = new LocationsAndTags();
1035                 this.mediaplayer = new MediaPlayer('contentMain');
1036                 this.messages = new Messages();
1037                 this.movies = new Movies('contentMain', 'navContent');
1038                 this.multiepg = new MultiEpg();
1039                 this.power = new Power();
1040                 this.remote = new RemoteControl();
1041                 this.screenshots = new Screenshots('contentMain');
1042                 this.services = new Services('contentServices', this.epg);
1043                 this.signal = new SignalWindow(3);
1044                 this.simplepages = new SimplePages('contentMain');
1045                 this.timers = new Timers('contentMain');
1046                 this.volume = new Volume('volContent');
1047
1048                 this.currentData = {};
1049                 this.currentLocation = this.lt.getCurrentLocation(function(location){this.currentLocation = location;}.bind(this));
1050                 this.currentTag = "";
1051                 this.deviceInfo = this.simplepages.getDeviceInfo(function(info){this.deviceInfo = info;}.bind(this));
1052
1053                 this.navlut = {
1054                         'tv': {
1055                                 'bouquets' : this.bouquets.loadBouquetsTv.bind(this.bouquets),
1056                                 'providers' : this.bouquets.loadProviderTv.bind(this.bouquets),
1057                                 'all' : this.services.loadAllTv.bind(this.services)
1058                                 },
1059                         'radio': {
1060                                 'bouquets' : this.bouquets.loadBouquetsRadio.bind(this.bouquets),
1061                                 'providers' : this.bouquets.loadProviderRadio.bind(this.bouquets),
1062                                 'all' : this.services.loadAllRadio.bind(this.services)
1063                         },
1064                         'movies':{
1065                                 'list' : function(){}
1066                         },
1067                         'timer': {
1068                                 'create' : this.timers.create.bind(this.timers),
1069                                 'edit' : false,
1070                                 'list' : function() { this.loadContentDynamic(this.timers.loadList.bind(this.timers), 'Timer'); }.bind(this)
1071                         },
1072                         'control': {
1073                                 'message' : this.simplepages.loadMessage.bind(this.simplepages),
1074                                 'power' : this.simplepages.loadPower.bind(this.simplepages),
1075                                 'osdshot' : this.screenshots.shootOsd.bind(this.screenshots),
1076                                 'screenshot' : this.screenshots.shootAll.bind(this.screenshots),
1077                                 'videoshot' : this.screenshots.shootVideo.bind(this.screenshots)
1078                         },
1079                         'extras': {
1080                                 'about' : this.simplepages.loadAbout.bind(this.simplepages),
1081                                 'deviceinfo' : this.simplepages.loadDeviceInfo.bind(this.simplepages),
1082                                 'mediaplayer' : function() { this.loadContentDynamic(this.mediaplayer.load.bind(this.mediaplayer), 'MediaPlayer'); }.bind(this),
1083                                 'settings' : this.simplepages.loadSettings.bind(this.simplepages),
1084                                 'tools' : this.simplepages.loadTools.bind(this.simplepages)
1085                         }
1086                 };
1087         },
1088
1089         hideNotifier: function(){
1090                 debug("[E2WebCore].hideNotifier");
1091                 $('notification').fadeOut(500);
1092         },
1093
1094         notify: function(text, state){
1095                 debug("[E2WebCore].notify");
1096                 notif = $('notification');
1097                 if(notif !== null){
1098                         //clear possibly existing hideNotifier timeout of a previous notfication
1099                         clearTimeout(this.hideNotifierTimeout);
1100                         if(state === false){
1101                                 notif.style.background = "#C00";
1102                         } else {
1103                                 notif.style.background = "#85C247";
1104                         }
1105                         this.set('notification', "<div>"+text+"</div>");
1106                         notif.fadeIn({'delay' : 500, 'to' : 90});
1107                         var _this = this;
1108                         this.hideNotifierTimeout = setTimeout(_this.hideNotifier.bind(this), 5000);
1109                 }
1110         },
1111
1112         set: function(element, value){
1113                 element = parent.$(element);
1114                 if (element){
1115                         element.update(value);
1116                 }
1117         },
1118
1119         setAjaxLoad: function(targetElement){
1120                 target = $(targetElement);
1121                 if(target != null){
1122                         target.update( getAjaxLoad() );
1123                 }
1124         },
1125
1126         messageBox: function(message){
1127                 alert(message);
1128         },
1129
1130         popUpBlockerHint: function(){
1131                 if(!this.popUpBlockerHinted){
1132                         this.popUpBlockerHinted = true;
1133                         this.messageBox("Please disable your Popup-Blocker for enigma2 WebControl to work flawlessly!");
1134
1135                 }
1136         },
1137
1138         setWindowContent: function(window, html){
1139                 window.document.write(html);
1140                 window.document.close();
1141         },
1142
1143         popup: function(title, html, width, height, x, y){
1144                 try {
1145                         var popup = window.open('about:blank',title,'scrollbars=yes, width='+width+',height='+height);
1146                         this.setWindowContent(popup, html);
1147                         return popup;
1148                 } catch(e){
1149                         this.popUpBlockerHint();
1150                         return "";
1151                 }
1152         },
1153
1154         updateItems: function(){
1155                 debug("[E2WebCore].updateItems");
1156                 this.current.load();
1157                 this.power.inStandby(this.onPowerStateAvailable.bind(this));
1158         },
1159
1160         onPowerStateAvailable: function(isStandby){
1161                 if(isStandby){
1162                         $('openSignalPanelImg').src="/web-data/img/transmit_grey.png";
1163                 } else {
1164                         $('openSignalPanelImg').src="/web-data/img/transmit_blue.png";
1165                 }
1166         },
1167
1168         updateItemsLazy: function(){
1169                 debug("[E2WebCore].updateItemsLazy");
1170                 this.services.getNowNext();
1171                 this.services.getSubservices();
1172         },
1173
1174         startUpdateCurrentPoller: function(){
1175                 debug("[E2WebCore].startUpdateCurrentPoller");
1176                 clearInterval(this.updateCurrentPoller);
1177                 var _this = this;
1178                 this.updateCurrentPoller = setInterval(_this.updateItems.bind(this), userprefs.data.updateCurrentInterval);
1179         },
1180
1181         stopUpdateCurrentPoller: function(){
1182                 clearInterval(this.updateCurrentPoller);
1183         },
1184
1185         startUpdateBouquetItemsPoller: function(){
1186                 debug("[E2WebCore].startUpdateBouquetItemsPoller");
1187                 clearInterval(this.updateBouquetItemsPoller);
1188                 var _this = this;
1189                 this.updateBouquetItemsPoller = setInterval(_this.updateItemsLazy.bind(this), userprefs.data.updateBouquetInterval);
1190         },
1191
1192         stopUpdateBouquetItemsPoller: function(){
1193                 debug("[E2WebCore].stopUpdateBouquetItemsPoller");
1194                 clearInterval(this.updateBouquetItemsPoller);
1195         },
1196
1197         onHashChanged: function(isReload){
1198                 var hash = hashListener.getHash();
1199                 var parts = hash.split("/");
1200
1201                 var len = parts.length;
1202                 if(len >= 2){
1203                         var mode = parts[1];
1204                         if(mode != this.mode || isReload || ( len <= 2 && this.subMode != '') ){
1205                                 this.switchMode(mode, len == 2);
1206                                 this.subMode = '';
1207                         }
1208                         this.mode = mode;
1209                         if(len > 2){
1210                                 var subMode = parts[2];
1211                                 if(subMode != this.subMode || isReload){
1212                                         this.subMode = subMode;
1213                                         if(!this.navlut[this.mode][this.subMode]){
1214                                                 return;
1215                                         } else {
1216                                                 if(this.mode != "movies")
1217                                                         this.navlut[this.mode][this.subMode]();
1218                                         }
1219                                 }
1220                                 if(len > 3){
1221                                         switch(this.mode){
1222                                         case 'tv':
1223                                         case 'radio':
1224                                                 this.services.load(unescape(parts[3]));
1225                                                 break;
1226                                         case 'movies':
1227                                                 var location = decodeURIComponent(parts[4]);
1228                                                 var tag = decodeURIComponent(parts[5]);
1229
1230                                                 this.currentLocation = location;
1231                                                 this.currentTag = tag;
1232                                                 this.loadContentDynamic(
1233                                                         function(){
1234                                                                 this.movies.load(location, tag);
1235                                                         }.bind(this),
1236                                                         'Movies'
1237                                                 );
1238
1239                                                 break;
1240                                         case 'extras':
1241                                                 if(subMode == 'mediaplayer'){
1242                                                         this.mediaplayer.load(decodeURIComponent(parts[3]));
1243                                                 }
1244                                                 break;
1245                                         default:
1246                                                 return;
1247                                         }
1248                                 }
1249                         }
1250                 }
1251         },
1252
1253         getBaseHash: function(){
1254                 var hash = ['#!', this.mode].join("/");
1255                 if(this.subMode != ''){
1256                         hash = [hash, this.subMode].join("/");
1257                 }
1258                 return hash;
1259         },
1260
1261         loadDefault: function(){
1262                 debug("[E2WebCore].loadDefault");
1263                 this.switchMode('tv');
1264                 this.mode = 'tv';
1265                 this.subMode = 'bouquets';
1266                 this.bouquets.load(bouquetsTv, true);
1267         },
1268
1269         run: function(){
1270                 debug("[E2WebCore].run");
1271                 if( parseNr(userprefs.data.updateCurrentInterval) < 10000){
1272                         userprefs.data.updateCurrentInterval = 120000;
1273                         userprefs.save();
1274                 }
1275
1276                 if( parseNr(userprefs.data.updateBouquetInterval) < 60000 ){
1277                         userprefs.data.updateBouquetInterval = 300000;
1278                         userprefs.save();
1279                 }
1280
1281                 if (typeof document.body.style.maxHeight == undefined) {
1282                         alert("Due to the tremendous amount of work needed to get everthing to " +
1283                         "work properly, there is (for now) no support for Internet Explorer Versions below 7");
1284                 }
1285                 hashListener.onHashChanged = this.onHashChanged.bind(this);
1286                 hashListener.init();
1287
1288                 this.registerEvents();
1289
1290                 this.setAjaxLoad('navContent');
1291                 this.setAjaxLoad('contentMain');
1292
1293                 templateEngine.fetch('tplServiceListEPGItem');
1294                 templateEngine.fetch('tplBouquetsAndServices');
1295                 templateEngine.fetch('tplCurrent');
1296                 if(!hashListener.getHash().length >= 1){
1297                         this.loadDefault();
1298                 }
1299                 this.updateItems();
1300                 this.startUpdateCurrentPoller();
1301         },
1302
1303         registerEvents: function(){
1304                 debug("[E2WebCore].registerEvents");
1305                 //Hash-Reload-Fix
1306                 //HACK :: THIS IS EVIL VOODOO, DON'T TRY THIS AT HOME!
1307                 document.on(
1308                         'click',
1309                         'a',
1310                         function(event, element){
1311                                 var parts = element.href.split('#');
1312                                 var curHost = window.location.href.split('#')[0];
1313                                 //Don't do this crazy stuff when the target is another host!
1314                                 if(curHost == parts[0]){
1315                                         if (parts.length > 1){
1316                                                 if(parts[1] != ''){
1317                                                         if(window.location == element.href){
1318                                                                 this.onHashChanged(true);
1319                                                                 return;
1320                                                         }else{
1321                                                                 window.location == element.href;
1322                                                                 return;
1323                                                         }
1324                                                 } else {
1325                                                         element.href = window.location;
1326                                                 }
1327                                                 return false;
1328                                         }
1329                                 }
1330                         }.bind(this)
1331                 );
1332                 //Header
1333                 $('openSignalPanel').on(
1334                         'click',
1335                         function(event, element){
1336                                 this.signal.load();
1337                                 event.stop();
1338                         }.bind(this)
1339                 );
1340                 $('instantRecord').on(
1341                         'click',
1342                         function(event, element){
1343                                 var menu = $('instantRecordMenu');
1344                                 if(menu.visible()){
1345                                         menu.hide();
1346                                 } else {
1347                                         menu.show();
1348                                 }
1349                                 event.stop();
1350                         }
1351                 );
1352                 document.on(
1353                         'click',
1354                         '.doInstantRecord',
1355                         function(event, element){
1356                                 var menu = $('instantRecordMenu');
1357                                 this.timers.recordNow(
1358                                         element.readAttribute('data-type'),
1359                                         function(result){
1360                                                 menu.hide();
1361                                         }
1362                                 );
1363                         }.bind(this)
1364                 );
1365                 //Current
1366                 $('current').on(
1367                         'click',
1368                         '.currentExtShowHide',
1369                         function(event, element){
1370                                 this.current.toggleVisibility(element);
1371                                 event.stop();
1372                         }.bind(this)
1373                 );
1374                 $('current').on(
1375                                 'click',
1376                                 '.currentEpg',
1377                                 function(event, element){
1378                                         var ref = unescape( element.readAttribute('data-servicereference') );
1379                                         this.epg.load(ref);
1380                                         event.stop();
1381                                 }.bind(this)
1382                         );
1383                 //EPG-Search
1384                 $('epgSearchForm').on(
1385                         'submit',
1386                         function(event, element){
1387                                 this.epg.search($F('epgSearch'));
1388                                 event.stop();
1389                         }.bind(this)
1390                 );
1391                 $('epgSearch').on(
1392                         'focus',
1393                         function(event, element){
1394                                 element.value = "";
1395                         }.bind(this)
1396                 );
1397                 $('epgSearchClear').on(
1398                                 'click',
1399                                 function(event, element){
1400                                         $('epgSearch').value = '';
1401                                         return false;
1402                                 }.bind(this)
1403                 );
1404                 //Movienav
1405                 var changeevt = Prototype.Browser.IE ? "click" : "change";
1406                 var nav = $('navContent');
1407                 nav.on(
1408                         changeevt,
1409                         '.mNavLocTag',
1410                         function(event, element){
1411                                 var l = $('locations');
1412                                 var t = $('tags');
1413                                 var location = l.options[l.selectedIndex].value;
1414                                 var tag = t.options[t.selectedIndex].value;
1415                                 var hash = [this.getBaseHash(), "filter", encodeURIComponent(location), encodeURIComponent(tag)].join("/");
1416                                 if(hash != '#'+hashListener.getHash() || !Prototype.Browser.IE)
1417                                         hashListener.setHash(hash);
1418                         }.bind(this)
1419                 );
1420                 //RemoteControl
1421                 nav.on(
1422                         'click',
1423                         '.webremote',
1424                         this.remote.open.bind(this.remote)
1425                 );
1426                 //Volume
1427                 $('navVolume').on(
1428                         'click',
1429                         'a.volume',
1430                         function(event, element){
1431                                 this.volume.set(element.readAttribute('data-volume'));
1432                                 return false;
1433                         }.bind(this)
1434                 );
1435
1436                 //Content
1437                 var content = $('contentMain');
1438                 //MediaPlayer
1439                 content.on(
1440                         'click',
1441                         '.mpCmd',
1442                         function(event, element){
1443                                 this.mediaplayer.command(element.readAttribute('data-command'));
1444                         }.bind(this)
1445                 );
1446                 content.on(
1447                         'click',
1448                         '.mpPlayFile',
1449                         function(event, element){
1450                                 var parent = element.up('.mpListItem');
1451                                 var ref = decodeURIComponent( parent.readAttribute('data-servicereference') );
1452                                 this.mediaplayer.playFile(ref);
1453                                 event.stop();
1454                         }.bind(this)
1455                 );
1456                 content.on(
1457                                 'click',
1458                                 '.mpAddFile',
1459                                 function(event, element){
1460                                         var parent = element.up('.mpListItem');
1461                                         var ref = decodeURIComponent( parent.readAttribute('data-servicereference') );
1462                                         this.mediaplayer.addFile(ref);
1463                                         event.stop();
1464                                 }.bind(this)
1465                         );
1466                 content.on(
1467                         'click',
1468                         '.mpRemoveFile',
1469                         function(event, element){
1470                                 var parent = element.up('.mpListItem');
1471                                 var ref = decodeURIComponent( parent.readAttribute('data-servicereference') );
1472                                 this.mediaplayer.removeFile(ref);
1473                                 event.stop();
1474                         }.bind(this)
1475                 );
1476                 content.on(
1477                                 'click',
1478                                 '.mpSavePlaylist',
1479                                 function(event, element){
1480                                         var filename = prompt('Please enter a filename for the playlist', 'playlist');
1481                                         if(filename != null && filename != ""){
1482                                                 this.mediaplayer.savePlaylist(filename);
1483                                         }
1484                                 }.bind(this)
1485                         );
1486                 //Message
1487                 content.on(
1488                         'click',
1489                         '.messageSend',
1490                         function(event, element){
1491                                 var t = $('messageType');
1492                                 text = $('messageText').value;
1493                                 timeout = $('messageTimeout').value;
1494                                 type = t.options[t.selectedIndex].value;
1495                                 this.messages.send(text, type, timeout);
1496                         }.bind(this)
1497                 );
1498                 //Movielist
1499                 content.on(
1500                         'click',
1501                         'a.mListDelete',
1502                         function(event, element){
1503                                 this.movies.del(element);
1504                                 event.stop();
1505                         }.bind(this)
1506                 );
1507                 //Powerstate
1508                 content.on(
1509                         'click',
1510                         '.powerState',
1511                         function(event, element){
1512                                 var cb = function(isStandby){
1513                                         var text = "Device is now Running";
1514                                         if(isStandby)
1515                                                 text = "Device is now in Standby";
1516                                         this.notify(text, true);
1517                                         this.onPowerStateAvailable(isStandby);
1518                                 }.bind(this);
1519                                 this.power.set(element.readAttribute("data-state"), cb);
1520                         }.bind(this)
1521                 );
1522                 //Settings
1523                 content.on(
1524                         'click',
1525                         '.saveSettings',
1526                         function(event, element){
1527                                 this.saveSettings();
1528                         }.bind(this)
1529                 );
1530                 //Bouquets
1531                 content.on(
1532                         'click',
1533                         'a.bListSLink',
1534                         function(event, element){
1535                                 setContentHd(element.readAttribute("data-servicename"));
1536                         }
1537                 );
1538                 content.on(
1539                         'click',
1540                         'a.bListEpg',
1541                         function(event, element){
1542                                 var sref = decodeURIComponent( element.readAttribute("data-servicereference") );
1543                                 this.multiepg.load(sref);
1544                                 event.stop();
1545                         }.bind(this)
1546                 );
1547
1548                 //Servicelist
1549                 content.on(
1550                         'click',
1551                         'a.sListSLink',
1552                         function(event, element){
1553                                 var ref = decodeURIComponent( element.id );
1554                                 this.services.zap(ref, this.updateItems.bind(this));
1555                                 event.stop();
1556                         }.bind(this)
1557                 );
1558                 content.on(
1559                         'click',
1560                         'a.sListServiceEpg',
1561                         function(event, element){
1562                                 var ref = unescape( element.readAttribute('data-servicereference') );
1563                                 this.epg.load(ref);
1564                                 event.stop();
1565                         }.bind(this)
1566                 );
1567                 content.on(
1568                         'click',
1569                         'a.sListExtEpg',
1570                         function(event, element){
1571                                 var target = element.up('.sListEPGItem').down('.sListExtEpgLong');
1572
1573                                 if(target){
1574                                         var bullet = element.down('.sListBulletToggle');
1575                                         if(target.visible()){
1576                                                 target.hide();
1577                                                 bullet.src = "/web-data/img/toggle_expand_small.png";
1578                                                 bullet.alt = "+";
1579                                         } else {
1580                                                 target.show();
1581                                                 bullet.src = "/web-data/img/toggle_collapse_small.png";
1582                                                 bullet.alt = "-";
1583                                         }
1584                                 }
1585                                 event.stop();
1586                         }.bind(this)
1587                 );
1588                 content.on(
1589                         'click',
1590                         '.sListAddTimer',
1591                         function(event, element){
1592                                 core.timers.addByEventId(element, 0);
1593                                 event.stop();
1594                         }
1595                 );
1596                 content.on(
1597                         'click',
1598                         '.sListZapTimer',
1599                         function(event, element){
1600                                 core.timers.addByEventId(element, 1);
1601                                 event.stop();
1602                         }
1603                 );
1604                 content.on(
1605                         'click',
1606                         '.sListEditTimer',
1607                         function(event, element){
1608                                 var hash = ["#!/timer", "edit"].join("/");
1609                                 hashListener.setHash(hash);
1610                                 core.timers.editFromEvent(element);
1611                                 event.stop();
1612                         }
1613                 );
1614
1615                 //Timerlist
1616                 content.on(
1617                         'click',
1618                         '.tListDelete',
1619                         function(event, element){
1620                                 this.timers.del(element);
1621                                 event.stop();
1622                         }.bind(this)
1623                 );
1624                 content.on(
1625                         'click',
1626                         '.tListToggleDisabled',
1627                         function(event, element){
1628                                 this.timers.toggleDisabled(element);
1629                                 event.stop();
1630                         }.bind(this)
1631                 );
1632                 content.on(
1633                         'click',
1634                         '.tListEdit',
1635                         function(event, element){
1636                                 var hash = ["#!/timer", "edit"].join("/");
1637                                 hashListener.setHash(hash);
1638                                 this.timers.edit(element);
1639                                 return false;
1640                         }.bind(this)
1641                 );
1642                 content.on(
1643                         'click',
1644                         '.tListCleanup',
1645                         function(event, element){
1646                                 this.timers.cleanupList();
1647                                 return false;
1648                         }.bind(this)
1649                 );
1650                 //Timer Editing
1651                 content.on(
1652                         'change',
1653                         '.tEditRepeated',
1654                         function(event, element){
1655                                 var days = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'];
1656                                 var weekdays = days.slice(0,5);
1657
1658                                 switch(element.id){
1659                                 case 'mf':
1660                                         var checked = element.checked;
1661                                         weekdays.each(function(day){
1662                                                 $(day).checked = checked;
1663                                         });
1664                                         if(checked){
1665                                                 var others = ['sa', 'su', 'ms'];
1666                                                 others.each(function(item){
1667                                                         $(item).checked = false;
1668                                                 });
1669                                         }
1670                                         break;
1671                                 case 'ms':
1672                                         var checked = element.checked;
1673                                         days.each(function(day){
1674                                                 $(day).checked = checked;
1675                                         });
1676                                         if(checked){
1677                                                 $('mf').checked = false;
1678                                         }
1679                                         break;
1680                                 default:
1681                                         var weekdays = true;
1682                                         var alldays = true;
1683                                         days.each(function(day){
1684                                                 day = $(day);
1685                                                 if(day.value <= 64){
1686                                                         if(!day.checked){
1687                                                                 alldays = false;
1688                                                                 if(day.value <= 16){
1689                                                                         weekdays = false;
1690                                                                         return
1691                                                                 }
1692                                                         } else {
1693                                                                 if(day.value > 16){
1694                                                                         weekdays = false;
1695                                                                 }
1696                                                         }
1697                                                 }
1698                                         });
1699                                         if(alldays){
1700                                                 $('mf').checked = false;
1701                                                 $('ms').checked = true;
1702                                         } else if (weekdays) {
1703                                                 $('mf').checked = true;
1704                                                 $('ms').checked = false;
1705                                         } else {
1706                                                 $('mf').checked = false;
1707                                                 $('ms').checked = false;
1708                                         }
1709                                 }
1710                         }
1711                 );
1712                 content.on(
1713                         'change',
1714                         '.tEditBouquet',
1715                         function(event, element){
1716                                 var value = unescape( element.options[element.selectedIndex].value );
1717                                 core.timers.onBouquetChanged(value);
1718                         }.bind(this)
1719                 );
1720                 content.on(
1721                         'click',
1722                         '.tEditTag',
1723                         function(event, element){
1724                                 var selected = 'selected';
1725                                 var attr = 'data-selected';
1726                                 if(element.hasClassName(selected)){
1727                                         element.removeClassName(selected);
1728                                         element.writeAttribute(attr, '');
1729                                 } else {
1730                                         element.addClassName(selected);
1731                                         element.writeAttribute(attr, selected);
1732                                 }
1733                                 event.stop();
1734                         }.bind(this)
1735                 );
1736                 content.on(
1737                         'click',
1738                         '.tEditSave',
1739                         function(event, element){
1740                                 this.timers.save($('timerEditForm'));
1741                         }.bind(this)
1742                 );
1743
1744                 $('webTv').on(
1745                         'click',
1746                         function(event, element){
1747                                 window.open('/web-data/tpl/default/streaminterface/index.html', 'WebTV', 'scrollbars=no, width=800, height=740');
1748                                 event.stop();
1749                         }.bind(this)
1750                 );
1751         },
1752
1753         /*
1754          * Loads another navigation template and sets the navigation header
1755          * @param template - The name of the template
1756          * @param title - The title to set for the navigation
1757          */
1758         reloadNav: function(template, title, callback){
1759                 this.setAjaxLoad('navContent');
1760                 templateEngine.process(template, null, 'navContent', callback);
1761                 setNavHd(title);
1762         },
1763
1764         reloadNavDynamic: function(fnc, title){
1765                 this.setAjaxLoad('navContent');
1766                 setNavHd(title);
1767                 fnc();
1768         },
1769
1770         /*
1771          * Loads dynamic content to $(contentMain) by calling a execution function
1772          * @param fnc - The function used to load the content
1773          * @param title - The Title to set on the contentpanel
1774          */
1775         loadContentDynamic: function(fnc, title){
1776                 setContentHd(title);
1777                 this.stopUpdateBouquetItemsPoller();
1778                 fnc();
1779         },
1780
1781         /*
1782          * Loads a static template to $(contentMain)
1783          * @param template - Name of the Template
1784          * @param title - The Title to set on the Content-Panel
1785          */
1786         loadContentStatic: function(template, title){
1787                 this.setAjaxLoad('contentMain');
1788                 setContentHd(title);
1789                 this.stopUpdateBouquetItemsPoller();
1790                 templateEngine.process(template, null, 'contentMain');
1791         },
1792
1793         setEmptyContent: function(id, text){
1794                 $(id).update('<div class="block center fullwidth oneliner">' + text + '</div>');
1795         },
1796
1797         switchMode: function(mode, initContent){
1798                 if(initContent){
1799                         this.setEmptyContent('contentMain', 'please select a submenu on the left...');
1800                         setContentHd('...');
1801                 }
1802
1803                 switch(mode){
1804                 case "tv":
1805                         if(this.mode != 'tv' && this.mode != 'radio'){
1806                                 this.services.registerEvents();
1807                         }
1808                         this.reloadNav('tplNavTv', 'TeleVision');
1809                         break;
1810
1811                 case "radio":
1812                         if(this.mode != 'TV' && this.mode != 'Radio'){
1813                                 this.services.registerEvents();
1814                         }
1815                         this.reloadNav('tplNavRadio', 'Radio');
1816                         break;
1817
1818                 case "movies":
1819                         this.reloadNavDynamic(this.movies.loadNav.bind(this.movies), 'Movies');
1820                         break;
1821
1822                 case "timer":
1823                         this.reloadNav('tplNavTimer', 'Timer');
1824                         break;
1825
1826                 case "control":
1827                         this.reloadNav('tplNavBoxControl', 'BoxControl');
1828                         break;
1829
1830                 case "extras":
1831                         this.reloadNav('tplNavExtras', 'Extras', this.externals.load.bind(this.externals));
1832                         break;
1833
1834                 default:
1835                         break;
1836                 }
1837         },
1838
1839         saveSettings: function(){
1840                 userprefs.load();
1841
1842                 var debug = $('enableDebug').checked;
1843                 var changed = false;
1844                 if(debug != undefined){
1845                         if( userprefs.data.debug != debug ){
1846                                 userprefs.data.debug = debug;
1847                                 changed = true;
1848                         }
1849                 }
1850
1851                 var updateCurrentInterval = parseNr( $F('updateCurrentInterval') ) * 1000;
1852                 if( updateCurrentInterval < 10000){
1853                         updateCurrentInterval = 120000;
1854                 }
1855
1856                 if( userprefs.data.updateCurrentInterval != updateCurrentInterval){
1857                         userprefs.data.updateCurrentInterval = updateCurrentInterval;
1858
1859                         changed = true;
1860                         this.startUpdateCurrentPoller();
1861                 }
1862
1863                 var updateBouquetInterval = parseNr( $F('updateBouquetInterval') ) * 1000;
1864                 if( updateBouquetInterval < 60000){
1865                         updateBouquetInterval = 300000;
1866                 }
1867
1868                 if( userprefs.data.updateBouquetInterval != updateBouquetInterval){
1869                         userprefs.data.updateBouquetInterval = updateBouquetInterval;
1870
1871                         changed = true;
1872                         this.startUpdateBouquetItemsPoller();
1873                 }
1874
1875                 if(changed){
1876                         userprefs.save();
1877                         this.notify("Settings saved");
1878                 } else {
1879                         this.notify("Nothing changed! No need to save!");
1880                 }
1881         }
1882 });
1883 core = new E2WebCore();