/* ********************************************************************
* Buffered Text-fade Effect - v3.0
* - Copyright 2008 - Licenced for free distribution under the BSDL
*   - http://www.opensource.org/licenses/bsd-license.php
***********************************************************************
* I) Setting Up
*
*   Copy the javascript from this page into an external .js file or
* into the <script> tag of your own HTML page.  You only need the code
* between the "Begin" and "End" lines.  This shouldn't be that
* difficult, but you wouldn't believe the kind of mail I get about
* this!  Just do it, okay?  Jeez.
*
*   a) The Fade Object
*   After that's done we need to create a fade object.  We do this by
* calling the fadeObj function with a number of arguments.  We'll use
* the default example included in the script: fader[0].  You can delete
* the fader[1] lines if you like.
*
* fader[0] = new fadeObj('fade0', 'dddddd', '000000', 20, 20);
*
*   The first argument ('fade0') is the id of the HTML tag which will
* be displaying the fading effect.  Usually you'll want to apply some
* height and width styles to this element, since it starts out with no
* text by default and will probably be collapsed.  You don't want it
* jumping around when the script writes new text to it.
*
*   The next two values are hexidecimal colour values, WITHOUT the
* preceding #.  The first value is the starting colour, or the colour
* the text is before it fades in.  The second value is the ending
* colour, or the colour the text will be when it finishes fading in.
*
*   The last two values are two integers which indicate the number of
* "steps" the script must take to complete a fade-in and a fade-out
* respectively.  With a value of 20 like in the example above, there
* will be 20 colour changes before the text is fully faded-in or faded-
* out.  The lower these numbers, the faster the fade will be.
*
*   b) The Fade Messages
*   After setting up our fade object, all we need to do now is write
* out all of the messages which will be displayed in this element.
* Remember that this script only affects text of a single colour.
* Images and multi-coloured text won't work.
*
*   Messages are included in the msg[] array.  Simply assign each
* message a number, like so:
*
* fader[0].msg[1] = "Fade text, message one.";
*
*   Each fade object can have as many messages as you want, and be in
* any numerical order.  You can even skip numbers, but note that if you
* use the fade() method pointed at a message number which doesn't
* exist, you will get an error.
*
* The msg[] array should start at element [1].  If you would like a
* default message to appear if there are no more fade-in events in the
* queue, assign the default message to element [0].
*
***********************************************************************
* II) The Events
*
*   Fades can be triggered by any DOM event, but most likely you'll be
* using mouseover and mouseout events.  I used those events as examples
* below.
*
*   To trigger a fade, you use the fade() method to add a fade action
* to the queue.  The reason we use a queue, is so that you can add this
* fade, even if another fade is already happening.  The fade() method
* takes two important arguments:
*
* Example: onmouseover="fader[0].fade(1, true);"
*
*   In this example we are still referencing fade object fader[0].
*
*   The first argument is the message this command refers to.  This one
* has been associated with msg[1] of fader[0].
*
*   The second argument indicates the direction of the fade.
*     -> true = fade in, false = fade out.
*
*   Examine the working example script to see how these events were
* placed on the <td> elements below.
*
***********************************************************************
* III) Tips
*
*   - All the text in each msg[] variable MUST be on one line in the
* code.  That means this:
*
*   fader[0].msg[1] = "Fader zero,
* message one";
*
* ... is not allowed!  The text should wrap automatically when it's
* displayed on your HTML page, but you can force line breaks with the
* <br> tag.  (If you have some Javascript experience you'll know how to
* get around this).
*
*   - If you're placing the fading text on a background image, make
* the starting colour an average sample of the background instead of
* just black or white.  This will enhance the "disappearing" effect.
*
*   - The script can only fade text, but can accept non-graphical HTML
* tags in which CSS text color is inherited, such as <p>, <table> (no
* borders), <strong> and <em>.  Use these tags to add structure and a
* simple text layout to your fades.
*
*   - To have links fade along with with the surrounding text, apply
* the CSS style: color:inherit !important; to all links within the fade
* text messages.
*
***********************************************************************
* That's it!  Isn't that amazing!?! :)
*
* If you have any problems with this script, don't hesitate to email me
* at wyvern@greywyvern.com and I'll be happy to answer your matter-of-
* life-and-death questions!  Cheers!
******************************************************************** */


