/********************************************************
Dieses Script besteht aus: gradient und rainbow
farbverlauf_text.js v. 1.4
Neue Version zu erfragen bei:
tlustulimu@web.de
Copyright des ganzen Scripts (c) Rene Philipp
erstellt vom 7.-21. Juli 2003
Dieses Programm unterliegt der GPL, d.h. es darf frei
kopiert und modifiziert werden.
Details zur GPL: http://www.gnu.org/copyleft/gpl.html
Die Funktion entet_ext() darf auch fuer andere Scripte verwandt
werden, wenn dort dieser Hinweis und der dortige Kommentar erhalten
bleiben. (Nicht vergessen die Funktion MakeArray()
"mitzunehmen"!)

Originalkommentar zu gradient()
******************* Browser Detector **********************
Possible values for browser are:
 "netscape"
 "opera"     (ewww)
 "msie"      (double ewww)
 "robot"
 "unknown"
Possible values for version are:
 any numerical value (3, 2.02, 4.04, etc.)
 0 if unable to determine    */

var browser = "unknown";
var version = 0;
if (navigator.userAgent.indexOf("Opera") >= 0)
 browser = "opera";
else if (navigator.userAgent.indexOf("obot") >= 0)
 browser = "robot";
else if (navigator.appName.indexOf("etscape") >= 0)
 browser = "netscape";
else if (navigator.appName.indexOf("icrosoft") >= 0)
 browser = "msie";

version = parseFloat(navigator.appVersion);
if (isNaN(version)) version = 0;
if ((browser == "msie")&&(version == 2)) version = 3;

/******************** Gradient Output ***********************
Syntax for use:

    gradient(TEXT_STRING_HERE,HEXCODES_STRING_HERE);

 use in similar way you would use document.write();
 note, it cannot be used to return a string value.
 gradient() takes two arguements. the first will
 be the original pure text string. (now htmlcodes too)
 the second argument is a string of color hexcodes
 seperated with spaces thru which the text should
 progress. for example say you wanted to print out
 the string "color gradient", and you wanted it to
 progress from blue to red. a color code for blue
 is 4444FF, and a color code for red is FF4444.
 taking those two codes, and the original string,
 somewhere in the body of the document you would
 write within a <Script> tag the following:
 gradient("color gradient","4444FF FF4444");
 if however, you wanted it to progress thru three
 or more colors, its as simple as adding them to the
 string of color codes. it is important to remember
 however that the string must be color HEXCODES, and
 not merely just color names, (e.x- "red", "yellow")
 if this seems like too much trouble, then perhaps
 you should try something simple like ripping off
 some annoying status bar text scroller. =Ž
 one last thing. if you overuse this script, i can
 pretty much gaurantee people will hate your webpage.
 the fact is, this javascript is memory intensive. if
 you overdo it, you're crashing some visitors' browsers.
 ***********************************/

/* lookup table  */
var tohex = new Array(256);
var hex = "0123456789ABCDEF";
var count = 0;
for (x=0; x<16; x++) {
 for (y=0; y<16; y++) {
 tohex[count] = hex.charAt(x) + hex.charAt(y);
 count++;
 }
}

/* ColorCode constructor  */
function ColorCode(hexcode) {
  if (hexcode.length == 7) {
    this.r = parseInt(hexcode.substring(1,3),16);
    this.g = parseInt(hexcode.substring(3,5),16);
    this.b = parseInt(hexcode.substring(5,7),16);
  }
  else if (hexcode.length == 6) {
    this.r = parseInt(hexcode.substring(0,2),16);
    this.g = parseInt(hexcode.substring(2,4),16);
    this.b = parseInt(hexcode.substring(4,6),16);
  }
  else {
    this.r = this.g = this.b = 0;
    alert("Error: ColorCode constructor failed");
  }
  if (isNaN(this.r)||isNaN(this.g)||isNaN(this.b))
    alert("Error: ColorCode constructor failed");
}

/* ColorList constructor  */
function ColorList(hexcodes) {
  var i = 0;
  var c = 0;
  this.codes = new Array(Math.round(hexcodes.length/7));
  while (i < hexcodes.length) {
    if (isNaN(parseInt(hexcodes.substring(i,i+6),16))) ++i;
    else {
      this.codes[c] = new ColorCode(hexcodes.substring(i,i+6));
      i += 7;
      ++c;
    }
  }
  this.len = c;
}

