   var SLIDE_SPEED = 20;
   var SPEECH_DELAY = 1;
   var SPEECH_CONSTANT = 45;
   var TODD_DEFAULT_SEQUENCE = "wpwwwwws";
   var DEREK_DEFAULT_SEQUENCE = "wwwsc";
   var DEFAULT_CHATTER = "";

   function aSprite(id, pageParent, x, y, z, w, h, top, left, slideOnX, img, onClick)
   {
    this.id = id;
    this.isOnX = slideOnX;
    this.inMotion = 0;
    this.commands = '';

    //Timing for accomplishing next movement
    this.maxDistance = 1;
    this.distance = 0;
    this.isOnAxisX = false;
    this.progress = function () {return ((this.maxDistance - this.distance) / this.maxDistance);};

    this.pageElement = document.createElement("div");
    this.pageElement.sprite = this;
    this.pageElement.setAttribute("id", this.id);
    this.pageElement.className = "cutout";
    this.pageElement.style.position = "absolute";
    this.pageElement.style.display = "none";
    pageParent.insertBefore(this.pageElement, null);

    this.balloon = new aBalloon(id + 'says', this.pageElement, -110, -30, z + 1, top, left, onClick);
    this.say = function(str)
    {
      this.balloon.say(str);
    }

    if (top)
    {
      if (left)
      {
        this.pageElement.style.background = "url('i/" + img + "') bottom right no-repeat";
      } else {
        this.pageElement.style.background = "url('i/" + img + "') bottom left no-repeat";
      }
    } else {
      if (left)
      {
        this.pageElement.style.background = "url('i/" + img + "') top right no-repeat";
      } else {
        this.pageElement.style.background = "url('i/" + img + "') top left no-repeat";
      }
    }

    this.setBoundaries = function(w, h)
    {
      this.width = parseInt(w);
      this.height = parseInt(h);
      this.pageElement.style.width = this.width + 'px';
      this.pageElement.style.height = this.height + 'px';
    }
    this.setBoundaries(w, h);

    this.setPosition = function(x, y, z, top, left)
    {
      this.x = parseInt(x);
      this.y = parseInt(y);
      this.z = parseInt(z);
      if (top)
      {
        this.pageElement.style.top = this.y + 'px';
        this.pageElement.style.bottom = '';
      } else {
        this.pageElement.style.bottom = this.y + 'px';
        this.pageElement.style.top = '';
      }
      if (left)
      {
        this.pageElement.style.left = this.x + 'px';
        this.pageElement.style.right = '';
      } else {
        this.pageElement.style.right = this.x + 'px';
        this.pageElement.style.left = '';
      }
      this.pageElement.style.zIndex = this.z;
    }
    this.setPosition(x, y, z, top, left);

    this.beginSlide = function(distanceRatio)
    {
      this.inMotion = 1;
      if (this.isOnX)
      {
        this.maxDistance = parseInt(distanceRatio * this.width);
      } else {
        this.maxDistance = parseInt(distanceRatio * this.height);
      }
    }

    this.beginReturnSlide = function()
    {
      this.inMotion = -1;
    }

    if(typeof(onClick) != "undefined")
    {
      this.pageElement.onmousedown = onClick;
    } else {
      this.pageElement.onmousedown = function (e) {this.sprite.commands = 'hwwwp';};
    }

    this.doCommand = function()
    {
      if(this.commands.length > 0)
      {
        switch(this.commands.charAt(0))
        {
          case 'm': //MENU MODE
            mode = 'menu';
            todd.commands += 'hwwwp';
            derek.commands += 'hwwwp';
            todd.pageElement.onmousedown = function (e) {this.sprite.commands = 'swc';};
            derek.pageElement.onmousedown = function (e) {this.sprite.commands = 's';};
            break;
          case 'n': //NEW CONVERSATION
            getNextChat();
            break;
          case 'c': //CHAT MODE
            mode = 'chat';
            todd.commands += 's';
            derek.commands += 's';
            break;
          case 'e': //EDGE PEEK
            this.beginSlide(0.08);
            this.pageElement.onmousedown = function (e) {this.sprite.commands = 's';};
            break;
          case 'p': //PEEK
            this.beginSlide(0.23);
            break;
          case 's': //SHOW
            this.beginSlide(1);
            this.pageElement.onmousedown = function (e) {this.sprite.commands = 'hmwwwwp';};
            break;
          case 'h': //HIDE
            this.beginReturnSlide();
            break;
          case 'w':
          default:
            break;
        }
        this.commands = this.commands.substring(1);
      }
    }

    this.update = function()
    {
      this.balloon.update();

      if (this.inMotion != 0)
      {
        this.distance = this.distance + this.inMotion * (parseInt(this.progress() * SLIDE_SPEED) + 1);
        if (this.distance > this.maxDistance)
        {
          this.distance = this.maxDistance;
          this.inMotion = 0;
        } else {
          if (this.distance < 0)
          {
            this.distance = 0;
            this.inMotion = 0;
            this.pageElement.style.display = "none";
          } else {
            if (this.isOnX)
            {
              this.pageElement.style.width = this.distance + "px";
              this.pageElement.style.display = "block";
            } else {
              this.pageElement.style.height = this.distance + "px";
              this.pageElement.style.display = "block";
            }
          }
        }
      }
    }
  }

   function aBalloon(id, pageParent, x, y, z, top, left, onClick)
   {
    this.id = id;
    this.holdIt = 0;

    this.pageElement = document.createElement("div");
    this.pageElement.balloon = this;
    this.pageElement.setAttribute("id", this.id);
    this.pageElement.className = "balloon";
    this.pageElement.style.position = "absolute";
    this.pageElement.style.display = "none";
    pageParent.insertBefore(this.pageElement, null);

    this.setPosition = function(x, y, z, top, left)
    {
      this.x = parseInt(x);
      this.y = parseInt(y);
      this.z = parseInt(z);
      if (top)
      {
        if (left)
        {
          this.pageElement.style.right = this.x + 'px';
          this.pageElement.style.bottom = this.y + 'px';
        } else {
          this.pageElement.style.left = this.x + 'px';
          this.pageElement.style.bottom = this.y + 'px';
        }
      } else {
        if (left)
        {
          this.pageElement.style.right = this.x + 'px';
          this.pageElement.style.top = this.y + 'px';
        } else {
          this.pageElement.style.left = this.x + 'px';
          this.pageElement.style.top = this.y + 'px';
        }
      }
      this.pageElement.style.zIndex = this.z;
    }
    this.setPosition(x, y, z, top, left);

    this.say = function(str)
    {
      if (str == '') str = '...';

      var length = str.length;
      var fontSize = '12px';
      this.holdIt = SPEECH_DELAY * length + SPEECH_CONSTANT;
      if (length < 100) fontSize = '15px';
      if (length < 50) fontSize = '20px';
      if (length < 25) fontSize = '25px';
      if (length < 12) fontSize = '30px';
      if (length < 8) fontSize = '33px';
      if (length < 6) fontSize = '35px';
      if (length < 4) fontSize = '40px';

      this.pageElement.innerHTML = str;
      this.pageElement.style.fontSize = fontSize;
      this.pageElement.style.display = 'block';
    }

    this.update = function()
    {
      if (this.holdIt > 0)
      {
        this.holdIt--;
      } else {
        this.pageElement.style.display = 'none';
      }
    }

   }


