CanvasGallery = function(element_id,frame,images,options) {
    var gal = this;

    this.init = function() {

      this.elem = document.getElementById(element_id); 
      if(!this.elem || !this.elem.getContext) return;
      this.canvas = this.elem.getContext('2d');  

      this.imgIdx = -1;
      this.timer = options.timeout || 3000;
      this.fadeTime = options.fade || 1000;

      this.loadedImages = [];
      this.slideshowImages = [];

      this.backgroundImage = this.createImage(frame, function() { gal.runGallery(); });

      for(var i=0;i<images.length;i++) {
        this.loadImage(i,images[i]);
      }

    }

    this.loadImage = function(i,img) {
      this.loadedImages[i] = false;
      this.slideshowImages[i] = this.createImage(images[i], function() { gal.loadedImages[i] = true; });
    }

    this.runGallery= function() { 
      var nextImage = (this.imgIdx+1) % this.slideshowImages.length;
      if(this.loadedImages[nextImage]) {
        this.lastImg = this.imgIdx;
        this.imgIdx = nextImage;
        this.draw(this.getTime(), this.fadeTime,this.lastImg == -1 ? 0 : this.fadeTime);
        } else {
        setTimeout(function() { gal.runGallery(); } ,20);
      }
    }

    this.getTime = function() { var d = new Date(); return d.getTime(); }

    this.createImage = function(src,callback) {
      var img = new Image;
      img.onload = callback;
      img.src = src;
      return img;
    }

    this.draw = function(lastTime,fadeTime,fadeRemaining) {
      curTime = this.getTime();
      var c = this.canvas

      fadeRemaining -= curTime - lastTime;
      if(fadeRemaining < 0 ) fadeRemaining = 0;

      c.clearRect(0,0,this.elem.width,this.elem.height);
      c.save();
      c.translate(this.elem.width/2,this.elem.width/2);
      c.rotate(options.angle / 180 * Math.PI);

      if(fadeRemaining > 0 && this.lastImg >= 0) {
        c.globalAlpha= fadeRemaining / fadeTime;
        c.drawImage(this.slideshowImages[this.lastImg],-this.backgroundImage.width/2+options.x,-this.backgroundImage.height/2 + options.y);
      }
      c.globalAlpha=(fadeTime - fadeRemaining) / fadeTime;
      c.drawImage(this.slideshowImages[this.imgIdx],-this.backgroundImage.width/2+options.x,-this.backgroundImage.height/2 + options.y);

      c.globalAlpha = 1.0;
      c.drawImage(this.backgroundImage,-this.backgroundImage.width/2,-this.backgroundImage.height/2);
      c.restore();

      if(fadeRemaining > 0) {
        setTimeout(function() { gal.draw(curTime,fadeTime,fadeRemaining); }, 10);

        } else {
        setTimeout(function() { gal.runGallery();} ,this.timer);
      }

    }

    this.fade = function() {

    }

    this.init();

};

