//@liv-in-sky   20.9.21 -09:13
// FORUM: https://forum.iobroker.net/topic/42855/html-liste-f%C3%BCr-telegram-und-vis
//WENN TRUE MÜSSEN DIESE DATENPUNKE SELBST ANGELEGT WERDEN - DAS SCRIPT LEGT KEINE DATENPUNKTE AN !!!
// @ts-ignore
let braucheEinVISWidget=true;                          // bei true wird ein html-tabelle in einen dp geschrieben - siehe nächste zeile
let  dpVIS="MeineToDoListe"                            //WICHTIG wenn braucheEinVISWidget auf true gesetzt !!  dp zusätzlich für VIS-HTML-Basic-Widget
let braucheEinJSON=true;                               // bei true wird ein html-tabelle in einen dp geschrieben - siehe nächste zeile
let  dpJSON="MeineToDoListeJSON"                       //WICHTIG wenn braucheEinJSON auf true gesetzt !!  dp zusätzlich für JSON
let mySchedule="  */15  * * * * ";                     //alle 15 minuten für vis
//ZUSÄTZLICH VARIABLEN
let mitAlphabet=false;
//TELEGRAM
let telegramInstance="1";
let myTeleUpdateSchedule="* * * * *"                       //minütlich für telegram update
let listenNameTele="Die Liste"                             // "listenüberschrift in telegram "
let einspaltigTele=false;                                  //  die Anzeige in Telegram  soll einspaltig sein
let ichWillEinDatum=true;                                  // bei fasle wird es so angezeigt: 2d 1s 30m
let myDatumFormat="DD.MM. - SS:mm"                         // für anzeige zeit in VIS
//---------------------------------------
//HIER DIE SPALTEN ANZAHL DEFINIEREN - jede Spalte einen Wert - in diesem Beispiel sind es 3 - es MÜSSEN in allen Arrays die GLEICHE Anzahl für die Werte sein
let val=             ["dummy1","dummy2","dummy3"];       //HIER SIND DIE  WERTE, DIE IN DER SCHLEIFE GEFILTERET WERDEN -  jeder val[x] muss unten in der schleife gesetzt werden !!
let Feld1lAlign=     ["left","center","center"];           // AUSRICHTUNG IN DER SPALTE
let htmlSpalte1Weite=["150","auto","auto"];            //BREITE DER SPALTE, wenn nicht auto
let htmlFeld=        ["ITEM","DATE","DEL"];       // NAME/ÜBERSCHRIFT DER SPALTE
let schalterInSpaltenUeberschrift=[false,true,true,false,false,false];
let symbolSchalter=["na","na","⊕","⊕","✗"];    // Symbol 3= x und symbol 4 = +
//-----------------------------------
//Symbole für Tabelle z.b.: ⚪  ⚫ ⭕  🔴 🔵 ⏱ 💀 👍 👎 📑 💲 👀 🔹 ✅ ❌ ⚠️ mehr: https://emojiterra.com/de/ oder https://unicode-table.com/de/html-entities/
//hier werden die styles für die tabelle definiert
//ÜBERSCHRIFT ÜBER TABELLE
const htmlUberschrift=false;                             // mit Überschrift über der tabelle
const htmlSignature=false;                               // anstatt der Überscghrift eine signature: - kleiner - anliegend
const htmlFeldUeber='ioBroker Instanzen';                // für Überschrift und Signature falls htmlUberschrift und htmlSignature ist true
const htmlFarbUber="white";                              // Farbe der Überschrift
const htmlSchriftWeite="normal";                         // bold, normal - Fettschrift für Überschrift
const htmlUEberFontGroesse="18px";                       // schriftgröße überschrift
//SEITENLEISTE
const ichWillSeitenLeiste=true;                          // links einblenden einer Seitenleiste
const nameSeitenLeiste="TODO"
const breiteSeitenleiste=25;
const schriftGroesseSeitenleiste=12;
const abstandSeitentextVonOben=3;
const htmlFarbSeiteSchrift="#E9E9E9";
const fontColor="#EEF1F5";
const htmlBackgroundFarbeSeitenliste="transparent"
//MEHRERE TABELLEN NEBENEINANDER
let mehrfachTabelle=1;                                   // bis zu 3 Tabellen werden nebeneinander geschrieben-  verkürzt das Ganze, dafür etwas breiter - MÖGLICH 1,2,3 !!!
const trennungsLinie="2";                                // extra trennungslinie bei mehrfachtabellen - evtl auf 0 stellen, wnn htmlRahmenLinien auf none sind
const farbetrennungsLinie="#5590CA";                     // bei mehreren Tabellen nebeneinander wird ein Strich zw. den Tabellen gezogen
const htmlFarbTableColorUber="white"                     // Spalten-Überschrift in der tabelle - für die einzelnen Spalten //"#BDBDBD"; 
const htmlFarbZweiteTabelle="white";                     // Farbe der Spalten-Überschrift bei jeder 2.ten Tabelle        
//ÜBERSCHRIFT SPALTEN - OBERSTE ZEILE IN TAB
const UeberSchriftHoehe="45";                            // Überschrift bekommt mehr Raum - darunter und darüber - Zellenhöhe
const LinieUnterUeberschrift="2";                        // Liniehoehe nur unter Spaltenüberschrift  
const farbeLinieUnterUeberschrift="blue";               // LinienFarbe unter Spaltenüberschrift
const groesseUeberschrift=16; 
const UeberschriftStyle="normal"                         // möglich "bold"
const UeberschriftSpalten=true;                          // ein- oder ausblenden der spatlen-überschriften
//GANZE TABELLE
const abstandZelle="2";                                  // legt den abstand in den zellen zum rahmen fest
const zeilenAbstand=3;                                   // legt den abstand zwischen den zeilen fest
const farbeUngeradeZeilen="#000000";                     // Farbe für ungerade Zeilenanzahl - Hintergrund der Spaltenüberschrift bleibt bei htmlFarbTableColorGradient1/2 - bei "transparent" gewinnt htmlFarbTableColorGradient1
const farbeGeradeZeilen="#151515";                       // Farbe für gerade Zeilenanzahl - Hintergrund der Spaltenüberschrift bleibt bei htmlFarbTableColorGradient1/2   - bei "transparent" gewinnt htmlFarbTableColorGradient2
const weite="400";                                      // Weite der Tabelle - verhindert das dynamische breiter werden, wenn werte unterschiedliche werte haben
const zentriert=true;                                    // ganze tabelle zentriert im html Widget
const backgroundAll="#000000";                           // Hintergrund für die ganze Seite - für direkten aufruf oder iqontrol sichtber - keine auswirkung auf vis-widget
const htmlSchriftart="Ubuntu-Regular"                    // "Jura-DemiBold"   //"RobotoCondensed-Bold"   //"Helvetica"; .....
const htmlSchriftgroesse="16px";                         // schriftgröße in den zellen
const rahmenBreite="1px";                                //mit 0 ist äußerer rahmen weg
//FELDER UND RAHMEN
const htmlFarbFelderschrift="#CBCBCA";                   // SchriftFarbe der Felder
const htmlFarbFelderschrift2="#CBCBCA";                  // SchriftFarbe der Felder für jede 2te Tabelle
const htmlGragient=[150,15,50];                          // einstellung des gradienten
const htmlFarbTableColorGradient1="blue";         // Gradient - Hintergrund der Tabelle - Verlauffarbe
const htmlFarbTableColorGradient2="#5590CA";              // Gradient - Hintergrund der Tabelle - ist dieser Wert gleich Gradient1 gibt es keinen verlauf
const htmlFarbTableBorderColor="grey";                   // Farbe des Rahmen - ist dieser gleich den gradienten, sind die rahmen unsichtbar
let htmlRahmenLinien="none";                             // Format für Rahmen: MÖGLICH: "none" oder "all" oder "cols" oder "rows"
// falls eine extra html datei gebraucht wird
const path = "/htmlexample.html";                        //FIlenamen definieren
const home ='vis.0'                                      //wo soll das file im iobroker-file-system liegen ? (oder z.b auch iqontrol.meta)
let   braucheEinFile=false;                              // bei true wird ein file geschrieben
// AB HIER NICHTS  ÄNDERN -------------------------------------------------------------------------------------------------
// AB HIER NICHTS  ÄNDERN -------------------------------------------------------------------------------------------------
// AB HIER NICHTS  ÄNDERN ---------------------------------erst wieder ab Zeile 134----------------------------------------
let borderHelpBottum;
let borderHelpRight;
let htmlcenterHelp;
let htmlcenterHelp2;
if(String(htmlRahmenLinien)=="rows") {borderHelpBottum=1;borderHelpRight=0;}
if(String(htmlRahmenLinien)=="cols") {borderHelpBottum=0;borderHelpRight=1;}
if(String(htmlRahmenLinien)=="none") {borderHelpBottum=0;borderHelpRight=0;}
if(String(htmlRahmenLinien)=="all")  {borderHelpBottum=1;borderHelpRight=1;}
zentriert ? htmlcenterHelp="auto" : htmlcenterHelp="left";
zentriert ? htmlcenterHelp2="center" : htmlcenterHelp2="left";
const htmlZentriert='<center>'
const htmlStart=    "<!DOCTYPE html><html lang=\"de\"><head><title>Vorlage</title><meta http-equiv=\"content-type\" content=\"text/html;  http-equiv=\"refresh\" content=\"30\"; charset=utf-8\">"+
                  "<style> * {  margin: 0;} body {background-color: "+backgroundAll+"; margin: 0 auto;  }"+
                  " p {padding-top: 10px; padding-bottom: 10px; text-align: "+htmlcenterHelp2+"}"+
                 // " div { margin: 0 auto;  margin-left: auto; margin-right: auto;}"+
                  " td { padding:"+abstandZelle+"px; border:0px solid "+htmlFarbTableBorderColor+";  border-right:"+borderHelpRight+"px solid "+htmlFarbTableBorderColor+";border-bottom:"+borderHelpBottum+"px solid "+htmlFarbTableBorderColor+";}"+ 
                  " table { width: "+weite+";  margin: 0 "+htmlcenterHelp+"; border:1px solid "+htmlFarbTableBorderColor+"; border-spacing=\""+abstandZelle+"0px\" ; }"+   // margin macht center
                  "td:nth-child(1) {width: "+htmlSpalte1Weite[0]+"}"+"td:nth-child(2) {width:"+htmlSpalte1Weite[1]+"}"+
                  " </style></head><body> <div>";
