// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_WM_SESSION_STATE_ANIMATOR_IMPL_H_
#define ASH_WM_SESSION_STATE_ANIMATOR_IMPL_H_

#include "ash/ash_export.h"
#include "ash/wm/session_state_animator.h"
#include "base/basictypes.h"
#include "ui/aura/window.h"

namespace ui {
class LayerAnimationObserver;
}

namespace ash {

// Displays onscreen animations for session state changes (lock/unlock, sign
// out, shut down).
class ASH_EXPORT SessionStateAnimatorImpl : public SessionStateAnimator {
 public:
  // Helper class used by tests to access internal state.
  class ASH_EXPORT TestApi {
   public:
    explicit TestApi(SessionStateAnimatorImpl* animator)
        : animator_(animator) {}

    // Returns true if containers of a given |container_mask|
    // were last animated with |type| (probably; the analysis is fairly ad-hoc).
    // |container_mask| is a bitfield of a Container.
    bool ContainersAreAnimated(int container_mask,
                               SessionStateAnimator::AnimationType type) const;

    // Returns true if root window was last animated with |type| (probably;
    // the analysis is fairly ad-hoc).
    bool RootWindowIsAnimated(SessionStateAnimator::AnimationType type) const;

   private:
    SessionStateAnimatorImpl* animator_;  // not owned

    DISALLOW_COPY_AND_ASSIGN(TestApi);
  };

  SessionStateAnimatorImpl();
  ~SessionStateAnimatorImpl() override;

  // Fills |containers| with the containers included in |container_mask|.
  static void GetContainers(int container_mask,
                            aura::Window::Windows* containers);

  // ash::SessionStateAnimator:
  void StartAnimation(int container_mask,
                      AnimationType type,
                      AnimationSpeed speed) override;
  void StartAnimationWithCallback(int container_mask,
                                  AnimationType type,
                                  AnimationSpeed speed,
                                  base::Closure callback) override;
  AnimationSequence* BeginAnimationSequence(base::Closure callback) override;
  bool IsBackgroundHidden() const override;
  void ShowBackground() override;
  void HideBackground() override;

 private:
  class AnimationSequence;
  friend class AnimationSequence;

  virtual void StartAnimationInSequence(int container_mask,
      AnimationType type,
      AnimationSpeed speed,
      AnimationSequence* observer);

  // Apply animation |type| to window |window| with |speed| and add |observer|
  // if it is not NULL to the last animation sequence.
  void RunAnimationForWindow(aura::Window* window,
                             SessionStateAnimator::AnimationType type,
                             SessionStateAnimator::AnimationSpeed speed,
                             ui::LayerAnimationObserver* observer);

  DISALLOW_COPY_AND_ASSIGN(SessionStateAnimatorImpl);
};

}  // namespace ash

#endif  // ASH_WM_SESSION_STATE_ANIMATOR_IMPL_H_
