Changes for the function delTimer. Now, the new WebInterface can delete timers too.
[enigma2-plugins.git] / webinterface / src / web-data / tools.js
1 var url_getvolume = '/web/vol?set=state'; 
2 var url_setvolume = '/web/vol?set=set'; // plus new value eq. set=set15
3 var url_volumeup = '/web/vol?set=up';
4 var url_volumedown = '/web/vol?set=down';
5 var url_volumemute = '/web/vol?set=mute';
6
7 var url_epgservice = "/web/epgservice?ref="; // plus serviceRev
8 var url_epgsearch = "/web/epgsearch?search="; // plus serviceRev
9 var url_epgnow = "/web/epgnow?bref="; // plus bouqetRev
10
11 var url_fetchchannels = "/web/fetchchannels?ServiceListBrowse="; // plus encoded serviceref
12
13 var url_updates= "/web/updates";
14
15 var url_movielist= "/web/movielist";
16
17 var url_timerlist= "/web/timerlist";
18 var url_timeradd= "/web/timeradd"; // plus serviceref,begin,end,name,description,eit,disabled,justplay,afterevent
19 var url_timeraddbyeventid= "/web/timeraddbyeventid"; // plus serviceref,eventid
20 var url_timerdelete= "/web/timerdelete"; // plus serviceref,bedin,end
21
22 var bouqet_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25)FROM BOUQUET "bouquets.tv" ORDER BY bouquet';
23 var bouqet_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)FROM BOUQUET "bouquets.radio" ORDER BY bouquet';
24 var bouqet_provider_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM PROVIDERS ORDER BY name';
25 var bouqet_provider_radio ='1:7:2:0:0:0:0:0:0:0:(type == 2) FROM PROVIDERS ORDER BY name';
26
27 var windowStyle = "alphacube";
28 var DBG = true;
29
30
31 /**
32 *
33 *  UTF-8 data encode / decode
34 *  http://www.webtoolkit.info/
35 *
36 **/
37
38 var Utf8 = {
39
40         // public method for url encoding
41         encode : function (string) {
42         string = string.replace(/\r\n/g,"\n");
43         var utftext = "";
44
45         for (var n = 0; n < string.length; n++) {
46
47         var c = string.charCodeAt(n);
48
49         if (c < 128) {
50                 utftext += String.fromCharCode(c);
51         }
52         else if((c > 127) && (c < 2048)) {
53                 utftext += String.fromCharCode((c >> 6) | 192);
54                 utftext += String.fromCharCode((c & 63) | 128);
55         }
56         else {
57                 utftext += String.fromCharCode((c >> 12) | 224);
58                 utftext += String.fromCharCode(((c >> 6) & 63) | 128);
59                 utftext += String.fromCharCode((c & 63) | 128);
60         }
61
62         }
63         
64         return utftext;
65         },
66
67         // public method for url decoding
68         decode : function (utftext) {
69                 var string = "";
70                 var i = 0;
71                 var c = c1 = c2 = 0;
72
73                 while ( i < utftext.length ) {
74
75                         c = utftext.charCodeAt(i);
76
77                         if (c < 128) {
78                                 string += String.fromCharCode(c);
79                                 i++;
80                         }
81                         else if((c > 191) && (c < 224)) {
82                                 c2 = utftext.charCodeAt(i+1);
83                                 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
84                                 i += 2;
85                         }
86                         else {
87                                 c2 = utftext.charCodeAt(i+1);
88                                 c3 = utftext.charCodeAt(i+2);
89                                 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
90                                 i += 3;
91                         }
92
93                 }
94                 
95                 return string;
96         }
97
98 }
99
100 // UpdateStreamReader
101 var UpdateStreamReaderNextReadPos = 0;
102 var UpdateStreamReaderPollTimer;
103 UpdateStreamReaderRequest = null;
104 function UpdateStreamReaderStart(){
105         var ua = navigator.userAgent;
106         if(navigator.userAgent.indexOf("MSIE") >=0) {
107                 debug("UpdateStreamReader IE Fix");
108
109                 var namespace = {       
110                                         'url_updates': url_updates
111                 };
112                 $('UpdateStreamReaderIEFixPanel').innerHTML = RND(tplUpdateStreamReaderIE, namespace);
113                 
114         }else {
115                 UpdateStreamReaderNextReadPos = 0;
116                 allMessages = "";
117                 UpdateStreamReaderRequest =new XMLHttpRequest();
118                 UpdateStreamReaderRequest.onload = UpdateStreamReaderOnLoad;
119                 UpdateStreamReaderRequest.onerror = UpdateStreamReaderOnError;
120                 UpdateStreamReaderRequest.open("GET", url_updates, true);
121                 UpdateStreamReaderRequest.send(null);
122                 UpdateStreamReaderPollTimer = setInterval(UpdateStreamReaderLatestResponse, 500);
123         }
124 }
125   
126 function UpdateStreamReaderLatestResponse() {
127         var allMessages = UpdateStreamReaderRequest.responseText;
128         do {
129                 var unprocessed = allMessages.substring(UpdateStreamReaderNextReadPos);
130                 var messageXMLEndIndex = unprocessed.indexOf("\n");
131                 
132                 if (messageXMLEndIndex!=-1) {
133                         var endOfFirstMessageIndex = messageXMLEndIndex + "\n".length;
134                         var anUpdate = unprocessed.substring(0, endOfFirstMessageIndex);
135
136                         anUpdate = anUpdate.replace(/<div id="scriptzone"\/>/,'');
137                         anUpdate = anUpdate.replace(/<script>parent./, '');
138                         anUpdate = anUpdate.replace(/<\/script>\n/, '');
139                         
140                         anUpdate = Utf8.decode(anUpdate);
141                                                 
142                         eval(anUpdate);
143                         UpdateStreamReaderNextReadPos += endOfFirstMessageIndex;
144                 }
145                 if(UpdateStreamReaderNextReadPos > 65000){
146                         debug(new Date().toLocaleString()+": Resetting StreamReader NOW!");
147                         UpdateStreamReaderRequest.abort();
148                         UpdateStreamReaderStart();
149                         messageXMLEndIndex = -1;
150                 }
151         } while (messageXMLEndIndex != -1);
152 }
153
154 function UpdateStreamReaderOnLoad(){
155         window.clearInterval(UpdateStreamReaderPollTimer);
156         debug("UpdateStreamReaderOnLoad");
157         Dialog.confirm(
158                 "Live Update Stream ends!<br><br>You will not receive any Update from Enigma2.<br>Should I reconnect?",
159                  {windowParameters: {width:300, className: windowStyle},
160                         okLabel: "reconnect",
161                         buttonClass: "myButtonClass",
162                         cancel: function(win) {debug("cancel confirm panel")},
163                         ok: function(win) {UpdateStreamReaderStart(); return true;}
164                         }
165                 );
166 }
167 function UpdateStreamReaderOnError(){
168         // TODO: change this, because it will be called on 'PageUnload' while the request is still running
169         debug("UpdateStreamReaderOnError");
170         window.clearInterval(UpdateStreamReaderPollTimer);
171         Dialog.confirm(
172                 "Live Update Stream has an Error!<br><br>You will not receive any Update from Enigma2.<br>Should I try to reconnect?",
173                  {windowParameters: {width:300, className: windowStyle},
174                          okLabel: "reconnect",
175                          buttonClass: "myButtonClass",
176                          cancel: function(win) {debug("cancel confirm panel")},
177                          ok: function(win) {UpdateStreamReaderStart(); return true;}
178                         }
179                 );
180 }
181
182 //end UpdateStreamReader
183
184 function openWindow(title, inner, width, height, id){
185                         if(id == null) id = new Date().toUTCString();
186                         
187                         //debug(id);
188                         var win = new Window(id, {className: windowStyle, title: title, width: width, height: height});
189                         win.getContent().innerHTML = inner;
190                         win.setDestroyOnClose();
191                         win.showCenter();
192                         debug("opening Window: "+title);
193                         return win;
194 }
195
196 function messageBox(t, m){
197         Dialog.alert(m, {windowParameters: {title: t, className: windowStyle, width:200}, okLabel: "Close"});
198 }
199
200 function getHTTPObject( ){
201         var xmlHttp = false;
202
203         // try to create a new instance of the xmlhttprequest object
204         try{
205                 // Internet Explorer
206                 if( window.ActiveXObject ){
207                         for( var i = 5; i; i-- ){
208                                 try{
209                                         // loading of a newer version of msxml dll (msxml3 - msxml5) failed
210                                         // use fallback solution
211                                         // old style msxml version independent, deprecated
212                                         if( i == 2 ){
213                                                 xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP" );
214                                         }
215                                         // try to use the latest msxml dll
216                                         else{
217                                                 xmlHttp = new ActiveXObject( "Msxml2.XMLHTTP." + i + ".0" );
218                                         }
219                                         break;
220                                 }
221                                 catch( excNotLoadable ){
222                                     xmlHttp = false;
223                                 }
224                         }
225                 }
226                 // Mozilla, Opera und Safari
227                 else if( window.XMLHttpRequest ){
228                         xmlHttp = new XMLHttpRequest();
229                 }
230         }
231         // loading of xmlhttp object failed
232         catch( excNotLoadable ){
233                 xmlHttp = false;
234         }
235         return xmlHttp ;
236 }
237
238 //RND Template Function
239 function RND(tmpl, ns) {
240         var fn = function(w, g) {
241                 g = g.split("|");
242                 var cnt = ns[g[0]];
243
244                 //Support for filter functions
245                 for(var i=1; i < g.length; i++) {
246                         cnt = eval(g[i])(cnt);
247                 }
248                 return cnt || w;
249         };
250         return tmpl.replace(/%\(([A-Za-z0-9_|.]*)\)/g, fn);
251 }
252
253 function debug(text){
254         if(DBG){
255                 try{
256                         debugWin.getContent().innerHTML += "DEBUG: "+text+"<br>";
257                 } catch (windowNotPresent) {}
258         }
259 }
260
261 function showhide(id){
262         o = document.getElementById(id).style;
263         o.display = (o.display!="none")? "none":"";
264 }
265
266 function set(what, value){
267         //debug(what+"-"+value);
268         element = parent.document.getElementById(what);
269         if (element){
270                 element.innerHTML = value;
271         }
272         if(navigator.userAgent.indexOf("MSIE") >=0) {
273                 elementscript= $('UpdateStreamReaderIEFixIFrame').document.getElementById('scriptzone');
274                 if(elementscript){
275                         elementscript.innerHTML = ""; // deleting set() from page, to keep the page short and to save memory                    
276                 }
277         }
278 }
279 // requestindikator
280 var requestcounter = 0;
281
282 function requestIndicatorUpdate(){
283         //debug(requestcounter+" open requests");
284         if(requestcounter>=1){
285                 $('RequestIndicator').style.display = "inline";
286         }else{
287                 $('RequestIndicator').style.display = "none";
288         }
289 }
290 function requestStarted(){
291         requestcounter +=1;
292         requestIndicatorUpdate();
293 }
294 function requestFinished(){
295         requestcounter -=1;
296         requestIndicatorUpdate();
297 }
298 // end requestindikator
299
300 function doRequest(url, readyFunction){
301         requestStarted();
302         new Ajax.Request(url,
303                 {
304                         method: 'get',
305                         requestHeaders: ['Pragma', 'no-cache', 'Cache-Control', 'must-revalidate', 'If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT'],
306                         onSuccess: readyFunction,
307                         onComplete: requestFinished 
308                 });
309 }
310
311 function getXML(request){
312         if (document.implementation && document.implementation.createDocument){
313                 var xmlDoc = request.responseXML
314         }
315         else if (window.ActiveXObject){
316                 var xmlInsert = document.createElement('xml');
317
318                 xmlInsert.setAttribute('innerHTML',request.responseText);
319                 xmlInsert.setAttribute('id','_MakeAUniqueID');
320                 document.body.appendChild(xmlInsert);
321                 xmlDoc = document.getElementById('_MakeAUniqueID');
322                 document.body.removeChild(document.getElementById('_MakeAUniqueID'));
323         } else {
324                 debug("Your Browser Sucks!");
325         }
326         return xmlDoc;
327 }
328
329 function zap(servicereference){
330         var url = "/web/zap?ZapTo=" + servicereference;
331         new Ajax.Request( url,
332                 {
333                         method: 'get'                           
334                 });
335 }
336 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
337 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
338 //++++       SignalPanel                           ++++
339 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
340 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
341
342 function initSignalPanel(){
343         $('SignalPanel').innerHTML = tplSignalPanelButton;
344 }
345 function openSignalDialog(){
346         openWindow("Signal Info",tplSignalPanel, 215, 75);
347 }
348
349 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
350 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
351 //++++ EPG functions                               ++++
352 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
353 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
354 var EPGList = Class.create();
355 EPGList.prototype = {
356         //contructor
357         initialize: function(){
358                 debug("init class EPGList");
359         },
360         getBySearchString: function(string){
361                 debug("requesting "+ url_epgsearch+string);
362                 doRequest(url_epgsearch+string,this.incomingEPGrequest);
363                 
364         },
365         getByServiceReference: function(servicereference){
366                 doRequest(url_epgservice+servicereference,this.incomingEPGrequest);
367         },
368         renderTable: function(epglist){
369                 debug("rendering Table with "+epglist.length+" events");
370                 var html = tplEPGListHeader;
371                 for (var i=0; i < epglist.length; i++){
372                         try{
373                                 var item = epglist[i];                          
374                                 //Create JSON Object for Template
375                                 var namespace = {       
376                                         'date': item.getTimeDay(), 
377                                         'eventid': item.getEventId(), 
378                                         'servicereference': item.getServiceReference(), 
379                                         'servicename': item.getServiceName(), 
380                                         'title': item.getTitle(),
381                                         'titleESC': escape(item.getTitle()),
382                                         'starttime': item.getTimeStartString(), 
383                                         'duration': Math.ceil(item.getDuration()/60000), 
384                                         'description': item.getDescription(), 
385                                         'endtime': item.getTimeEndString(), 
386                                         'extdescription': item.getDescriptionExtended()
387                                 }; Math.cei
388                                 //Fill template with data and add id to our result
389                                 html += RND(tplEPGListItem, namespace);
390                         } catch (blubb) {
391                                 //debug("Error rendering: "+blubb);
392                         }
393                 }               
394                 html += tplEPGListFooter;
395                 openWindow("Electronic Program Guide", html, 900, 500);
396                 
397         },
398         incomingEPGrequest: function(request){
399                 debug("incoming request" +request.readyState);          
400                 if (request.readyState == 4)
401                 {
402                         var EPGItems = getXML(request).getElementsByTagName("e2eventlist").item(0).getElementsByTagName("e2event");                     
403                         debug("have "+EPGItems.length+" e2events");
404                         if(EPGItems.length > 0){                        
405                                 epglist = new Array();
406                                 for(var i=0; i < EPGItems.length; i++){         
407                                         epglist.push(new EPGEvent(EPGItems.item(i)));
408                                 }
409                                 debug("Calling prototype.renderTable(epglist)");
410                                 EPGList.prototype.renderTable(epglist);
411                                 
412                         } else {
413                                 messageBox('No Items found!', 'Sorry but i could not find any EPG Content containing your search value');
414                         }
415                         
416                 }
417         }
418         
419 }
420 /////////////////////////
421
422 function loadServiceEPGNowNext(servicereference){
423         var url = url_epgnow+servicereference;
424         doRequest(url, incomingServiceEPGNowNext);      
425 }
426
427 function incomingServiceEPGNowNext(request){
428         if(request.readyState == 4){
429                 var epgevents = getXML(request).getElementsByTagName("e2eventlist").item(0).getElementsByTagName("e2event");
430                 for (var c =0; c < epgevents.length;c++){
431                         var eventnow = new EPGEvent(epgevents.item(c));
432                         
433                         if (eventnow.getEventId() != 'None'){
434                                 buildServiceListEPGItem(eventnow,"NOW");
435                         }
436                 }
437         }
438 }
439 function buildServiceListEPGItem(epgevent,nownext){
440         var e = $(epgevent.getServiceReference()+'EPG'+nownext);
441                 try{
442                         var namespace = {       
443                                 'starttime': epgevent.getTimeStartString(), 
444                                 'title': epgevent.getTitle(), 
445                                 'length': Math.ceil(epgevent.duration/60) 
446                         };
447                         e.innerHTML = RND(tplServiceListEPGItem, namespace);
448                 } catch (blubb) {
449                         debug("Error rendering: "+blubb);
450                 }       
451 }
452 ///////////////////
453
454
455 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
456 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
457 //++++ GUI functions                               ++++
458 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
459 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
460
461 var currentBodyMainElement = null
462
463 function setBodyMainContent(newelementname){
464         newelement =document.getElementById(newelementname);
465         if(currentBodyMainElement != null){
466                 currentBodyMainElement.style.display = "none";
467                 
468         }
469         newelement.style.display = "";
470         currentBodyMainElement = newelement;
471 }
472
473 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
474 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
475 //++++ volume functions                            ++++
476 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
477 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
478
479 function initVolumePanel(){
480         document.getElementById('VolumePanel').innerHTML = tplVolumePanel;
481         getVolume(); 
482 }
483 function getVolume()
484 {
485         doRequest(url_getvolume,handleVolumeRequest);
486 }
487 function volumeSet(newvalue)
488 {
489         doRequest(url_setvolume+newvalue,handleVolumeRequest);
490 }
491 function volumeUp()
492 {
493         doRequest(url_volumeup,handleVolumeRequest);
494 }
495 function volumeDown()
496 {
497         doRequest(url_volumedown,handleVolumeRequest);  
498 }
499 function volumeMute()
500 {
501         doRequest(url_volumemute,handleVolumeRequest);
502 }
503 function handleVolumeRequest(request){
504         if (request.readyState == 4) {
505                 var b = getXML(request).getElementsByTagName("e2volume");
506                 var newvalue = b.item(0).getElementsByTagName('e2current').item(0).firstChild.data;
507                 var mute = b.item(0).getElementsByTagName('e2ismuted').item(0).firstChild.data;
508                 debug("volume"+newvalue+";"+mute);
509                 
510                 for (var i = 1; i <= 10; i++)
511                 {
512                         if ( (newvalue/10)>=i){
513                                 $("volume"+i).src = "/webdata/gfx/led_on.png";
514                         }else{
515                                 $("volume"+i).src = "/webdata/gfx/led_off.png";
516                         }
517                 }
518                 if (mute == "False"){
519                         $("speaker").src = "/webdata/gfx/speak_on.png";
520                 }else{
521                         $("speaker").src = "/webdata/gfx/speak_off.png";
522                 }
523         }       
524 }
525 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
526 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
527 //++++ bouquet managing functions                  ++++
528 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
529 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
530 function initChannelList(){
531         //debug("init ChannelList");    
532         var url = url_fetchchannels+encodeURIComponent(bouqet_tv);
533         doRequest(url, incomingTVBouquetList);
534
535         var url = url_fetchchannels+encodeURIComponent(bouqet_radio);
536         doRequest(url, incomingRadioBouquetList);
537
538         var url = url_fetchchannels+encodeURIComponent(bouqet_provider_tv);
539         doRequest(url, incomingProviderTVBouquetList);
540
541         var url = url_fetchchannels+encodeURIComponent(bouqet_provider_radio);
542         doRequest(url, incomingProviderRadioBouquetList);
543 }
544 var servicereftoloadepgnow="";
545 function loadBouquet(servicereference){ 
546         debug("loading bouquet with "+servicereference);
547         servicereftoloadepgnow = servicereference;
548         doRequest(url_fetchchannels+servicereference, incomingChannellist);
549 }
550
551 function incomingTVBouquetList(request){
552         if (request.readyState == 4) {
553                 var list0 = new ServiceList(getXML(request)).getArray();
554                 debug("have "+list0.length+" TV Bouquet ");     
555                 $('accordionMenueBouquetContentTV').innerHTML = renderBouquetTable(list0,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
556                 //loading first entry of TV Favorites as default for ServiceList
557                 loadBouquet(list0[0].getServiceReference());
558         }
559 }
560 function incomingRadioBouquetList(request){
561         if (request.readyState == 4) {
562                 var list1 = new ServiceList(getXML(request)).getArray();
563                 debug("have "+list1.length+" Radio Bouquet ");  
564                 $('accordionMenueBouquetContentRadio').innerHTML = renderBouquetTable(list1,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
565         }       
566 }
567 function incomingProviderTVBouquetList(request){
568         if (request.readyState == 4) {
569                 var list2 = new ServiceList(getXML(request)).getArray();
570                 debug("have "+list2.length+" TV Provider Bouquet ");    
571                 $('accordionMenueBouquetContentProviderTV').innerHTML = renderBouquetTable(list2,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
572         }       
573 }
574 function incomingProviderRadioBouquetList(request){
575         if (request.readyState == 4) {
576                 var list2 = new ServiceList(getXML(request)).getArray();
577                 debug("have "+list2.length+" Radio Provider Bouquet "); 
578                 $('accordionMenueBouquetContentProviderRadio').innerHTML = renderBouquetTable(list2,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
579         }       
580 }
581
582 function renderBouquetTable(bouquet,templateHeader,templateItem,templateFooter){
583         debug("renderBouquetTable with "+bouquet.length+" Bouqet");     
584         var html = templateHeader;
585         for (var i=0; i < bouquet.length; i++){
586                 try{
587                         var namespace = {
588                                 'servicereference': bouquet[i].getServiceReference(), 
589                                 'bouquetname': bouquet[i].getServiceName()
590                         };
591                         html += RND(templateItem, namespace);
592                 } catch (blubb) {}
593         }
594         html += templateFooter;
595         return html;
596 }       
597
598 function incomingChannellist(request){
599         if(request.readyState == 4){
600                 var services = new ServiceList(getXML(request)).getArray();
601                 listerHtml      = tplServiceListHeader;         
602                 debug("got "+services.length+" Services");
603                 for ( var i = 0; i < services.length ; i++){
604                         var reference = services[i];
605                         var namespace = {       
606                                 'servicereference': reference.getServiceReference(),
607                                 'servicename': reference.getServiceName() 
608                         };
609                         listerHtml += RND(tplServiceListItem, namespace);
610                 }               
611                 listerHtml += tplServiceListFooter;
612                 document.getElementById('BodyContentChannellist').innerHTML = listerHtml;
613                 setBodyMainContent('BodyContentChannellist');
614                 loadServiceEPGNowNext(servicereftoloadepgnow);
615         }
616 }
617 // Movies
618 function loadMovieList(){
619         debug("loading movies");
620         doRequest(url_movielist, incomingMovieList);    
621 }
622
623 function incomingMovieList(request){
624         if(request.readyState == 4){
625                 var movies = new MovieList(getXML(request)).getArray();
626                 debug("have "+movies.length+" movies");
627                 listerHtml      = tplMovieListHeader;           
628                 for ( var i = 0; i <movies.length; i++){
629                         var movie = movies[i];
630                         var namespace = {       
631                                 'servicereference': movie.getServiceReference(),
632                                 'servicename': movie.getServiceName() ,
633                                 'title': movie.getTitle(), 
634                                 'description': movie.getDescription(), 
635                                 'tags': movie.getTags().join(', ') 
636                         };
637                         listerHtml += RND(tplMovieListItem, namespace);
638                 }
639                 listerHtml += tplMovieListFooter;
640                 document.getElementById('BodyContentChannellist').innerHTML = listerHtml;
641                 setBodyMainContent('BodyContentChannellist');
642                 
643         }               
644 }
645
646 // Timer
647 function addTimerByID(serviceRef,eventID){
648         debug("adding timer by eventid="+eventID+" for "+serviceRef);
649         doRequest(url_timeraddbyeventid+"?serviceref="+serviceRef+"&eventid="+eventID, incomingTimerAddResult); 
650 }
651 function incomingTimerAddResult(request){
652         debug("onTimerAdded");
653         if(request.readyState == 4){
654                 var addresult = new TimerAddResult(getXML(request));
655                 if(addresult.getState()){
656                         //timer was add
657                         loadTimerList();
658                 }else{
659                         messageBox("Timer Error","your Timer could not be added!\nReason: "+addresult.getStateText());
660                 }
661         }               
662 }
663 function loadTimerList(){
664         debug("loading timers");
665         doRequest(url_timerlist, incomingTimerList);    
666 }
667
668 function incomingTimerList(request){
669         if(request.readyState == 4){
670                 var timers = new TimerList(getXML(request)).getArray();
671                 debug("have "+timers.length+" timer");
672                 listerHtml      = tplTimerListHeader;           
673                 for ( var i = 0; i <timers.length; i++){
674                         var timer = timers[i];
675                         var namespace = {       
676                                 'servicereference': timer.getServiceReference(),
677                                 'servicename': timer.getServiceName() ,
678                                 'title': timer.getName(), 
679                                 'description': timer.getDescription(), 
680                                 'begin': timer.getTimeBegin(), 
681                                 'end': timer.getTimeEnd(), 
682                                 'state': timer.getState(),
683                                 'duration': (timer.getDuration()/60) 
684                         };
685                         listerHtml += RND(tplTimerListItem, namespace);
686                 }
687                 listerHtml += tplTimerListFooter;
688                 document.getElementById('BodyContentChannellist').innerHTML = listerHtml;
689                 setBodyMainContent('BodyContentChannellist');
690                 
691         }
692 }
693 function delTimer(serviceRef,begin,end){
694         debug("deleting timer with serviceRef="+serviceRef+" and start="+begin+"end="+end );
695         debug(url_timerdelete+"?serviceref="+serviceRef+"&begin="+begin+"&end="+end);
696         doRequest(url_timerdelete+"?serviceref="+serviceRef+"&begin="+begin+"&end="+end, incomingTimerDelResult);       
697 }
698
699 function incomingTimerDelResult(request){
700         debug("onTimerDeleted");
701         debug(request.readyState);
702         if(request.readyState == 4){
703                 var delresult = new TimerAddResult(getXML(request));
704                 debug("Lade liste");
705                 loadTimerList();
706         }               
707 }