// Except as otherwise noted, the following code is copyright 2008, 2009
// by Matthew Williams <matt@matthewkwilliams.com>
//
// Usage and description of the script may be found at:
// http://matthewkwilliams.com/
//
// In order to use it, you need the following:
// + A sprite file
// + CSS entries for the locations of the sprites.
//   These are named FOO-frame-n where foo is the name of the animation,
//   and n is the frame.
// + A block entity in which the animation will be placed.
//   This entity needs the following css rules since we're using the css
//   background trick:
//   + width
//   + height
//
// + A sample use would be as follows:
//   <script type="text/javascript" src="sprite-animator.js"></script>
//   <div id="gear">
//   </div>
//   <script>
//     var gearanim = new SpriteAnimator("gear","sprite.png",true,15);
//   </script>
//   <button onClick="gearanim.start(); return false;">Start</button><br/>
//   <button onClick="gearanim.stop(); return false;">Stop</button>


// This object does the updating of the sprite animation
function SpriteUpdater(instance)
{
   var obj = instance;
   this.updateSprite = function()
   {
      var elem = document.getElementById(obj.id + '-sprite-container');
      var a = elem.className.split('-');
      var num = parseInt(a[a.length - 1]);
      var newNum = num;
      if (num >= obj.numFrames) {
         newNum = obj.loop ? 1 : obj.numFrames;
      } else {
         newNum = newNum + 1;
      }
      if(newNum != num)
         elem.className = obj.id + '-frame-' + newNum;
      else
         clearInterval(obj.intervalID);
   };

}


// This object handles the animation
// + id = the id of the block
// + file = the file which contains the sprites
// + loop = true/false whether it loops or not
// + delay = what is the delay between frames?
function SpriteAnimator(id, file, loop, delay) {

   // this function and the next are from css-toolbox.js
   // created by Patrick Hunlock :: http://www.hunlock.com
   // and originally found at the JavaScript Source:
   // http://javascript.internet.com
   function getCSSRule(ruleName, deleteFlag) {
      if (document.styleSheets) {
         for (var i=0; i<document.styleSheets.length; i++) {
            var styleSheet=document.styleSheets[i];
            var ii=0;
            var cssRule=false;
            do {
               if (styleSheet.cssRules) {
                  cssRule = styleSheet.cssRules[ii];
               } else {
                  cssRule = styleSheet.rules[ii];
               }
               if (cssRule)  {
                  if (cssRule.selectorText==ruleName) {
                     if (deleteFlag=='delete') {
                        if (styleSheet.cssRules) {
                           styleSheet.deleteRule(ii);
                        } else {
                           styleSheet.removeRule(ii);
                        }
                        return true;
                     } else {
                        return cssRule;
                     }
                  }
               }
               ii++;
            } while (cssRule)
         }
      }
      return false;
   }
   function addCSSRule(ruleName) {
      if (document.styleSheets) {
         if (!getCSSRule(ruleName)) {
            if (document.styleSheets[0].addRule) {
               document.styleSheets[0].addRule(ruleName, null,0);
            } else {
               document.styleSheets[0].insertRule(ruleName+' { }', 0);
            }
         }
      }
      return getCSSRule(ruleName);
   }
     // count frames counts the number of frames in the animation
   this.countFrames = function()
   {
      var name = "." + this.id + "-frame";
      var count = 1;
      var flag = false;
      while (getCSSRule(name + '-' + count) != false)
      {
         count ++;
         flag = true;
      }
      return flag ? (count - 1): 0;
   };

   // this code creates the sprite container
   this.updateHTML = function()
   {
      var element = document.getElementById(this.id);
      var insertion = '<div id="' + this.id + '-sprite-container"';
      insertion += ' class="' + this.id + '-frame-1"></div>';
      element.innerHTML = insertion + element.innerHTML;
   };

   // add css rules for the sprite container
   this.updateCSS = function()
   {
      var rule = addCSSRule('#' + this.id + '-sprite-container');
      rule.style.backgroundImage = 'url("' + file + '")';
      rule.style.backgroundRepeat = 'none';
      rule.style.padding = '0';
      rule.style.margin = '0';
      rule.style.width = '100%';
      rule.style.height = '100%';
   };

   // stop the animation
   this.stop = function() {
      if (this.intervalID != false)
      {
         clearInterval(this.intervalID);
      }
   };

   // start the animation
   this.start = function(){
      updater = new SpriteUpdater(this);
      this.intervalID = setInterval(updater.updateSprite,this.delay);
   };

   this.id = id;
   this.file = file;
   this.loop = loop;
   this.delay = delay;
   this.updateHTML();
   this.updateCSS();
   this.numFrames = this.countFrames();
   this.intervalID = false;
}