﻿var anim_dt = 5;
var anim_ismoving = [];
var anim_obj = [];
var anim_timer = [];
var anim_contexts = [];
var anim_callbacks = [];
var anim_animators = [];

function getSlidingValue(from, to, index, max_index) {
    var i = from + index * (to - from) / max_index;
    return i;
}

function Animation(t) {
    this.is_h = false; // changes height
    this.is_w = false; // changes width
    this.is_top = false; // changes top
    this.is_bottom = false; // changes bottom
    this.is_left = false; // changes left
    this.is_right = false; // changes right
    this.is_opacity = false; // changes opacity
    this.is_show = false; // whether to set initial display to block or not.
    this.is_hide = false; // whether to set final display to none or not.
    this.is_background = false; // changes background color.
    this.is_color = false; // changes foreground color.
    this.h_start = 0;
    this.h_end = 0;
    this.w_start = 0;
    this.w_end = 0;
    this.top_start = 0;
    this.top_end = 0;
    this.bottom_start = 0;
    this.bottom_end = 0;    
    this.left_start = 0;
    this.left_end = 0;
    this.right_start = 0;
    this.right_end = 0;    
    this.opacity_start = 0;
    this.opacity_end = 0;
    this.bg_r_start = 0;
    this.bg_r_end = 0;
    this.bg_g_start = 0;
    this.bg_g_end = 0;
    this.bg_b_start = 0;
    this.bg_b_end = 0;
    this.fg_r_start = 0;
    this.fg_r_end = 0;
    this.fg_g_start = 0;
    this.fg_g_end = 0;
    this.fg_b_start = 0;
    this.fg_b_end = 0;    
    this.time = t;
    this.tick_max = 0;
    this.tick = 0;
}
Animation.prototype.height = function(from, to) {
    this.h_start = from;
    this.h_end = to;
    this.is_h = true;
    return this;
};
Animation.prototype.width = function(from, to) {
    this.w_start = from;
    this.w_end = to;
    this.is_w = true;
    return this;
};
Animation.prototype.top = function(from, to) {
    this.top_start = from;
    this.top_end = to;
    this.is_top = true;
    return this;
};
Animation.prototype.bottom = function(from, to) {
    this.bottom_start = from;
    this.bottom_end = to;
    this.is_bottom = true;
    return this;
};
Animation.prototype.left = function(from, to) {
    this.left_start = from;
    this.left_end = to;
    this.is_left = true;
    return this;
};
Animation.prototype.right = function(from, to) {
    this.right_start = from;
    this.right_end = to;
    this.is_right = true;
    return this;
};
Animation.prototype.opacity = function(from, to) {
    this.opacity_start = from;
    this.opacity_end = to;
    this.is_opacity = true;
    return this;
};
Animation.prototype.background = function(r0, r1, g0, g1, b0, b1) {
    this.bg_r_start = parseInt(r0);
    this.bg_r_end = parseInt(r1);
    this.bg_g_start = parseInt(g0);
    this.bg_g_end = parseInt(g1);
    this.bg_b_start = parseInt(b0);
    this.bg_b_end = parseInt(b1);
    this.is_background = true;
    return this;
};
Animation.prototype.color = function(r0, r1, g0, g1, b0, b1) {
    this.fg_r_start = parseInt(r0);
    this.fg_r_end = parseInt(r1);
    this.fg_g_start = parseInt(g0);
    this.fg_g_end = parseInt(g1);
    this.fg_b_start = parseInt(b0);
    this.fg_b_end = parseInt(b1);
    this.is_color = true;
    return this;
};
Animation.prototype.show = function() {
    this.is_show = true;
    return this;
};
Animation.prototype.hide = function() {
    this.is_hide = true;
    return this;
};
Animation.prototype.initializeObject = function(obj) {
    if (this.is_h) { obj.style.height = this.h_start + 'px'; }
    if (this.is_w) { obj.style.width = this.w_start + 'px'; }
    if (this.is_top) { obj.style.top = this.top_start + 'px'; }
    if (this.is_bottom) { obj.style.bottom = this.bottom_start + 'px'; }
    if (this.is_left) { obj.style.left = this.left_start + 'px'; }
    if (this.is_right) { obj.style.right = this.right_start + 'px'; }
    if (this.is_opacity) {
        obj.style.opacity = this.opacity_start / 100;
        obj.style.filter = 'alpha(opacity=' + this.opacity_start + ')';
    }
    if (this.is_background) {
        obj.style.backgroundColor = 'rgb(' + this.bg_r_start + ',' + this.bg_g_start + ',' + this.bg_b_start + ')';
    }
    if (this.is_color) {
        obj.style.color = 'rgb(' + this.fg_r_start + ',' + this.fg_g_start + ',' + this.fg_b_start + ')';
    }    
    if (this.is_show) {
        obj.style.display = 'block';
    }
};
Animation.prototype.updateObject = function(obj) {
    if (this.is_h) {
        obj.style.height = getSlidingValue(this.h_start, this.h_end, this.tick, this.tick_max) + 'px';
    }
    if (this.is_w) {
        obj.style.width = getSlidingValue(this.w_start, this.w_end, this.tick, this.tick_max) + 'px';
    }
    if (this.is_top) {
        obj.style.top = getSlidingValue(this.top_start, this.top_end, this.tick, this.tick_max) + 'px';
    }
    if (this.is_bottom) {
        obj.style.bottom = getSlidingValue(this.bottom_start, this.bottom_end, this.tick, this.tick_max) + 'px';
    }
    if (this.is_left) {
        obj.style.left = getSlidingValue(this.left_start, this.left_end, this.tick, this.tick_max) + 'px';
    }
    if (this.is_right) {
        obj.style.right = getSlidingValue(this.right_start, this.right_end, this.tick, this.tick_max) + 'px';
    }
    if (this.is_opacity) {
        var op = getSlidingValue(this.opacity_start, this.opacity_end, this.tick, this.tick_max);
        obj.style.opacity = op / 100;
        obj.style.filter = 'alpha(opacity=' + op + ')';
    }
    if (this.is_background) {
        var r = parseInt(getSlidingValue(this.bg_r_start, this.bg_r_end, this.tick, this.tick_max));
        var g = parseInt(getSlidingValue(this.bg_g_start, this.bg_g_end, this.tick, this.tick_max));
        var b = parseInt(getSlidingValue(this.bg_b_start, this.bg_b_end, this.tick, this.tick_max));
        obj.style.backgroundColor = 'rgb(' + r + ',' + g + ',' + b + ')';
    }
    if (this.is_color) {
        var r = parseInt(getSlidingValue(this.fg_r_start, this.fg_r_end, this.tick, this.tick_max));
        var g = parseInt(getSlidingValue(this.fg_g_start, this.fg_g_end, this.tick, this.tick_max));
        var b = parseInt(getSlidingValue(this.fg_b_start, this.fg_b_end, this.tick, this.tick_max));
        obj.style.color = 'rgb(' + r + ',' + g + ',' + b + ')';
    }    
};
Animation.prototype.finalizeObject = function(obj) {
    if (this.is_h) { obj.style.height = this.h_end + 'px'; }
    if (this.is_w) { obj.style.width = this.w_end + 'px'; }
    if (this.is_top) { obj.style.top = this.top_end + 'px'; }
    if (this.is_bottom) { obj.style.bottom = this.bottom_end + 'px'; }
    if (this.is_left) { obj.style.left = this.left_end + 'px'; }
    if (this.is_right) { obj.style.right = this.right_end + 'px'; }
    if (this.is_opacity) {
        obj.style.opacity = this.opacity_end / 100;
        obj.style.filter = 'alpha(opacity=' + this.opacity_end + ')';
    }
    if (this.is_background) {
        obj.style.backgroundColor = 'rgb(' + this.bg_r_end + ',' + this.bg_g_end + ',' + this.bg_b_end + ')';
    }
    if (this.is_color) {
        obj.style.color = 'rgb(' + this.fg_r_end + ',' + this.fg_g_end + ',' + this.fg_b_end + ')';
    }        
    if (this.is_hide) {
        obj.style.display = 'none';
    }
};

