
    var StickerAnimation = function(){};
    StickerAnimation.prototype = 
    {
        duration : null,
        obj : null,
        from : null,
        to : null,
        timer : 0,
        step : 0,
        start : function(obj, from, to, duration, type){
            var self = this;
            this.obj = obj;
            this.from = from;
            this.to = to;
            this.now = new Date;
            this.duration = duration || 1000;
            this._delta = this['_delta' +(type || 'Elastic')];

            if(this.timer)
                this.stop();

            this.timer = setInterval(function(){self.run();}, 10);
        },
        run : function(){

            var time = ((new Date) - this.now) / this.duration;
            var delta = this._delta(time);

            var step = Math.pow(2, this.step);
            var dep_x = (this.to.x - this.from.x) * delta;
            var dep_y = (this.to.y - this.from.y) * delta;

            if(time > 1){
                this.stop();
                this.end();
            }else{

                this.obj.style.marginLeft = this.from.x + dep_x + "px";
                this.obj.style.marginTop = this.from.y + dep_y + "px";
            }
        },
        end : function(){
            this.obj.style.marginLeft = (this.to.x) + "px";
            this.obj.style.marginTop = (this.to.y) + "px";
        },
        stop : function(){
            clearInterval(this.timer);
            this.timer = 0;
        },

        _deltaBounce : function(pos){
            var p = 1 - pos;

            var value;
            for (var a = 0, b = 1; 1; a += b, b /= 2){
                if (p >= (7 - 4 * a) / 11){
                    value = - Math.pow((11 - 6 * a - 11 * p) / 4, 2) + b * b;
                    break;
                }
            }
            return 1 - value;
        },

        _deltaExpo : function(pos){
            var p = 1 - pos;
            return 1 - Math.pow(2, 8 * (p - 1));
        },

        _deltaElastic : function(pos){
            var p = 1 - pos;
            return 1 - Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * 1 / 3);
        },

        _deltaStatic : function(pos){
            return 1;
        }

    }

    var StickerManager = {
        init : false,
        stickers : [],
        opts : [],
        add : function(id, duration, type){

            if(!this.init){
                var self = this;
                var init_event = function(){self.oninit();};
                var scroll_event = function(){self.onscroll();};

                if(window.attachEvent){
                    window.attachEvent('onload', init_event);
                    window.attachEvent('onscroll', scroll_event);
                }else{
                    window.addEventListener('load', init_event, false);
                    document.addEventListener('scroll', scroll_event, false);
                }

                this.init = true;
            }

            this.stickers.push(id);
            this.opts.push({duration:duration,type:type});
        },

        oninit : function(){
            var sticker;
            for(var x = 0, len = this.stickers.length; x < len; x++){
                sticker = document.getElementById(this.stickers[x]);
                if(!sticker){
                    alert(this.stickers[x] + ' is bad id.');
                    this.stickers[x] = null;
                    continue;
                }
                this.stickers[x] = sticker;
                sticker.style.marginLeft = sticker.style.marginTop = "0px";
            }
        },

        onscroll : function(){
            var left = parseInt(document.documentElement.scrollLeft);
            var top = parseInt(document.documentElement.scrollTop);
            var sticker;
            for(var x = 0, len = this.stickers.length; x < len; x++){
                sticker = this.stickers[x];

                if(!sticker)
                    continue;

                if(!sticker.animation){
                    sticker.animation = new StickerAnimation();
                }else{
                    sticker.animation.stop();
                }
                
                sticker.animation.start(
                    sticker, 
                    {x:parseInt(sticker.style.marginLeft), y:parseInt(sticker.style.marginTop)},
                    {x:left, y:top},
                    this.opts[x].duration,
                    this.opts[x].type
                );

            }
        }
    }