//const htmlUeber=    "<p style=\"color:"+htmlFarbUber+"; font-family:"+htmlSchriftart+"; font-weight: bold\">"+htmlFeldUeber+"</p>";                    
const htmlTabStyle= "<table bordercolor=\""+htmlFarbTableBorderColor+"\" border=\""+rahmenBreite+"\" cellspacing=\""+abstandZelle+"\" cellpadding=\""+abstandZelle+"\" width=\""+weite+"\" rules=\""+htmlRahmenLinien+"\" style=\"color:"+htmlFarbFelderschrift+";  font-size:"+htmlSchriftgroesse+
                     "; font-family:"+htmlSchriftart+";background-image: linear-gradient("+htmlGragient[0]+"deg,"+htmlFarbTableColorGradient2+" "+htmlGragient[1]+"%,"+htmlFarbTableColorGradient1+" "+htmlGragient[2]+"%);\">";
let htmlTabUeber4="<tr style=\" height:"+UeberSchriftHoehe+"px; color:"+htmlFarbTableColorUber+"; font-size: "+groesseUeberschrift+"px; font-weight: "+UeberschriftStyle+" ;  border-bottom: "+LinieUnterUeberschrift+"px solid "+farbeLinieUnterUeberschrift+" \">";
const htmlTabUeber3="</tr>";
let myzufall=Math.floor(Math.random() * (100000 - 100 + 1)) + 100;  
// const nametest = {wid}; /*const fn = {[nametest]: function() {}}[nametest];*/         var aa=\`{wid}\`; console.log("widgeeet: "+aa);
const buttonScript =   `<script>
                     function deleteMyItem${myzufall}(myval) {console.log(myval); vis.setValue(\"javascript.${instance}.Tabellen@Liv.${dpVIS}.toDelete\",myval)};
                     function addTheMyItem${myzufall}() { var strr = $('#myInput${myzufall}${dpVIS}').val(); console.log(strr); vis.setValue(\"javascript.${instance}.Tabellen@Liv.${dpVIS}.toAdd\",strr)      };
                     $('#myBtnt${dpVIS}').click(function(){console.log("eee");var str = $("#myInput${myzufall}${dpVIS}").val(); vis.setValue(\"javascript.${instance}.Tabellen@Liv.${dpVIS}.toAdd\",str) ;console(str)     });
                     $('#myInput${myzufall}${dpVIS}').keypress(function(event){
                     var keycode = (event.keyCode ? event.keyCode : event.which);
                      console.log(keycode)
                     if(keycode == '13'){ console.log("über enter eingegeben"+ keycode); 
                     var str = $("#myInput${myzufall}${dpVIS}").val(); vis.setValue("javascript.0.Tabellen@Liv.MeineToDoListe.toAdd",str); console.log(str);
                     }
                     });
                      function setOnOtherValuesA${myzufall}(myval) {	var Self = this;	Self.servConn.getStates(myval, (error, states) => {  console.log(states); self.servConn.setState(myval, !states[myval].val);}  )} 
                     </script>`
                    
