channellist and subchannellist is now hold in memory.
[enigma2-plugins.git] / webinterface / src / web-data / tools.js
1 var DBG = false;
2
3 var url_getvolume = '/web/vol?set=state'; 
4 var url_setvolume = '/web/vol?set=set'; // plus new value eq. set=set15
5 var url_volumeup = '/web/vol?set=up';
6 var url_volumedown = '/web/vol?set=down';
7 var url_volumemute = '/web/vol?set=mute';
8
9 var url_epgservice = "/web/epgservice?ref="; // plus serviceRev
10 var url_epgsearch = "/web/epgsearch?search="; // plus serviceRev
11 var url_epgnow = "/web/epgnow?bref="; // plus bouqetRev
12
13 var url_fetchchannels = "/web/fetchchannels?ServiceListBrowse="; // plus encoded serviceref
14 var url_subservices = "/web/subservices"; // subservices for current service
15
16 var url_updates= "/web/updates.html";
17
18 var url_movielist= "/web/movielist";
19
20 var url_settings= "/web/settings";
21
22 var url_timerlist= "/web/timerlist";
23 var url_timeradd= "/web/timeradd"; // plus serviceref,begin,end,name,description,eit,disabled,justplay,afterevent
24 var url_timerchange= "/web/timerchange"; // plus serviceref,begin,end,name,description,eit,disabled,justplay,afterevent
25 var url_timeraddbyeventid= "/web/timeraddbyeventid"; // plus serviceref,eventid
26 var url_timerdelete= "/web/timerdelete"; // plus serviceref,bedin,end
27 var url_timertoggleOnOff= "/web/timeronoff"; // plus serviceref,bedin,end
28
29 var url_message = "/web/message"; // plus text,type,timeout
30
31 var url_powerstate = "/web/powerstate"; // plus new powerstate
32 var url_remotecontrol = "/web/remotecontrol"; // plus command
33
34 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';
35 var bouqet_radio = '1:7:2:0:0:0:0:0:0:0:(type == 2)FROM BOUQUET "bouquets.radio" ORDER BY bouquet';
36 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';
37 var bouqet_provider_radio ='1:7:2:0:0:0:0:0:0:0:(type == 2) FROM PROVIDERS ORDER BY name';
38
39 var windowStyle = "alphacube";
40
41 // TimerEdit variables:
42 var addTimerEditFormObject = new Object();
43 addTimerEditFormObject["TVListFilled"] = 0;
44 addTimerEditFormObject["RadioListFilled"] = 0;
45 addTimerEditFormObject["deleteOldOnSave"] = 0;
46
47 // Get Settings
48 var settings;
49
50 // UpdateStreamReader
51 var UpdateStreamReaderNextReadPos = 0;
52 var UpdateStreamReaderPollTimer;
53 var UpdateStreamReaderPollTimerCounter = 0;
54 UpdateStreamReaderRequest = null;
55 function UpdateStreamReaderStart(){
56         var ua = navigator.userAgent;
57         if(navigator.userAgent.indexOf("MSIE") >=0) {
58                 debug("UpdateStreamReader IE Fix");
59
60                 var namespace = {       
61                                         'url_updates': url_updates
62                 };
63                 $('UpdateStreamReaderIEFixPanel').innerHTML = RND(tplUpdateStreamReaderIE, namespace);
64                 
65         }else {
66                 UpdateStreamReaderNextReadPos = 0;
67                 allMessages = "";
68                 UpdateStreamReaderRequest = new XMLHttpRequest();
69                 UpdateStreamReaderRequest.onload = UpdateStreamReaderOnLoad;
70                 UpdateStreamReaderRequest.onerror = UpdateStreamReaderOnError;
71                 UpdateStreamReaderRequest.open("GET", url_updates, true);
72                 UpdateStreamReaderRequest.send(null);
73                 UpdateStreamReaderPollTimer = setInterval(UpdateStreamReaderLatestResponse, 1000);
74         }
75 }
76   
77 function UpdateStreamReaderLatestResponse() {
78 // Quickhack jjbig start
79 // Its not great, but the best I could come up with to solve the 
80 // problem with the memory leak
81         UpdateStreamReaderPollTimerCounter++;
82         if(UpdateStreamReaderPollTimerCounter > 20) {
83                 clearInterval(UpdateStreamReaderPollTimer);
84                 UpdateStreamReaderRequest.abort();
85                 UpdateStreamReaderRequest = null;
86                 UpdateStreamReaderPollTimerCounter = 0;
87                 UpdateStreamReaderStart();
88                 return;
89         }
90 // Quickhack jjbig end
91         var allMessages = UpdateStreamReaderRequest.responseText;
92         do {
93                 var unprocessed = allMessages.substring(UpdateStreamReaderNextReadPos);
94                 var messageXMLEndIndex = unprocessed.indexOf("\n");
95                 
96                 if (messageXMLEndIndex!=-1) {
97                         var endOfFirstMessageIndex = messageXMLEndIndex + "\n".length;
98                         var anUpdate = unprocessed.substring(0, endOfFirstMessageIndex);
99         
100                         var re = new RegExp("<script>parent\.(.*)</script>");
101                         anUpdate = re.exec(anUpdate);
102
103                         if(anUpdate != null){
104                                 if (anUpdate.length == 2){
105                                         eval(anUpdate[1]);
106                                 }
107                         }
108                         
109                         UpdateStreamReaderNextReadPos += endOfFirstMessageIndex;
110                 }
111                 if(UpdateStreamReaderNextReadPos > 65000){
112                         UpdateStreamReaderRequest.abort();
113                         UpdateStreamReaderRequest = null;
114                         UpdateStreamReaderPollTimerCounter = 0;
115                         UpdateStreamReaderStart();
116                         messageXMLEndIndex = -1;
117                 }
118         } while (messageXMLEndIndex != -1);
119 }
120
121 function UpdateStreamReaderOnLoad(){
122         window.clearInterval(UpdateStreamReaderPollTimer);
123         debug("UpdateStreamReaderOnLoad");
124         Dialog.confirm(
125                 "Live Update Stream ends!<br><br>You will not receive any Update from Enigma2.<br>Should I reconnect?",
126                  {windowParameters: {width:300, className: windowStyle},
127                         okLabel: "reconnect",
128                         buttonClass: "myButtonClass",
129                         cancel: function(win) {debug("cancel confirm panel")},
130                         ok: function(win) {UpdateStreamReaderStart(); return true;}
131                         }
132                 );
133 }
134 function UpdateStreamReaderOnError(){
135         // TODO: change this, because it will be called on 'PageUnload' while the request is still running
136         debug("UpdateStreamReaderOnError");
137         window.clearInterval(UpdateStreamReaderPollTimer);
138         Dialog.confirm(
139                 "Live Update Stream has an Error!<br><br>You will not receive any Update from Enigma2.<br>Should I try to reconnect?",
140                  {windowParameters: {width:300, className: windowStyle},
141                          okLabel: "reconnect",
142                          buttonClass: "myButtonClass",
143                          cancel: function(win) {debug("cancel confirm panel")},
144                          ok: function(win) {UpdateStreamReaderStart(); return true;}
145                         }
146                 );
147 }
148
149 //end UpdateStreamReader
150
151 function openWindow(title, inner, width, height, id){
152                         if(id == null) id = new Date().toUTCString();
153                         
154                         //debug(id);
155                         var win = new Window(id, {className: windowStyle, title: title, width: width, height: height});
156                         win.getContent().innerHTML = inner;
157                         win.setDestroyOnClose();
158                         win.showCenter();
159                         debug("opening Window: "+title);
160                         return win;
161 }
162
163 function messageBox(t, m){
164         Dialog.alert(m, {windowParameters: {title: t, className: windowStyle, width:200}, okLabel: "Close"});
165 }
166
167 //RND Template Function (http://www.amix.dk)
168
169 function RND(tmpl, ns) {
170         var fn = function(w, g) {
171                 g = g.split("|");
172                 var cnt = ns[g[0]];
173
174                 //Support for filter functions
175                 for(var i=1; i < g.length; i++) {
176                         cnt = eval(g[i])(cnt);
177                 }
178                 return cnt || w;
179         };
180         return tmpl.replace(/%\(([A-Za-z0-9_|.]*)\)/g, fn);
181 }
182
183 function debug(text){
184         if(DBG){
185                 try{
186                         debugWin.getContent().innerHTML += "DEBUG: "+text+"<br>";
187                 } catch (windowNotPresent) {}
188         }
189 }
190
191 function showhide(id){
192         o = document.getElementById(id).style;
193         o.display = (o.display!="none")? "none":"";
194 }
195
196 function set(what, value){
197         //debug(what+"-"+value);
198         element = parent.document.getElementById(what);
199         if(value.length > 550) {
200                 value = value.substr(0,550) + "[...]";
201         }
202         if (element){
203                 element.innerHTML = value;
204         }
205         if(navigator.userAgent.indexOf("MSIE") >=0) {
206                 elementscript= $('UpdateStreamReaderIEFixIFrame').document.getElementById('scriptzone');
207                 if(elementscript){
208                         elementscript.innerHTML = ""; // deleting set() from page, to keep the page short and to save memory                    
209                 }
210         }
211 }
212 function setComplete(what, value){
213         //debug(what+"-"+value);
214         element = parent.document.getElementById(what);
215         if (element){
216                 element.innerHTML = value;
217         }
218         if(navigator.userAgent.indexOf("MSIE") >=0) {
219                 elementscript= $('UpdateStreamReaderIEFixIFrame').document.getElementById('scriptzone');
220                 if(elementscript){
221                         elementscript.innerHTML = ""; // deleting set() from page, to keep the page short and to save memory                    
222                 }
223         }
224 }
225 // requestindikator
226 var requestcounter = 0;
227
228 function requestIndicatorUpdate(){
229         //debug(requestcounter+" open requests");
230         if(requestcounter>=1){
231                 $('RequestIndicator').style.display = "inline";
232         }else{
233                 $('RequestIndicator').style.display = "none";
234         }
235 }
236 function requestStarted(){
237         requestcounter +=1;
238         requestIndicatorUpdate();
239 }
240 function requestFinished(){
241         requestcounter -=1;
242         requestIndicatorUpdate();
243 }
244 // end requestindikator
245
246 function doRequest(url, readyFunction){
247         requestStarted();
248         //var password = "";
249         //var username = "";
250         debug(url);
251         new Ajax.Request(url,
252                 {
253                         method: 'get',
254                         requestHeaders: ['Pragma', 'no-cache', 'Cache-Control', 'must-revalidate', 'If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT'],
255                         onSuccess: readyFunction,
256                         onComplete: requestFinished 
257                 });
258 }
259
260 function getXML(request){
261         if (document.implementation && document.implementation.createDocument){
262                 var xmlDoc = request.responseXML
263         }
264         else if (window.ActiveXObject){
265                 var xmlInsert = document.createElement('xml');
266
267                 xmlInsert.setAttribute('innerHTML',request.responseText);
268                 xmlInsert.setAttribute('id','_MakeAUniqueID');
269                 document.body.appendChild(xmlInsert);
270                 xmlDoc = document.getElementById('_MakeAUniqueID');
271                 document.body.removeChild(document.getElementById('_MakeAUniqueID'));
272         } else {
273                 debug("Your Browser Sucks!");
274         }
275         return xmlDoc;
276 }
277
278 function zap(servicereference){
279         var url = "/web/zap?ZapTo=" + servicereference;
280         new Ajax.Request( url, { method: 'get', requestHeaders: ['Pragma', 'no-cache', 'Cache-Control', 'must-revalidate', 'If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT'] });
281 }
282 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
283 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
284 //++++       SignalPanel                           ++++
285 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
286 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
287
288 function initSignalPanel(){
289         $('SignalPanel').innerHTML = tplSignalPanelButton;
290 }
291 function openSignalDialog(){
292         openWindow("Signal Info",tplSignalPanel, 215, 75);
293 }
294
295 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
296 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
297 //++++ EPG functions                               ++++
298 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
299 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
300 function loadEPGBySearchString(string){
301                 doRequest(url_epgsearch+string,incomingEPGrequest);
302 }
303 function loadEPGByServiceReference(servicereference){
304                 doRequest(url_epgservice+servicereference,incomingEPGrequest);
305 }
306 function incomingEPGrequest(request){
307         debug("incoming request" +request.readyState);          
308         if (request.readyState == 4){
309                 var EPGItems = new EPGList(getXML(request)).getArray(true);
310                 debug("have "+EPGItems.length+" e2events");
311                 if(EPGItems.length > 0){                        
312                         var html = tplEPGListHeader;
313                         for (var i=0; i < EPGItems.length; i++){
314                                 try{
315                                         var item = EPGItems[i];                         
316                                         //Create JSON Object for Template
317                                         var namespace = {       
318                                                         'date': item.getTimeDay(), 
319                                                         'eventid': item.getEventId(), 
320                                                         'servicereference': item.getServiceReference(), 
321                                                         'servicename': item.getServiceName(), 
322                                                         'title': item.getTitle(),
323                                                         'titleESC': escape(item.getTitle()),
324                                                         'starttime': item.getTimeStartString(), 
325                                                         'duration': Math.ceil(item.getDuration()/60000), 
326                                                         'description': item.getDescription(), 
327                                                         'endtime': item.getTimeEndString(), 
328                                                         'extdescription': item.getDescriptionExtended(),
329                                                         'number': String(i),
330                                                         'extdescriptionSmall': extdescriptionSmall(item.getDescriptionExtended(),String(i))
331                                                 };
332                                         //Fill template with data and add id to our result
333                                         html += RND(tplEPGListItem, namespace);
334                                 } catch (blubb) { debug("Error rendering: "+blubb);     }
335                         }               
336                         html += tplEPGListFooter;
337                         openWindow("Electronic Program Guide", html, 900, 500);
338                 } else {
339                         messageBox('No Items found!', 'Sorry but i could not find any EPG Content containing your search value');
340                 }
341         }
342 }
343 function extdescriptionSmall(txt,num) {
344         if(txt.length > 410) {
345                 var shortTxt = txt.substr(0,410);
346                 txt = txt.replace(/\'\'/g, '&quot;');
347                 txt = txt.replace(/\\/g, '\\\\');
348                 txt = txt.replace(/\'/g, '\\\'');
349                 txt = txt.replace(/\"/g, '&quot;');
350                 var smallNamespace = { 'txt':txt,'number':num, 'shortTxt':shortTxt};
351                 return RND(tplEPGListItemExtend, smallNamespace);
352         } else {
353                 return txt;
354         }
355 }       
356
357 /////////////////////////
358
359 function loadServiceEPGNowNext(servicereference){
360         var url = url_epgnow+servicereference;
361         doRequest(url, incomingServiceEPGNowNext);      
362 }
363
364 function incomingServiceEPGNowNext(request){
365         if(request.readyState == 4){
366                 var epgevents = getXML(request).getElementsByTagName("e2eventlist").item(0).getElementsByTagName("e2event");
367                 for (var c =0; c < epgevents.length;c++){
368                         var eventnow = new EPGEvent(epgevents.item(c));
369                         
370                         if (eventnow.getEventId() != 'None'){
371                                 buildServiceListEPGItem(eventnow,"NOW");
372                         }
373                 }
374         }
375 }
376 function buildServiceListEPGItem(epgevent,nownext){
377         var e = $(epgevent.getServiceReference()+'EPG'+nownext);
378                 try{
379                         var namespace = {       
380                                 'starttime': epgevent.getTimeStartString(), 
381                                 'title': epgevent.getTitle(), 
382                                 'length': Math.ceil(epgevent.duration/60) 
383                         };
384                         e.innerHTML = RND(tplServiceListEPGItem, namespace);
385                 } catch (blubb) {
386                         debug("Error rendering: "+blubb);
387                 }       
388 }
389 ///////////////////
390
391
392 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
393 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
394 //++++ GUI functions                               ++++
395 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
396 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
397
398 var currentBodyMainElement = null
399
400 function setBodyMainContent(newelementname){
401         newelement =document.getElementById(newelementname);
402         if(currentBodyMainElement != null){
403                 currentBodyMainElement.style.display = "none";
404                 
405         }
406         newelement.style.display = "";
407         currentBodyMainElement = newelement;
408 }
409
410 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
411 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
412 //++++ volume functions                            ++++
413 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
414 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
415
416 function initVolumePanel(){
417         document.getElementById('VolumePanel').innerHTML = tplVolumePanel;
418         getVolume(); 
419 }
420 function getVolume()
421 {
422         doRequest(url_getvolume,handleVolumeRequest);
423 }
424 function volumeSet(newvalue)
425 {
426         doRequest(url_setvolume+newvalue,handleVolumeRequest);
427 }
428 function volumeUp()
429 {
430         doRequest(url_volumeup,handleVolumeRequest);
431 }
432 function volumeDown()
433 {
434         doRequest(url_volumedown,handleVolumeRequest);  
435 }
436 function volumeMute()
437 {
438         doRequest(url_volumemute,handleVolumeRequest);
439 }
440 function handleVolumeRequest(request){
441         if (request.readyState == 4) {
442                 var b = getXML(request).getElementsByTagName("e2volume");
443                 var newvalue = b.item(0).getElementsByTagName('e2current').item(0).firstChild.data;
444                 var mute = b.item(0).getElementsByTagName('e2ismuted').item(0).firstChild.data;
445                 debug("volume"+newvalue+";"+mute);
446                 
447                 for (var i = 1; i <= 10; i++)
448                 {
449                         if ( (newvalue/10)>=i){
450                                 $("volume"+i).src = "/webdata/gfx/led_on.png";
451                         }else{
452                                 $("volume"+i).src = "/webdata/gfx/led_off.png";
453                         }
454                 }
455                 if (mute == "False"){
456                         $("speaker").src = "/webdata/gfx/speak_on.png";
457                 }else{
458                         $("speaker").src = "/webdata/gfx/speak_off.png";
459                 }
460         }       
461 }
462 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
463 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
464 //++++ bouquet managing functions                  ++++
465 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
466 //+++++++++++++++++++++++++++++++++++++++++++++++++++++
467 function initChannelList(){
468         //debug("init ChannelList");    
469         var url = url_fetchchannels+encodeURIComponent(bouqet_tv);
470         doRequest(url, incomingTVBouquetList);
471
472         var url = url_fetchchannels+encodeURIComponent(bouqet_radio);
473         doRequest(url, incomingRadioBouquetList);
474
475         var url = url_fetchchannels+encodeURIComponent(bouqet_provider_tv);
476         doRequest(url, incomingProviderTVBouquetList);
477
478         var url = url_fetchchannels+encodeURIComponent(bouqet_provider_radio);
479         doRequest(url, incomingProviderRadioBouquetList);
480         
481         //getSettings();
482 }
483
484 var servicereftoloadepgnow="";
485 var loadedChannellist = new Object();
486 function loadBouquet(servicereference){ 
487         debug("loading bouquet with "+servicereference);
488         servicereftoloadepgnow = servicereference;
489         debug("loadBouquet " + typeof(loadedChannellist[servicereftoloadepgnow]));
490         if(typeof(loadedChannellist[servicereftoloadepgnow]) == "undefined") {
491                 doRequest(url_fetchchannels+servicereference, incomingChannellist);
492         } else {
493                 incomingChannellist();
494         }
495 }
496
497 function incomingTVBouquetList(request){
498         if (request.readyState == 4) {
499                 var list0 = new ServiceList(getXML(request)).getArray();
500                 debug("have "+list0.length+" TV Bouquet ");     
501                 $('accordionMenueBouquetContentTV').innerHTML = renderBouquetTable(list0,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
502                 //loading first entry of TV Favorites as default for ServiceList
503                 loadBouquet(list0[0].getServiceReference());
504         }
505 }
506 function incomingRadioBouquetList(request){
507         if (request.readyState == 4) {
508                 var list1 = new ServiceList(getXML(request)).getArray();
509                 debug("have "+list1.length+" Radio Bouquet ");  
510                 $('accordionMenueBouquetContentRadio').innerHTML = renderBouquetTable(list1,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
511         }       
512 }
513 function incomingProviderTVBouquetList(request){
514         if (request.readyState == 4) {
515                 var list2 = new ServiceList(getXML(request)).getArray();
516                 debug("have "+list2.length+" TV Provider Bouquet ");    
517                 $('accordionMenueBouquetContentProviderTV').innerHTML = renderBouquetTable(list2,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
518         }       
519 }
520 function incomingProviderRadioBouquetList(request){
521         if (request.readyState == 4) {
522                 var list2 = new ServiceList(getXML(request)).getArray();
523                 debug("have "+list2.length+" Radio Provider Bouquet "); 
524                 $('accordionMenueBouquetContentProviderRadio').innerHTML = renderBouquetTable(list2,tplBouquetListHeader,tplBouquetListItem,tplBouquetListFooter);
525         }       
526 }
527
528 function renderBouquetTable(bouquet,templateHeader,templateItem,templateFooter){
529         debug("renderBouquetTable with "+bouquet.length+" Bouqet");     
530         var html = templateHeader;
531         for (var i=0; i < bouquet.length; i++){
532                 try{
533                         var namespace = {
534                                 'servicereference': bouquet[i].getServiceReference(), 
535                                 'bouquetname': bouquet[i].getServiceName()
536                         };
537                         html += RND(templateItem, namespace);
538                 } catch (blubb) {}
539         }
540         html += templateFooter;
541         return html;
542 }       
543
544 function incomingChannellist(request){
545         var services = null;
546         if(typeof(loadedChannellist[servicereftoloadepgnow]) != "undefined"){
547                 services = loadedChannellist[servicereftoloadepgnow];
548         } else if(request.readyState == 4) {
549                 services = new ServiceList(getXML(request)).getArray();
550                 loadedChannellist[servicereftoloadepgnow] = services;
551                 debug("got "+services.length+" Services");
552         }
553         if(services != null) {
554                 var smallNamespace = {'mainServiceRef': servicereftoloadepgnow };
555                 listerHtml = RND(tplServiceListHeader, smallNamespace);
556                 for ( var i = 0; i < services.length ; i++){
557                         var reference = services[i];
558                         var namespace = {       
559                                 'servicereference': reference.getServiceReference(),
560                                 'servicename': reference.getServiceName()
561                         };
562                         listerHtml += RND(tplServiceListItem, namespace);
563                 }               
564                 listerHtml += tplServiceListFooter;
565                 document.getElementById('BodyContentChannellist').innerHTML = listerHtml;
566                 setBodyMainContent('BodyContentChannellist');
567                 loadServiceEPGNowNext(servicereftoloadepgnow);
568                 debug("incomingChannellist " + typeof(loadedChannellist[servicereftoloadepgnow]));
569         }
570 }
571 // Movies
572 function loadMovieList(){
573         debug("loading movies");
574         doRequest(url_movielist, incomingMovieList);    
575 }
576
577 function incomingMovieList(request){
578         if(request.readyState == 4){
579                 var movies = new MovieList(getXML(request)).getArray();
580                 debug("have "+movies.length+" movies");
581                 listerHtml      = tplMovieListHeader;           
582                 for ( var i = 0; i <movies.length; i++){
583                         var movie = movies[i];
584                         var namespace = {       
585                                 'servicereference': movie.getServiceReference(),
586                                 'servicename': movie.getServiceName() ,
587                                 'title': movie.getTitle(), 
588                                 'description': movie.getDescription(), 
589                                 'descriptionextended': movie.getDescriptionExtended(), 
590                                 'tags': movie.getTags().join(', ') 
591                         };
592                         debug(movie.getServiceReference());
593                         listerHtml += RND(tplMovieListItem, namespace);
594                 }
595                 listerHtml += tplMovieListFooter;
596                 document.getElementById('BodyContentChannellist').innerHTML = listerHtml;
597                 setBodyMainContent('BodyContentChannellist');
598                 
599         }               
600 }
601
602 // Timer
603 function addTimerByID(serviceRef,eventID,justplay){
604         debug("adding timer by eventid="+eventID+" for "+serviceRef);justplay
605         doRequest(url_timeraddbyeventid+"?serviceref="+serviceRef+"&eventid="+eventID+"&justplay="+justplay, incomingTimerAddResult);   
606 }
607 function incomingTimerAddResult(request){
608         debug("onTimerAdded");
609         if(request.readyState == 4){
610                 var addresult = new TimerAddResult(getXML(request));
611                 if(addresult.getState()){
612                         //timer was add
613                         loadTimerList();
614                 }else{
615                         messageBox("Timer Error","your Timer could not be added!\nReason: "+addresult.getStateText());
616                 }
617         }               
618 }
619 function loadTimerList(){
620         debug("loading timers");
621         doRequest(url_timerlist, incomingTimerList);    
622 }
623
624 function incomingTimerList(request){
625         if(request.readyState == 4){
626                 var timers = new TimerList(getXML(request)).getArray();
627                 debug("have "+timers.length+" timer");
628                 listerHtml      = tplTimerListHeader;
629                 
630                 var aftereventReadable = new Array ('Nothing', 'Standby', 'Deepstandby/Shutdown');
631                 var justplayReadable = new Array('record', 'zap');
632                 var OnOff = new Array('on', 'off');
633
634                 for ( var i = 0; i <timers.length; i++){
635                         var timer = timers[i];
636                         var beginDate = new Date(Number(timer.getTimeBegin())*1000);
637                         var endDate = new Date(Number(timer.getTimeEnd())*1000);
638                         debug(timer.getDisabled());
639                         debug(OnOff[Number(timer.getDisabled())]);
640                         var namespace = {       
641                                 'servicereference': timer.getServiceReference(),
642                                 'servicename': timer.getServiceName() ,
643                                 'title': timer.getName(), 
644                                 'description': timer.getDescription(), 
645                                 'descriptionextended': timer.getDescriptionExtended(), 
646                                 'begin': timer.getTimeBegin(),
647                                 'beginDate': beginDate.toLocaleString(),
648                                 'end': timer.getTimeEnd(),
649                                 'endDate': endDate.toLocaleString(),
650                                 'state': timer.getState(),
651                                 'duration': Math.ceil((timer.getDuration()/60)),
652                                 'repeated': timer.getRepeated(),
653                                 'repeatedReadable': repeatedReadable(timer.getRepeated()),
654                                 'justplay': timer.getJustplay(),
655                                 'justplayReadable': justplayReadable[Number(timer.getJustplay())],
656                                 'afterevent': timer.getAfterevent(),
657                                 'aftereventReadable': aftereventReadable[Number(timer.getAfterevent())],
658                                 'disabled': timer.getDisabled(),
659                                 'onOff': OnOff[Number(timer.getDisabled())],
660                                 'color': colorTimerListEntry( timer.getState() )
661                         };
662                         listerHtml += RND(tplTimerListItem, namespace);
663                 }
664                 listerHtml += tplTimerListFooter;
665                 document.getElementById('BodyContentChannellist').innerHTML = listerHtml;
666                 setBodyMainContent('BodyContentChannellist');
667         }
668 }
669 function repeatedReadable(num) {
670         num = Number(num);
671         
672         if(num == 0) {
673                 return "One Time";
674         }
675         
676         var html = "";
677         
678         var Repeated = new Object();
679         Repeated["Mo-Su"] =127;
680         Repeated["Su"] =    64;
681         Repeated["Sa"] =    32;
682         Repeated["Mo-Fr"] = 31;
683         Repeated["Fr"] =    16;
684         Repeated["Th"] =     8;
685         Repeated["We"] =     4;
686         Repeated["Tu"] =     2;
687         Repeated["Mo"] =     1;
688         
689         for(rep in Repeated) {
690                 if(rep.toString() != "extend") {
691                         var check = Number(Repeated[rep]);
692                         if(check <= num) {
693                                 num -= check;
694                                 if(html == "") {
695                                         html += rep.toString();
696                                 } else {
697                                         html += "," + rep.toString();
698                                 }
699                         }
700                 }
701         }
702         return html;
703 }
704
705 function colorTimerListEntry (state) {
706         if (state == 0) {
707                 return "000000";
708         } else if(state == 1) {
709                 return "00BCBC";
710         } else if(state == 2) {
711                 return "9F1919";
712         } else {
713                 return "00BCBC";
714         }
715 }
716 function delTimer(serviceRef,begin,end){
717         debug(url_timerdelete+"?serviceref="+serviceRef+"&begin="+begin+"&end="+end);
718         doRequest(url_timerdelete+"?serviceref="+serviceRef+"&begin="+begin+"&end="+end, incomingTimerDelResult);       
719 }
720
721 function incomingTimerDelResult(request){
722         debug("onTimerDeleted");
723         if(request.readyState == 4){
724                 var delresult = new TimerAddResult(getXML(request));
725                 debug("Lade liste");
726                 loadTimerList();
727         }               
728 }
729
730 // send Messages
731 function showMessageSendForm(){
732                 document.getElementById('BodyContentChannellist').innerHTML = tplMessageSendForm;
733 }
734 function sendMessage(messagetext,messagetype,messagetimeout){
735         if(!messagetext){
736                 messagetext = $('MessageSendFormText').value;
737         }       
738         if(!messagetimeout){
739                 messagetimeout = $('MessageSendFormTimeout').value;
740         }       
741         if(!messagetype){
742                 var index = $('MessageSendFormType').selectedIndex;
743                 messagetype = $('MessageSendFormType').options[index].value;
744         }       
745         doRequest(url_message+'?text='+messagetext+'&type='+messagetype+'&timeout='+messagetimeout, incomingMessageResult);
746 }
747 function incomingMessageResult(request){
748
749         if(request.readyState== 4){
750                 var b = getXML(request).getElementsByTagName("e2message");
751                 var result = b.item(0).getElementsByTagName('e2result').item(0).firstChild.data;
752                 var resulttext = b.item(0).getElementsByTagName('e2resulttext').item(0).firstChild.data;
753                 if (result=="True"){
754                         messageBox('message send','message send successfully! it appears on TV-Screen');
755                 }else{
756                         messageBox('message send failed',resulttext);
757                 }
758         }               
759 }
760
761 // PowerState Code
762 function showPowerStateSendForm(){
763                 document.getElementById('BodyContentChannellist').innerHTML = tplPowerStateSendForm;
764 }
765 function sendPowerState(newState){
766         doRequest(url_powerstate+'?newstate='+newState, incomingPowerStateResult);
767 }
768 function incomingPowerStateResult(request){
769         debug(request.readyState);
770         if(request.readyState == 4){
771                 var b = getXML(request).getElementsByTagName("e2powerstate");
772                 var result = b.item(0).getElementsByTagName('e2result').item(0).firstChild.data;
773                 var resulttext = b.item(0).getElementsByTagName('e2resulttext').item(0).firstChild.data;
774                 var tplPowerStateSendForm2 = '<h1>PowerState is changing to:'+resulttext+ '</h1>' + tplPowerStateSendForm;
775                 document.getElementById('BodyContentChannellist').innerHTML = tplPowerStateSendForm2;
776         } else {
777                 document.getElementById('BodyContentChannellist').innerHTML = "<h1>some unknown error</h1>" + tplPasswordSendForm;
778         }
779 }
780
781 // RemoteControl Code
782 function showRemoteControllSendForm(){
783                 document.getElementById('BodyContentChannellist').innerHTML = tplRemoteControlForm;
784 }
785 function sendRemoteControlRequest(command){
786         doRequest(url_remotecontrol+'?command='+command, incomingRemoteControlResult);
787 }
788 function incomingRemoteControlResult(request){
789         if(request.readyState == 4){
790                 var b = getXML(request).getElementsByTagName("e2remotecontrol");
791                 var result = b.item(0).getElementsByTagName('e2result').item(0).firstChild.data;
792                 var resulttext = b.item(0).getElementsByTagName('e2resulttext').item(0).firstChild.data;
793                 showRemoteControllSendForm();
794         } else {
795                 document.getElementById('BodyContentChannellist').innerHTML = "<h1>some unknown error</h1>" + tplRemoteControlForm;
796         }
797 }
798
799 function loadTimerFormNow() {
800         var now = new Date();
801         addTimerEditFormObject["syear"] = now.getFullYear();
802         addTimerEditFormObject["smonth"] = now.getMonth() + 1;
803         addTimerEditFormObject["sday"] = now.getDate();
804         addTimerEditFormObject["shour"] = now.getHours();
805         addTimerEditFormObject["smin"] = now.getMinutes();
806
807         var     plusTwoHours = new Date(now.getTime() + ((120 *60)*1000) );
808         addTimerEditFormObject["eyear"] = plusTwoHours.getFullYear();
809         addTimerEditFormObject["emonth"] = plusTwoHours.getMonth() + 1;
810         addTimerEditFormObject["eday"] = plusTwoHours.getDate();
811         addTimerEditFormObject["ehour"] = plusTwoHours.getHours();
812         addTimerEditFormObject["emin"] = plusTwoHours.getMinutes();
813                 
814         addTimerEditFormObject["justplay"] = "record";
815         addTimerEditFormObject["channel"] = "";
816         addTimerEditFormObject["channelSort"] = "tv";
817         addTimerEditFormObject["name"] = "";
818         addTimerEditFormObject["description"] = "";
819         addTimerEditFormObject["repeated"] = 0;
820         addTimerEditFormObject["afterEvent"] = "0";
821         addTimerEditFormObject["deleteOldOnSave"] = 0;
822         
823         addTimerEditFormObject["beginOld"] = 0;
824         addTimerEditFormObject["endOld"] = 0;
825         
826         
827         debug("loadTimerFormNow 2");
828         loadTimerFormChannels();
829 }
830
831 function loadTimerFormSeconds(justplay,begin,end,repeated,channel,name,description,afterEvent,deleteOldOnSave) {
832
833         var start = new Date(Number(begin)*1000);
834         addTimerEditFormObject["syear"] = start.getFullYear();
835         addTimerEditFormObject["smonth"] = start.getMonth() + 1;
836         addTimerEditFormObject["sday"] = start.getDate();
837         addTimerEditFormObject["shour"] = start.getHours();
838         addTimerEditFormObject["smin"] = start.getMinutes();
839         
840         var     stopp = new Date(Number(end)*1000);
841         addTimerEditFormObject["eyear"] = stopp.getFullYear();
842         addTimerEditFormObject["emonth"] = stopp.getMonth() + 1;
843         addTimerEditFormObject["eday"] = stopp.getDate();
844         addTimerEditFormObject["ehour"] = stopp.getHours();
845         addTimerEditFormObject["emin"] = stopp.getMinutes();
846         
847         addTimerEditFormObject["justplay"] = String(justplay);
848         addTimerEditFormObject["channel"] = decodeURIComponent(String(channel));
849         addTimerEditFormObject["channelSort"] = "";
850         addTimerEditFormObject["name"] = String(name);
851         addTimerEditFormObject["description"] = String(description);
852         addTimerEditFormObject["repeated"] = Number(repeated);
853         addTimerEditFormObject["afterEvent"] = Number(afterEvent);
854         
855         debug(justplay+"|"+begin+"|"+end+"|"+repeated+"|"+channel+"|"+name+"|"+description+"|"+afterEvent);
856
857         addTimerEditFormObject["deleteOldOnSave"] = Number(deleteOldOnSave);
858         addTimerEditFormObject["beginOld"] = Number(begin);
859         addTimerEditFormObject["endOld"] = Number(end);
860         
861         loadTimerFormChannels();
862 }
863
864 // startin to load for TV
865 function loadTimerFormChannels() {
866         if(addTimerEditFormObject["TVListFilled"] == 1 && addTimerEditFormObject["RadioListFilled"] == 1) {
867                 loadTimerForm();
868         } else if(addTimerEditFormObject["TVListFilled"] == 1 && addTimerEditFormObject["RadioListFilled"] == 0) {
869                 addTimerListFormatTV();
870         } else {
871                 var favorites = '1%3A7%3A1%3A0%3A0%3A0%3A0%3A0%3A0%3A0%3AFROM%20BOUQUET%20%22userbouquet.favourites.tv%22%20ORDER%20BY%20bouquet'
872                 doRequest(url_fetchchannels+favorites, addTimerListFormatTV);
873         }
874 }
875
876 function addTimerListFormatTV(request) {
877         if(addTimerEditFormObject["RadioListFilled"] == 0) {
878                 if(request.readyState == 4){
879                         var services = new ServiceList(getXML(request)).getArray();
880                         var tv = new Object();
881                         for ( var i = 0; i < services.length ; i++){
882                                 var reference = services[i];
883                                 tv[reference.servicereference] = reference.servicename;
884                         }
885                         addTimerEditFormObject["TVListFilled"] = 1;
886                         addTimerEditFormObject["TVList"] = tv;
887                 }
888         }
889         if(addTimerEditFormObject["RadioListFilled"] == 1) {
890                 loadTimerForm()
891         } else {
892                 var favorites = '1%3A7%3A1%3A0%3A0%3A0%3A0%3A0%3A0%3A0%3AFROM%20BOUQUET%20%22userbouquet.favourites.radio%22%20ORDER%20BY%20bouquet';
893                 doRequest(url_fetchchannels+favorites, addTimerListFormatRadio);
894         }
895 }
896 function addTimerListFormatRadio(request) {
897         if(request.readyState == 4){
898                 var services = new ServiceList(getXML(request)).getArray();
899                 var radio = new Object();
900                 for ( var i = 0; i < services.length ; i++){
901                         var reference = services[i];
902                         radio[reference.servicereference] = reference.servicename;
903                 }
904                 addTimerEditFormObject["RadioListFilled"] = 1;
905                 addTimerEditFormObject["RadioList"] = radio;
906         }
907         loadTimerForm();
908 }
909
910 function loadTimerForm(){
911
912         var Action = new Object();
913         Action["0"] = "Record";
914         Action["1"] = "Zap";
915         
916         var Repeated = new Object();
917         Repeated["1"] =  "mo";
918         Repeated["2"] = "tu";
919         Repeated["4"] =  "we";
920         Repeated["8"] =  "th";
921         Repeated["16"] = "fr";
922         Repeated["32"] = "sa";
923         Repeated["64"] = "su";
924         Repeated["31"] = "mf";
925         Repeated["127"] ="ms";
926         
927         var AfterEvent = new Object();
928         AfterEvent["0"] = "Nothing";
929         AfterEvent["1"] = "Standby";
930         AfterEvent["2"] = "Deepstandby/Shutdown";
931         
932         addTimerEditFormObject["name"] = (typeof(addTimerEditFormObject["name"]) != "undefined") ? addTimerEditFormObject["name"] : "";
933         addTimerEditFormObject["name"] = (addTimerEditFormObject["name"] == "") ? " " : addTimerEditFormObject["name"];
934
935         addTimerEditFormObject["description"] = (typeof(addTimerEditFormObject["description"]) != "undefined") ? addTimerEditFormObject["description"] : "";
936         addTimerEditFormObject["description"] = (addTimerEditFormObject["description"] == "") ? " " : addTimerEditFormObject["description"];
937
938         var channelObject = addTimerEditFormObject["TVList"];
939         if(     addTimerEditFormObject["channelSort"] == "tv") {
940                 // already set
941         } else if( addTimerEditFormObject["channelSort"] == "radio") {
942                 channelObject = addTimerEditFormObject["RadioList"];
943         } else {
944                 var found = 0;
945                 for( element in addTimerEditFormObject["TVList"]) {
946                         if( element = addTimerEditFormObject["channel"]) {
947                                 // already set
948                                 found = 1;
949                                 break;
950                         }
951                 }
952                 if(found == 0) {
953                         for( element in addTimerEditFormObject["RadioList"]) {
954                                 if( element = addTimerEditFormObject["channel"]) {
955                                         channelObject = addTimerEditFormObject["RadioList"];
956                                         found = 1;
957                                         break;
958                                 }
959                         }
960                 }
961                 if(found == 0) {
962                         addTimerEditFormObject["TVList"][addTimerEditFormObject["channel"]] = "Unknown selected Channel";
963                 }
964         }
965
966         var namespace = {       
967                                 'justplay': addTimerFormCreateOptionList(Action, addTimerEditFormObject["justplay"]),
968                                 'syear': addTimerFormCreateOptions(2007,2010,addTimerEditFormObject["syear"]),
969                                 'smonth': addTimerFormCreateOptions(1,12,addTimerEditFormObject["smonth"]),
970                                 'sday': addTimerFormCreateOptions(1,31,addTimerEditFormObject["sday"]),
971                                 'shour': addTimerFormCreateOptions(0,23,addTimerEditFormObject["shour"]),
972                                 'smin': addTimerFormCreateOptions(0,59,addTimerEditFormObject["smin"]),
973                                 'eyear': addTimerFormCreateOptions(2007,2010,addTimerEditFormObject["eyear"]),
974                                 'emonth': addTimerFormCreateOptions(1,12,addTimerEditFormObject["emonth"]),
975                                 'eday': addTimerFormCreateOptions(1,31,addTimerEditFormObject["eday"]),
976                                 'ehour': addTimerFormCreateOptions(0,23,addTimerEditFormObject["ehour"]),
977                                 'emin': addTimerFormCreateOptions(0,59,addTimerEditFormObject["emin"]),
978                                 'channel': addTimerFormCreateOptionList(channelObject, addTimerEditFormObject["channel"]),
979                                 'name': addTimerEditFormObject["name"],
980                                 'description': addTimerEditFormObject["description"],
981                                 'repeated': addTimerFormCreateOptionListRepeated(Repeated, addTimerEditFormObject["repeated"]),
982                                 'deleteOldOnSave': addTimerEditFormObject["deleteOldOnSave"],
983                                 'channelOld': addTimerEditFormObject["channel"],
984                                 'beginOld': addTimerEditFormObject["beginOld"],
985                                 'endOld': addTimerEditFormObject["endOld"],
986                                 'afterEvent': addTimerFormCreateOptionList(AfterEvent, addTimerEditFormObject["afterEvent"])
987                 };
988         var listerHtml = RND(tplAddTimerForm, namespace);
989         document.getElementById('BodyContentChannellist').innerHTML = listerHtml;
990
991         // Empty some stuff, but keep others to have the performance
992         var tmp1 = addTimerEditFormObject["RadioList"];
993         var tmp2 = addTimerEditFormObject["TVList"];
994         addTimerEditFormObject = new Object();
995         addTimerEditFormObject["deleteOldOnSave"] = 0;
996         addTimerEditFormObject["RadioList"] = tmp1;
997         addTimerEditFormObject["TVList"] = tmp2;
998         addTimerEditFormObject["TVListFilled"] = 1;
999         addTimerEditFormObject["RadioListFilled"] = 1;
1000 }
1001
1002 function addTimerFormCreateOptions(start,end,number) {
1003         var html = '';
1004         for(i = start; i <= end; i++) {
1005                 var txt = (String(i).length == 1) ? "0" + String(i) : String(i);
1006                 var selected =  (i == Number(number)) ? "selected" : " ";
1007                 var namespace = {
1008                         'value': i,
1009                         'txt': txt,
1010                         'selected': selected };
1011                 html += RND(tplAddTimerFormOptions, namespace);
1012         }
1013         return html;
1014 }
1015 function addTimerFormCreateOptionList(object,selected) {
1016         html = '';
1017         for(var element in object) {
1018                 var txt = String(object[element]);
1019                 var sel = (element == selected) ? "selected" : " ";
1020                 var namespace = {
1021                         'value': element,
1022                         'txt': txt,
1023                         'selected': sel };
1024                 if(element != "extend") {
1025                         html += RND(tplAddTimerFormOptions, namespace);
1026                 }
1027         }
1028         return html;
1029 }
1030
1031 function addTimerFormChangeTime(which) {
1032         var start = new Date( $('syear').value, ($('smonth').value -1), $('sday').value, $('shour').value, $('smin').value, 0);
1033         var end = new Date($('eyear').value, ($('emonth').value -1), $('eday').value, $('ehour').value, $('emin').value, 0);
1034 //      debug("("+start+")(" + end+")");
1035
1036         if(start.getTime() > end.getTime()) {
1037                 opponent = (which.substr(0,1) == 's') ? 'e' +  which.substr(1, which.length -1) : 's' +  which.substr(1, which.length -1) ;
1038                 $(opponent).value = $(which).value;
1039         }
1040         var all = new Array('year','month','day','hour','min');
1041         for(i=0; i < all.length; i++) {
1042                 if(which.substr(1, which.length -1) == all[i]) {
1043                         addTimerFormChangeTime(which.substr(0,1) + all[i+1] );
1044                         break;
1045                 }
1046         }
1047 }
1048 function addTimerFormChangeType() {
1049         var selected = ($('tvradio').checked == true) ? addTimerEditFormObject["TVList"]: addTimerEditFormObject["RadioList"];
1050         for (i = $('channel').options.length; i != 0; i--) {
1051                 $('channel').options[i - 1] = null;
1052         }
1053         var i = -1;
1054         for(element in selected) {
1055                 if(element != "extend") {
1056                         i++;
1057                         $('channel').options[i] = new Option(selected[element]);
1058                         $('channel').options[i].value = element;
1059                 }
1060         }
1061 }
1062 function addTimerFormCreateOptionListRepeated(Repeated,repeated) {
1063         var num = Number(repeated);
1064         var html = "";
1065         var html2 = "";
1066         var list = new Array(127, 64, 32, 31, 16, 8, 4, 2, 1);
1067         for(i = 0; i < list.length; i++) {
1068                 var txt = String(Repeated[String(list[i])]);
1069                 if( String(Repeated[String(list[i])]) == "mf") {
1070                         txt = "Mo-Fr";
1071                 } else if( String(Repeated[String(list[i])]) == "ms") {
1072                         txt = "Mo-Su";
1073                 } else {
1074                         txt = txt.substr(0,1).toUpperCase() + txt.substr(1,1);
1075                 }
1076                 var checked = " ";
1077                 if(num >=  list[i]) {
1078                         num -= list[i];
1079                         checked = "checked";
1080                 }
1081                 var namespace = {
1082                         'id': Repeated[String(list[i])],
1083                         'name': Repeated[String(list[i])],
1084                         'value': list[i],
1085                         'txt': txt,
1086                         'checked': checked };
1087                 if(String(Repeated[String(list[i])]) == "mf" || String(Repeated[String(list[i])]) == "ms") {
1088                         html2 = RND(tplAddTimerFormCheckbox, namespace) + html2;
1089                 } else {
1090                         html = RND(tplAddTimerFormCheckbox, namespace) + html;
1091                 }
1092         }
1093         return html + html2;
1094 }
1095 function sendAddTimer() {
1096         var beginD = new Date(ownLazyNumber($('syear').value), (ownLazyNumber($('smonth').value) - 1), ownLazyNumber($('sday').value), ownLazyNumber($('shour').value), ownLazyNumber($('smin').value));
1097         var begin = beginD.getTime()/1000;
1098         
1099         var endD = new Date(ownLazyNumber($('eyear').value), (ownLazyNumber($('emonth').value) - 1), ownLazyNumber($('eday').value), ownLazyNumber($('ehour').value), ownLazyNumber($('emin').value));
1100         var end = endD.getTime()/1000;
1101
1102         var repeated = 0;
1103         if( $('ms').checked ) {
1104                 repeated = 127;
1105         } else if($('mf').checked) {
1106                 repeated = 31;
1107                 if($('sa').checked) {
1108                         repeated += ownLazyNumber($('sa').value);
1109                 }
1110                 if($('su').checked) {
1111                         repeated += ownLazyNumber($('su').value);
1112                 }
1113         } else {
1114                 var check = new Array('mo', 'tu', 'we', 'th', 'fr');
1115                 for(i = 0; i < check.length; i++) {
1116                         if($(check[i]).cheked) {
1117                                 repeated += Number($(check[i]).value);
1118                         }
1119                 }
1120         }
1121         
1122         /*if(ownLazyNumber($('deleteOldOnSave').value) == 1) {
1123                 delTimer($('channelOld').value,$('beginOld').value,$('endOld').value);
1124         }*/
1125         var descriptionClean = ($('descr').value == " " || $('descr').value == "N/A") ? "" : $('descr').value;
1126         var nameClean = ($('name').value == " " || $('name').value == "N/A") ? "" : $('name').value;
1127         
1128         var repeated = 0;
1129         if($('ms').checked) {
1130                 repeated = ownLazyNumber($('ms').value);
1131         } else if($('mf').checked) {
1132                 repeated = ownLazyNumber($('mf').value);
1133                 if($('su').checked) {
1134                         repeated += ownLazyNumber($('su').value);
1135                 }
1136                 if($('sa').checked) {
1137                         repeated += ownLazyNumber($('sa').value);
1138                 }
1139         } else {
1140                 if($('mo').checked) {
1141                         repeated += ownLazyNumber($('mo').value);
1142                 }
1143                 if($('tu').checked) {
1144                         repeated += ownLazyNumber($('tu').value);
1145                 }
1146                 if($('we').checked) {
1147                         repeated += ownLazyNumber($('we').value);
1148                 }
1149                 if($('th').checked) {
1150                         repeated += ownLazyNumber($('th').value);
1151                 }
1152                 if($('fr').checked) {
1153                         repeated += ownLazyNumber($('fr').value);
1154                 }
1155                 if($('sa').checked) {
1156                         repeated += ownLazyNumber($('sa').value);
1157                 }
1158                 if($('su').checked) {
1159                         repeated += ownLazyNumber($('su').value);
1160                 }
1161         }
1162         debug(repeated);
1163         doRequest(url_timerchange+"?"+"serviceref="+$('channel').value+"&begin="+begin
1164          +"&end="+end+"&name="+nameClean+"&description="+descriptionClean
1165          +"&afterevent="+$('after_event').value+"&eit=0&disabled=0"
1166          +"&justplay="+ownLazyNumber($('justplay').value)+"&repeated="+repeated
1167          +"&channelOld="+$('channelOld').value
1168          +"&beginOld="+$('beginOld').value+"&endOld="+$('endOld').value
1169          +"&deleteOldOnSave="+ownLazyNumber($('deleteOldOnSave').value), incomingTimerAddResult);
1170         
1171 }
1172
1173 function getSettings(){
1174         doRequest(url_settings, incomingGetSettings);
1175 }
1176
1177 function incomingGetSettings(request){
1178         if(request.readyState == 4){
1179                 settings = new Settings(getXML(request)).getArray();
1180 /*              for ( var i = 0; i <settings.length; i++){
1181                         var setting = settings[i];
1182                         debug(setting.getSettingValue() +":" + setting.getSettingName());
1183                 }*/
1184                 
1185         }               
1186 }
1187 function sendToggleTimerDisable(justplay,begin,end,repeated,channel,name,description,afterEvent,disabled){
1188         disabled = (ownLazyNumber(disabled) == 0) ? 1 : 0;
1189         
1190         var descriptionClean = (description == " " || description == "N/A") ? "" : description;
1191         var nameClean = (name == " " || name == "N/A") ? "" : name;
1192
1193         doRequest(url_timerchange+"?"+"serviceref="+channel+"&begin="+begin
1194          +"&end="+end+"&name="+nameClean+"&description="+descriptionClean
1195          +"&afterevent="+afterEvent+"&eit=0&disabled="+disabled
1196          +"&justplay="+justplay+"&repeated="+repeated
1197          +"&channelOld="+channel
1198          +"&beginOld="+begin+"&endOld="+end
1199          +"&deleteOldOnSave=1", incomingTimerAddResult);
1200 }
1201 function ownLazyNumber(num) {
1202         if(isNaN(num)){
1203                 return 0;
1204         } else {
1205                 return Number(num);
1206         }
1207 }
1208
1209 var subServicesInsertedList = new Object();
1210
1211 function getSubServices(servicereference) {
1212                 doRequest(url_subservices,incomingSubServiceRequest);
1213 }
1214 function incomingSubServiceRequest(request){
1215         if(request.readyState == 4){
1216                 var services = new ServiceList(getXML(request)).getArray();
1217                 listerHtml      = '';           
1218                 debug("got "+services.length+" SubServices");
1219                 if(services.length > 1) {
1220
1221                         first = services[0];
1222                         var mainChannellist = loadedChannellist[String($('mainServiceRef').value)];
1223                         
1224                         var oldEntryPosition = -1;
1225                         for(i = 0; i < mainChannellist.length; i++) {
1226                                 var service = mainChannellist[i];
1227                                 if(String(service.getServiceReference()) == String(first.getServiceReference())) {
1228                                         oldEntryPosition = i + 1;
1229                                         break;
1230                                 }
1231                         }
1232                         if(typeof(subServicesInsertedList[String(first.getServiceReference())]) != "undefined") {
1233                                 for ( var i = 1; i < subServicesInsertedList[String(first.getServiceReference())].length ; i++){
1234                                         var reference = subServicesInsertedList[String(first.getServiceReference())][i];
1235                                         document.getElementById(reference.getServiceReference()+'extend').innerHTML = "";
1236                                 }
1237                                 for(i = oldEntryPosition; i < oldEntryPosition + subServicesInsertedList[String(first.getServiceReference())].length; i++) {
1238                                         mainChannellist.splice(i);
1239                                 }
1240                         }
1241
1242                         for ( var i = 0; i < services.length ; i++){
1243                                 var reference = services[i];
1244                                 var namespace = {       
1245                                         'servicereference': reference.getServiceReference(),
1246                                         'servicename': reference.getServiceName()
1247                                 };
1248                                 listerHtml += RND(tplServiceListItem, namespace);
1249                                 if(oldEntryPosition > -1) {
1250                                         mainChannellist = mainChannellist.insert(oldEntryPosition++, reference);
1251                                 }
1252                         }
1253
1254                         document.getElementById(first.getServiceReference()+'extend').innerHTML = listerHtml;
1255                         subServicesInsertedList[String(first.getServiceReference())] = services;
1256                         loadedChannellist[$('mainServiceRef').value] = mainChannellist;
1257                 }
1258         }
1259 }
1260 // Array.insert( index, value ) - Insert value at index, without overwriting existing keys
1261 Array.prototype.insert = function( j, v ) {
1262  if( j>=0 ) {
1263   var a = this.slice(), b = a.splice( j );
1264   a[j] = v;
1265   return a.concat( b );
1266  }
1267 }
1268 // Array.splice() - Remove or replace several elements and return any deleted elements
1269 if( typeof Array.prototype.splice==='undefined' ) {
1270  Array.prototype.splice = function( a, c ) {
1271   var i = 0, e = arguments, d = this.copy(), f = a, l = this.length;
1272   if( !c ) { c = l - a; }
1273   for( i; i < e.length - 2; i++ ) { this[a + i] = e[i + 2]; }
1274   for( a; a < l - c; a++ ) { this[a + e.length - 2] = d[a - c]; }
1275   this.length -= c - e.length + 2;
1276   return d.slice( f, f + c );
1277  };
1278 }