﻿AnimationService = {
    INTERVAL: 30, 															// Default delay between steps
    STEP: 150, 																// Default pixels to move each step
    animations: new Object(), 												// Used to reference a given animation by id
    addAnimation: function(id, obj) {
        obj.id = id;
        this.animations[id] = obj;
        return obj;
    },
    startById: function(id) {
        if (this.animations[id]) {
            this.animations[id].start();
        }
    },
    stopById: function(id) {
        if (this.animations[id]) {
            this.animations[id].stop();
        }
    },
    runScene: function(scene, cb) {											// Runs an array of Animations and executes a callback when finished.
        var completed = new Array();
        if (scene.length) {
            for (var n = 0; n < scene.length; n++) {
                scene[n].sceneIndex = n;
                completed[n] = false;
                scene[n].complete = function() {
                    completed[this.sceneIndex] = true;
                    this.sceneIndex = 0;
                    allDone = true;
                    for (var j = 0; j < completed.length; j++) {
                        if (!completed[j]) {
                            allDone = false;
                        }
                    }
                    if (allDone) {
                        cb();
                    }
                }
                scene[n].start();
            }
        } else {
            cb();
        }
    }
}

fadeAnimation = function(element) {
    this.element = element;
    this.interval = AnimationService.INTERVAL;
    this.step = AnimationService.STEP;
    this.running = false;
    this.intervalId = null;
    this.startTime = null;
    this.sceneIndex = 0;
    this.id = null;

    this.toOpacity = 0;

    this.startOpacity = getOpacity(this.element);

    this.start = function() {
        //debug("start: " + this.element.id);
        if (this.intervalId == null) {
            this.beforeStart();
            this.running = true;

            if (this.toOpacity < 0) {
                this.toOpacity = 0;
            }

            this.startOpacity = getOpacity(this.element);

            var dist = this.toOpacity > this.startOpacity ? 1 : -1;

            //debug("Start: " + this.startOpacity + " To: " + this.toOpacity + " dist: " + dist);
            var self = this;
            this.intervalId = setInterval(function() {
                var currentOpacity = getOpacity(self.element)
                var dif = currentOpacity + self.step * dist;

                // debug("Current: " + currentOpacity + " dif: " + dif);
                if ((dist > 0 && dif <= self.toOpacity) || (dist < 0 && dif >= self.toOpacity)) {
                    setOpacity(self.element, dif);
                } else {
                    setOpacity(self.element, self.toOpacity);
                }

                if (currentOpacity == self.toOpacity) {
                    //debug("Complete: " + self.element.id);
                    self.stop();
                    self.complete();
                }
            },
				this.interval
			);

        } else {
            throw new Error("fadeAnimation already started for " + this.element.id);
        }
    }
    this.stop = function() {
        if (this.intervalId != null) {
            clearInterval(this.intervalId);
            this.intervalId = null;
        }
        this.running = false;
    }
    this.complete = function() { }
    this.beforeStart = function() {
        this.startTime = new Date().getTime();
    }
}


getOpacity = function(element) {
    if (element.currentStyle) {
        if (element.currentStyle.filter) {
            if (value = (element.currentStyle.filter || '').match(/alpha\(opacity=(.*)\)/))
                if (value[1]) return parseFloat(value[1]);
        } else {
            return 100;
        }
    } else if (element.style.opacity) {
        return element.style.opacity * 100;
    } else if (element.style.MozOpacity) {
        return element.style.MozOpacity * 100;
    } else {
        var css = document.defaultView.getComputedStyle(element, null);
        return css ? css["opacity"] * 100 : null;
    }
}

setOpacity = function(element, value) {
    function stripAlpha(filter) {
        return filter.replace(/alpha\([^\)]*\)/gi, '');
    }

    var filter = null;
    if (element.currentStyle) {
        var currentStyle = element.currentStyle;
        filter = (currentStyle.filter) ? currentStyle.filter : "";
    }
    var style = element.style;

    if (value == 100 || value === '') {
        if (filter != null) {
            (filter = stripAlpha(filter)) ? style.filter = filter : style.removeAttribute('filter');
        }
        element.style.opacity = 1;
        element.style.MozOpacity = 1;
        return element;
    } else if (value < 0.00001) value = 0;

    if (filter != null) {
        style.filter = stripAlpha(filter) + 'alpha(opacity=' + value + ')';
    }
    element.style.opacity = value / 100;
    element.style.MozOpacity = value / 100;

    return element;
}