//NICHTS ÄNDERN - abhängig von den oben definierten _Spalten - in diesem Beispiel sind es 3
let htmlTabUeber2=""
for (let ue=0;ue<htmlSpalte1Weite.length;ue++) { if (!schalterInSpaltenUeberschrift[ue] ) { 
                                                    htmlTabUeber2=htmlTabUeber2.concat("<td width="+htmlSpalte1Weite[ue]+" align="+Feld1lAlign[ue]+" style=\"color:"+htmlFarbTableColorUber+"\">"+htmlFeld[ue]+"</td>")} 
                                                    else {let valButton="javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte"+ue
                                                    htmlTabUeber2=htmlTabUeber2.concat("<td width="+htmlSpalte1Weite[ue]+" align="+Feld1lAlign[ue]+">"+""+"<button  style\=\" border-radius: 4px; border:1px solid; background-color\:"+htmlFarbTableColorGradient2+"\; color: "+htmlFarbTableColorUber+"; font\-size\:1em\; text\-align:left\" value=\"toggle\" onclick=\"setOnOtherValuesA\(\'"+valButton+"\')\">"+htmlFeld[ue]+"</button></td>")  //symbolSchalter[ue]   
                                                    }
}
let  htmlTabUeber2_1=""
for (let ue=0;ue<htmlSpalte1Weite.length;ue++) { htmlTabUeber2_1=htmlTabUeber2_1.concat("<td width="+htmlSpalte1Weite[ue]+" align="+Feld1lAlign[ue]+" style=\"color:"+htmlFarbZweiteTabelle+"\">"+htmlFeld[ue]+"</td>")}
//------------------------------------------------------
if ( !(val.length == Feld1lAlign.length && htmlSpalte1Weite.length == htmlFeld.length && val.length == htmlFeld.length) || (mehrfachTabelle<1 || mehrfachTabelle>3) ) 
    { log("Anzahle der Definitions Arrays sind ungleich ODER mehrfachTabelle ist falsch - Script wurde gestoppt !!!","error");
        // @ts-ignore
        stopScript();}
