WebIf - Movies: Move location selection to the right of the content header to avoid...
[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, locTarget){
524                 $super(new MovieListHandler(listTarget));
525                 this.navHandler = new MovieNavHandler(navTarget, locTarget);
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                 var cls = 'even';
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                                 cls = cls == 'odd' ? 'even' : 'odd';
767                                 notCls = cls == 'odd' ? 'even' : 'odd';
768
769                                 var td = row.firstDescendant();
770                                 td.removeClassName(notCls);
771                                 td.addClassName(cls);
772
773                                 row.show();
774                         }
775                 }
776         },
777
778         addFilterInput: function(){
779                 var input = new Element('input');
780                 input.id = 'serviceFilter';
781                 input.value = 'Filter Services';
782                 $('contentHdExt').update(input);
783                 input.on('focus', this.onFilterFocus.bind(this));
784                 input.on('keyup', this.filter.bind(this));
785         },
786
787         onFinished: function(){
788                 this.addFilterInput();
789                 core.startUpdateBouquetItemsPoller();
790         }
791 });
792
793 var SignalWindow = Class.create(Controller, {
794         initialize: function($super, seconds){
795                 $super(new SignalHandler(this.show.bind(this)));
796                 this.window = '';
797                 if(!isNaN(Number(seconds))){
798                         this.seconds = seconds * 1000;
799                 } else {
800                         this.seconds = 5000;
801                 }
802                 this.interval = '';
803         },
804
805         load: function(){
806                 this.handler.load({});
807         },
808
809         reload: function(){
810                 debug('[SignalWindow].reload');
811                 if (!this.window.closed && this.window.location){
812                         this.load();
813                 } else {
814                         clearInterval(this.interval);
815                 }
816         },
817
818         show: function(html){
819                 debug('[SignalWindow].show');
820                 if (this.window.closed || !this.window.location){
821                         this.window = core.popup("SignalPanel", html, 220, 120);
822                         this.window.onbeforeunload = function(){
823                                 clearInterval(this.interval);
824                         };
825
826                         var _this = this;
827                         clearInterval(_this.interval);
828                         this.interval = setInterval(_this.reload.bind(this), _this.seconds);
829                 } else if(!this.window.closed && this.window.location) {
830                         this.window.document.write(html);
831                         this.window.document.close();
832                 }
833         }
834 });
835
836 var SimplePages = Class.create({
837         PAGE_ABOUT : 'tplAbout',
838         PAGE_MESSAGE : 'tplSendMessage',
839         PAGE_POWER : 'tplPower',
840         PAGE_SETTINGS: 'tplSettings',
841         PAGE_TOOLS: 'tplTools',
842
843         initialize: function(target){
844                 this.simpleHandler = new SimplePageHandler(target);
845                 this.deviceInfoHandler = new DeviceInfoHandler(target);
846         },
847
848         show: function(tpl, data){
849                 if(!data)
850                         data = {};
851                 this.simpleHandler.show(tpl, data);
852         },
853
854         loadAbout: function(){
855                 setContentHd('About');
856                 this.show(this.PAGE_ABOUT);
857         },
858
859         loadMessage: function(){
860                 setContentHd('Message');
861                 this.show(this.PAGE_MESSAGE);
862         },
863
864         loadPower: function(){
865                 setContentHd('PowerControl');
866                 this.show(this.PAGE_POWER);
867         },
868
869         loadSettings: function(){
870                 setContentHd('Settings');
871                 var debug = userprefs.data.debug;
872                 var debugChecked = "";
873                 if(debug){
874                         debugChecked = 'checked';
875                 }
876
877                 var updateCurrentInterval = userprefs.data.updateCurrentInterval / 1000;
878                 var updateBouquetInterval = userprefs.data.updateBouquetInterval / 1000;
879
880                 data = {'debug' : debugChecked,
881                                 'updateCurrentInterval' : updateCurrentInterval,
882                                 'updateBouquetInterval' : updateBouquetInterval
883                 };
884                 this.show(this.PAGE_SETTINGS, data);
885         },
886
887         loadTools: function(){
888                 setContentHd('Tools');
889                 this.show(this.PAGE_TOOLS);
890         },
891
892         loadDeviceInfo: function(){
893                 setContentHd('Device Info');
894                 this.deviceInfoHandler.load({});
895         },
896
897         getDeviceInfo: function(callback){
898                 this.deviceInfoHandler.get({}, callback);
899         }
900 });
901
902 var Timers = Class.create({
903         initialize: function(target){
904                 this.listHandler = new TimerListHandler(target);
905                 this.timerHandler = new TimerHandler(target, this.loadList.bind(this), [this.onTimerEditLoadFinished.bind(this)]);
906         },
907
908         loadList: function(){
909                 this.listHandler.load({});
910         },
911
912         cleanupList: function(){
913                 this.listHandler.cleanup();
914         },
915
916         create: function(){
917                 this.timerHandler.load({}, false, true);
918         },
919
920         edit: function(element){
921                 this.timerHandler.load(element, true);
922         },
923
924         editFromEvent: function(element){
925                 this.timerHandler.load(element, false, false, true);
926         },
927
928         save: function(element){
929                 this.timerHandler.commitForm(element);
930         },
931
932         onBouquetChanged: function(bRef){
933                 this.timerHandler.onBouquetChanged(bRef, this.onUpdatedServiceListReady.bind(this));
934         },
935
936         onUpdatedServiceListReady: function(data, timer){
937                 var serviceSel = $('service');
938                 var options = serviceSel.options;
939                 options.length = 0;
940
941                 var i = 0;
942                 data.services.each(function(s){
943                         var selected = false;
944                         if(timer.servicereference == unescape(s.servicereference)){
945                                 selected = true;
946                         }
947                         options.add ( new Option(s.servicename, s.servicereference, false, selected) );
948                         i++;
949                 });
950         },
951
952         recordNow: function(type, callback){
953                 this.timerHandler.recordNow(type, callback);
954         },
955
956         addByEventId: function(element, justplay){
957                 var parent = element.up('.epgListItem');
958                 var sRef = unescape(parent.readAttribute('data-servicereference'));
959                 var eventId = unescape(parent.readAttribute('data-eventid'));
960                 this.timerHandler.addByEventId(sRef, eventId, justplay);
961         },
962
963         toggleDisabled: function(element){
964                 this.timerHandler.toggleDisabled(element);
965         },
966
967         del: function(element){
968                 this.timerHandler.del(element);
969         },
970
971         onTimerEditLoadFinished: function(){
972                 debug("[Timers].onTimerEditLoadFinished");
973                 datePickerController.destroyDatePicker('sdate');
974                 datePickerController.destroyDatePicker('edate');
975                 var today = new Date();
976                 var pad = function(value, length) {
977                         length = length || 2;
978                         return "0000".substr(0,length - Math.min(String(value).length, length)) + value;
979                 };
980                 var opts = {
981                                 showWeeks: true,
982                                 noFadeEffect: true,
983                                 rangeLow: today.getFullYear() + "" + pad(today.getMonth()+1) + pad(today.getDate())
984                         };
985
986
987                 opts['formElements'] = { 'sdate' : 'Y-ds-m-ds-d'};
988                 datePickerController.createDatePicker(opts);
989
990                 opts['formElements'] = { 'edate' : 'Y-ds-m-ds-d'};
991                 datePickerController.createDatePicker(opts);
992
993         }
994 });
995
996 var Volume = Class.create(Controller, {
997         initialize: function($super, target){
998                 $super(new VolumeHandler(target));
999         },
1000
1001         load: function(){
1002                 this.handler.load({});
1003         },
1004
1005         set: function(value){
1006                 this.handler.load({'set' : value});
1007         }
1008 });
1009
1010 var E2WebCore = Class.create({
1011         initialize: function(){
1012                 this.mediaPlayerStarted = false;
1013                 this.popUpBlockerHinted = false;
1014                 this.settings = null;
1015                 this.parentControlList = null;
1016
1017                 this.debugWin = '';
1018                 this.signalWin = '';
1019                 this.webRemoteWin = '';
1020                 this.EPGListWin = '';
1021
1022                 this.currentBouquet = bouquetsTv;
1023
1024                 this.updateBouquetItemsPoller = '';
1025                 this.updateCurrentPoller = '';
1026                 this.signalPanelUpdatePoller = '';
1027
1028                 this.hideNotifierTimeout = '';
1029
1030                 this.isActive = {};
1031                 this.isActive.getCurrent = false;
1032
1033                 this.mode = "";
1034                 this.subMode = "";
1035
1036                 //create required Instances
1037                 this.bouquets = new Bouquets('contentBouquets', 'contentMain');
1038                 this.current = new Current('currentContent', 'volContent');
1039                 this.externals = new Externals('navExternalsContainer');
1040                 this.epg = new EPG(new EpgListHandler());
1041                 this.lt = new LocationsAndTags();
1042                 this.mediaplayer = new MediaPlayer('contentMain');
1043                 this.messages = new Messages();
1044                 this.movies = new Movies('contentMain', 'navContent', 'contentHdExt');
1045                 this.multiepg = new MultiEpg();
1046                 this.power = new Power();
1047                 this.remote = new RemoteControl();
1048                 this.screenshots = new Screenshots('contentMain');
1049                 this.services = new Services('contentServices', this.epg);
1050                 this.signal = new SignalWindow(3);
1051                 this.simplepages = new SimplePages('contentMain');
1052                 this.timers = new Timers('contentMain');
1053                 this.volume = new Volume('volContent');
1054
1055                 this.currentData = {};
1056                 this.currentLocation = this.lt.getCurrentLocation(function(location){this.currentLocation = location;}.bind(this));
1057                 this.currentTag = "";
1058                 this.deviceInfo = this.simplepages.getDeviceInfo(function(info){this.deviceInfo = info;}.bind(this));
1059
1060                 this.navlut = {
1061                         'tv': {
1062                                 'bouquets' : this.bouquets.loadBouquetsTv.bind(this.bouquets),
1063                                 'providers' : this.bouquets.loadProviderTv.bind(this.bouquets),
1064                                 'all' : this.services.loadAllTv.bind(this.services)
1065                                 },
1066                         'radio': {
1067                                 'bouquets' : this.bouquets.loadBouquetsRadio.bind(this.bouquets),
1068                                 'providers' : this.bouquets.loadProviderRadio.bind(this.bouquets),
1069                                 'all' : this.services.loadAllRadio.bind(this.services)
1070                         },
1071                         'movies':{
1072                                 'list' : function(){}
1073                         },
1074                         'timer': {
1075                                 'create' : this.timers.create.bind(this.timers),
1076                                 'edit' : false,
1077                                 'list' : function() { this.loadContentDynamic(this.timers.loadList.bind(this.timers), 'Timer'); }.bind(this)
1078                         },
1079                         'control': {
1080                                 'message' : this.simplepages.loadMessage.bind(this.simplepages),
1081                                 'power' : this.simplepages.loadPower.bind(this.simplepages),
1082                                 'osdshot' : this.screenshots.shootOsd.bind(this.screenshots),
1083                                 'screenshot' : this.screenshots.shootAll.bind(this.screenshots),
1084                                 'videoshot' : this.screenshots.shootVideo.bind(this.screenshots)
1085                         },
1086                         'extras': {
1087                                 'about' : this.simplepages.loadAbout.bind(this.simplepages),
1088                                 'deviceinfo' : this.simplepages.loadDeviceInfo.bind(this.simplepages),
1089                                 'mediaplayer' : function() { this.loadContentDynamic(this.mediaplayer.load.bind(this.mediaplayer), 'MediaPlayer'); }.bind(this),
1090                                 'settings' : this.simplepages.loadSettings.bind(this.simplepages),
1091                                 'tools' : this.simplepages.loadTools.bind(this.simplepages)
1092                         }
1093                 };
1094         },
1095
1096         hideNotifier: function(){
1097                 debug("[E2WebCore].hideNotifier");
1098                 $('notification').fadeOut(500);
1099         },
1100
1101         notify: function(text, state){
1102                 debug("[E2WebCore].notify");
1103                 notif = $('notification');
1104                 if(notif !== null){
1105                         //clear possibly existing hideNotifier timeout of a previous notfication
1106                         clearTimeout(this.hideNotifierTimeout);
1107                         if(state === false){
1108                                 notif.style.background = "#C00";
1109                         } else {
1110                                 notif.style.background = "#85C247";
1111                         }
1112                         this.set('notification', "<div>"+text+"</div>");
1113                         notif.fadeIn({'delay' : 500, 'to' : 90});
1114                         var _this = this;
1115                         this.hideNotifierTimeout = setTimeout(_this.hideNotifier.bind(this), 5000);
1116                 }
1117         },
1118
1119         set: function(element, value){
1120                 element = parent.$(element);
1121                 if (element){
1122                         element.update(value);
1123                 }
1124         },
1125
1126         setAjaxLoad: function(targetElement){
1127                 target = $(targetElement);
1128                 if(target != null){
1129                         target.update( getAjaxLoad() );
1130                 }
1131         },
1132
1133         messageBox: function(message){
1134                 alert(message);
1135         },
1136
1137         popUpBlockerHint: function(){
1138                 if(!this.popUpBlockerHinted){
1139                         this.popUpBlockerHinted = true;
1140                         this.messageBox("Please disable your Popup-Blocker for enigma2 WebControl to work flawlessly!");
1141
1142                 }
1143         },
1144
1145         setWindowContent: function(window, html){
1146                 window.document.write(html);
1147                 window.document.close();
1148         },
1149
1150         popup: function(title, html, width, height, x, y){
1151                 try {
1152                         var popup = window.open('about:blank',title,'scrollbars=yes, width='+width+',height='+height);
1153                         this.setWindowContent(popup, html);
1154                         return popup;
1155                 } catch(e){
1156                         this.popUpBlockerHint();
1157                         return "";
1158                 }
1159         },
1160
1161         delayedUpdateItems: function(){
1162                 var _this = this;
1163                 setTimeout(_this.updateItems.bind(this), 2000);
1164         },
1165
1166         updateItems: function(){
1167                 debug("[E2WebCore].updateItems");
1168                 this.current.load();
1169                 this.power.inStandby(this.onPowerStateAvailable.bind(this));
1170         },
1171
1172         onPowerStateAvailable: function(isStandby){
1173                 if(isStandby){
1174                         $('openSignalPanelImg').src="/web-data/img/transmit_grey.png";
1175                 } else {
1176                         $('openSignalPanelImg').src="/web-data/img/transmit_blue.png";
1177                 }
1178         },
1179
1180         updateItemsLazy: function(){
1181                 debug("[E2WebCore].updateItemsLazy");
1182                 this.services.getNowNext();
1183                 this.services.getSubservices();
1184         },
1185
1186         startUpdateCurrentPoller: function(){
1187                 debug("[E2WebCore].startUpdateCurrentPoller");
1188                 clearInterval(this.updateCurrentPoller);
1189                 var _this = this;
1190                 this.updateCurrentPoller = setInterval(_this.updateItems.bind(this), userprefs.data.updateCurrentInterval);
1191         },
1192
1193         stopUpdateCurrentPoller: function(){
1194                 clearInterval(this.updateCurrentPoller);
1195         },
1196
1197         startUpdateBouquetItemsPoller: function(){
1198                 debug("[E2WebCore].startUpdateBouquetItemsPoller");
1199                 clearInterval(this.updateBouquetItemsPoller);
1200                 var _this = this;
1201                 this.updateBouquetItemsPoller = setInterval(_this.updateItemsLazy.bind(this), userprefs.data.updateBouquetInterval);
1202         },
1203
1204         stopUpdateBouquetItemsPoller: function(){
1205                 debug("[E2WebCore].stopUpdateBouquetItemsPoller");
1206                 clearInterval(this.updateBouquetItemsPoller);
1207         },
1208
1209         setNavHighlight: function(){
1210                 var navitems = $$(".navmenu");
1211                 navitems.each(function(element){
1212                         var mode = element.readAttribute("data-mode");
1213                         var navselected = "navselected";
1214                         if(mode == this.mode){
1215                                 element.addClassName(navselected);
1216                         } else {
1217                                 element.removeClassName(navselected);
1218                         }
1219                 }.bind(this));
1220         },
1221
1222         onHashChanged: function(isReload){
1223                 var hash = hashListener.getHash();
1224                 var parts = hash.split("/");
1225
1226                 var len = parts.length;
1227                 if(len >= 2){
1228                         var mode = parts[1];
1229                         if(mode != this.mode || isReload || ( len <= 2 && this.subMode != '') ){
1230                                 this.switchMode(mode, len == 2);
1231                                 this.subMode = '';
1232                         }
1233                         this.mode = mode;
1234
1235                         this.setNavHighlight();
1236
1237                         if(len > 2){
1238                                 var subMode = parts[2];
1239                                 if(subMode != this.subMode || isReload){
1240                                         this.subMode = subMode;
1241                                         if(!this.navlut[this.mode][this.subMode]){
1242                                                 return;
1243                                         } else {
1244                                                 if(this.mode != "movies")
1245                                                         this.navlut[this.mode][this.subMode]();
1246                                         }
1247                                 }
1248                                 if(len > 3){
1249                                         switch(this.mode){
1250                                         case 'tv':
1251                                         case 'radio':
1252                                                 this.services.load(unescape(parts[3]));
1253                                                 break;
1254                                         case 'movies':
1255                                                 var location = decodeURIComponent(parts[4]);
1256                                                 var tag = decodeURIComponent(parts[5]);
1257
1258                                                 this.currentLocation = location;
1259                                                 this.currentTag = tag;
1260                                                 this.loadContentDynamic(
1261                                                         function(){
1262                                                                 this.movies.load(location, tag);
1263                                                         }.bind(this),
1264                                                         'Movies',
1265                                                         true
1266                                                 );
1267
1268                                                 break;
1269                                         case 'extras':
1270                                                 if(subMode == 'mediaplayer'){
1271                                                         this.mediaplayer.load(decodeURIComponent(parts[3]));
1272                                                 }
1273                                                 break;
1274                                         default:
1275                                                 return;
1276                                         }
1277                                 }
1278                         }
1279                 }
1280         },
1281
1282         getBaseHash: function(){
1283                 var hash = ['#!', this.mode].join("/");
1284                 if(this.subMode != ''){
1285                         hash = [hash, this.subMode].join("/");
1286                 }
1287                 return hash;
1288         },
1289
1290         loadDefault: function(){
1291                 debug("[E2WebCore].loadDefault");
1292                 this.switchMode('tv');
1293                 this.mode = 'tv';
1294                 this.subMode = 'bouquets';
1295                 this.bouquets.load(bouquetsTv, true);
1296         },
1297
1298         run: function(){
1299                 debug("[E2WebCore].run");
1300                 if( parseNr(userprefs.data.updateCurrentInterval) < 10000){
1301                         userprefs.data.updateCurrentInterval = 120000;
1302                         userprefs.save();
1303                 }
1304
1305                 if( parseNr(userprefs.data.updateBouquetInterval) < 60000 ){
1306                         userprefs.data.updateBouquetInterval = 300000;
1307                         userprefs.save();
1308                 }
1309
1310                 if (typeof document.body.style.maxHeight == undefined) {
1311                         alert("Due to the tremendous amount of work needed to get everthing to " +
1312                         "work properly, there is (for now) no support for Internet Explorer Versions below 7");
1313                 }
1314                 hashListener.onHashChanged = this.onHashChanged.bind(this);
1315                 hashListener.init();
1316
1317                 this.registerEvents();
1318
1319                 this.setAjaxLoad('navContent');
1320                 this.setAjaxLoad('contentMain');
1321
1322                 templateEngine.fetch('tplServiceListEPGItem');
1323                 templateEngine.fetch('tplBouquetsAndServices');
1324                 templateEngine.fetch('tplCurrent');
1325                 if(!hashListener.getHash().length >= 1){
1326                         this.loadDefault();
1327                 }
1328                 this.updateItems();
1329                 this.startUpdateCurrentPoller();
1330         },
1331
1332         registerEvents: function(){
1333                 debug("[E2WebCore].registerEvents");
1334                 //Hash-Reload-Fix
1335                 //HACK :: THIS IS EVIL VOODOO, DON'T TRY THIS AT HOME!
1336                 document.on(
1337                         'click',
1338                         'a',
1339                         function(event, element){
1340                                 var parts = element.href.split('#');
1341                                 var curHost = window.location.href.split('#')[0];
1342                                 //Don't do this crazy stuff when the target is another host!
1343                                 if(curHost == parts[0]){
1344                                         if (parts.length > 1){
1345                                                 if(parts[1] != ''){
1346                                                         if(window.location == element.href){
1347                                                                 this.onHashChanged(true);
1348                                                                 return;
1349                                                         }else{
1350                                                                 window.location == element.href;
1351                                                                 return;
1352                                                         }
1353                                                 } else {
1354                                                         element.href = window.location;
1355                                                 }
1356                                                 return false;
1357                                         }
1358                                 }
1359                         }.bind(this)
1360                 );
1361                 //Header
1362                 $('openSignalPanel').on(
1363                         'click',
1364                         function(event, element){
1365                                 this.signal.load();
1366                                 event.stop();
1367                         }.bind(this)
1368                 );
1369                 $('instantRecord').on(
1370                         'click',
1371                         function(event, element){
1372                                 var menu = $('instantRecordMenu');
1373                                 if(menu.visible()){
1374                                         menu.hide();
1375                                 } else {
1376                                         menu.show();
1377                                 }
1378                                 event.stop();
1379                         }
1380                 );
1381                 document.on(
1382                         'click',
1383                         '.doInstantRecord',
1384                         function(event, element){
1385                                 var menu = $('instantRecordMenu');
1386                                 this.timers.recordNow(
1387                                         element.readAttribute('data-type'),
1388                                         function(result){
1389                                                 menu.hide();
1390                                         }
1391                                 );
1392                         }.bind(this)
1393                 );
1394                 //Current
1395                 $('current').on(
1396                         'click',
1397                         '.currentExtShowHide',
1398                         function(event, element){
1399                                 this.current.toggleVisibility(element);
1400                                 event.stop();
1401                         }.bind(this)
1402                 );
1403                 $('current').on(
1404                                 'click',
1405                                 '.currentEpg',
1406                                 function(event, element){
1407                                         var ref = unescape( element.readAttribute('data-servicereference') );
1408                                         this.epg.load(ref);
1409                                         event.stop();
1410                                 }.bind(this)
1411                         );
1412                 //EPG-Search
1413                 $('epgSearchForm').on(
1414                         'submit',
1415                         function(event, element){
1416                                 this.epg.search($F('epgSearch'));
1417                                 event.stop();
1418                         }.bind(this)
1419                 );
1420                 $('epgSearch').on(
1421                         'focus',
1422                         function(event, element){
1423                                 element.value = "";
1424                         }.bind(this)
1425                 );
1426                 $('epgSearchClear').on(
1427                                 'click',
1428                                 function(event, element){
1429                                         $('epgSearch').value = '';
1430                                         return false;
1431                                 }.bind(this)
1432                 );
1433                 //Movienav
1434                 var changeevt = Prototype.Browser.IE ? "click" : "change";
1435                 var nav = $('navContent');
1436                 nav.on(
1437                         changeevt,
1438                         '.mNavLocTag',
1439                         function(event, element){
1440                                 var l = $('locations');
1441                                 var t = $('tags');
1442                                 var location = l.options[l.selectedIndex].value;
1443                                 var tag = t.options[t.selectedIndex].value;
1444                                 var hash = [this.getBaseHash(), "filter", encodeURIComponent(location), encodeURIComponent(tag)].join("/");
1445                                 if(hash != '#'+hashListener.getHash() || !Prototype.Browser.IE)
1446                                         hashListener.setHash(hash);
1447                         }.bind(this)
1448                 );
1449                 $('contentHdExt').on(
1450                         changeevt,
1451                         '.mNavLocTag',
1452                         function(event, element){
1453                                 var l = $('locations');
1454                                 var t = $('tags');
1455                                 var location = l.options[l.selectedIndex].value;
1456                                 var tag = t.options[t.selectedIndex].value;
1457                                 var hash = [this.getBaseHash(), "filter", encodeURIComponent(location), encodeURIComponent(tag)].join("/");
1458                                 if(hash != '#'+hashListener.getHash() || !Prototype.Browser.IE)
1459                                         hashListener.setHash(hash);
1460                         }.bind(this)
1461                 );
1462                 //RemoteControl
1463                 nav.on(
1464                         'click',
1465                         '.webremote',
1466                         this.remote.open.bind(this.remote)
1467                 );
1468                 //Volume
1469                 $('navVolume').on(
1470                         'click',
1471                         'a.volume',
1472                         function(event, element){
1473                                 this.volume.set(element.readAttribute('data-volume'));
1474                                 return false;
1475                         }.bind(this)
1476                 );
1477
1478                 //Content
1479                 var content = $('contentMain');
1480                 //MediaPlayer
1481                 content.on(
1482                         'click',
1483                         '.mpCmd',
1484                         function(event, element){
1485                                 this.mediaplayer.command(element.readAttribute('data-command'));
1486                         }.bind(this)
1487                 );
1488                 content.on(
1489                         'click',
1490                         '.mpPlayFile',
1491                         function(event, element){
1492                                 var parent = element.up('.mpListItem');
1493                                 var ref = decodeURIComponent( parent.readAttribute('data-servicereference') );
1494                                 this.mediaplayer.playFile(ref);
1495                                 event.stop();
1496                         }.bind(this)
1497                 );
1498                 content.on(
1499                                 'click',
1500                                 '.mpAddFile',
1501                                 function(event, element){
1502                                         var parent = element.up('.mpListItem');
1503                                         var ref = decodeURIComponent( parent.readAttribute('data-servicereference') );
1504                                         this.mediaplayer.addFile(ref);
1505                                         event.stop();
1506                                 }.bind(this)
1507                         );
1508                 content.on(
1509                         'click',
1510                         '.mpRemoveFile',
1511                         function(event, element){
1512                                 var parent = element.up('.mpListItem');
1513                                 var ref = decodeURIComponent( parent.readAttribute('data-servicereference') );
1514                                 this.mediaplayer.removeFile(ref);
1515                                 event.stop();
1516                         }.bind(this)
1517                 );
1518                 content.on(
1519                                 'click',
1520                                 '.mpSavePlaylist',
1521                                 function(event, element){
1522                                         var filename = prompt('Please enter a filename for the playlist', 'playlist');
1523                                         if(filename != null && filename != ""){
1524                                                 this.mediaplayer.savePlaylist(filename);
1525                                         }
1526                                 }.bind(this)
1527                         );
1528                 //Message
1529                 content.on(
1530                         'click',
1531                         '.messageSend',
1532                         function(event, element){
1533                                 var t = $('messageType');
1534                                 text = $('messageText').value;
1535                                 timeout = $('messageTimeout').value;
1536                                 type = t.options[t.selectedIndex].value;
1537                                 this.messages.send(text, type, timeout);
1538                         }.bind(this)
1539                 );
1540                 //Movielist
1541                 content.on(
1542                         'click',
1543                         'a.mListDelete',
1544                         function(event, element){
1545                                 this.movies.del(element);
1546                                 event.stop();
1547                         }.bind(this)
1548                 );
1549                 //Powerstate
1550                 content.on(
1551                         'click',
1552                         '.powerState',
1553                         function(event, element){
1554                                 var newState = element.readAttribute("data-state");
1555                                 var cb = function(isStandby){
1556                                         var text = "Device is now Running";
1557                                         switch(this.power.STATES[newState]){
1558                                         case this.power.STATES.toggle:
1559                                                 if(isStandby)
1560                                                         text = "Device is now in Soft-Standby";
1561                                                 break;
1562                                         case this.power.STATES.deep:
1563                                                 if(isStandby)
1564                                                         text = "Device will go into deep standby (if possible, check OSD for messages)";
1565                                                 else
1566                                                         text = "Cannot shutdown!";
1567                                                 break;
1568                                         case this.power.STATES.reboot:
1569                                                 if(isStandby)
1570                                                         text = "Device will reboot now (if possible, check OSD for messages)";
1571                                                 else
1572                                                         text = "Cannot reboot!";
1573                                                 break;
1574                                         case this.power.STATES.gui:
1575                                                 if(isStandby)
1576                                                         text = "GUI will restart now (if possible, check OSD for messages)";
1577                                                 else
1578                                                         text = "Cannot restart GUI!";
1579                                                 break;
1580                                         }
1581                                         this.notify(text, true);
1582                                         this.onPowerStateAvailable(isStandby);
1583                                 }.bind(this);
1584                                 this.power.set(newState, cb);
1585                         }.bind(this)
1586                 );
1587                 //Settings
1588                 content.on(
1589                         'click',
1590                         '.saveSettings',
1591                         function(event, element){
1592                                 this.saveSettings();
1593                         }.bind(this)
1594                 );
1595                 //Bouquets
1596                 content.on(
1597                         'click',
1598                         'a.bListSLink',
1599                         function(event, element){
1600                                 setContentHd(element.readAttribute("data-servicename"));
1601                         }
1602                 );
1603                 content.on(
1604                         'click',
1605                         'a.bListEpg',
1606                         function(event, element){
1607                                 var sref = decodeURIComponent( element.readAttribute("data-servicereference") );
1608                                 this.multiepg.load(sref);
1609                                 event.stop();
1610                         }.bind(this)
1611                 );
1612
1613                 //Servicelist
1614                 content.on(
1615                         'click',
1616                         'a.sListSLink',
1617                         function(event, element){
1618                                 var ref = decodeURIComponent( element.id );
1619                                 this.services.zap(ref, this.delayedUpdateItems.bind(this));
1620                                 event.stop();
1621                         }.bind(this)
1622                 );
1623                 content.on(
1624                         'click',
1625                         'a.sListServiceEpg',
1626                         function(event, element){
1627                                 var ref = unescape( element.readAttribute('data-servicereference') );
1628                                 this.epg.load(ref);
1629                                 event.stop();
1630                         }.bind(this)
1631                 );
1632                 content.on(
1633                         'click',
1634                         'a.sListExtEpg',
1635                         function(event, element){
1636                                 var target = element.up('.sListEPGItem').down('.sListExtEpgLong');
1637
1638                                 if(target){
1639                                         var bullet = element.down('.sListBulletToggle');
1640                                         if(target.visible()){
1641                                                 target.hide();
1642                                                 bullet.src = "/web-data/img/toggle_expand_small.png";
1643                                                 bullet.alt = "+";
1644                                         } else {
1645                                                 target.show();
1646                                                 bullet.src = "/web-data/img/toggle_collapse_small.png";
1647                                                 bullet.alt = "-";
1648                                         }
1649                                 }
1650                                 event.stop();
1651                         }.bind(this)
1652                 );
1653                 content.on(
1654                         'click',
1655                         '.sListAddTimer',
1656                         function(event, element){
1657                                 core.timers.addByEventId(element, 0);
1658                                 event.stop();
1659                         }
1660                 );
1661                 content.on(
1662                         'click',
1663                         '.sListZapTimer',
1664                         function(event, element){
1665                                 core.timers.addByEventId(element, 1);
1666                                 event.stop();
1667                         }
1668                 );
1669                 content.on(
1670                         'click',
1671                         '.sListEditTimer',
1672                         function(event, element){
1673                                 var hash = ["#!/timer", "edit"].join("/");
1674                                 hashListener.setHash(hash);
1675                                 core.timers.editFromEvent(element);
1676                                 event.stop();
1677                         }
1678                 );
1679
1680                 //Timerlist
1681                 content.on(
1682                         'click',
1683                         '.tListDelete',
1684                         function(event, element){
1685                                 this.timers.del(element);
1686                                 event.stop();
1687                         }.bind(this)
1688                 );
1689                 content.on(
1690                         'click',
1691                         '.tListToggleDisabled',
1692                         function(event, element){
1693                                 this.timers.toggleDisabled(element);
1694                                 event.stop();
1695                         }.bind(this)
1696                 );
1697                 content.on(
1698                         'click',
1699                         '.tListEdit',
1700                         function(event, element){
1701                                 var hash = ["#!/timer", "edit"].join("/");
1702                                 hashListener.setHash(hash);
1703                                 this.timers.edit(element);
1704                                 return false;
1705                         }.bind(this)
1706                 );
1707                 content.on(
1708                         'click',
1709                         '.tListCleanup',
1710                         function(event, element){
1711                                 this.timers.cleanupList();
1712                                 return false;
1713                         }.bind(this)
1714                 );
1715                 //Timer Editing
1716                 content.on(
1717                         'change',
1718                         '.tEditRepeated',
1719                         function(event, element){
1720                                 var days = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'];
1721                                 var weekdays = days.slice(0,5);
1722
1723                                 switch(element.id){
1724                                 case 'mf':
1725                                         var checked = element.checked;
1726                                         weekdays.each(function(day){
1727                                                 $(day).checked = checked;
1728                                         });
1729                                         if(checked){
1730                                                 var others = ['sa', 'su', 'ms'];
1731                                                 others.each(function(item){
1732                                                         $(item).checked = false;
1733                                                 });
1734                                         }
1735                                         break;
1736                                 case 'ms':
1737                                         var checked = element.checked;
1738                                         days.each(function(day){
1739                                                 $(day).checked = checked;
1740                                         });
1741                                         if(checked){
1742                                                 $('mf').checked = false;
1743                                         }
1744                                         break;
1745                                 default:
1746                                         var weekdays = true;
1747                                         var alldays = true;
1748                                         days.each(function(day){
1749                                                 day = $(day);
1750                                                 if(day.value <= 64){
1751                                                         if(!day.checked){
1752                                                                 alldays = false;
1753                                                                 if(day.value <= 16){
1754                                                                         weekdays = false;
1755                                                                         return
1756                                                                 }
1757                                                         } else {
1758                                                                 if(day.value > 16){
1759                                                                         weekdays = false;
1760                                                                 }
1761                                                         }
1762                                                 }
1763                                         });
1764                                         if(alldays){
1765                                                 $('mf').checked = false;
1766                                                 $('ms').checked = true;
1767                                         } else if (weekdays) {
1768                                                 $('mf').checked = true;
1769                                                 $('ms').checked = false;
1770                                         } else {
1771                                                 $('mf').checked = false;
1772                                                 $('ms').checked = false;
1773                                         }
1774                                 }
1775                         }
1776                 );
1777                 content.on(
1778                         'change',
1779                         '.tEditBouquet',
1780                         function(event, element){
1781                                 var value = unescape( element.options[element.selectedIndex].value );
1782                                 core.timers.onBouquetChanged(value);
1783                         }.bind(this)
1784                 );
1785                 content.on(
1786                         'click',
1787                         '.tEditTag',
1788                         function(event, element){
1789                                 var selected = 'selected';
1790                                 var attr = 'data-selected';
1791                                 if(element.hasClassName(selected)){
1792                                         element.removeClassName(selected);
1793                                         element.writeAttribute(attr, '');
1794                                 } else {
1795                                         element.addClassName(selected);
1796                                         element.writeAttribute(attr, selected);
1797                                 }
1798                                 event.stop();
1799                         }.bind(this)
1800                 );
1801                 content.on(
1802                         'click',
1803                         '.tEditSave',
1804                         function(event, element){
1805                                 this.timers.save($('timerEditForm'));
1806                         }.bind(this)
1807                 );
1808
1809                 $('webTv').on(
1810                         'click',
1811                         function(event, element){
1812                                 window.open('/web-data/tpl/default/streaminterface/index.html', 'WebTV', 'scrollbars=no, width=800, height=740');
1813                                 event.stop();
1814                         }.bind(this)
1815                 );
1816         },
1817
1818         /*
1819          * Loads another navigation template and sets the navigation header
1820          * @param template - The name of the template
1821          * @param title - The title to set for the navigation
1822          */
1823         reloadNav: function(template, title, callback){
1824                 this.setAjaxLoad('navContent');
1825                 templateEngine.process(template, null, 'navContent', callback);
1826                 setNavHd(title);
1827         },
1828
1829         reloadNavDynamic: function(fnc, title){
1830                 this.setAjaxLoad('navContent');
1831                 setNavHd(title);
1832                 fnc();
1833         },
1834
1835         /*
1836          * Loads dynamic content to $(contentMain) by calling a execution function
1837          * @param fnc - The function used to load the content
1838          * @param title - The Title to set on the contentpanel
1839          */
1840         loadContentDynamic: function(fnc, title, keepHdExt){
1841                 setContentHd(title, keepHdExt);
1842                 this.stopUpdateBouquetItemsPoller();
1843                 fnc();
1844         },
1845
1846         /*
1847          * Loads a static template to $(contentMain)
1848          * @param template - Name of the Template
1849          * @param title - The Title to set on the Content-Panel
1850          */
1851         loadContentStatic: function(template, title){
1852                 this.setAjaxLoad('contentMain');
1853                 setContentHd(title);
1854                 this.stopUpdateBouquetItemsPoller();
1855                 templateEngine.process(template, null, 'contentMain');
1856         },
1857
1858         setEmptyContent: function(id, text){
1859                 $(id).update('<div class="block center fullwidth oneliner">' + text + '</div>');
1860         },
1861
1862         switchMode: function(mode, initContent){
1863                 if(initContent){
1864                         this.setEmptyContent('contentMain', 'please select a submenu on the left...');
1865                         setContentHd('...');
1866                 }
1867
1868                 switch(mode){
1869                 case "tv":
1870                         if(this.mode != 'tv' && this.mode != 'radio'){
1871                                 this.services.registerEvents();
1872                         }
1873                         this.reloadNav('tplNavTv', 'TeleVision');
1874                         break;
1875
1876                 case "radio":
1877                         if(this.mode != 'TV' && this.mode != 'Radio'){
1878                                 this.services.registerEvents();
1879                         }
1880                         this.reloadNav('tplNavRadio', 'Radio');
1881                         break;
1882
1883                 case "movies":
1884                         this.reloadNavDynamic(this.movies.loadNav.bind(this.movies), 'Movies');
1885                         break;
1886
1887                 case "timer":
1888                         this.reloadNav('tplNavTimer', 'Timer');
1889                         break;
1890
1891                 case "control":
1892                         this.reloadNav('tplNavBoxControl', 'BoxControl');
1893                         break;
1894
1895                 case "extras":
1896                         this.reloadNav('tplNavExtras', 'Extras', this.externals.load.bind(this.externals));
1897                         break;
1898
1899                 default:
1900                         break;
1901                 }
1902         },
1903
1904         saveSettings: function(){
1905                 userprefs.load();
1906
1907                 var debug = $('enableDebug').checked;
1908                 var changed = false;
1909                 if(debug != undefined){
1910                         if( userprefs.data.debug != debug ){
1911                                 userprefs.data.debug = debug;
1912                                 changed = true;
1913                         }
1914                 }
1915
1916                 var updateCurrentInterval = parseNr( $F('updateCurrentInterval') ) * 1000;
1917                 if( updateCurrentInterval < 10000){
1918                         updateCurrentInterval = 120000;
1919                 }
1920
1921                 if( userprefs.data.updateCurrentInterval != updateCurrentInterval){
1922                         userprefs.data.updateCurrentInterval = updateCurrentInterval;
1923
1924                         changed = true;
1925                         this.startUpdateCurrentPoller();
1926                 }
1927
1928                 var updateBouquetInterval = parseNr( $F('updateBouquetInterval') ) * 1000;
1929                 if( updateBouquetInterval < 60000){
1930                         updateBouquetInterval = 300000;
1931                 }
1932
1933                 if( userprefs.data.updateBouquetInterval != updateBouquetInterval){
1934                         userprefs.data.updateBouquetInterval = updateBouquetInterval;
1935
1936                         changed = true;
1937                         this.startUpdateBouquetItemsPoller();
1938                 }
1939
1940                 if(changed){
1941                         userprefs.save();
1942                         this.notify("Settings saved");
1943                 } else {
1944                         this.notify("Nothing changed! No need to save!");
1945                 }
1946         }
1947 });
1948 core = new E2WebCore();