function interpolate (x1, y1, x3, y3, x2) {
  if (x3 == x1) return y1
  else return (x2-x1)*(y3-y1)/(x3-x1) + y1
}

/* x=index of letter, y=number of letters, z=number of colors  */
function lowcolorindex (x, y, z) {
  if (y == 1) return 0
  else return Math.floor( (x*(z-1))/(y-1) )
}

function hicolorindex (x, y, z, low) {
  if ( low*(y-1) == x*(z-1) ) return low
  else if (y == 1) return 0
  else return Math.floor( (x*(z-1))/(y-1) + 1 )
}
/***********************************************************************
hier enden die Funktionen, welche nur von gradient() verwendet werden. |
***********************************************************************/

/*  Variablenfeld wird erzeugt */
function MakeArray(n){
   this.length=n;
   for(var i=1; i<=n; i++) this[i]=i-1;
   return this
}
hex=new MakeArray(16);
hex[11]="A"; hex[12]="B"; hex[13]="C"; hex[14]="D"; hex[15]="E"; hex[16]="F";
/******************************************************************************
Hier soll der Text in Portionen zerlegt werden, die Entitys sowie HTML-Tags   |
landen als Ganzes im Variablenfeld - Achtung: ich habe noch keine Fehler-     |
toleranz (wie z.B. für fehlendes ;) eingebaut - etwas kompliziert, da         |
'falsche Zeichen' vorher aus dem Feld mit Entity entfernt werden muessen.     |
Auszerdem werden jetzt HTML-Tags extra behandelt.                             |
*******************************************************************************
Diese Funktion wird von gradient() und rainbow() verwendet.
*/
function entet_ext(anfang,laenge,text2) {
   var a,z,h,f,laenge2,b,c,ha,he,ht;
   a="";        /* String, der im Variablenfeld landet */
   z=0;         /* Position im String */
   h=0;         /* Position im Entity */
   f=0;         /* Anzahl der Felder */
   b="&";       /* Anfang eines Entity */
   c=";";       /* Ende eines Entity */
   ha="<";      /* HTML-Tag beginnt */
   he=">";      /* HTML-Tag endet */
   ht=0;        /* Anzahl der Tags */
   laenge2=laenge;  /* Laenge aus Gesamtsumme aller belegten Felder */
   textteil=new MakeArray(laenge);   /* Feld fuer die Zeichen sowie Entitys */
   for(var i=1;i<=laenge;i++) textteil[i]="";/* z.B.: &#x0109;u vi estas dika?*/
   for (z;z<=laenge;z++) {  /* Beginn des Zaehlens fuer die Zerlegung */
  /*   a=text2.substring(z,z+1);  alter Code */
     a=text2.charAt(z);     /* Entnahme des aktuellen (per z) Zeichens */
     if(a==b) {             /* Abfrage, ob Entity beginnt (Zeichen "&") */
     h=0;
     f=f+1;                 /* Feldzaehler wird erhoeht */
     textteil[f]=a;         /* Entity in ein Variablenfeld befoerdern */
     for(h;h<=7;h++)        /* Schleife mit Maximallaenge eines Entity
                               JavaScript zaehlt ab 0, daher hier 7 */
       {
       z=z+1;               /* Gesamtzaehler wird erhoeht */
    /* a=text2.substring(z,z+1);  alter Code */
       a=text2.charAt(z);   /* Entnahme des aktuellen Zeichens */
       textteil[f]=textteil[f]+a;/* Zusammensetzung des Entity im Variablenfeld*/
       laenge2=laenge2-1;   /* wird bei jedem Entity reduziert, da es ja die
                               Gesamtzahl der Felder darstellen soll. */

       if(a==c) { break }   /* Entityendekennung (";") erreicht */
         }
     }
     else if(a==ha) {       /* HTML-Codierung verwerten (analog zur Entity-
                               erkennung) */
            h=0;            /* funktioniert nun richtig mit IE6, NN7,
                               K-Meleon 0.7 und Opera 6.01
                               Wie laesst sich das erweitern? */
            f=f+1;
            textteil[f]=a;
            for(h;h<=300;h++)
            {
            z=z+1;
        /*  a=text2.substring(z,z+1);  alter Code */
            a=text2.charAt(z);
            textteil[f]=textteil[f]+a;
            laenge2=laenge2-1;

            if(a==he)
                {
                ht=ht+1;
              /*  document.write(ht);  */
                break
                } /* Ende des HTML-Tags (">") */
              }

             }

     else                     /* kein Entity oder HTML-Code */
     {
     f=f+1;
     textteil[f]=a;

     }

   }
   textteil[laenge+1]=laenge2;
   /* Uebergabe der benutzten Zahl von Feldern, da JavaScript nur EINE(!)
   Uebergabe ueber return gestattet. Sollte mal ein Gradient ohne Entitys
   bzw. HTML-Tags verwendet werden, so musz nichts besonderes getan werden,
   da der Wert ja ueber ein zusaetzliches Variablenfeld uebergeben wird.
   (Daher +1 im Befehl) */
   textteil[laenge+2]=ht;
   /* Uebergabe der Anzahl der HTML-Tags */

   return textteil /* Uebergabe des Variablenfeldes mit dem Mix aus Zeichen,
                      Entitys und HTML-Tags  */
}
/* Ende meiner neu erstellten Funktion */