let sortierenEIN=true;                  // bei true : neuste einträge oben; bei false ist der neuste unten
if(sortierenEIN) mitAlphabet=false
let langeGesamt=0;  //für colspan
let htmlTabUeber="";
let htmlOut="";
let mix;
let counter;
let makeJsonWidget;
let myObject=[];
let welcheSortierung=0;
let timerSammlung=false;
needDP()
function writeHTML(){
let zaehler=0;
let seitenLeistenTest="";
let htmlTabUeber1=htmlTabUeber4;
myObject=[]
let helperLeerzeile=""
let makeJsonWidget=[];
htmlOut="";
counter=-1;
//--------------------------------------------------------------------------------------------------------------------------------------------------
//---------hier kommt eure schleife rein counter++, tabelleBind() und tabelleFinish() müssen so integriert bleiben !!!------------------------------
//---------alle val[x] werte müssen von euch bestimmt werden - val[0],val[1],val[2] !!!-------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------------
let myListData=JSON.parse(getState("javascript." + instance + ".Tabellen@Liv."+dpVIS+".List_JSON").val)
//log(myListData.length)
if(myListData.length>0){
for(let ii=0;ii<myListData.length;ii++){
   zaehler++;
     myObject.push({                  "value0" : myListData[ii].Item,            //  "INSTANCE"
                                      "value1" : myListData[ii].Time,
                                      "value2" : myListData[ii].Time
                                                      })
              
         makeJsonWidget.push({        [htmlFeld[0]] :  myListData[ii].Item,
                                      [htmlFeld[1]] :  myListData[ii].Time
                                                      })  
}}
  
 welcheSortierung=1
  if(sortierenEIN ) switch (welcheSortierung) {
      case 0: sortMe("alpha","value0");break;  
      case 1: sortMe("num","value1");break;   
      case 2: sortMe("alpha","value2");break;}
     //  langeGesamt= myObject.length; log(langeGesamt.toString())
   myObject.push({     "value0" :  "<input id=\"myInput"+`${myzufall}`+dpVIS+"\" style=\"color: "+htmlFarbTableColorUber+"; background-image: linear-gradient(150deg,"+htmlFarbTableColorGradient2+" 40%,"+htmlFarbTableColorGradient1+" 80%); width: "+(Number(htmlSpalte1Weite[0])-20)+"px; \" type=\"text\"  name=\"vname\">",            //  "INSTANCE"
                       "value1" : "",
                       "value2" : symbolSchalter[3]
})   
  for(let zz=0;zz<myObject.length;zz++){
// Unterüberschften ------------------------------------------------------       
       if (mitAlphabet){
         if( myObject[zz].value0[0]!=helperLeerzeile){ tabelleAusbessern();
                                                       counter=-1;  for(let ic=0;ic<mehrfachTabelle;ic++ ) { for (let tt=0 ;tt<val.length;tt++) 
                                                                                                                 { tt==0 && ic==0 ? val[tt]=(myObject[zz].value0[0]).toUpperCase() : val[tt]=" "
                                                                                                                 }   
                                                                                                             counter++;tabelleBind();langeGesamt++ }
         helperLeerzeile=myObject[zz].value0[0] } ; sortierenEIN=false;}
// Unterüberschften Ende---------------------------------------------------  
   
   val[0]= myObject[zz].value0
   let yy= (Math.round((new Date()).getTime() / 1000))-Math.round(myObject[zz].value1/1000);
   !ichWillEinDatum ?  val[1]= Math.floor( ((yy)/60/60/24) )+"d "+ Math.floor(((yy)/60/60) % 24) +"h "+ Math.floor( ((yy)/60) % 60 )+"m" : 
                       val[1]=formatDate(getDateObject((new Date(myObject[zz].value1).getTime())), myDatumFormat);
   if(myObject[zz].value2==symbolSchalter[3] ) val[1]=""  ;                       
   let valButton=myObject[zz].value1
   //log(symbolSchalter[3])
   myObject[zz].value2 != symbolSchalter[3] ? val[2]=  "<button id=\"my1Button"+dpVIS+"\" style\=\"border:none\; background-color\:transparent\; color\:white\; font\-size\:1em\; text\-align:left\" value=\"toggle\" onclick=\"deleteMyItem"+`${myzufall}`+"\(\'"+valButton+"\')\">"+symbolSchalter[4]+ "</button>"   
                                            : val[2]=  "<button id=\"myBtn"+dpVIS+"\" style\=\"border:none\; background-color\:transparent\; color\:white\; font\-size\:1em\; \" onclick=\"addTheMyItem"+`${myzufall}`+"()   \">"+myObject[zz].value2+"</button>"
  
    counter++;                                       // SEHR WICHTIG - MUSS IN JEDER SCHLEIFE INTEGRIERT SEIN
    tabelleBind();                        // HIER NICHTS ÄNDERN : HIER WERDEN DIE DATEN DER SCHLEIFE ZUSAMMENGESETZT  
    langeGesamt++;
  }
//-------------------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------Ende der schleife------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------------------
let valButton="javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte3"
let valButton2="javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte4"
let valButton3="javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte5"
seitenLeistenTest=seitenLeistenTest+String(zaehler)
let einmalAbstand=`</br>
`
for (let f=0;f<abstandSeitentextVonOben;f++){
    seitenLeistenTest=seitenLeistenTest+`<br>
`}
// seitenLeistenTest=`<br>
 //                 </br>
   //               `
for (let i=0;i<nameSeitenLeiste.length;i++){
 // log(choseMonthArr[i])
  seitenLeistenTest=seitenLeistenTest+nameSeitenLeiste[i]+`</br>
` }
//seitenLeistenTest=seitenLeistenTest+"</br>"+String(zaehler)
/*
let buttonBkGround="transparent"
let buttonBkGround2="transparent"
let buttonBkGround3=1
mitAlphabet ? buttonBkGround="#DA8749" :buttonBkGround="transparent"    //<button style=\"border:1px solid; background-color:transparent; font-size:1em; text-align:left\" value=\"toggle\" onclick=setOnOtherValue\()>"+"A"+"</button>
sortierenEIN ? buttonBkGround2="#DA8749" :buttonBkGround2="transparent"
seitenLeistenTest=einmalAbstand+einmalAbstand+einmalAbstand+
                              "<button style=\" color: "+fontColor+"; border-radius: 4px; height: 50px; border:1px solid; background-color:"+buttonBkGround+"; font-size:"+groesseUeberschrift+"; text-align:left\" value=\"toggle\" onclick=\"setOnOtherValue\(\'"+valButton+"\')\">"+"A"+"</button>"+
                              
                              "<button style=\" color: "+fontColor+"; border-radius: 4px; height: 50px; border:1px solid; background-color:"+"transparent"+"; font-size:"+groesseUeberschrift+"; text-align:left\" value=\"toggle\" onclick=\"setOnOtherValue\(\'"+valButton3+"\')\">"+"+"+"</button>"+seitenLeistenTest
 */
htmlTabUeber="";
if (ichWillSeitenLeiste) htmlTabUeber1=htmlTabUeber1+"<td style=\" background-color: "+htmlBackgroundFarbeSeitenliste+"; margin-top: 200px; color: "+htmlFarbSeiteSchrift+ ";font-size:"+schriftGroesseSeitenleiste+"px; vertical-align:top; text-align:center \" width=\""+breiteSeitenleiste+"\" rowspan=\""+(langeGesamt+1)+"\">"+seitenLeistenTest+"</td>"
switch (mehrfachTabelle) { 
  case 1: htmlTabUeber=htmlTabUeber1+htmlTabUeber2+htmlTabUeber3;  break;
  case 2: htmlTabUeber=htmlTabUeber1+htmlTabUeber2+htmlTabUeber2_1+htmlTabUeber3; break;
  case 3: htmlTabUeber=htmlTabUeber1+htmlTabUeber2+htmlTabUeber2_1+htmlTabUeber2_1+htmlTabUeber3; break;
  case 4: htmlTabUeber=htmlTabUeber1+htmlTabUeber2+htmlTabUeber2_1+htmlTabUeber2+htmlTabUeber2_1+htmlTabUeber3; break;
 };   
 if (!UeberschriftSpalten) {htmlTabUeber=""}
 tabelleFinish(); // AB HIER NICHTS ÄNDERN - tabelle fertigstellen
 if (braucheEinJSON ) {setStateDelayed("javascript." + instance + ".Tabellen@Liv."+dpVIS+".JSONVis",JSON.stringify(makeJsonWidget),1000 )}
    
} // function ende
//MAIN:
schedule(mySchedule,  function () {  
writeHTML();
if (braucheEinFile) {writeFile(home, path ,htmlOut, function (error) { /* log('file written');*/  });}
}); 
setTimeout(function () {writeHTML();  }, 2050);                              
function tabelleBind(){
 
  switch (mehrfachTabelle) { 
  case 1: if(counter%2==0)   {htmlOut=htmlOut+"<tr cellspacing=\""+abstandZelle+"\"  bgcolor=\""+farbeGeradeZeilen+"\">";
                              for(let u=0;u<val.length;u++){ htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+">"+val[u]+"</td>");
                                                           }  htmlOut=htmlOut.concat("</tr>");   break;
                              } else   {htmlOut=htmlOut+"<tr cellspacing=\""+abstandZelle+"\"  bgcolor=\""+farbeUngeradeZeilen+"\">";
                                        for(let u=0;u<val.length;u++){ htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+">"+val[u]+"</td>");
                                                                     }  htmlOut=htmlOut.concat("</tr>");   break;
                              }
  
  case 2: if(counter%4==0){  if(counter%2==0)  {htmlOut = htmlOut+"<tr cellspacing=\""+abstandZelle+"\"  bgcolor=\""+farbeGeradeZeilen+"\">";
                                                for(let u=0;u<val.length;u++){ if(u<val.length-1) {htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+">"+val[u]+"</td>");} else
                                                                             {htmlOut=htmlOut.concat("<td style=\" border-right:"+trennungsLinie+"px solid "+farbetrennungsLinie+ ";\" align="+Feld1lAlign[u]+">"+val[u]+"</td>")}
                                                                             }  
                                                                          
                               } else { for(let u=0;u<val.length;u++){ htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+" style=\"color:"+htmlFarbFelderschrift2+"\">"+val[u]+"</td>");
                                                                     }  htmlOut=htmlOut.concat("</tr>");  } break;
                          } else {
                            if(counter%2==0)  {htmlOut=htmlOut+"<tr cellspacing=\""+abstandZelle+"\"  bgcolor=\""+farbeUngeradeZeilen+"\">";
                                               for(let u=0;u<val.length;u++){  if(u<val.length-1) {htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+">"+val[u]+"</td>");} else
                                                                            {htmlOut=htmlOut.concat("<td style=\" border-right:"+trennungsLinie+"px solid "+farbetrennungsLinie+ ";\" align="+Feld1lAlign[u]+">"+val[u]+"</td>")}
                                                                            }  
                               } else {        for(let u=0;u<val.length;u++){ htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+" style=\"color:"+htmlFarbFelderschrift2+"\">"+val[u]+"</td>");
                                                                            }  htmlOut=htmlOut.concat("</tr>");  }  break;}
  case 3: if(counter%2==0)  {  if(counter%3==0 ) {htmlOut = htmlOut+"<tr cellspacing=\""+abstandZelle+"\"  bgcolor=\""+farbeGeradeZeilen+"\">";
                                                  for(let u=0;u<val.length;u++){if(u<val.length-1) {htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+">"+val[u]+"</td>");} else
                                                                               {htmlOut=htmlOut.concat("<td style=\" border-right:"+trennungsLinie+"px solid "+farbetrennungsLinie+ ";\" align="+Feld1lAlign[u]+">"+val[u]+"</td>")}
                                                                                                       }  
                              } else { if(counter%3==1)  {for(let u=0;u<val.length;u++){  if(u<val.length-1) {htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+" style=\"color:"+htmlFarbFelderschrift2+"\">"+val[u]+"</td>");} else
                                                                                                             {htmlOut=htmlOut.concat("<td  align="+Feld1lAlign[u]+" style=\" border-right: "+trennungsLinie+"px solid "+farbetrennungsLinie+ "; color:"+htmlFarbFelderschrift2+"\">"+val[u]+"</td>")}
                                                                                                       }  
                                                         } else  { for(let u=0;u<val.length;u++){  htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+">"+val[u]+"</td>");
                                                                                                }  htmlOut=htmlOut.concat("</tr>");  } }  break;
                            } 
                            else {
                               if(counter%3==0 )  {htmlOut = htmlOut+"<tr cellspacing=\""+abstandZelle+"\"  bgcolor=\""+farbeUngeradeZeilen+"\">";
                                                  for(let u=0;u<val.length;u++){ if(u<val.length-1) {htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+">"+val[u]+"</td>");} else
                                                                                                    {htmlOut=htmlOut.concat("<td style=\" border-right:"+trennungsLinie+"px solid "+farbetrennungsLinie+ ";\" align="+Feld1lAlign[u]+">"+val[u]+"</td>")}
                                                                                                       }  
                                                                                                       
                            } else{ if(counter%3==1 )  { for(let u=0;u<val.length;u++){ if(u<val.length-1) {htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+" style=\"color:"+htmlFarbFelderschrift2+"\">"+val[u]+"</td>");} else
                                                                                                           {htmlOut=htmlOut.concat("<td  align="+Feld1lAlign[u]+" style=\" border-right: "+trennungsLinie+"px solid "+farbetrennungsLinie+ "; color:"+htmlFarbFelderschrift2+"\">"+val[u]+"</td>")}
                                                                                                       }  
                                                        } else {        for(let u=0;u<val.length;u++){ htmlOut=htmlOut.concat("<td align="+Feld1lAlign[u]+">"+val[u]+"</td>");
                                                                                                     }  htmlOut=htmlOut.concat("</tr>"); } } break;
                            }                                        
                               
       } //switch ende
}
function tabelleAusbessern() {         // bessert mei mehrfachtabellen die nicht vollen zeilenn aus - bevor die unterüberschriften kommen
switch (mehrfachTabelle) {
       
      case 1:    break;
      case 2:    let helpMehrfach="</td>";
                 for(let w=0;w<val.length;w++){helpMehrfach=helpMehrfach.concat("<td> </td>")};helpMehrfach=helpMehrfach.concat("</tr>")
                 if(counter%2==0)  htmlOut = htmlOut.replace(/<\/td>$/, helpMehrfach);
                 break;
      case 3:   let helpMehrfach2="</td>";
                for(let w=0;w<val.length;w++){helpMehrfach2=helpMehrfach2.concat("<td> </td>")};helpMehrfach2=helpMehrfach2.concat("</tr>")
                if(counter%3==2)  htmlOut = htmlOut.replace(/<\/td>$/, "</td></tr>");
                if(counter%3==1)  htmlOut = htmlOut.replace(/<\/td>$/, helpMehrfach2);
                let helpMehrfach3="</td>";
                let helpMehrfach31="";for(let w=0;w<val.length;w++){helpMehrfach31=helpMehrfach31.concat("<td> </td>")}
                for(let w=0;w<val.length;w++){if(w<val.length-1) {helpMehrfach3=helpMehrfach3.concat("<td> </td>")} else
                                                        {helpMehrfach3=helpMehrfach3.concat("<td style=\" border-right: "+trennungsLinie+"px solid "+farbetrennungsLinie+"\"> </td>"+helpMehrfach31)}
                                                  };helpMehrfach3=helpMehrfach3.concat("</tr>")        
                if(counter%3==0)  htmlOut = htmlOut.replace(/<\/td>$/, helpMehrfach3);  break; }}
