/*
/*  engage.js
*/

var Engage = new Object({
  SlideAnimator: Class.create({
    initialize: function (canvas) {
      this.canvas  = canvas;
      this.context = canvas.getContext("2d");
      this.width   = canvas.getWidth();
      this.height  = canvas.getHeight();
      
      this.loadImage("border",      "home/slides-border.png");
      this.loadImage("slide1",      "home/slides-1.png");
      this.loadImage("slide1Title", "home/slides-1-title.png");
      this.loadImage("slide2",      "home/slides-2.png");
      this.loadImage("slide2Title", "home/slides-2-title.png");
      
      this.time     = 0.0;
      this.timeStep = 0.0;
      
      this.circleTime      = 0.0;
      this.circleTimeSpeed = 0.0;
      
      this.stage = 0;
      this.stage1Time = 0.0;
      this.stage2Time = 0.0;
      
      this.startAnimation();
    },
    
    loadImage: function (name, path) {
      this[name + "Image"]       = new Image();
      this[name + "ImageLoaded"] = false;
      
      this[name + "Image"].onload = function () {
        this[name + "ImageLoaded"] = true;
        this.update();
      }.bind(this);
      
      if (!path.startsWith("/"))
        path = "/images/" + path;
      this[name + "Image"].src = path;
    },
    
    startAnimation: function () {
      var lastTime = (new Date()).getTime();
      this.timer = window.setInterval(function () {
        var newTime    = (new Date()).getTime();
        this.timeStep  = (newTime - lastTime) / 1000.0;
        this.time     += this.timeStep;
        
        if (this.timeStep > 1.0)
          this.timeStep = 1.0;
        
        lastTime = newTime;
        
        this.update();
      }.bind(this), 1000 / 30.0);
    },
    
    stopAnimation: function () {
      window.setInterval(this.timer);
    },
    
    goToStage: function (stage) {
      if (this.stage == stage)
        return;
      
      this.stage1Time = 0.0;
      this.stage2Time = 0.0;
      
      this.nextStripeAngle = Math.random() * Math.PI;
      this.nextStripeScale = 100.0 + Math.random() * 100.0;
      
      if (this.stage == 0 && stage == 1)
        this.stage1Time = 4.0;
      
      this.stage = stage;
    },
    
    update: function () {
      var context = this.context,
          width   = this.width,
          height  = this.height;
      
      this.circleTime += this.circleTimeSpeed * this.timeStep;
      
      if (this.circleTime > 1.0) {
        this.circleTime      = 1.0;
        this.circleTimeSpeed = 0.0;
      } else if (this.circleTime < 0.0) {
        this.circleTime      = 0.0;
        this.circleTimeSpeed = 0.0;
      }
      
      var circleValue = this.smoothValue(this.circleTime);
      var circleX     = 200.0 +  720.0 * circleValue;
      var circleY     = 420.0 + -240.0 * circleValue;
      var circleRad   = 340.0 + -280.0 * 
        Math.sin(circleValue * Math.PI) +
        Math.sin(this.time / 3.0) * 20.0;
      
      this.drawBackground(context, width, height);
      this.drawCircle(context, circleX, circleY, circleRad, 1.0);
      
      (this["updateStage" + this.stage])({
        beforeTitle: function () {
          this.drawCircle(context, circleX, circleY, circleRad, 0.8);
        }.bind(this)
      });
      
      if (this.borderImageLoaded)
        context.drawImage(this.borderImage, 0, 0);
    },
    
    smoothValue: function (value) {
      return (1.0 - Math.cos(value * Math.PI)) / 2.0;
    },
    
    drawBackground: function (context, width, height) {
      context.fillStyle = "#59b3b3";
      context.fillRect(0, 0, width, height);
    },
    
    drawCircle: function (context, x, y, radius, opacity) {
      context.beginPath();
      context.arc(x, y, radius, 0, Math.PI * 2, true);
      context.closePath();
      
      context.fillStyle = "rgba(143, 204, 82, " + opacity + ")";
      context.fill();
    },
    
    updateStage0: function () {
      if (this.borderImageLoaded &&
          this.slide1ImageLoaded &&
          this.slide1TitleImageLoaded &&
          this.slide2ImageLoaded &&
          this.slide2TitleImageLoaded)
        this.goToStage(1);
    },
    
    updateStage1: function (options) {
      var context = this.context,
          width   = this.width,
          height  = this.height;
      
      this.stage1Time += this.timeStep;
      
      var duration      = 8.0;
      var transDuration = 0.5;
      var transOutTime  = duration - transDuration;
      var transValue    = 1.0;
      
      if (this.stage1Time < transDuration)
        transValue = this.stage1Time / transDuration;
      else if (this.stage1Time >= transOutTime)
        transValue = 1.0 - ((this.stage1Time - transOutTime) / transDuration);
      
      transValue = this.smoothValue(transValue);
      
      this.drawStripes(context, {
        angle:     this.nextStripeAngle,
        scale:     this.nextStripeScale,
        timeValue: transValue
      });
      context.save();
      context.clip();
      context.drawImage(this.slide1Image, 0, 0);
      context.restore();
      
      context.beginPath();
      context.rect(0, 0, width * transValue, height);
      context.closePath();
      context.save();
      context.clip();
      
      if (options.beforeTitle)
        (options.beforeTitle)();
      
      context.drawImage(this.slide1TitleImage, 59, 147);
      context.restore();
      
      if (this.stage1Time > duration - 0.5)
        this.circleTimeSpeed = 1.0;
      
      if (this.stage1Time > duration)
        this.goToStage(2);
    },
    
    updateStage2: function (options) {
      var context = this.context,
          width   = this.width,
          height  = this.height;
      
      this.stage2Time += this.timeStep;
      
      var duration      = 8.0;
      var transDuration = 0.5;
      var transOutTime  = duration - transDuration;
      var transValue    = 1.0;
      
      if (this.stage2Time < transDuration)
        transValue = this.stage2Time / transDuration;
      else if (this.stage2Time >= transOutTime)
        transValue = 1.0 - ((this.stage2Time - transOutTime) / transDuration);
      
      transValue = this.smoothValue(transValue);
      
      this.drawStripes(context, {
        angle:     this.nextStripeAngle,
        scale:     this.nextStripeScale,
        timeValue: transValue
      });
      context.save();
      context.clip();
      context.drawImage(this.slide2Image, 0, 0);
      context.restore();
      
      context.beginPath();
      context.rect(0, 0, width * transValue, height);
      context.closePath();
      context.save();
      context.clip();
      
      if (options.beforeTitle)
        (options.beforeTitle)();
      
      context.drawImage(this.slide2TitleImage, 626, 77);
      context.restore();
      
      if (this.stage2Time > duration - 0.5)
        this.circleTimeSpeed = -1.0;
      
      if (this.stage2Time > duration)
        this.goToStage(1);
    },
    
    drawStripes: function (context, options) {
      var width     = this.width,
          height    = this.height,
          angle     = options.angle,
          scale     = options.scale,
          timeValue = options.timeValue;
      
      var boundsW, boundsH;
      
      boundsW  = Math.sin(Math.abs(Math.PI / 2.0 - angle)) * width;
      boundsW += Math.sin(angle) * height;
      boundsW  = Math.abs(boundsW);
      
      boundsH  = Math.sin(angle) * width;
      boundsH += Math.sin(Math.abs(Math.PI / 2.0 - angle)) * height;
      boundsH  = Math.abs(boundsH);
      
      context.save();
      context.translate(width / 2.0, height / 2.0);
      context.rotate(angle);
      context.beginPath();
      
      var index;
      var stripeCount = Math.ceil(boundsW / scale);
      
      for (index = -1; index < stripeCount + 1; index++)
        context.rect(-boundsW / 2.0 + index * scale - (scale / 2.0 * timeValue),
                     -boundsH / 2.0,
                     scale * timeValue,
                     boundsH);
      
      context.closePath();
      context.restore();
    }
  }),
  
  animateSlidesInCanvas: function (canvas) {
    var animator = new Engage.SlideAnimator(canvas);
  },
});

document.observe("dom:loaded", function () {
  var canvas;
  if (canvas = $$("#slides canvas")[0])
    if (canvas.getContext)
      Engage.animateSlidesInCanvas(canvas);
});