/***************************************************************************
Hier steht die Hauptfunktion von gradient()                                |
****************************************************************************
*/
function gradient (thetext,thecolors) {
  if (((browser == "netscape")||(browser == "msie")||(browser == "opera"))&&(version>=3.0)) {
    var colors = new ColorList(thecolors);
    var numcolors = colors.len;
    textfelder=entet_ext(0,thetext.length,thetext);  /* Stringzerlegung */
    var numchars=textfelder[thetext.length+1]+1;  /* Laengenrueckgabe ueber
    zusaetzliches Variablenfeld */
    var nombro_ht=textfelder[thetext.length+2];
    /* var numchars = thetext.length; alter Code */
    var rr = 0;
    var gg = 0;
    var bb = 0;
    var lci = 0; //lower color index
    var hci = 0; //high color index
    var first=""; /* helfen beim Unterscheiden zwischen HTML und nicht-HTML  */
    var last="";
    var farbe1,farbe2; /* kodieren die Farbdefinition ueber HTML-Tags       */
    var i2=1;  /* Index fuer Farbeposition */
    var page; /* speichert den per JavaScript erstellten HTML-Code */
    var sen_ht=numchars-nombro_ht;  /* Laenge ohne Tags */
    for (i=1; i<numchars; ++i) {
     /* lci = lowcolorindex(i2, numchars, numcolors); */
      lci=lowcolorindex(i2,sen_ht,numcolors);
      hci = hicolorindex(i2, numchars, numcolors, lci);
     /* hci = hicolorindex(i2, sen_ht, numcolors, lci);  verursacht Fehlermeldung, warum weisz
     ich noch nicht */
      rr = Math.round(interpolate( lci/(numcolors-1), colors.codes[lci].r, hci/(numcolors-1), colors.codes[hci].r, i2/(sen_ht-1)));
     /* rr = Math.round(interpolate( lci/(numcolors-1), colors.codes[lci].r, hci/(numcolors-1), colors.codes[hci].r, i2/(numchars-1)));   */
      gg = Math.round(interpolate( lci/(numcolors-1), colors.codes[lci].g, hci/(numcolors-1), colors.codes[hci].g, i2/(sen_ht-1)));
    /*  gg = Math.round(interpolate( lci/(numcolors-1), colors.codes[lci].g, hci/(numcolors-1), colors.codes[hci].g, i2/(numchars-1)));   */
      bb = Math.round(interpolate( lci/(numcolors-1), colors.codes[lci].b, hci/(numcolors-1), colors.codes[hci].b, i2/(sen_ht-1)));
    /* bb = Math.round(interpolate( lci/(numcolors-1), colors.codes[lci].b, hci/(numcolors-1), colors.codes[hci].b, i2/(numchars-1))); */
      if ((browser == "opera") && (version==3)) {
        rr = 255 - rr;
        gg = 255 - gg;
        bb = 255 - bb;
      }
      first=textfelder[i].indexOf("<");  /* Erkennung der HTML-Tags */
      last=textfelder[i].indexOf(">");
     /* alert(textfelder[i]); */
      /* Fuer Netscape und Opera muessen die HTML-Codes ohne umklammernde Font-
      befehle realisiert werden, weil sonst Muell angezeigt wird. */
      if((first=="-1") && (last=="-1"))   /* kein HTML-Tag */
        {
        farbe1='<FONT COLOR="#'+tohex[rr]+tohex[gg]+tohex[bb]+'">';
        farbe2="<\/FONT>";
        /* document.write(textfelder[i].fontcolor(tohex[rr]+tohex[gg]+tohex[bb])); */
        i2++;
         }
      else                       /* HTML-Tag */
        {
        farbe1="";
        farbe2="";
        }
        page=farbe1;
        page+=textfelder[i]+farbe2;
        document.write(page);
        /* document.write(textfelder[i]); */
    }
  }
  else document.write(thetext); /* unrecognized browser, better not to attempt anything fancy  */
}