function tabelleFinish() {
switch (mehrfachTabelle) {
       
      case 1:    break;
      case 2:    let helpMehrfach="</td>";
                 for(let w=0;w<val.length;w++){helpMehrfach=helpMehrfach.concat("<td> </td>")};helpMehrfach=helpMehrfach.concat("</tr>")
                 if(counter%2==0)  htmlOut = htmlOut.replace(/<\/td>$/, helpMehrfach);
                 break;
      case 3:   let helpMehrfach2="</td>";
                for(let w=0;w<val.length;w++){helpMehrfach2=helpMehrfach2.concat("<td> </td>")};helpMehrfach2=helpMehrfach2.concat("</tr>")
                if(counter%3==2)  htmlOut = htmlOut.replace(/<\/td>$/, "</td></tr>");
                if(counter%3==1)  htmlOut = htmlOut.replace(/<\/td>$/, helpMehrfach2);
                let helpMehrfach3="</td>";
                let helpMehrfach31="";for(let w=0;w<val.length;w++){helpMehrfach31=helpMehrfach31.concat("<td> </td>")}
                for(let w=0;w<val.length;w++){if(w<val.length-1) {helpMehrfach3=helpMehrfach3.concat("<td> </td>")} else
                                                        {helpMehrfach3=helpMehrfach3.concat("<td style=\" border-right: "+trennungsLinie+"px solid "+farbetrennungsLinie+"\"> </td>"+helpMehrfach31)}
                                                  };helpMehrfach3=helpMehrfach3.concat("</tr>")        
                if(counter%3==0)  htmlOut = htmlOut.replace(/<\/td>$/, helpMehrfach3);  break; }
        var htmlUeber=    "<p style=\"color:"+htmlFarbUber+"; font-family:"+htmlSchriftart+"; font-size: "+htmlUEberFontGroesse+"; font-weight:"+htmlSchriftWeite+ "\">"+htmlFeldUeber+"  Last Update: "+formatDate(getDateObject((new Date().getTime())), "SS:mm:ss");+"</p>"; 
      var htmlUnter= "<div  style=\"color:"+htmlFarbUber+"; font-family:"+htmlSchriftart+"; font-size: 70%; text-align: center;\" >"+htmlFeldUeber+"  Last Update: "+formatDate(getDateObject((new Date().getTime())), "SS:mm:ss");+"</div>";
       
       if (!htmlSignature) htmlUnter="";
         //Ausgabe über VIS html widget - tabelle in datenpunkt schreiben - html tabelle ohne html header und body
          var htmlOutVIS="";
        //  htmlUberschrift ? htmlOutVIS=htmlUeber+htmlTabStyle+htmlTabUeber+htmlOut+"</table>" : htmlOutVIS=htmlTabStyle+htmlTabUeber+htmlOut+"</table>";
           if (htmlUberschrift) 
               { zentriert ? htmlOutVIS=htmlZentriert+htmlUeber+htmlTabStyle+htmlTabUeber+htmlOut+"</table>"+htmlUnter+ buttonScript : htmlOutVIS=htmlUeber+htmlTabStyle+htmlTabUeber+htmlOut+"</table>"+htmlUnter+ buttonScript ;
             } else {
              zentriert ?  htmlOutVIS=htmlZentriert+htmlTabStyle+htmlTabUeber+htmlOut+"</table>"+htmlUnter+ buttonScript :  htmlOutVIS=htmlTabStyle+htmlTabUeber+htmlOut+"</table>"+htmlUnter+ buttonScript;
                }
                
 // log("bin raus aus tabelleBind");
          if (braucheEinVISWidget)  setStateDelayed("javascript." + instance + ".Tabellen@Liv."+dpVIS+".HTMLTableVis", htmlOutVIS ,1000);
var htmlUnter= "<div  style=\"color:"+htmlFarbUber+"; font-family:"+htmlSchriftart+"; font-size: 80%;  text-align: center; \" >"+htmlFeldUeber+"  Last Update: "+formatDate(getDateObject((new Date().getTime())), "SS:mm:ss");+"</div>"
if (!htmlSignature) htmlUnter="";
 var htmlEnd="</table>"+htmlUnter+"</div></body>";
//mit oder ohne überschrift - zentriert oder links
htmlUberschrift ? htmlOut=htmlStart+htmlUeber+htmlTabStyle+htmlTabUeber+htmlOut+htmlEnd : htmlOut=htmlStart+htmlTabStyle+htmlTabUeber+htmlOut+htmlEnd;
//log(htmlOut);
}
async function needDP(){
  for(let s=0;s<schalterInSpaltenUeberschrift.length;s++){ if(schalterInSpaltenUeberschrift[s]){
  if (!(await existsStateAsync("javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte"+s))) {
      await createStateAsync("Tabellen@Liv."+dpVIS+".Spalte"+s, false,{type: "boolean", name: "Schalter_Spalte"+s, role: "value", read: true, write: true, } ); } 
    }}
  if (!(await existsStateAsync("javascript." + instance + ".Tabellen@Liv."+dpVIS+".HTMLTableVis"))) {
      await createStateAsync("Tabellen@Liv."+dpVIS+".HTMLTableVis", "empty",{type: "string", name: "HTML_Standard_Widget_mit_Binding", role: "value", read: true, write: true, } ); } 
   if (!(await existsStateAsync("javascript." + instance + ".Tabellen@Liv."+dpVIS+".JSONVis"))) { 
      await createStateAsync("Tabellen@Liv."+dpVIS+".JSONVis","",{type: "string", name: "JSON Format", role: "value", read: true, write: true, } ); }   
    if (!(await existsStateAsync("javascript." + instance + ".Tabellen@Liv."+dpVIS+".List_JSON"))) { let tt=JSON.stringify( [])
      await createStateAsync("Tabellen@Liv."+dpVIS+".List_JSON",tt,{type: "string", name: "List_JSON", role: "value", read: true, write: true, } ); }  
    if (!(await existsStateAsync("javascript." + instance + ".Tabellen@Liv."+dpVIS+".toDelete"))) { 
      await createStateAsync("Tabellen@Liv."+dpVIS+".toDelete",{type: "number", name: "toDelete", role: "value", read: true, write: true, } ); } 
    if (!(await existsStateAsync("javascript." + instance + ".Tabellen@Liv."+dpVIS+".toAdd"))) { 
      await createStateAsync("Tabellen@Liv."+dpVIS+".toAdd",{type: "string", name: "toAdd", role: "value", read: true, write: true, } ); }          
  
let tt={"ToDo-Liste": [{}]}
//  log(arrTriggerSchalter.toString())
}
  setTimeout(function () { 
        let arrTriggerSchalter=[]
  $("javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte*").each(function(id, i) {  
         arrTriggerSchalter.push(id) 
  });
 // log(arrTriggerSchalter.toString())
  on({id: arrTriggerSchalter, change: "any"}, function (obj) { 
    //  log(obj.id);log(String(mehrfachTabelle))
//     obj.id=="javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte1"  ? welcheSortierung=1 : welcheSortierung=2;
    if (obj.id=="javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte2") {
        var myListDataDel=[]
       setState(`javascript.${instance}.Tabellen@Liv.${dpVIS}.List_JSON`,JSON.stringify(myListDataDel))
    
     //  setTimeout(function () {writeHTML();  }, 1000);  
     // timerSammlung=true;
       sendTo('telegram.'+telegramInstance, { 
           text: 'Liste wurde gelöscht'
       });
        }
        if (obj.id=="javascript." + instance + ".Tabellen@Liv."+dpVIS+".Spalte1") { log(ichWillEinDatum.toString()); ichWillEinDatum=!ichWillEinDatum;log(ichWillEinDatum.toString())
                                                                                 setTimeout(function () {writeHTML();  }, 1000);  }
  
  //  log(String(mehrfachTabelle))
 setTimeout(function () {  
      writeHTML();
      if (braucheEinFile) {writeFile(home, path ,htmlOut, function (error) { /* log('file written');*/  });}
}, 350);
   
    
  });}, 5050);