/* ***** Begin ***************************************************** */
function fadeObject(id, c1, c2, s1, s2) {
  var self = this;
  this.id      = id;
  this.elem    = false;
  this.colour  = {
    stt: [parseInt(c1.substr(0, 2), 16), parseInt(c1.substr(2, 2), 16), parseInt(c1.substr(4, 2), 16)],
    end: [parseInt(c2.substr(0, 2), 16), parseInt(c2.substr(2, 2), 16), parseInt(c2.substr(4, 2), 16)],
    now: [parseInt(c1.substr(0, 2), 16), parseInt(c1.substr(2, 2), 16), parseInt(c1.substr(4, 2), 16)]
  };
  this.steps   = [s1, s2];
  this.dir     = false;
  this.active  = false;
  this.queue   = [];
  this.msg     = [];
  this.message = 0;
  function d2h(num) {
    num = Math.round(num);
    return ((num < 16) ? "0" : "") + num.toString(16);
  }
  this.fade = function(message, direction) {
    this.elem = this.elem || document.getElementById(this.id);
    this.queue.push([message, direction]);
    for (var x = 0; x < this.queue.length; x++) {
      for (var y = x + 1; y < this.queue.length; y++) {
        if (this.queue[x][0] == this.queue[y][0] && this.queue[x][1] != this.queue[y][1]) {
          this.queue.splice(x, 1);
          this.queue.splice(y - 1, 1);
        }
      }
    }
    if (!this.active) setTimeout(function() { self.fadeLoop(); }, 0);
  };
  this.fadeLoop = function() {
    if (!this.active && this.queue.length) {
      if (this.dir && this.message != this.queue[0][0]) this.queue.unshift([this.message, false]);
      var msg = this.queue.shift();
      if (this.msg[msg[0]]) {
        this.active = true;
        this.elem.innerHTML = this.msg[this.message = msg[0]];
        this.dir = msg[1];
      }
    }
    if (this.dir) {
      var c1 = this.colour.stt, c2 = this.colour.end, s = this.steps[0];
    } else var c1 = this.colour.end, c2 = this.colour.stt, s = this.steps[1];
    for (var x = 0, cnow = "", inc = 0; x < 3; x++) {
      this.colour.now[x] += inc = (c2[x] - c1[x]) / s;
      cnow += this.colour.now[x] = (inc < 0) ? Math.max(this.colour.now[x], c2[x]) : Math.min(this.colour.now[x], c2[x]);
    } this.elem.style.color = "#" + d2h(this.colour.now[0]) + d2h(this.colour.now[1]) + d2h(this.colour.now[2]);
    if (cnow == c2.join("")) {
      this.active = false;
      if (!this.queue.length) {
        if (!this.dir) {
          if (this.msg[0]) {
            this.queue.push([0, true]);
            setTimeout(function() { self.fadeLoop(); }, 0);
          } else this.elem.innerHTML = "&nbsp;";
        }
      } else setTimeout(function() { self.fadeLoop(); }, 0);
    } else setTimeout(function() { self.fadeLoop(); }, 0);
  };
  if (window.addEventListener) {
    window.addEventListener('load', function() { self.fade(0, true); }, false); 
  } else if (window.attachEvent)
    window.attachEvent('onload', function() { self.fade(0, true); });
}
/* ***** End ******************************************************* */




/* *****
 * User defined fade objects and messages
 *
 * These messages are used in fades triggered by mouseovers and
 * mouseouts on table cells.  They are the simplest type of fade and
 * require no extra Javascript code.
 */
var fader = new Array();

fader[0] = new fadeObject('fade0', 'dddddd', '000000', 20, 20);
fader[0].msg[0] = "This is an optional default message; the fade object on the right side has no default.  Mouseover each topic to make quotes fade in and out.";
fader[0].msg[1] = "Nowhere can a man find a quieter or more untroubled retreat than in his own soul.<br />- Marcus Aurelius";
fader[0].msg[2] = "Feeding the starving poor only increases their number.<br />- Ben Bova";
fader[0].msg[3] = "The limits of tyrants are prescribed by the endurance of those whom they oppose.<br />- Frederick Douglass";
fader[0].msg[4] = "The foolish man seeks happiness in the distance, the wise grows it under his feet.<br />- James Oppenheim";

fader[1] = new fadeObject('fade1', 'bbbbbb', '000000', 20, 20);
fader[1].msg[1] = "Success is relative. It is what we can make of the mess we have made of things.<br />- T.S. Eliot";
fader[1].msg[2] = "We have two ears and one mouth so we may listen more and talk the less.<br />- Epictetus";
fader[1].msg[3] = "It is better to be violent, if there is violence in our hearts, than to put on the cloak of nonviolence to cover impotence.<br />- Mahatma Gandhi";
fader[1].msg[4] = "Don't part with your illusions. When they are gone you may still exist, but you have ceased to live.<br />- Mark Twain";



/* *****
 * The code below describes how to make a throbbing or automatic fade
 * sequence of messages.  It is important to note that this function is
 * NOT part of the Buffered Text-Fade Effect, but merely an example of
 * how it can be used.  In this example, the throb() function controls
 * the commands which are sent to the fade engine; it is called
 * repeatedly at set time intervals rather than using mouseover events
 * as triggers.
 *
 * Notes:
 * - A global array "hash" is used to keep track of where each
 *   animation is currently in the sequence.
 * - The list of messages defined in the fader *must* start at one (1)
 *   and count upwards without skipping any integers.
 * - The third line of the throb() function controls how fast
 *   commands get sent to the fade engine.  It waits only 100 milli-
 *   seconds when fading out, but 5000 milliseconds (5 seconds) when
 *   fading in; this means the message will remain visible for about 5
 *   seconds before fading out again.
 *
 * Other types of fade animation are possible simply by designing
 * different ways to control the fade-ins and fade-outs!
 */