/*  Dieses Script basiert auf dem Script mit folgendem Vermerk:
***************************************************************************
    This code is compliments of superhoi's javascript's disigners.        |
                                                                          |
        It can be found at http://hoi.mypage.org/.                        |
                                                                          |
        For more info e-mail superhoi@hotmail.com.                        |
                                                                          |
                                 ---------                                |
                                                                          |
        This JavaScript may be used and modified freely, so long          |
                                                                          |
        as this message and the comments above remain intact.             |
*******************************************************************************
Ich, Rene Philipp (E-Mail: tlustulimu@web.de) habe das Script so erweitert,   |
dass es mit Entitys und HTML-Tags funktioniert und mehrere Modi (Parameter    |
Style) aufweist. Auszerdem ist das Script jetzt problemlos mit dem            |
wz_tooltips.js-Script von Walter Zorn (www.walterzorn.de) kombinierbar.       |
Bearbeitet am 7. bis 21. Juli 2003. Getestet mit IE6, K-Meleon 0.7,           |
Opera 6.01 und Netscape 7.02. Scriptversion 1.4                               |
*******************************************************************************
Verbesserungsvorschlaege an:                                                  |
tlustulimu@web.de - bitte, wenn moeglich in Deutsch, da meine                 |
Englischkenntnisse verbesserungsbeduerftig sind mangels Praxis.               |
******************************************************************************/

