﻿// Animation controller
function Animator() {
    var self = this;
    this.intervalRate = 20;

    this.tweenTypes = {
        'smooth': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
        'blast': [12, 12, 11, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
        'superblast': [20, 20, 20, 20, 10, 3, 3, 2, 1, 1],
        'linear': [10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
        'halflinear': [20, 20, 20, 20, 20],
        'fastlinear': [25, 25, 25, 25]
    }

    this.queue = new Array();
    this.queueHash = new Array();
    this.active = false;
    this.timer = null;

    this.createTween = function(start, end, type) {
        // return array of tween coordinate data (start->end)
        type = type || 'linear';

        var tween = new Array();
        var tmp = start;
        var diff = end - start;
        var x = self.tweenTypes[type].length;

        for (var i = 0; i < x - 1; i++) {
            tmp += diff * self.tweenTypes[type][i] * 0.01;

            tween[i] = {
                data: tmp,
                event: null
            };
        }

        tween[tween.length] = {
            data: end,
            event: null
        };

        return tween;
    }

    this.enqueue = function(o) {
        // add object and associated methods to animation queue
        self.queue.push(o);
        o.active = true;
    }

    this.animate = function() {
        var active = 0;
        for (var i = 0; i < self.queue.length; i++) {
            if (self.queue[i].active) {
                self.queue[i].animate();
                active++;
            }
        }
        if (active == 0 && self.timer) {
            // all animations finished
            self.stop();
        }
    }

    this.start = function() {
        if (self.timer || self.active) {
            return false;
        }
        self.active = true;
        self.timer = setInterval(self.animate, self.intervalRate);
    }

    this.stop = function() {
        // reset some things, clear for next batch of animations
        clearInterval(self.timer);
        self.timer = null;
        self.active = false;
        self.queue = [];
    }

}

//var animator = new Animator();

function Animation(anParams) {
    var self = this;

    this.animator = new Animator();

    if (typeof anParams.tweenType == 'undefined') {
        anParams.tweenType = 'linear';
    }
    if (typeof anParams.intervalRate != 'undefined') {
        this.animator.intervalRate = anParams.intervalRate;
    }

    this.src = anParams.src;
    this.object = anParams.object;
    this.ontween = (anParams.ontween || null);
    this.oncomplete = (anParams.oncomplete || null);
    this.tween = this.animator.createTween(anParams.from, anParams.to, anParams.tweenType);
    this.frameCount = this.animator.tweenTypes[anParams.tweenType].length;
    this.frame = 0;
    this.active = false;

    this.animate = function() {
        // generic animation method
        if (self.active) {
            if (self.ontween && self.tween[self.frame]) {
                self.ontween(self.tween[self.frame].data, self.src);
            }
            if (self.frame++ >= self.frameCount) {
                self.active = false;
                self.frame = 0;
                if (self.oncomplete) {
                    self.oncomplete(self.src);
                }
                return false;
            }
            return true;
        }
        return false;
    }

    this.start = function() {
        // add this to the main animation queue
        self.animator.enqueue(self);
        if (!self.animator.active) {
            self.animator.start();
        }
    }

    this.stop = function() {
        if (self.animator.active) {
            self.animator.stop();
        }
        self.active = false;
    }

}
