                         currentCard.pop_addAnimation(alphaAnimation, forKey: "alpha")
                     }
                 }
-                
+
                 currentCard.userInteractionEnabled = index == 0
                 frameAnimation.toValue = NSValue(CGRect: frameForCardAtIndex(UInt(index)))
-                
+
                 currentCard.pop_addAnimation(frameAnimation, forKey: "frameAnimation")
             }
         } else {

    func kolodaShouldMoveBackgroundCard(koloda: KolodaView) -> Bool
    func kolodaShouldTransparentizeNextCard(koloda: KolodaView) -> Bool
    func kolodaBackgroundCardAnimation(koloda: KolodaView) -> POPPropertyAnimation?
    
}

public class KolodaView: UIView, DraggableCardDelegate {
    
    public weak var dataSource: KolodaViewDataSource! {
        didSet {
            setupDeck()
        }
    }
    public weak var delegate: KolodaViewDelegate?
    
    private(set) public var currentCardNumber = 0
    private(set) public var countOfCards = 0
    
    public var countOfVisibleCards = defaultCountOfVisibleCards
    private var visibleCards = [DraggableCardView]()
    private var animating = false
    private var configured = false
    
    public var alphaValueOpaque: CGFloat = defaultAlphaValueOpaque
    public var alphaValueTransparent: CGFloat = defaultAlphaValueTransparent
    public var alphaValueSemiTransparent: CGFloat = defaultAlphaValueSemiTransparent
    
    //MARK: Lifecycle
    required public init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configure()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        configure()
    }
    
    deinit {
        unsubsribeFromNotifications()
    }
    
    override public func layoutSubviews() {
        super.layoutSubviews()
        
        if !self.configured {
            
            if self.visibleCards.isEmpty {
                reloadData()
            } else {
                layoutDeck()
            }
            
            self.configured = true
        }
    }
    
    //MARK: Configurations
    
    private func subscribeForNotifications() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "layoutDeck", name: UIDeviceOrientationDidChangeNotification, object: nil)
    }
    
    private func unsubsribeFromNotifications() {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    private func configure() {
        subscribeForNotifications()
    }
    
    private func setupDeck() {
        countOfCards = Int(dataSource!.kolodaNumberOfCards(self))
        
        if countOfCards - currentCardNumber > 0 {
            
            let countOfNeededCards = min(countOfVisibleCards, countOfCards - currentCardNumber)
            
            for index in 0..<countOfNeededCards {
                if let nextCardContentView = dataSource?.kolodaViewForCardAtIndex(self, index: UInt(index)) {
                    let nextCardView = DraggableCardView(frame: frameForCardAtIndex(UInt(index)))
                    
                    nextCardView.delegate = self
                    nextCardView.alpha = index == 0 ? alphaValueOpaque : alphaValueSemiTransparent
                    nextCardView.userInteractionEnabled = index == 0
                    
                    let overlayView = overlayViewForCardAtIndex(UInt(index))
                    
                    nextCardView.configure(nextCardContentView, overlayView: overlayView)
                    visibleCards.append(nextCardView)
                    index == 0 ? addSubview(nextCardView) : insertSubview(nextCardView, belowSubview: visibleCards[index - 1])

        } else {
            animating = false
        }

    }

    func cardTapped(card: DraggableCardView) {
        let index = currentCardNumber + find(visibleCards, card)!

        delegate?.kolodaDidSelectCardAtIndex(self, index: UInt(index))
    }

    //MARK: Private

    private func clear() {
        currentCardNumber = 0

        for card in visibleCards {
            card.removeFromSuperview()
        }

        visibleCards.removeAll(keepCapacity: true)

    }

    private func overlayViewForCardAtIndex(index: UInt) -> OverlayView? {
        return dataSource.kolodaViewForCardOverlayAtIndex(self, index: index)
    }

    //MARK: Actions

    private func swipedAction(direction: SwipeResultDirection) {
        animating = true
        visibleCards.removeAtIndex(0)

        currentCardNumber++
        let shownCardsCount = currentCardNumber + countOfVisibleCards
        if shownCardsCount - 1 < countOfCards {

            if let dataSource = self.dataSource {

                let lastCardContentView = dataSource.kolodaViewForCardAtIndex(self, index: UInt(shownCardsCount - 1))
                let lastCardOverlayView = dataSource.kolodaViewForCardOverlayAtIndex(self, index: UInt(shownCardsCount - 1))
                let lastCardFrame = frameForCardAtIndex(UInt(currentCardNumber + visibleCards.count))
                let lastCardView = DraggableCardView(frame: lastCardFrame)

                lastCardView.hidden = true
                lastCardView.userInteractionEnabled = true

                lastCardView.configure(lastCardContentView, overlayView: lastCardOverlayView)

                lastCardView.delegate = self

                insertSubview(lastCardView, belowSubview: visibleCards.last!)
                visibleCards.append(lastCardView)
            }
        }

        if !visibleCards.isEmpty {

            for (index, currentCard) in enumerate(visibleCards) {
                var frameAnimation: POPPropertyAnimation
                if let delegateAnimation = delegate?.kolodaBackgroundCardAnimation(self) where delegateAnimation.property.name == kPOPViewFrame {