//SORTIEREN
function sortMe(myType,value){
if(myType=="alpha" ){
  if( typeof myObject[0][value] != "boolean" ){ 
   myObject.sort(function (alpha, beta) {
           if ((alpha[value].toString().toUpperCase()).trim() > (beta[value].toString().toUpperCase()).trim())
              return 1;
           if ((beta[value].toString().toUpperCase()).trim()> (alpha[value].toUpperCase().toString()).trim())
              return -1;
           return 0;
          });
  }  else { 
     myObject.sort(function(x, y) {
    
      return (x[value] === y[value])? 0 : x[value]? -1 : 1;
      
    
  });
  }
}     else { 
          
     myObject.sort(function (alpha, beta) {
      return  beta[value] -alpha[value]; 
     
  });}
//    log(JSON.stringify(myObject))
  
}
//------------------------------------------------------
//-----------------anlegen vis      ----------------------   
on({id: `javascript.${instance}.Tabellen@Liv.${dpVIS}.toAdd`,  change: "any"}, function (obj) { 
   if(obj.state.val!="" && obj.state.val[0]!=" " ){
   let myListData=JSON.parse(getState("javascript." + instance + ".Tabellen@Liv."+dpVIS+".List_JSON").val)
  
   myListData.push({ "Item":obj.state.val,
                     "Time":new Date().getTime()
   })
   setState(`javascript.${instance}.Tabellen@Liv.${dpVIS}.List_JSON`,JSON.stringify(myListData))
}  
      setTimeout(function () {writeHTML();  }, 1000);  
      timerSammlung=true;
   });
