Animation = function(imageUtil) {
	this.imageUtil = imageUtil;

	this.currentAngle = 0.0;
	this.t = null;
	this.step = null;
	this.timeSliceSize = 100;
	this.clockWise = true;
	this.rotationStepCount = 0;
	this.fadeStep = 0;
	this.currentFadeStage = 100;
	this.toFadeStage = 0;

  this.turnTo = function(toAngle, duration) {
    if (this.currentAngle < toAngle) {
      this.rotateTo(toAngle, duration, true);
    } else {
      this.rotateTo(toAngle, duration, false);
    }
  }
  
	this.rotateTo = function(toAngle, duration, clockWise) {
		Animation.logger.debug("Rotating to angle: " + toAngle + ", duration: "	+ duration + ", clockwise: " + clockWise);
		this.clockWise = clockWise;
		var degsToIterate = 0.0;

		if (this.clockWise) {
			if (toAngle >= this.currentAngle) {
				degsToIterate = toAngle - this.currentAngle;
			} else {
				degsToIterate = 360 - this.currentAngle + toAngle;
			}
		} else {
			if (toAngle <= this.currentAngle) {
				degsToIterate = this.currentAngle - toAngle;
			} else {
				degsToIterate = this.currentAngle + 360 - toAngle;
			}
		}

		Animation.logger.debug("There are " + degsToIterate + " degrees to iterate over");
		this.step = degsToIterate * this.timeSliceSize / duration;
		Animation.logger.debug("The step size will be: " + this.step);
		this.rotationStepCount = duration / this.timeSliceSize;
		Animation.logger.debug("Animation total framecount: " + this.rotationStepCount);
		var oThis = this;
		this.t = setTimeout( function() {
			oThis.timerCallback()
		}, oThis.timeSliceSize);
	}

	this.calculateNextAngle = function() {
		if (this.clockWise) {
			this.currentAngle += this.step;
		} else {
			this.currentAngle -= this.step;
		}
		this.rotationStepCount--;
	}
	
	this.calculateNextFadeStage = function() {
		if (this.currentFadeStage - this.fadeStep > this.toFadeStage) { 
			this.currentFadeStage -= this.fadeStep;
		} else if (this.currentFadeStage + this.fadeStep < this.toFadeStage) {
			this.currentFadeStage += this.fadeStep;
		} else {
			this.currentFadeStage = this.toFadeStage;
		}
	}

	this.timerCallback = function() {
		if (this.rotationStepCount > 0) {
			this.calculateNextAngle();
			imageUtil.rotate(this.currentAngle);
		}
		if (this.currentFadeStage != this.toFadeStage) {
			this.calculateNextFadeStage();
			imageUtil.changeOpacity(this.currentFadeStage);
			
		}
		

		if (this.rotationStepCount <= 0 && this.currentFadeStage == this.toFadeStage) {
			clearTimeout(this.t);
		} else {
			var oThis = this;
			this.t = setTimeout( function() {
				oThis.timerCallback();
			}, oThis.timeSliceSize);
		}
	}
	
	this.fadeIn = function(duration) {
		this.toFadeStage = 100;
		if (duration == 0) {
			this.imageUtil.changeOpacity(100);
			this.currentFadeStage = 100;
		} else {
			this.fadeStep = Math.round(Math.abs(this.toFadeStage - this.currentFadeStage)/ duration * this.timeSliceSize);
			
			var oThis = this;
			this.t = setTimeout( function() {
				oThis.timerCallback();
			}, oThis.timeSliceSize);
		}
	}
	
	this.fadeOut = function(duration) {
		this.toFadeStage = 0;
		if (duration==0) {
			imageUtil.changeOpacity(0);
			this.currentFadeStage = 0;
		} else {
			
			this.fadeStep = Math.round(Math.abs(this.toFadeStage - this.currentFadeStage)/ duration * this.timeSliceSize);
			
			var oThis = this;
			this.t = setTimeout( function() {
				oThis.timerCallback();
			}, oThis.timeSliceSize);
		}
	}
};
Animation.logger = Logger.getLogger("Animation");
