function animSprite(id, callback, timing)
{
  var self = this;
  this.id = id;
  this.feedback = new functionQueue();
  this.timing = timing;

  // position
  this.xinit = null;
  this.yinit = null;
  this.xend = null;
  this.yend = null;
  // size
  this.winit = null;
  this.hinit = null;
  this.wend = null;
  this.hend = null;
  // color
  this.rinit = null;
  this.ginit = null;
  this.binit = null;
  this.rend = null;
  this.gend = null;
  this.bend = null;
  // backgroundcolor
  this.brinit = null;
  this.bginit = null;
  this.bbinit = null;
  this.brend = null;
  this.bgend = null;
  this.bbend = null;
  // transparency
  this.tinit = null;
  this.tend = null;

  this.starttime = null;

  this.getHex = getHex;
  function getHex(v)
  {
    if (v < 0 ) v = 0;
    if (v > 255) v = 255;
    var s = v.toString(16).toUpperCase();
    if (s.length < 2)
      s = '0' + s;
    return s;
  }

  this.setPosition = setPosition;
  function setPosition(xinit, yinit, xend, yend)
  {
    self.xinit = xinit;
    self.yinit = yinit;
    self.xend = xend;
    self.yend = yend;
  }

  this.setSize = setSize;
  function setSize(winit, hinit, wend, hend)
  {
    self.winit = winit;
    self.hinit = hinit;
    self.wend = wend;
    self.hend = hend;
  }

  this.setColor = setColor;
  function setColor(rinit, ginit, binit, rend, gend, bend)
  {
    self.rinit = rinit;
    self.ginit = ginit;
    self.binit = binit;
    self.rend = rend;
    self.gend = gend;
    self.bend = bend;
  }

  this.setBackgroundColor = setBackgroundColor;
  function setBackgroundColor(brinit, bginit, bbinit, brend, bgend, bbend)
  {
    self.brinit = brinit;
    self.bginit = bginit;
    self.bbinit = bbinit;
    self.brend = brend;
    self.bgend = bgend;
    self.bbend = bbend;
  }

  this.setTransparency = setTransparency;
  function setTransparency(tinit, tend)
  {
    self.tinit = tinit;
    self.tend = tend;
  }

  this.start = start;
  function start()
  {
    var d = new Date();
    self.starttime = d.getTime();
    setTimeout(self.anim, 10);
  }

  this.anim = anim;
  function anim()
  {
    var d = new Date();
    starttime = d.getTime();
    var diff = d - self.starttime;
    if (diff > self.timing)
    {
      if (self.xend != null)
        $(self.id).style.left = self.xend+'px';
      if (self.yend != null)
        $(self.id).style.top = self.yend+'px';
      if (self.wend != null)
        $(self.id).style.width = self.wend+'px';
      if (self.hend != null)
        $(self.id).style.height = self.hend+'px';
      if (self.rend != null)
      {
        $(self.id).style.color = '#' + self.getHex(self.rend) + self.getHex(self.gend) + self.getHex(self.bend);
      }
      if (self.brend != null)
      {
        $(self.id).style.backgroundColor = '#' + self.getHex(self.brend) + self.getHex(self.bgend) + self.getHex(self.bbend);
      }
      if (self.tend != null)
      {
        $(self.id).style.opacity = self.tend/100;
        $(self.id).style.filter = 'alpha(opacity: '+self.tend+')';
      }
      self.feedback.call();
    }
    else
    {
      if (self.xend != null)
      {
        var x = self.xinit + Math.ceil((self.xend-self.xinit)/self.timing*diff);
        $(self.id).style.left = x+'px';
      }
      if (self.yend != null)
      {
        var y = self.yinit + Math.ceil((self.yend-self.yinit)/self.timing*diff);
        $(self.id).style.top = y+'px';
      }
      if (self.wend != null)
      {
        var w = self.winit + Math.ceil((self.wend-self.winit)/self.timing*diff);
        $(self.id).style.width = w+'px';
      }
      if (self.hend != null)
      {
        var h = self.hinit + Math.ceil((self.hend-self.hinit)/self.timing*diff);
        $(self.id).style.height = h+'px';
      }
      if (self.rend != null)
      {
        var r = self.rinit + Math.ceil((self.rend-self.rinit)/self.timing*diff);
        var g = self.ginit + Math.ceil((self.gend-self.ginit)/self.timing*diff);
        var b = self.binit + Math.ceil((self.bend-self.binit)/self.timing*diff);
        $(self.id).style.color = '#' + self.getHex(r) + self.getHex(g) + self.getHex(b);
      }
      if (self.brend != null)
      {
        var br = self.brinit + Math.ceil((self.brend-self.brinit)/self.timing*diff);
        var bg = self.bginit + Math.ceil((self.bgend-self.bginit)/self.timing*diff);
        var bb = self.bbinit + Math.ceil((self.bbend-self.bbinit)/self.timing*diff);
        $(self.id).style.backgroundColor = '#' + self.getHex(br) + self.getHex(bg) + self.getHex(bb);
      }
      if (self.tend != null)
      {
        var t = self.tinit + Math.ceil((self.tend-self.tinit)/self.timing*diff);
        $(self.id).style.opacity = t/100;
        $(self.id).style.filter = 'alpha(opacity: '+t+')';
      }
      setTimeout(self.anim, 10);
    }
  }

  this.stop = stop;
  function stop()
  {

  }

  this.synchronize = synchronize;
  function synchronize(anim)
  {

  }

  this.destroy = destroy;
  function destroy()
  {

  }

  this.addFeedback = addFeedback;
  function addFeedback(feedback)
  {
    self.feedback.registerFunction(feedback);
  }

  if (callback)
    this.addFeedback(callback);
}

var animManager =
{
  animSprites: new Array(),

  // private
  registerSprite: function(r)
  {
    this.animSprites.push(r);
  },

  //private
  unregisterSprite: function(id)
  {
    for (var i=0, l=this.animSprites.length; i < l; i++)
    {
      if (this.animSprites[i].id == id)
      {
        this.animSprites[i].destroy();
        this.animSprites.splice(i, 1);
        return true;
      }
    }
    return false;
  },

  //public
  createSprite: function(id, callback, timing)
  {
    var r = new animSprite(id, callback, timing);
    if (r)
    {
      this.registerSprite(r);
    }
    return r;
  },

  destroySprite: function(id)
  {
    this.unregisterSprite(id);
  }
}
