lclass("CardDeck", {
    cons: function(el, params) {
        this.el = $(el);
        $PM(this, params, {
            initialSpeed: 0.5, maxSpeed: 10, acceleration: 0.2, fps: 10, animDelay: 100, defaultCard: 0, transformStart: 0.2
        });

        this.cards = $C("li", this.el);

        var i, card, height = 0, maxTopHeight = 0;
        
        for (i = 0; i < this.cards.length; i++) {
            card = this.cards[i];
            card.apply({
                position: "absolute",
                zIndex: (this.cards.length - i) + ""
            });
            card.v = 0;
            card.index = i;
            card.topHeight = CardDeck.getHeight($S(".DeckTop", card));
            card.bottomHeight = CardDeck.getHeight($S(".DeckBottom", card));
            card.attachEvent("mouseover", this, this.cardMouseOver);
            //card.attachEvent("mouseout", this, this.cardMouseOut);

            height += card.bottomHeight;
            if (card.topHeight > maxTopHeight) {
                maxTopHeight = card.topHeight;
            }
        }

        this.el.style().height = (height + maxTopHeight) + "px";
        
        this.activeCard = -1;
        this.setActiveCard(this.defaultCard, true);

        this.animTimer = new LTimer(this.fps, this, this.animate);
        this.animDelayTimer = new LTimer(this.animDelay, this, this.startAnimating);
    },

    cardMouseOver: function(e) {
        this.setActiveCard(e.thisElement().index);
    },

    cardMouseOut: function(e) {
        if (e.target() == e.thisElement()) {
            this.animDelayTimer.stop();
        }
    },

    setActiveCard: function(index, initial) {
        if (index == this.activeCard) {
            return;
        }

        var i, cy, y, card;

        for (i = 0, y = 0; i < this.cards.length; i++) {
            card = this.cards[i];

            if (i == index) {
                y += card.topHeight;
            }

            cy = y - card.topHeight;
            
            /*if (card.v < this.initialSpeed) {
                card.v = this.initialSpeed;
            }*/
            
            card.targetY = cy;
            card.dirSign = Math.sgn(card.targetY - card.y);

            if (initial) {
                card.y = cy;
                card.style().top = cy + "px";   
            }

            card.moving = (card.targetY != card.y);

            y += card.bottomHeight;
        }
        
        if (!initial) {
            this.newActiveCard = index;
            if (this.animTimer.running()) {
                this.chooseActiveCard();
                this.animTimer.reset();
            } else {
                this.animDelayTimer.reset();
            }
        } else {
            this.activeCard = index;
            this.cards[this.activeCard].addClass("DeckActive");
        }
    },

    chooseActiveCard: function() {
        if (this.newActiveCard != -1) {
            this.cards[this.activeCard].removeClass("DeckActive");
            this.activeCard = this.newActiveCard;
            this.cards[this.activeCard].addClass("DeckActive");
            this.newActiveCard = -1;
        }
    },

    startAnimating: function() {
        this.chooseActiveCard();
        
        this.ms = new Date().getTime();
        this.animTimer.start();
    },

    animate: function() {
        var i, v, card, cardsMoving = false;

        var curms = new Date().getTime();
        var delta = (curms - this.ms) * 0.001 * this.fps;
        this.ms = curms;
        
        for (i = 0; i < this.cards.length; i++) {
            card = this.cards[i];
            
            if (!card.moving) {
                continue;
            }

            cardsMoving = true;
            
            /*card.y += card.v * card.dirSign;
            card.style().top = Math.floor(card.y) + "px";
            card.v += this.acceleration;*/
            
            v = card.targetY - card.y;
            var sign = 1;
            if (v < 0) {
                sign = -1;
                v = -v;
            }

            card.y += Math.sqrt(v) * 2.0 * sign * delta;
            card.style().top = Math.floor(card.y) + "px";
            
            /*if (card.v > this.maxSpeed) {
                card.v = this.maxSpeed;
            }*/

            //if (card.dirSign != Math.sgn(card.targetY - card.y)) {
            if (Math.abs(card.targetY - card.y) <= 3 || Math.sgn(card.targetY - card.y) != card.dirSign) {
                card.y = card.targetY;
                card.style().top = card.y + "px";
                card.moving = false;
            }
        }

        if (cardsMoving) {
            this.animTimer.start();
        }
    }
}, {
    getHeight: function(el) {
        //return el.offsetHeight() + parseInt(el.getStyle("padding-top")) + parseInt(el.getStyle("padding-bottom"));
        return el.offsetHeight(); // + parseInt(el.getStyle("padding-top")) + parseInt(el.getStyle("padding-bottom"));
    }
});

