/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SKY_ENGINE_CORE_ANIMATION_ACTIVEANIMATIONS_H_
#define SKY_ENGINE_CORE_ANIMATION_ACTIVEANIMATIONS_H_

#include "sky/engine/core/animation/AnimationStack.h"
#include "sky/engine/core/animation/css/CSSAnimations.h"
#include "sky/engine/wtf/HashCountedSet.h"
#include "sky/engine/wtf/HashMap.h"
#include "sky/engine/wtf/RefPtr.h"
#include "sky/engine/wtf/Vector.h"

namespace blink {

class CSSAnimations;
class RenderObject;
class Element;

typedef HashCountedSet<RawPtr<AnimationPlayer> > AnimationPlayerCountedSet;

class ActiveAnimations {
    WTF_MAKE_NONCOPYABLE(ActiveAnimations);
public:
    ActiveAnimations()
        : m_animationStyleChange(false)
    {
    }

    ~ActiveAnimations();

    // Animations that are currently active for this element, their effects will be applied
    // during a style recalc. CSS Transitions are included in this stack.
    AnimationStack& defaultStack() { return m_defaultStack; }
    const AnimationStack& defaultStack() const { return m_defaultStack; }
    // Tracks the state of active CSS Animations and Transitions. The individual animations
    // will also be part of the default stack, but the mapping betwen animation name and
    // player is kept here.
    CSSAnimations& cssAnimations() { return m_cssAnimations; }
    const CSSAnimations& cssAnimations() const { return m_cssAnimations; }

    // AnimationPlayers which have animations targeting this element.
    AnimationPlayerCountedSet& players() { return m_players; }

    bool isEmpty() const { return m_defaultStack.isEmpty() && m_cssAnimations.isEmpty() && m_players.isEmpty(); }

    void setAnimationStyleChange(bool animationStyleChange) { m_animationStyleChange = animationStyleChange; }

    void addAnimation(Animation* animation) { m_animations.append(animation); }
    void notifyAnimationDestroyed(Animation* animation) { m_animations.remove(m_animations.find(animation)); }

private:
    bool isAnimationStyleChange() const { return m_animationStyleChange; }

    AnimationStack m_defaultStack;
    CSSAnimations m_cssAnimations;
    AnimationPlayerCountedSet m_players;
    bool m_animationStyleChange;

    // This is to avoid a reference cycle that keeps Elements alive.
    Vector<Animation*> m_animations;

    // CSSAnimations checks if a style change is due to animation.
    friend class CSSAnimations;
};

} // namespace blink

#endif  // SKY_ENGINE_CORE_ANIMATION_ACTIVEANIMATIONS_H_