//------------------------------------------------------
//-----------------löschen vis      ----------------------   
on({id: `javascript.${instance}.Tabellen@Liv.${dpVIS}.toDelete`,  change: "any"}, function (obj) { 
   var myListDataDel=JSON.parse(getState("javascript." + instance + ".Tabellen@Liv."+dpVIS+".List_JSON").val)
   let helpingHand=0
   for (let bb=0;bb<myListDataDel.length;bb++){
       if(myListDataDel[bb].Time==obj.state.val) helpingHand=bb
   }
    //log(helpingHand.toString())
   myListDataDel.splice(helpingHand , 1);
  
      setState(`javascript.${instance}.Tabellen@Liv.${dpVIS}.List_JSON`,JSON.stringify(myListDataDel))
   setTimeout(function () {writeHTML();  }, 1000); 
   timerSammlung=true;
   })
 
       
   // TELEGRAM
/*
            sendTo('telegram', {
          
          text: "Wohnzimmer Status angefragt",
          answerCallbackQuery: {
          text: 
                  'Schranklicht ' +"123" +
                  ' %\nWohnzimmerlicht ' +"123" +
                  ' %\nEsszimmerlicht ' +"123" +
                  '\nSteckdose Laptop ' +"123" +
                  '\nSteckdose Tablet ' +"123" +
                  '\nTerrassentür ' +"123" 
          ,
          showAlert: true 
          }
      });*/
