// 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) René Philipp
// erstellt vom 7.-21. Juli 2003 und 11. August 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
// Ren'e Philipp fuegte konqueror hinzu!

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";
else if ((navigator.userAgent.indexOf("Konq")>=0)||(navigator.userAgent.indexOf("safari")>=0))
 browser="konq";

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")||(browser=="konq"))&&(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, Netscape 7.02 und Konqueror 3.1.0. 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 */

