/*-------------------------------------------------------------------*
 *
 *  dynamic.js
 *
 *  function :
 *
 *    fade( beginColor, endColor [, steps ] )
 *    typeWrite( [ typeWriterColor, speed ] )
 *
 *-------------------------------------------------------------------*/
var SPEED    = 70;        // default speed
var STEPS    = 20;        // default fade steps
var COLOR    = "#AA0000"; // default typeWriter color
var _speed   = SPEED;
var _steps   = STEPS;
var _color   = COLOR;
var _index   = 0;
var _timerId = null;
var _target  = null;
var _wait    = false;
var _end     = false;
var _objArr  = new Array();

function init() {

  var name = window.navigator.appName.charAt( 0 );
  var ver  = window.navigator.appVersion.charAt( 0 );

  if ( name != "M" || ver < 4 ) {
    return;
  }

  setObjArr();

  if ( _objArr.length == 0 ) {
    return;
  }

  dynamic();
}

function dynamic() {

  for ( var i = 0; i < _objArr.length; i++ ) {
    if ( !_wait ) {
      _target = _objArr[ i ];
      _wait   = true;
    } else {
      if ( _objArr[ i ] == _target ) {
        divideType();
      }
    }
  }
  if ( _end ) {
    _objArr = arrShift( _objArr );
    _end = false;
  }
  if ( _objArr.length != 0 ) {
    _timerId = setTimeout( "dynamic()", _speed );
  }
}

function divideType() {

  switch ( _target.func ) {
  case "typeWrite" :
    typeWrite();
    break;
  case "fade" :
    fade();
    break;
  default:
    nextTarget();
  }
}

function nextTarget() {

  _color = COLOR;
  _speed = SPEED;
  _steps = STEPS;
  _wait  = false;
  _end   = true;
  _index = 0;
}

function fade() {

  var r;
  var g;
  var b;
  var rgb1;
  var rgb2;
  var rgb;

  if ( _target.argc < 2 ) {
    nextTarget();
    return;
  }

  rgb1   = new Rgb( _target.args[ 0 ] );
  rgb2   = new Rgb( _target.args[ 1 ] );
  _steps = _target.argc > 2 ? _target.args[ 2 ] : _steps;

  if ( !rgb1.validate || !rgb2.validate ) {
    nextTarget();
    return;
  }

  if ( _index == 0 ) {
    rgb = rgb1.rgb;
    _index++;
  } else if ( _index > _steps ) {
    rgb = rgb2.rgb;
    nextTarget();
  } else {
    r   = rgb1.r - ( rgb1.r - rgb2.r ) / _steps * _index;
    r   = paddingZero( parseInt( r ).toString( 16 ), 2 );
    g   = rgb1.g - ( rgb1.g - rgb2.g ) / _steps * _index;
    g   = paddingZero( parseInt( g ).toString( 16 ), 2 );
    b   = rgb1.b - ( rgb1.b - rgb2.b ) / _steps * _index;
    b   = paddingZero( parseInt( b ).toString( 16 ), 2 );
    rgb = String( r ) + String( g ) + String( b );
    _index++;
  }

  _target.elm.innerHTML = "<span style = \"color:#" + rgb + "\">"
                        + _target.html
                        + "</span>";

  return;
}

function paddingZero( src, digit ) {

  while ( src.length < digit ) {
    src = "0" + src;
  }
  return src;
}

function hexToDec( hex ) {

  return Number( "0x" + hex );
}

function typeWrite() {

  _color = _target.argc > 0 ? _target.args[ 0 ] : _color;
  _speed = _target.argc > 1 ? _target.args[ 1 ] : _speed;

  if ( _index > _target.html.length ) {
    nextTarget();
    return;
  }
  _target.elm.innerHTML = getTypeWriteString();
  _index++;
}

function getTypeWriteString() {

  _target.html = _target.html.replace( / +/g, " " );
  skipSingleTag();
  return _target.html.substring( 0, _index )
       + "<span style = \"color:" + _color + "\">"
       + _target.html.charAt( _index )
       + "</span>";
}

function skipSingleTag() {

  if ( _target.html.charAt( _index ) != "<" ) {
    return;
  }
  for ( var i = _index; i < _target.html.length; i++ ) {
    if ( _target.html.charAt( i - 1 ) == ">" &&
         _target.html.charAt( i )     != "<" ) {
      _index = i;
      break;
    } else if ( i == _target.html.length - 1 ) {
      _target.html += " ";
      _index = i + 1;
      break;
    }
  }
  return;
}

function setObjArr() {

  var elms = window.document.all;
  var obj;

  for ( var i = 0; i < elms.length; i++ ) {
    if ( elms[ i ].id != "" ) {
      obj = new DynamicObject( elms[ i ] );
      obj.htmlClear();
      _objArr = arrPush( _objArr, obj );
    }
  }
}

function getFuncName( func ) {

  func = trim( func );
  if ( func.match( /([^\(]+)\(.*\)/ ) ) {
    return RegExp.$1;
  } else {
    return func;
  }
}

function getArgs( func ) {

  var arr  = new Array();
  var args = new String();

  if ( func.match( /\(([^\)]*)\)/ ) ) {
    args = RegExp.$1;
  }
  arr = args.split( "," );
  for ( var i = 0; i < arr.length; i++ ) {
    arr[ i ] = trim( arr[ i ] );
  }
  return arr;
}

function cut( str, cut ) {

  var pattern = "/" + cut + "/g";
  str = str.replace( eval( pattern ), "" );
  return str;
}

function trim( str ) {

  str = new String( str );
  str = str.replace( /^ +/g, "" );
  str = str.replace( / +$/g, "" );
  return str;
}

function arrPush( arr, obj ) {

  var tmp = new Array( obj );
  return arr.concat( tmp );
}

function arrPop( arr ) {

  return arr.length > 0 ? arr.slice( 0, arr.length - 1 ) : arr;
}

function arrShift( arr ) {

  return arr.length > 0 ? arr.slice( 1 ) : arr;
}

function Rgb( rgb ) {

  this.rgb = rgb;
  this.rgb = cut( this.rgb, "#" );
  this.rgb = cut( this.rgb, "'" );

  if ( !this.rgb.match( /^[a-fA-F0-9]{6}$/ ) ) {
    this.r = new String();
    this.g = new String();
    this.b = new String();
    this.validate = false;
  } else {
    this.r = hexToDec( this.rgb.substring( 0, 2 ) );
    this.g = hexToDec( this.rgb.substring( 2, 4 ) );
    this.b = hexToDec( this.rgb.substring( 4, 6 ) );
    this.validate = true;
  }
}

function DynamicObject( elm ) {

  this.elm  = elm;
  this.html = elm.innerHTML;
  this.func = getFuncName( elm.id );
  this.args = getArgs( elm.id );
  this.argc = this.args.length;

  this.htmlClear = function() {

    this.elm.innerHTML = "&nbsp;";
  }

  this.toString = function() {

    var buf = "html: " + this.html + "\n"
            + "func: " + this.func + "\n"
            + "argc: " + this.argc + "\n";

    for ( var i = 0; i < this.args.length; i++ ) {
      buf += "arg" + i + ": " + this.args[ i ] + "\n";
    }
    return buf;
  }
}