var hash = new Array();
function throb(item) {

  // If the hash array does not have an entry for this item, initialise it at 2
  if (!hash[item]) hash[item] = 2;

  // Send a fade command using the hash array to tell us what parameters we should use
  fader[item].fade(Math.floor(hash[item] / 2), !(hash[item] % 2));

  // Call this function again for this same item after a certain amount of time
  setTimeout(function() { throb(item); }, (hash[item] % 2) ? 100 : 15000);

  // If we have exceeded the number of messages in this fader, start over again at 2
  if (++hash[item] > fader[item].msg.length * 2 - 1) hash[item] = 2;
}

fader[2] = new fadeObject('fade2', 'acacac', '232936', 30, 30);
fader[2].msg[1] = "<span style='background: url(images/quoteleft.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style='line-height: 145%; font-size: 14px; font-style: italic;'>Anne Stern is the perfect recording engineer. She is not satisfied until you and she have created the best possible recording. If you want to sound your best (and then some), you want to work with Anne.&nbsp;</span><span style='background: url(images/quoteright.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;</span><br><span style='line-height: 145%; font-size: 14px;'>&mdash; </span><span style='font-size: 85%;'>Stephen Nelson, client of Stern Studios</span>";
fader[2].msg[2] = "<span style='background: url(images/quoteleft.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style='line-height: 145%; font-size: 14px; font-style: italic;'>One of my soloists commented that he preferred Anne's recordings to those done while he was in the Chamber Chorale, Stanford's foremost vocal ensemble.&nbsp;</span><span style='background: url(images/quoteright.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;</span><br><span style='line-height: 145%; font-size: 14px;'>&mdash; </span><span style='font-size: 85%;'>Elizabeth Brimhall, Director, Stanford Institute Choir</span>";
fader[2].msg[3] = "<span style='background: url(images/quoteleft.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style='line-height: 145%; font-size: 14px; font-style: italic;'>Anne has amazing technical skills, a knack for arranging, and the creativity of the constantly curious. She's got a lovely voice, great chops, and she's a heckuva nice gal too.&nbsp;</span><span style='background: url(images/quoteright.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;</span><br><span style='line-height: 145%; font-size: 14px;'>&mdash; </span><span style='font-size: 85%;'>Kathy Goll-Derstine, singer, songwriter, and client of Stern Studios</span>";
fader[2].msg[4] = "<span style='background: url(images/quoteleft.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style='line-height: 145%; font-size: 14px; font-style: italic;'>Above and beyond her skill as an audio enginneer, Anne has been amazingly quick and professional in her turn around time, always getting our CD's back in a timely fashion. She is fabulous!&nbsp;</span><span style='background: url(images/quoteright.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;</span><br><span style='line-height: 145%; font-size: 14px;'>&mdash; </span><span style='font-size: 85%;'>Elizabeth Brimhall, Director, Stanford Insitute Choir</span>";
fader[2].msg[5] = "<span style='background: url(images/quoteleft.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style='line-height: 145%; font-size: 14px; font-style: italic;'>Hey Anne! They are SO good! I can't believe it. Both are perfect and I really appreciate and admire the work done. It makes me want to write a bunch of new songs so we can record them!&nbsp;</span><span style='background: url(images/quoteright.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;</span><br><span style='line-height: 145%; font-size: 14px;'>&mdash; </span><span style='font-size: 85%;'>Shelli Kesler, singer, songwriter, client of Stern Studios</span>";
fader[2].msg[6] = "<span style='background: url(images/quoteleft.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style='line-height: 145%; font-size: 14px; font-style: italic;'>Anne, you are a tech wizard in your understanding of theory, not to mention your many gifts and talents.&nbsp;</span><span style='background: url(images/quoteright.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;</span><br><span style='line-height: 145%; font-size: 14px;'>&mdash; </span><span style='font-size: 85%;'>Trish McDonald, singer and songwriter</span>";
fader[2].msg[7] = "<span style='background: url(images/quoteleft.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style='line-height: 145%; font-size: 14px; font-style: italic;'>Anne, you seriously rock, and your timing is great.  Seriously rock, I mean. Sheesh. They'll take away my English major card and my black turtleneck and won't let me into coffeehouses where they're doing poetry readings anymore.&nbsp;</span><span style='background: url(images/quoteright.jpg) no-repeat scroll left top;'>&nbsp;&nbsp;&nbsp;&nbsp;</span><br><span style='line-height: 145%; font-size: 14px;'>&mdash; </span><span style='font-size: 85%;'>Stephen Nelson, client of Stern Studios</span>";

// Start this fader
setTimeout(function() { throb(2); }, 1000);
