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