function Animator(id) {
    this.obj_id = id;
    this.contexts = [];
    this.index = 0;
    anim_animators[id] = this;
}
Animator.prototype.add = function(context){
    this.contexts[this.contexts.length] = context;
    return this;
};
Animator.prototype.start = function() {
    if (this.contexts.length > 0) {
        animate(this.obj_id, this.contexts[0], NextAnimator);
    }
};
Animator.prototype.next = function() {
    this.index++;
    if (this.index < this.contexts.length) {
        animate(this.obj_id, this.contexts[this.index], NextAnimator);
    }
    else {
        delete (anim_animators[this.obj_id]);
    }
};
function NextAnimator(id) {
    if (anim_animators[id]) {
        anim_animators[id].next();
    }
}

function animate(id, context, callback) {
    if (anim_ismoving[id]) { return; }
    var o = $(id);
    if (o) {
        context.initializeObject(o);
        context.tick = 0;
        context.tick_max = context.time / anim_dt;

        anim_contexts[id] = context;
        anim_ismoving[id] = true;
        anim_obj[id] = o;
        anim_callbacks[id] = callback;
        anim_timer[id] = setInterval('animateTick(\'' + id + '\');', anim_dt);
    }
}

function animateTick(id) {
    var context = anim_contexts[id];
    context.tick++;
    if (context.tick == context.tick_max) {
        animateEnd(id);
    }
    else {
        context.updateObject(anim_obj[id]);
    }
    return;
}

function animateEnd(id) {
    var c = anim_callbacks[id];
    clearInterval(anim_timer[id]);
    anim_contexts[id].finalizeObject(anim_obj[id]);
    delete (anim_ismoving[id]);
    delete (anim_timer[id]);
    delete (anim_obj[id]);
    delete (anim_contexts[id]);
    delete (anim_callbacks[id]);
    if (c) { c(id); }
}
