﻿function Animator() {
    // controller for animation objects.
    var self = this;
    var intervalRate = 20;
    this.tweenTypes = {
        // % of total distance to move per-frame, total always = 100
        'default': [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],
        'linear': [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
    }
    this.queue = [];
    this.queueHash = [];
    this.active = false;
    this.timer = null;
    this.createTween = function (start, end, type) {
        // return array of tween coordinate data (start->end)
        type = type || 'default';
        var tween = [start];
        var tmp = start;
        var diff = end - start;
        var x = self.tweenTypes[type].length;
        for (var i = 0; i < x; i++) {
            tmp += diff * self.tweenTypes[type][i] * 0.01;
            tween[i] = {};
            tween[i].data = tmp;
            tween[i].event = null;
        }
        return tween;
    };

    this.enqueue = function (o, fMethod, fOnComplete) {
        // add object and associated methods to animation queue

        // writeDebug('animator.enqueue()');
        if (!fMethod) {
            // writeDebug('animator.enqueue(): missing fMethod');
        }
        self.queue.push(o);
        o.active = true;
    };

    this.animate = function () {
        // interval-driven loop: process queue, stop if done
        var active = 0;

        for (var i = 0, j = self.queue.length; i < j; i++) {


            //   alert(self.queue.length);


            if (self.queue[i].active) {
                self.queue[i].animate();
                active++;
            }
        }
        if (active == 0 && self.timer) {
            // all animations finished

            // writeDebug('Animations complete');
            self.stop();
        } else {
            // writeDebug(active+' active');
        }
    };

    this.start = function () {
        if (self.timer || self.active) {
            // writeDebug('animator.start(): already active');
            return false;
        }
        // writeDebug('animator.start()');

        // report only if started
        self.active = true;
        self.timer = setInterval(self.animate, intervalRate);
    };

    this.stop = function () {
        // writeDebug('animator.stop()',true);

        // reset some things, clear for next batch of animations
        clearInterval(self.timer);
        self.timer = null;
        self.active = false;
        self.queue = [];
    };

};

function Animation(oParams) {
    // Individual animation sequence
    /*
    oParams = {
    control: img1,
    from: 200,
    to: 300,
    tweenType: 'default', // see animator.tweenTypes (optional)
    ontween: function(value) { ... }, // method called each time (required)
    oncomplete: function() { ... } // when finished (optional)
    }
    */
    var self = this;
    if (typeof oParams.tweenType == 'undefined') {
        oParams.tweenType = 'default';
    }
    this.control = oParams.control;
    this.ontween = (oParams.ontween || null);
    this.oncomplete = (oParams.oncomplete || null);
    this.tween = animator.createTween(oParams.from, oParams.to, oParams.tweenType);
    this.frameCount = animator.tweenTypes[oParams.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.control, self.tween[self.frame].data);
            }
            if (self.frame++ >= self.frameCount - 1) {
                // writeDebug('animation(): end');
                self.active = false;
                self.frame = 0;
                if (self.oncomplete) {
                    self.oncomplete(this.control);
                }
                return false;
            }
            return true;
        } else {
            return false;
        }
    };

    this.start = function () {
        // add this to the main animation queue
        animator.enqueue(self, self.animate, self.oncomplete);
        if (!animator.active) {
            animator.start();
        }
    };

    this.stop = function () {
        self.active = false;
    };

};



var animator = new Animator();