/****************************************************************************
Umwandlung von dezimal (Basis=10) nach hexadezimal (Basis=16)               |
****************************************************************************/
function ToHex(x){
   var high=x/16;
   var s=high+"";
   s=s.substring(0,2);
   high=parseInt(s,10);
   var left=hex[high+1];
   var low=x-high*16;
   s=low+"";
   s=s.substring(0,2);
   low=parseInt(s,10);
   var right=hex[low+1];
   var string=left+""+right;
   return string;
}
/*****************************************************************************
Hier folgt das Hauptprogramm, welches im HTML-Code einzubinden ist:          |
<script language="JavaScript">                                               |
<!--                                                                         |
rainbow("Hallo! Wie geht's euch?",3)                                         |
//-->                                                                        |
</script>                                                                    |
Bitte eventuell noetige Maskierungen beachten!                               |
Anwender mit dem alten Rainbow, das fuer uralte Browser ohne JavaScript den  |
Text in --> und <!-- einschlosz, muessen die Variante rainbow2() wie         |
folgt verwenden:                                                             |
                                                                             |
rainbow2("-->Hallo Maxe!<!--",2)                                             |
                                                                             |
oder die Kommentare sind bei Einbindung dieses Scripts zu entfernen:         |
                                                                             |
rainbow("Hallo Maxe!",2)                                                     |
                                                                             |
Die Angabe zum 'Style' (in den Beispielen die 3 und zweimal die 2) kann      |
weggelassen werden, wenn der Wert 1 gesetzt wuerde, denn dies geschieht      |
automatisch, wenn der Style auszerhalb des zulaessigen Bereichs (z.Z.1-3)    |
liegt oder fehlt.                                                            |
                                                                             |
*****************************************************************************/
function rainbow(text,style,farben) {
   /*  alert(texte); */
   if(style==4)                 /* Variante 4 ruft gradient auf */
   gradient(text,farben)
   else {
   textfelder=entet_ext(0,text.length,text); /* Textzerlegung aufrufen */
   var test1=typeof style;
   /* Falscher Typ fuer style wird abgelehnt und durch Variante 1 ersetzt */
   if((test1=="string") || (test1=="boolean") || (test1=="object") || (test1=="undefined"))
   { style=1 }
   var lang=textfelder[text.length+1];
   /* +1 ist noetig um das zusaetzliche Variablenfeld auszulesen, welches fuer
   den Fall verwendet wird, dass keine Entitys und Tags da sind und das
   eigentlich letzte Feld dann hierfuer nicht frei waere. */
   var nombro_ht2=textfelder[text.length+2]; /* Enthaelt Anzahl der Tags */
  /* document.write(nombro_ht2); */
   var sen_ht2=lang-nombro_ht2;
 /*   document.write(lang," ",sen_ht2," ",text.length); Test */
   lang=lang+1;
   /* Addition von 1 notwendig, weil sonst immer das letzte Zeichen
      verschwindet */
   if((style==1) || (style==2))  /* Variantenunterscheidung A */
     { color_d1=255; }
   else if(style==3)
     { color_d1=200; }
   mul=color_d1/text.length;
   var page;         /* speichert den per Javascript erstellten HTML-Code */
   var farbe1,farbe2;/* kodieren die Farbdefinition ueber HTML-Tags  */
   var first="";     /* helfen beim Unterscheiden zwischen HTML und Nicht-HTML*/
   var last="";      /* -""- */
   var i2=1;  /* Index fuer Farbeposition - wird nicht erhoeht bei HTML-Tags */
   var max=3; /* Maximum der Varianten */
   var min=1; /* Minimum der Varianten */
   for(i=1;i<lang;i++) {
  /* for(i=1;i<text.length;i++) {     alter Code  */
      if((style==1) || (style==2) || (style>max) || (style<min))
      /* Variantenunterscheidung B */
      { color_d1=255*Math.sin(i2/(sen_ht2/3)); }  /* Var. 1 und 2 */
      /* some other things you can try>> "=255-mul*i" to fade out, "=mul*i"
      to fade in, or try "255*Math.sin(i/(text.length/3))" */
      else if(style==3)                               /* Var. 3 */
      { color_d1=200*Math.sin(i2/(sen_ht2/2)); }
      color_h1=ToHex(color_d1);
      color_d2=mul*i;
      color_h2=ToHex(color_d2);
      first=textfelder[i].indexOf("<");   /* Erkennung der HTML-Tags */
      last=textfelder[i].indexOf(">");
      k=text.length;                /* Fuer Varianten 2 und 3 */
      j=k-i;
      if(j<0) j=0;
      color_d3=mul*j;
      color_h3=ToHex(color_d3);
      /* Fuer Netscape und Opera muessen die HTML-Codes ohne umklammernde Font-
      befehle realisiert werden, weil sonst Muell angezeigt wird. */
        if((first=="-1") && (last=="-1")) {  /* kein HTML-Code */
           if(!style || style==1 || style>max || style<min) { /* Variante 1 */
              farbe1='<FONT COLOR="#FF' + color_h1+color_h2+ '">'; }
           else if(style==2 || style==3) {         /* Varianten 2 und 3 */
              farbe1='<FONT COLOR="#' + color_h3 + color_h1 + color_h1 + '">';
               }
           farbe2="<\/FONT>";
           i2++; }     /* Farbindex erhoehen */
        else { farbe1="";  /* HTML-Code   */
               farbe2=""; }
        page = farbe1;
        page += textfelder[i]+ farbe2;
      /*  document.write(textfelder[i]);  */
        document.write(page);   /* schreibt die Codehaeppchen in HTML */
        }
        }
}
/******************************************************************************
Die Kommentarvariante                                                         |
******************************************************************************/
function rainbow2(text3,style2,farben2)
{
  text3=text3.substring(3,text3.length-4);
  rainbow(text3,style2,farben2)

}




/* Ende des ganzen Scripts */