//------------------------------------------------------
//-----------------empfängt telegram-- add,delete.antwort auf button drücken----------------------
//telegram.1.communicate.request
on({id: `telegram.${telegramInstance}.communicate.request`, ack: true, change: "any"}, function (obj) { 
    if(obj.state.val!="") {
sendTo(`telegram.${telegramInstance}`, {
      
      answerCallbackQuery: {
          text: "Gelöscht!",
          showAlert: false // Optional parameter
      }
 });
    let rausSortieren=obj.state.val.replace(/^.+](.+)--xyx/,"$1");
    var myListDataDel=JSON.parse(getState("javascript." + instance + ".Tabellen@Liv."+dpVIS+".List_JSON").val)
if(obj.state.val.includes("--xyx")){
//log(obj.state.val,"warn")
                 
if(obj.state.val.includes("66666666--xyx")) {                                                                    // alles löschen
            let myListDataAllDel=[]
       setState(`javascript.${instance}.Tabellen@Liv.${dpVIS}.List_JSON`,JSON.stringify(myListDataAllDel))
     //  setTimeout(function () {writeHTML();  }, 1000);  
     // timerSammlung=true;
       sendTo('telegram.'+telegramInstance, { 
           text: listenNameTele+' wurde gelöscht'
       });
        setTimeout(function () {writeHTML();   }, 1000);
       } else{                                                                                                    // löschen
              let helpingHand=0  //welche stelle muss gelöscht werden
              for (let bb=0;bb<myListDataDel.length;bb++){
                  if(myListDataDel[bb].Time==rausSortieren) helpingHand=bb  }
    
              myListDataDel.splice(helpingHand , 1);
  
             setState(`javascript.${instance}.Tabellen@Liv.${dpVIS}.List_JSON`,JSON.stringify(myListDataDel))  
             setTimeout(function () {writeHTML();   }, 1000);
            //timerSammlung=true; 
             setTimeout(function () {sendToTeleg(listenNameTele);   }, 1500);
           }
   } else {                                                                                                         //anlegen              
      
            let reinSortieren=obj.state.val.replace(/^.+](.+)/,"$1");
             myListDataDel.push({  "Item":   reinSortieren,
                             "Time":new Date().getTime()  })
            setState(`javascript.${instance}.Tabellen@Liv.${dpVIS}.List_JSON`,JSON.stringify(myListDataDel))
            setTimeout(function () {writeHTML();   }, 1000);
            //timerSammlung=true;
            setTimeout(function () {sendToTeleg(listenNameTele);   }, 1500);   
    
   } 
}
   })
//gesammeltes löschen
schedule(myTeleUpdateSchedule,  function () { if (timerSammlung) sendToTeleg(listenNameTele+" ist refreshed") ;  timerSammlung=false  })
//script start sendet liste
setTimeout(function () {sendToTeleg(listenNameTele);   }, 1500);   
//------------------------------------------------------
//-----------------sendet telegram------------------------
  
function sendToTeleg(refreshed) {
   
   var myListDataTele=JSON.parse(getState("javascript." + instance + ".Tabellen@Liv."+dpVIS+".List_JSON").val);
   if(myListDataTele.length==0) {refreshed="Liste leer"} else{myListDataTele.push({"Item":"ALLES LÖSCHEN","Time":66666666})}
   let Arr1=[];
   let Arr2=[];
   let Arr3=[];
   let ArrSend=[];
   let langerText=false;
   let ArrHelp=[];
  //  log(JSON.stringify(myListDataTele))
   for(let cc=0;cc<myListDataTele.length;cc++){
    //   let yy= (Math.round((new Date()).getTime() / 1000))-Math.round(myListDataTele[cc].Time/1000);
      // let xx = Math.floor( ((yy)/60/60/24) )+"d "+ Math.floor(((yy)/60/60) % 24) +"h "+ Math.floor( ((yy)/60) % 60 )+"m" 
       //!myListDataTele[cc].Item.includes("ALLES LÖSCHEN") ? xx=formatDate(getDateObject((new Date(myListDataTele[cc].Time).getTime())), myDatumFormat) : xx="";
    //   xx=xx.replace(/0(.\.)/g,"$1")
      /* Arr2.push([{ text:myListDataTele[cc].Item+"\n"+xx,
                   callback_data:+myListDataTele[cc].Time}])*/
                
        if (myListDataTele[cc].Item.length>40 || einspaltigTele) langerText=true;
        Arr1.push([{ text:myListDataTele[cc].Item,
                   callback_data:+myListDataTele[cc].Time+"--xyx"}])          
        Arr2.push({ text:myListDataTele[cc].Item,
                   callback_data:+myListDataTele[cc].Time+"--xyx"}) 
   }
   //log(Arr2.length.toString())
   for(let uu=0;uu<Arr2.length;uu++){ let aa=uu+1; //log("aa: "+aa.toString())
                                      ArrHelp.push(Arr2[uu])
                                      if (aa %2==0) {Arr3.push(ArrHelp);ArrHelp=[]}
                                    }
    if(ArrHelp.length>0) Arr3.push(ArrHelp)
   
   langerText ? ArrSend = Arr1.map((x) => x) : ArrSend = Arr3.map((x) => x);
 
 
  sendTo('telegram.'+telegramInstance, {
 
  text: refreshed,
  parse_mode:"Markdown",
  reply_markup: {
      inline_keyboard:ArrSend, 
                 
      resize_keyboard:      false,
      one_time_keyboard:    false,
      disable_notification: false,
      remove_Keyboard:      true  
  }
});
}