// Ken's Morphing Text Routines
// February 28, 2007
// Ken O. Burtch
//
// Message format:
// Remember: whitespace will compress.  Some tags can be put in (not anchors)
// ~ = start of line(s), % = line break (must end with one), hex is text
// colour
// --------------------------------------------------------------------------

// String Constants

var random_text = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcedefghijklmnopqrstuvwxyz                ";
var hexDigit=new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
var TextClockID;

// Utilities

function dec2hex(dec){return(hexDigit[dec>>4]+hexDigit[dec&15]);}
function hex2dec(hex){return(parseInt(hex,16))};
function rnd(max){return(Math.round((max-1)*Math.random())+1)};
function grab(s,n) {
   var i;
   var j=n;
   var v1;
   for(i=0;i<s.length;i++) {
     if (s[i] == '~') {
        j--;
        if ( j==0 ) {
           v1 = i+1;
           break;
        }
     }
   }
   var v2 = s.indexOf('~',v1+1);
   return (s.substring( v1, v2 ));
} // grab

var background_red;
var background_green;
var background_blue;

var message_text;
var message_number = 1;
var message_red = 128;
var message_green = 0;
var message_blue = 0;

var counter_max = 20;
var counter = counter_max;
var counter_hold_time = -250;

var textClockID;


function UpdateText() {
   var textRef;
   var tmp;
   var text;
   var text_colour;
   var text_colour_str;
   var red;
   var green;
   var blue;
   var background_percent;
   var colour_percent;
   var tag_nesting_count;
   var morph_line;
   var i;
   var text_em;

   // Disable clock while we work.

   if(textClockID) {
      clearTimeout(textClockID);
      textClockID  = 0;
   }

   // Advance the animation counter.
   // If the counter hits the limit, reset the counter and use the next
   // message.  If there are no more messages, repeat the first one.

   counter--;
   if ( counter < counter_hold_time ) {
      counter = counter_max;
      message_number++;
      message_text = grab( messages, message_number );
      if ( message_text == "EOF" ) {
         message_number = 1;
         message_text = grab( messages, 1 );
      }
      message_red   = hex2dec( message_text.substr(0,2) );
      message_green = hex2dec( message_text.substr(2,2) );
      message_blue  = hex2dec( message_text.substr(4,2) );
      message_text = message_text.substring( 6, message_text.length );
   }

   // Animate based on the three phases.

   // Fade in with random characters ----------------------------------------

   if ( counter > 0 ) {
      text_em = (20 * counter / counter_max );
      text_colour = (15 * counter / counter_max );
      if (text_colour < 0 ) {
         text_colour = 0;
      } else if (text_colour > 15 ) {
         text_colour = 15;
      }
      background_percent = text_colour / 15;
      colour_percent = 1.0 - background_percent;

      // should mix with the background colour

      red   = Math.round( message_red * colour_percent +
                          background_red * background_percent  );
      green = Math.round( message_green * colour_percent +
                          background_green * background_percent );
      blue  = Math.round( message_blue * colour_percent +
                          background_blue * background_percent );

      text_colour_str = "#" +
             dec2hex( red ) + dec2hex( green ) + dec2hex( blue );

      morph_line = 0;

      tag_nesting_count = 0;
      text = "";
      for (i=0;i<message_text.length;i++){
         if ( message_text[i] == '%' ) {
            morph_line++;
            textRef = document.getElementById("morph_text" + morph_line);
            textRef.style.letterSpacing = text_em/40 + "em";
            textRef.style.marginLeft = text_em/2 + "em";
            textRef.style.color = text_colour_str;
            textRef.innerHTML = text;
            tag_nesting_count = 0;
            text = "";
         } else if ( message_text[i] == '<' ) {
            tag_nesting_count++;
            text = text + '<';
         } else if ( message_text[i] == '>' ) {
            tag_nesting_count--;
            text = text + '>';
         } else if ( tag_nesting_count > 0 ) {
            if ( message_text[i] == ' ' ) {
               text = text + '&nbsp;';
            } else {
               text = text + message_text[i];
            }
         } else if ( rnd(3) > 1 ) {
            if ( message_text[i] == ' ' ) {
               text = text + '&nbsp;';
            } else {
               text = text + message_text[i];
            }
         } else {
            tmp = rnd( random_text.length )-1;
            if ( random_text[tmp] == ' ' ) {
               text = text + '&nbsp;';
            } else {
               text = text + random_text[tmp];
            }
         }
      }

   // Text fade out ---------------------------------------------------------

   } else if ( counter < (counter_hold_time+25) ) {
      tmp = (-counter) + (counter_hold_time+25);
      text_colour =(-counter) + (counter_hold_time+25);
      if (text_colour < 0 ) {
         text_colour = 0;
      } else if (text_colour > 15 ) {
         text_colour = 15;
      }
      background_percent = text_colour / 15;
      colour_percent = 1.0 - background_percent;
      red   = Math.round( message_red * colour_percent +
                          background_red * background_percent  );
      green = Math.round( message_green * colour_percent +
                          background_green * background_percent );
      blue  = Math.round( message_blue * colour_percent +
                          background_blue * background_percent );

      text_colour_str = "#" +
             dec2hex( red ) + dec2hex( green ) + dec2hex( blue );
      morph_line = 0;
      text = "";
      for ( i = 0; i < message_text.length; i++ ) {
          if ( message_text[i] != '%' ) {
             if ( message_text[i] == ' ' ) {
                text = text +  "&nbsp;";
             } else {
                text = text +  message_text[i];
             }
          } else {
             morph_line++;
             textRef = document.getElementById("morph_text" + morph_line);
             // textRef.style.letterSpacing = text_em/40 + "em";
             // textRef.style.marginLeft = text_em/2 + "em";
             textRef.style.color = text_colour_str;
             textRef.innerHTML = text;
             text = "";
          }
      }

   // Reached margin --------------------------------------------------------

   } else if ( counter == 0 ) {
      morph_line = 0;
      text = "";
      for ( i = 0; i < message_text.length; i++ ) {
          if ( message_text[i] != '%' ) {
             if ( message_text[i] == ' ' ) {
                text = text +  "&nbsp;";
             } else {
                text = text +  message_text[i];
             }
          } else {
             morph_line++;
             textRef = document.getElementById("morph_text" + morph_line);
             textRef.style.letterSpacing = "0em";
             textRef.style.marginLeft = "0em";
             // textRef.style.color = text_colour_str;
             textRef.innerHTML = text;
             text = "";
          }
      }

   // Holding ---------------------------------------------------------------

   } else {
      // Nothing to do
   }

   textClockID = setTimeout("UpdateText()", 50);
   //textClockID = setTimeout("UpdateText()", 500);
} // UpdateText

function StartTextClock() {
   TextClockID = setTimeout("UpdateText()", 500);
} // StartTextClock

function KillTextClock() {
   if(TextClockID) {
      clearTimeout(TextClockID);
      TextClockID  = 0;
   }
} // KillTextClock

