﻿/*

 "Noch ne Uhr" v0.9, Copyleft (K) 2009 Hendrik Dilling

 Basierend auf einer Idee von Patrick Bussmann und einem nur von weitem gesehenen iGoogle-Widget.
 Mit freundlichen Grüssen an die nicos AG in Münster, und allen ihren Mitarbeitern.

 Installation:

 1) Script über <script>-tag laden.
   Beispiel: <script src="nochneuhr.js" type="text/javascript"></script>

 2) onload="uhren_starten();" in den <body>-tag packen.
   Beispiel: <body onload="uhren_starten();">

 3a) <canvas>-tag positionieren
 3b) class="uhr" zuweisen
 3c) mit width="x" eine Breite festlegen. Höhe wird automatisch relativ zur Breite gesetzt.
 3d) optional: canvas mit title="(Ort)" zu einer bestimmten Zeitzone zuweisen.
   Beispiel: <canvas class="uhr" width="300" title="San Francisco"></canvas>

 4a) optional: über folgenden Tag Zeitzonen definieren: <input class="zeit" name="(Ort)" value="+/-X">
   Beispiel: <input type="hidden" class="zeit" name="San Francisco" value="-6">



*/

   // Graphikoptionen. Breite/Höhe/Länge sind Prozentangaben der Breite des gesamten Canvas.
   var option=new Array();
   
   option['rahmen_dicke']            = 2.0;
   option['rahmen_farbe']            = '#000000';

   option['marker_minuten_sichtbar'] = 'TRUE';
   option['marker_minuten_laenge']   = 3;
   option['marker_minuten_breite']   = 0.25;
   option['marker_minuten_typ']      = 'round';
   option['marker_minuten_farbe']    = '#111';

   option['marker_stunden_sichtbar'] = 'TRUE';
   option['marker_stunden_laenge']   = 4
   option['marker_stunden_breite']   = 1.5;
   option['marker_stunden_typ']      = 'round';
   option['marker_stunden_farbe']    = '#111';

   option['marker_viertel_sichtbar'] = 'TRUE';
   option['marker_viertel_laenge']   = 8;
   option['marker_viertel_breite']   = 3;
   option['marker_viertel_typ']      = 'round';
   option['marker_viertel_farbe']    = '#008060';

   option['zeiger_sekunde_sichtbar'] = 'FALSE';
   option['zeiger_sekunde_laenge']   = 30;
   option['zeiger_sekunde_breite']   = 0.75;
   option['zeiger_sekunde_typ']      = 'square';
   option['zeiger_sekunde_farbe']    = '#111';

   option['zeiger_minute_sichtbar']  = 'TRUE';
   option['zeiger_minute_laenge']    = 40;
   option['zeiger_minute_breite']    = 1.75;
   option['zeiger_minute_typ']       = 'square';
   option['zeiger_minute_farbe']     = '#008060';

   option['zeiger_stunde_sichtbar']  = 'TRUE';
   option['zeiger_stunde_laenge']    = 30;
   option['zeiger_stunde_breite']    = 3.75;
   option['zeiger_stunde_typ']       = 'square';
   option['zeiger_stunde_farbe']     = '#222';

   option['titel_groesse']           = 10;
   option['titel_font']              = 'Arial Black';
   option['titel_farbe']             = 'black';
   option['digitaluhr_groesse']        = 15;
   option['digitaluhr_font']         = 'Arial';
   option['digitaluhr_farbe']        = 'black';
   option['abstand']                 = 1;

   option['licht_offset']            = -7;
   option['licht_staerke']           = 0.5;
   option['schatten_hoehe']          = 1.5;
   option['schatten_schaerfe']       = 5;
   option['schatten_farbe']          = 'rgba(0,0,0,0.75)';
   option['hintergrund']             = 'rgba(200,195,180,1.0)';

   // Die Konfiguration endet hier.
   var zeitzonen=new Array();

   function IsNumeric(input) {
      return (input-0)==input&&input.length>0;
   }

   // Funktion zum auslesen der in HTML angegebenen Zeitzonen
   function ladezonen() {
      var zonen_liste=document.getElementsByTagName('input');
      for(var c=0; c<zonen_liste.length; c++) {
         var zeitzone=zonen_liste[c];
         if(zeitzone.getAttribute('class')=='zeit') {
            zeitzonen[zeitzone.getAttribute('name')]=zeitzone.getAttribute('value');
         }
      }
   }

   // Hilfsfunktion zum Zeichnen der Markierungen für Minuten/Stunden/Viertel
   function zeiger(w, canvas, winkel, laenge, breite, cap, farbe) {
      var img=canvas.getContext('2d');
      img.strokeStyle=farbe;                       // Farbe setzen

      img.lineWidth=w*breite;                      // Linientyp setzen
      img.lineCap=cap;

      img.shadowOffsetX=w*v(canvas,'schatten_hoehe');          // Schatten setzen
      img.shadowOffsetY=w*v(canvas,'schatten_hoehe');
      img.shadowBlur=w*v(canvas,'schatten_schaerfe');
      img.shadowColor=v(canvas,'schatten_farbe');

      var x=w*50-(w*laenge*Math.cos(winkel*Math.PI/180+Math.PI/2)); // Zielpunkt-Koordinaten
      var y=w*50-(w*laenge*Math.sin(winkel*Math.PI/180+Math.PI/2));

      img.beginPath();                             // Zeiger zeichnen
      img.moveTo(w*50,w*50);
      img.lineTo(x,y);
      img.stroke();
   }

   // Hilfsfunktion zum Zeichnen der Zeiger Sekunden/Minuten/Stunden
   function marker(w, canvas, anzahl, laenge, breite, cap, farbe) {
      var img=canvas.getContext('2d');
      img.strokeStyle=farbe;        // Farbe setzen
      img.lineWidth=w*breite;       // Linienbreite setzen
      img.shadowOffsetX=0;
      img.shadowOffsetY=0;
      img.shadowBlur=w*10;
      img.shadowColor='rgba(0,0,0,0.25)';
      img.beginPath();              // Los gehts.
      for(var winkel=0; winkel<anzahl; winkel++) {
         var x=Math.cos(winkel*Math.PI*2/anzahl); // x-Abweichung von 0..1
         var y=Math.sin(winkel*Math.PI*2/anzahl); // y-Abweichung von 0..1
         var fx=Math.round((w*x*(50-v(canvas,'rahmen_dicke')))+(w*50));      // x-Koordinate Startpunkt
         var fy=Math.round((w*y*(50-v(canvas,'rahmen_dicke')))+(w*50));      // y-Koordinate Startpunkt
         var tx=Math.round((w*x*(50-laenge-v(canvas,'rahmen_dicke')))+(w*50)); // x-Koordinate Zielpunkt
         var ty=Math.round((w*y*(50-laenge-v(canvas,'rahmen_dicke')))+(w*50)); // y-Koordinate Zielpunkt
         img.moveTo(fx,fy); // Linie definieren
         img.lineCap=cap;
         img.lineTo(tx,ty);
      }
      img.stroke(); // Konstrukt zeichnen
   }

   // Hilfsfunktion, die Vorgabewerte mit Canvas-Attributen abgleicht
   function v(canvas,attribut) {
    if(canvas.getAttribute(attribut)) {
     return canvas.getAttribute(attribut);
    }
    return option[attribut];
   }

   // Haupt-Funktion zum zeichnen der Uhren.
   // Muss beim laden der Seite aufgerufen werden und zeichnet in alle Canvas-Elemente der Klasse "uhr".
   function zeichnen() {
      var canvas_list=document.getElementsByTagName('canvas');  // Für alle Canvas-Elemente...
      var jetzt=new Date();
      for (var c=0; c<canvas_list.length; c++) {
         var canvas=canvas_list[c];
         var titel=canvas.getAttribute('title');
         var sekunden=jetzt.getSeconds();
         var stunden=jetzt.getUTCHours()+jetzt.getUTCMinutes()/60.0+jetzt.getSeconds()/3600.0;
         if(canvas.getAttribute('lokalzeit')=="TRUE") stunden=jetzt.getHours()+jetzt.getMinutes()/60.0+jetzt.getSeconds()/3600.0;
         if(IsNumeric(canvas.getAttribute('zeitzone'))) stunden+=Number(canvas.getAttribute('zeitzone'));
         while(stunden<0) stunden+=24;
         var minuten=(stunden-Math.floor(stunden))*60;
         if(canvas.getAttribute('class') == 'uhr') {            // ...mit Klassen-Namen "uhr":
            var img=canvas.getContext('2d');                    // - Zeichen-Context holen

            var w=canvas.getAttribute('width')/100.0;           // - Breite und Höhe prozentual merken
            var h=Math.round(w*(100+v(canvas,'titel_groesse')+v(canvas,'abstand')+v(canvas,'digitaluhr_groesse')+v(canvas,'abstand')));
            if(canvas.getAttribute('height')!=h) canvas.setAttribute('height',h);

            // Canvas löschen
            img.fillStyle='white';
            img.fillRect(0,0,w*100,w*(100+v(canvas,'titel_groesse')+v(canvas,'abstand')+v(canvas,'digitaluhr_groesse')+v(canvas,'abstand')));

            // Uhren-v(canvas,'hintergrund') zeichnen
            img.fillStyle=v(canvas,'hintergrund');
            img.beginPath();
            img.arc(w*50,w*50,w*(50-v(canvas,'rahmen_dicke')/2),0,Math.PI*2,0);
            img.fill();

            // Uhrblattreflektion aufbringen
            var face = img.createRadialGradient(w*(50+v(canvas,'licht_offset')),w*(50+v(canvas,'licht_offset')),w*10,w*(50+v(canvas,'rahmen_dicke')/2),w*(50+v(canvas,'rahmen_dicke')/2),w*50);
            face.addColorStop(0.000, 'rgba(255,255,255,'+1.00*v(canvas,'licht_staerke')+')');
            face.addColorStop(0.700, 'rgba(255,255,255,'+0.20*v(canvas,'licht_staerke')+')');
            face.addColorStop(0.800, 'rgba(255,255,255,'+0.05*v(canvas,'licht_staerke')+')');
            face.addColorStop(0.995, 'rgba(255,255,255,'+0.00*v(canvas,'licht_staerke')+')');
            face.addColorStop(1.000, 'rgba(255,255,255,'+1.00*v(canvas,'licht_staerke')+')');
            img.fillStyle=face;
            img.beginPath();
            img.arc(w*50,w*50,w*(50-v(canvas,'rahmen_dicke')),0,Math.PI*2,0);
            img.fill();

            // Markierungen für Minuten, Stunden und Viertel zeichnen
            if(v(canvas,'marker_minuten_sichtbar')=="TRUE") marker(w,canvas,60,v(canvas,'marker_minuten_laenge'),v(canvas,'marker_minuten_breite'),v(canvas,'marker_minuten_typ'),v(canvas,'marker_minuten_farbe'));
            if(v(canvas,'marker_stunden_sichtbar')=="TRUE") marker(w,canvas,12,v(canvas,'marker_stunden_laenge'),v(canvas,'marker_stunden_breite'),v(canvas,'marker_stunden_typ'),v(canvas,'marker_stunden_farbe'));
            if(v(canvas,'marker_viertel_sichtbar')=="TRUE") marker(w,canvas,04,v(canvas,'marker_viertel_laenge'),v(canvas,'marker_viertel_breite'),v(canvas,'marker_viertel_typ'),v(canvas,'marker_viertel_farbe'));

            // Schatten montieren
            face=img.createRadialGradient(w*40,w*40,w*10,w*(50+v(canvas,'rahmen_dicke')/2),w*(50+v(canvas,'rahmen_dicke')/2),w*50);
            face.addColorStop(0.00,'rgba(0,0,0,0.0)');
            face.addColorStop(0.75,'rgba(0,0,0,0.0625)');
            face.addColorStop(1.00,'rgba(0,0,0,0.35)');
            img.fillStyle=face;
            img.beginPath();
            img.arc(w*50,w*50,w*(50-v(canvas,'rahmen_dicke')),0,Math.PI*2,0);
            img.fill();

            // Zeiger zeichnen
            if(v(canvas,'zeiger_stunde_sichtbar')=="TRUE") zeiger(w,canvas,30.0*stunden,v(canvas,'zeiger_stunde_laenge'),v(canvas,'zeiger_stunde_breite'),v(canvas,'zeiger_stunde_typ'),v(canvas,'zeiger_stunde_farbe'));
            if(v(canvas,'zeiger_minute_sichtbar')=="TRUE") zeiger(w,canvas,6.0*minuten,v(canvas,'zeiger_minute_laenge'),v(canvas,'zeiger_minute_breite'),v(canvas,'zeiger_minute_typ'),v(canvas,'zeiger_minute_farbe'));
            if(v(canvas,'zeiger_sekunde_sichtbar')=="TRUE") zeiger(w,canvas,6.0*(sekunden),v(canvas,'zeiger_sekunde_laenge'),v(canvas,'zeiger_sekunde_breite'),v(canvas,'zeiger_sekunde_typ'),v(canvas,'zeiger_sekunde_farbe'));
            img.shadowOffsetX=0;  // Schatten löschen
            img.shadowOffsetY=0;
            img.shadowBlur=0;
            img.shadowColor='rgba(0,0,0,0.0)';

            // Rahmen zeichnen
            img.strokeStyle=v(canvas,'rahmen_farbe');
            img.lineWidth=w*v(canvas,'rahmen_dicke');
            img.beginPath();
            img.arc(w*50,w*50,w*(50-v(canvas,'rahmen_dicke')/2),0,Math.PI*2,0);
            img.stroke();

/*            // Glasreflektion darstellen
            face=img.createRadialGradient(w*65,w*65,w*10,w*(50+v(canvas,'rahmen_dicke')/2),w*(50+v(canvas,'rahmen_dicke')/2),w*58);
            face.addColorStop(0.000,'rgba(255,255,255,0.0)');
            face.addColorStop(0.550,'rgba(255,255,255,0.0)');
            face.addColorStop(0.800,'rgba(255,255,255,0.2)');
            face.addColorStop(0.850,'rgba(255,255,255,0.65)');
            face.addColorStop(0.900,'rgba(255,255,255,0.2)');
            face.addColorStop(1.000,'rgba(255,255,255,0.0)');
            img.fillStyle=face;
            img.beginPath();
            img.arc(w*50,w*50,w*(50-v(canvas,'rahmen_dicke')),0,Math.PI*2,0);//Math.PI/15*14,Math.PI/5*8.2,0);
            img.fill();
*/
            // Titel anzeigen
            img.font=w*v(canvas,'titel_groesse')+"px "+v(canvas,'titel_font');
            img.fillStyle=v(canvas,'titel_farbe');
            var titel_weite=img.measureText(titel);
            img.fillText(titel,(w*100.0-titel_weite.width)/2.0,w*(100.0+v(canvas,'titel_groesse')),w*100.0);

            var h=Math.floor(stunden)%24;
            var m=Math.floor(minuten)%60;
            var s=Math.floor(sekunden)%60;
            var digitaluhr=(h<10?'0'+h:h)+":"+(m<10?'0'+m:m);///+":"+(s<10?'0'+s:s);
            var digitaluhr_weite=img.measureText(digitaluhr);
            img.font=w*v(canvas,'digitaluhr_groesse')+"px "+v(canvas,'digitaluhr_font');
            img.fillStyle=v(canvas,'digitaluhr_farbe');
            img.fillText(digitaluhr,(w*100.0-digitaluhr_weite.width)/2.0,w*(100.0+v(canvas,'titel_groesse')+v(canvas,'abstand')+v(canvas,'digitaluhr_groesse')),w*100.0);
            
            

         }
      }
   }

   function uhren_starten() {
    ladezonen();
    zeichnen();
    window.setInterval('zeichnen();',1000);
   }