////////////////////////////////////////////////////////////////////////////////

var xmlhttp=false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can cope with old IE versions.
// and security blocked creation of the objects.
 try {
  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (e) {
  try {
   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (E) {
   xmlhttp = false;
  }
 }
@end @*/
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  xmlhttp = new XMLHttpRequest();
}

var serverConnection;
function startAjax(path, innerFunction)
{
  serverConnection = new aAjax(innerFunction);
//  serverConnection.syncStep(path);
}

function aAjax(innerFunction)
{
//  this.timeout;
  this.onReturn = innerFunction;

  this.syncStep = function(path)
  {
    xmlhttp.open("GET", path, true);
//    this.timeout = setTimeout("xmlhttp.abort(); serverConnection.syncStep('" + path + "');", 5000);
    xmlhttp.onreadystatechange=function()
    {
      if (xmlhttp.readyState==4)
      {
//        clearTimeout(serverConnection.timeout);
        serverConnection.onReturn(xmlhttp.responseText);
      }
    }
    xmlhttp.send(null);
  }
}


function getNextChat()
{
  serverConnection.syncStep('u.asp');
}

var curDate = '';
function innerAjax(str)
{
  var arr = str.split("[|||]");
  curDate = arr[0];
  chatter = arr[1].split("|");
  chatIndex = 0;
  todd.commands='sc';
  derek.commands='sc';
}

/////////////////////////////////////////


  var theChatter = "D";
  var thisStep = 0;
  var chatIndex = 0;
  var mode = 'open';
  function stepper()
  {

    if (mode == 'chat')
    {
      var waitToSpeak = SPEECH_CONSTANT / 2;
      
      if ((chatIndex < chatter.length))
      {
        var theChat = chatter[chatIndex];
        theChatter = theChat.charAt(0);
        if ((theChatter == "T") && (derek.balloon.holdIt < waitToSpeak) && (todd.balloon.holdIt < 1))
        {
          todd.say(theChat.substring(5));
          chatIndex++;
        }
        if ((theChatter == "D") && (derek.balloon.holdIt < 1) && (todd.balloon.holdIt < waitToSpeak))
        {
          derek.say(theChat.substring(6));
          chatIndex++;
        }
      } else {
        if (theChatter == "D")
        {
          todd.commands = 'wwwh';
          derek.commands = 'wwwwwhwn';
        } else {
          todd.commands = 'wwwwwwhwn';
          derek.commands = 'wwwwh';
        }
        mode = 'find';
      }
    }

    if (thisStep % 33 == 0) //every second
    {
      for (x in sprites) sprites[x].doCommand();
    } 

    for (x in sprites) sprites[x].update();

    thisStep++;
    if (thisStep >= 400000) thisStep = 0; // to prevent overflow

    setTimeout("stepper();", 30)
  }

  var chatter;
  var sprites, canvas;
  var derek, todd;
  function init()
  {
    chatter = DEFAULT_CHATTER.split("|");
    sprites = new Array();
    canvas = document.getElementById('canvas');
    derek = new aSprite('derek', canvas, 0, 0, 3, 325, 468, false, true,  true, 'derek-yeah.png');
    todd = new aSprite('todd',  canvas, 5, 0, 4, 533, 306, false, false, false, 'todd-what.png');
    derek.commands = DEREK_DEFAULT_SEQUENCE;
    todd.commands = TODD_DEFAULT_SEQUENCE;
    sprites.splice(0,0, todd);
    sprites.splice(0,0, derek);
    startAjax('u.asp', innerAjax);
    stepper();
}
