// Copyright 2014 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.

#include "athena/home/public/home_card.h"

#include <cmath>
#include <limits>

#include "athena/common/container_priorities.h"
#include "athena/home/app_list_view_delegate.h"
#include "athena/home/athena_start_page_view.h"
#include "athena/home/minimized_home.h"
#include "athena/home/public/app_model_builder.h"
#include "athena/input/public/accelerator_manager.h"
#include "athena/screen/public/screen_manager.h"
#include "athena/wm/public/window_manager.h"
#include "athena/wm/public/window_manager_observer.h"
#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "ui/app_list/search_provider.h"
#include "ui/app_list/views/app_list_main_view.h"
#include "ui/app_list/views/contents_view.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/window.h"
#include "ui/compositor/closure_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/visibility_controller.h"
#include "ui/wm/core/window_animations.h"
#include "ui/wm/public/activation_change_observer.h"
#include "ui/wm/public/activation_client.h"

namespace athena {
namespace {

HomeCard* instance = NULL;
const int kHomeCardHeight = 100;
const int kHomeCardMinimizedHeight = 6;

gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds,
                            HomeCard::State state) {
  switch (state) {
    case HomeCard::HIDDEN:
      break;

    case HomeCard::VISIBLE_CENTERED:
      return screen_bounds;

    case HomeCard::VISIBLE_BOTTOM:
      return gfx::Rect(0,
                       screen_bounds.bottom() - kHomeCardHeight,
                       screen_bounds.width(),
                       kHomeCardHeight);
    case HomeCard::VISIBLE_MINIMIZED:
      return gfx::Rect(0,
                       screen_bounds.bottom() - kHomeCardMinimizedHeight,
                       screen_bounds.width(),
                       kHomeCardMinimizedHeight);
  }

  NOTREACHED();
  return gfx::Rect();
}

// Makes sure the homecard is center-aligned horizontally and bottom-aligned
// vertically.
class HomeCardLayoutManager : public aura::LayoutManager {
 public:
  class Delegate {
   public:
    virtual ~Delegate() {}

    virtual HomeCard::State GetState() = 0;
    virtual aura::Window* GetNativeWindow() = 0;
  };

  explicit HomeCardLayoutManager(Delegate* delegate)
      : delegate_(delegate) {}

  virtual ~HomeCardLayoutManager() {}

  void Layout() {
    aura::Window* home_card = delegate_->GetNativeWindow();
    // |home_card| could be detached from the root window (e.g. when it is being
    // destroyed).
    if (!home_card || !home_card->GetRootWindow())
      return;

    {
      ui::ScopedLayerAnimationSettings settings(
          home_card->layer()->GetAnimator());
      settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
      SetChildBoundsDirect(home_card, GetBoundsForState(
          home_card->GetRootWindow()->bounds(), delegate_->GetState()));
    }
  }

 private:
  // aura::LayoutManager:
  virtual void OnWindowResized() OVERRIDE { Layout(); }
  virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { Layout(); }
  virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {}
  virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {
    Layout();
  }
  virtual void OnChildWindowVisibilityChanged(aura::Window* child,
                                              bool visible) OVERRIDE {
    Layout();
  }
  virtual void SetChildBounds(aura::Window* child,
                              const gfx::Rect& requested_bounds) OVERRIDE {
    SetChildBoundsDirect(child, requested_bounds);
  }

  Delegate* delegate_;

  DISALLOW_COPY_AND_ASSIGN(HomeCardLayoutManager);
};

class HomeCardGestureManager {
 public:
  class Delegate {
   public:
    // Called when the gesture has ended. The state of the home card will
    // end up with |final_state|.
    virtual void OnGestureEnded(HomeCard::State final_state) = 0;

    // Called when the gesture position is updated so that |delegate| should
    // update the visual. The arguments represent the state of the current
    // gesture position is switching from |from_state| to |to_state|, and
    // the level of the progress is at |progress|, which is 0 to 1.
    // |from_state| and |to_state| could be same. For example, if the user moves
    // the finger down to the bottom of the screen, both states are MINIMIZED.
    // In that case |progress| is 0.
    virtual void OnGestureProgressed(
        HomeCard::State from_state,
        HomeCard::State to_state,
        float progress) = 0;
  };

  HomeCardGestureManager(Delegate* delegate,
                         const gfx::Rect& screen_bounds)
      : delegate_(delegate),
        last_state_(HomeCard::Get()->GetState()),
        y_offset_(0),
        last_estimated_top_(0),
        screen_bounds_(screen_bounds) {}

  void ProcessGestureEvent(ui::GestureEvent* event) {
    switch (event->type()) {
      case ui::ET_GESTURE_SCROLL_BEGIN:
        y_offset_ = event->location().y();
        event->SetHandled();
        break;
      case ui::ET_GESTURE_SCROLL_END:
        event->SetHandled();
        delegate_->OnGestureEnded(GetClosestState());
        break;
      case ui::ET_GESTURE_SCROLL_UPDATE:
        UpdateScrollState(*event);
        break;
      case ui::ET_SCROLL_FLING_START: {
        const ui::GestureEventDetails& details = event->details();
        const float kFlingCompletionVelocity = 100.0f;
        if (::fabs(details.velocity_y()) > kFlingCompletionVelocity) {
          int step = (details.velocity_y() > 0) ? 1 : -1;
          int new_state = static_cast<int>(last_state_) + step;
          if (new_state >= HomeCard::VISIBLE_CENTERED &&
              new_state <= HomeCard::VISIBLE_MINIMIZED) {
            last_state_ = static_cast<HomeCard::State>(new_state);
          }
          delegate_->OnGestureEnded(last_state_);
        }
        break;
      }
      default:
        // do nothing.
        break;
    }
  }

 private:
  HomeCard::State GetClosestState() {
    // The top position of the bounds for one smaller state than the current
    // one.
    int smaller_top = -1;
    for (int i = HomeCard::VISIBLE_MINIMIZED;
         i >= HomeCard::VISIBLE_CENTERED; --i) {
      HomeCard::State state = static_cast<HomeCard::State>(i);
      int top = GetBoundsForState(screen_bounds_, state).y();
      if (last_estimated_top_ == top) {
        return state;
      } else if (last_estimated_top_ > top) {
        if (smaller_top < 0)
          return state;

        if (smaller_top - last_estimated_top_ > (smaller_top - top) / 5) {
          return state;
        } else {
          return static_cast<HomeCard::State>(i + 1);
        }
      }
      smaller_top = top;
    }

    NOTREACHED();
    return last_state_;
  }

  void UpdateScrollState(const ui::GestureEvent& event) {
    last_estimated_top_ = event.root_location().y() - y_offset_;

    // The bounds which is at one smaller state than the current one.
    gfx::Rect smaller_bounds;

    for (int i = HomeCard::VISIBLE_MINIMIZED;
         i >= HomeCard::VISIBLE_CENTERED; --i) {
      HomeCard::State state = static_cast<HomeCard::State>(i);
      const gfx::Rect bounds = GetBoundsForState(screen_bounds_, state);
      if (last_estimated_top_ == bounds.y()) {
        delegate_->OnGestureProgressed(last_state_, state, 1.0f);
        last_state_ = state;
        return;
      } else if (last_estimated_top_ > bounds.y()) {
        if (smaller_bounds.IsEmpty()) {
          // Smaller than minimized -- returning the minimized bounds.
          delegate_->OnGestureProgressed(last_state_, state, 1.0f);
        } else {
          // The finger is between two states.
          float progress =
              static_cast<float>((smaller_bounds.y() - last_estimated_top_)) /
              (smaller_bounds.y() - bounds.y());
          if (last_state_ == state) {
            if (event.details().scroll_y() > 0) {
              state = static_cast<HomeCard::State>(state + 1);
              progress = 1.0f - progress;
            } else {
              last_state_ = static_cast<HomeCard::State>(last_state_ + 1);
            }
          }
          delegate_->OnGestureProgressed(last_state_, state, progress);
        }
        last_state_ = state;
        return;
      }
      smaller_bounds = bounds;
    }
    NOTREACHED();
  }

  Delegate* delegate_;
  HomeCard::State last_state_;

  // The offset from the top edge of the home card and the initial position of
  // gesture.
  int y_offset_;

  // The estimated top edge of the home card after the last touch event.
  int last_estimated_top_;

  // The bounds of the screen to compute the home card bounds.
  gfx::Rect screen_bounds_;

  DISALLOW_COPY_AND_ASSIGN(HomeCardGestureManager);
};

// The container view of home card contents of each state.
class HomeCardView : public views::WidgetDelegateView {
 public:
  HomeCardView(app_list::AppListViewDelegate* view_delegate,
               aura::Window* container,
               HomeCardGestureManager::Delegate* gesture_delegate)
      : gesture_delegate_(gesture_delegate),
        weak_factory_(this) {
    bottom_view_ = new AthenaStartPageView(view_delegate);
    AddChildView(bottom_view_);
    bottom_view_->SetPaintToLayer(true);
    bottom_view_->layer()->SetFillsBoundsOpaquely(false);

    main_view_ = new app_list::AppListMainView(
        view_delegate, 0 /* initial_apps_page */, container);
    AddChildView(main_view_);
    main_view_->set_background(
        views::Background::CreateSolidBackground(SK_ColorWHITE));
    main_view_->SetPaintToLayer(true);

    minimized_view_ = CreateMinimizedHome();
    minimized_view_->SetPaintToLayer(true);
    AddChildView(minimized_view_);
  }

  void SetStateProgress(HomeCard::State from_state,
                        HomeCard::State to_state,
                        float progress) {
    if (from_state == HomeCard::VISIBLE_BOTTOM &&
        to_state == HomeCard::VISIBLE_MINIMIZED) {
      SetStateProgress(to_state, from_state, 1.0 - progress);
      return;
    }

    // View from minimized to bottom.
    if (from_state == HomeCard::VISIBLE_MINIMIZED &&
        to_state == HomeCard::VISIBLE_BOTTOM) {
      bottom_view_->SetVisible(true);
      minimized_view_->SetVisible(true);
      minimized_view_->layer()->SetOpacity(1.0f - progress);
      return;
    }

    SetState(to_state);
  }

  void SetState(HomeCard::State state) {
    bottom_view_->SetVisible(state == HomeCard::VISIBLE_BOTTOM);
    main_view_->SetVisible(state == HomeCard::VISIBLE_CENTERED);
    minimized_view_->SetVisible(state == HomeCard::VISIBLE_MINIMIZED);
    if (minimized_view_->visible())
      minimized_view_->layer()->SetOpacity(1.0f);
    if (state == HomeCard::VISIBLE_CENTERED) {
      app_list::ContentsView* contents_view = main_view_->contents_view();
      contents_view->SetActivePage(contents_view->GetPageIndexForNamedPage(
          app_list::ContentsView::NAMED_PAGE_START));
    }
    wm::SetShadowType(GetWidget()->GetNativeView(),
                      state == HomeCard::VISIBLE_MINIMIZED ?
                      wm::SHADOW_TYPE_NONE :
                      wm::SHADOW_TYPE_RECTANGULAR);
  }

  void SetStateWithAnimation(HomeCard::State from_state,
                             HomeCard::State to_state) {
    if ((from_state == HomeCard::VISIBLE_MINIMIZED &&
         to_state == HomeCard::VISIBLE_BOTTOM) ||
        (from_state == HomeCard::VISIBLE_BOTTOM &&
         to_state == HomeCard::VISIBLE_MINIMIZED)) {
      minimized_view_->SetVisible(true);
      bottom_view_->SetVisible(true);
      {
        ui::ScopedLayerAnimationSettings settings(
            minimized_view_->layer()->GetAnimator());
        settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
        settings.AddObserver(new ui::ClosureAnimationObserver(
            base::Bind(&HomeCardView::SetState,
                       weak_factory_.GetWeakPtr(),
                       to_state)));
        minimized_view_->layer()->SetOpacity(
            (to_state == HomeCard::VISIBLE_MINIMIZED) ? 1.0f : 0.0f);
      }
    } else {
      // TODO(mukai): Take care of other transition.
      SetState(to_state);
    }
  }

  void ClearGesture() {
    gesture_manager_.reset();
  }

  // views::View:
  virtual void Layout() OVERRIDE {
    for (int i = 0; i < child_count(); ++i) {
      views::View* child = child_at(i);
      if (child->visible()) {
        if (child == minimized_view_) {
          gfx::Rect minimized_bounds = bounds();
          minimized_bounds.set_y(
              minimized_bounds.bottom() - kHomeCardMinimizedHeight);
          minimized_bounds.set_height(kHomeCardMinimizedHeight);
          child->SetBoundsRect(minimized_bounds);
        } else {
          child->SetBoundsRect(bounds());
        }
      }
    }
  }
  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
    if (!gesture_manager_ &&
        event->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
      gesture_manager_.reset(new HomeCardGestureManager(
          gesture_delegate_,
          GetWidget()->GetNativeWindow()->GetRootWindow()->bounds()));
    }

    if (gesture_manager_)
      gesture_manager_->ProcessGestureEvent(event);
  }

 private:
  // views::WidgetDelegate:
  virtual views::View* GetContentsView() OVERRIDE {
    return this;
  }

  app_list::AppListMainView* main_view_;
  views::View* bottom_view_;
  views::View* minimized_view_;
  scoped_ptr<HomeCardGestureManager> gesture_manager_;
  HomeCardGestureManager::Delegate* gesture_delegate_;
  base::WeakPtrFactory<HomeCardView> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(HomeCardView);
};

class HomeCardImpl : public HomeCard,
                     public AcceleratorHandler,
                     public HomeCardLayoutManager::Delegate,
                     public HomeCardGestureManager::Delegate,
                     public WindowManagerObserver,
                     public aura::client::ActivationChangeObserver {
 public:
  explicit HomeCardImpl(AppModelBuilder* model_builder);
  virtual ~HomeCardImpl();

  void Init();

 private:
  enum Command {
    COMMAND_SHOW_HOME_CARD,
  };
  void InstallAccelerators();

  // Overridden from HomeCard:
  virtual void SetState(State state) OVERRIDE;
  virtual State GetState() OVERRIDE;
  virtual void RegisterSearchProvider(
      app_list::SearchProvider* search_provider) OVERRIDE;
  virtual void UpdateVirtualKeyboardBounds(
      const gfx::Rect& bounds) OVERRIDE;

  // AcceleratorHandler:
  virtual bool IsCommandEnabled(int command_id) const OVERRIDE { return true; }
  virtual bool OnAcceleratorFired(int command_id,
                                  const ui::Accelerator& accelerator) OVERRIDE;

  // HomeCardLayoutManager::Delegate:
  virtual aura::Window* GetNativeWindow() OVERRIDE;

  // HomeCardGestureManager::Delegate:
  virtual void OnGestureEnded(State final_state) OVERRIDE;
  virtual void OnGestureProgressed(
      State from_state, State to_state, float progress) OVERRIDE;

  // WindowManagerObserver:
  virtual void OnOverviewModeEnter() OVERRIDE;
  virtual void OnOverviewModeExit() OVERRIDE;

  // aura::client::ActivationChangeObserver:
  virtual void OnWindowActivated(aura::Window* gained_active,
                                 aura::Window* lost_active) OVERRIDE;

  scoped_ptr<AppModelBuilder> model_builder_;

  HomeCard::State state_;

  // original_state_ is the state which the home card should go back to after
  // the virtual keyboard is hidden.
  HomeCard::State original_state_;

  views::Widget* home_card_widget_;
  HomeCardView* home_card_view_;
  scoped_ptr<AppListViewDelegate> view_delegate_;
  HomeCardLayoutManager* layout_manager_;
  aura::client::ActivationClient* activation_client_;  // Not owned

  // Right now HomeCard allows only one search provider.
  // TODO(mukai): port app-list's SearchController and Mixer.
  scoped_ptr<app_list::SearchProvider> search_provider_;

  DISALLOW_COPY_AND_ASSIGN(HomeCardImpl);
};

HomeCardImpl::HomeCardImpl(AppModelBuilder* model_builder)
    : model_builder_(model_builder),
      state_(HIDDEN),
      original_state_(VISIBLE_MINIMIZED),
      home_card_widget_(NULL),
      home_card_view_(NULL),
      layout_manager_(NULL),
      activation_client_(NULL) {
  DCHECK(!instance);
  instance = this;
  WindowManager::GetInstance()->AddObserver(this);
}

HomeCardImpl::~HomeCardImpl() {
  DCHECK(instance);
  WindowManager::GetInstance()->RemoveObserver(this);
  if (activation_client_)
    activation_client_->RemoveObserver(this);
  home_card_widget_->CloseNow();
  instance = NULL;
}

void HomeCardImpl::Init() {
  InstallAccelerators();
  ScreenManager::ContainerParams params("HomeCardContainer", CP_HOME_CARD);
  params.can_activate_children = true;
  aura::Window* container = ScreenManager::Get()->CreateContainer(params);
  layout_manager_ = new HomeCardLayoutManager(this);

  container->SetLayoutManager(layout_manager_);
  wm::SetChildWindowVisibilityChangesAnimated(container);

  view_delegate_.reset(new AppListViewDelegate(model_builder_.get()));
  if (search_provider_)
    view_delegate_->RegisterSearchProvider(search_provider_.get());

  home_card_view_ = new HomeCardView(view_delegate_.get(), container, this);
  home_card_widget_ = new views::Widget();
  views::Widget::InitParams widget_params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  widget_params.parent = container;
  widget_params.delegate = home_card_view_;
  widget_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  home_card_widget_->Init(widget_params);

  SetState(VISIBLE_MINIMIZED);
  home_card_view_->Layout();

  activation_client_ =
      aura::client::GetActivationClient(container->GetRootWindow());
  if (activation_client_)
    activation_client_->AddObserver(this);
}

void HomeCardImpl::InstallAccelerators() {
  const AcceleratorData accelerator_data[] = {
      {TRIGGER_ON_PRESS, ui::VKEY_L, ui::EF_CONTROL_DOWN,
       COMMAND_SHOW_HOME_CARD, AF_NONE},
  };
  AcceleratorManager::Get()->RegisterAccelerators(
      accelerator_data, arraysize(accelerator_data), this);
}

void HomeCardImpl::SetState(HomeCard::State state) {
  if (state_ == state)
    return;

  // Update |state_| before changing the visibility of the widgets, so that
  // LayoutManager callbacks get the correct state.
  HomeCard::State old_state = state_;
  state_ = state;
  original_state_ = state;
  if (state_ == HIDDEN) {
    home_card_widget_->Hide();
  } else {
    if (state_ == VISIBLE_CENTERED)
      home_card_widget_->Show();
    else
      home_card_widget_->ShowInactive();
    home_card_view_->SetStateWithAnimation(old_state, state);
    layout_manager_->Layout();
  }
}

HomeCard::State HomeCardImpl::GetState() {
  return state_;
}

void HomeCardImpl::RegisterSearchProvider(
    app_list::SearchProvider* search_provider) {
  DCHECK(!search_provider_);
  search_provider_.reset(search_provider);
  view_delegate_->RegisterSearchProvider(search_provider_.get());
}

void HomeCardImpl::UpdateVirtualKeyboardBounds(
    const gfx::Rect& bounds) {
  if (state_ == VISIBLE_MINIMIZED && !bounds.IsEmpty()) {
    SetState(HIDDEN);
    original_state_ = VISIBLE_MINIMIZED;
  } else if (state_ == VISIBLE_BOTTOM && !bounds.IsEmpty()) {
    SetState(VISIBLE_CENTERED);
    original_state_ = VISIBLE_BOTTOM;
  } else if (state_ != original_state_ && bounds.IsEmpty()) {
    SetState(original_state_);
  }
}

bool HomeCardImpl::OnAcceleratorFired(int command_id,
                                      const ui::Accelerator& accelerator) {
  DCHECK_EQ(COMMAND_SHOW_HOME_CARD, command_id);

  if (state_ == VISIBLE_CENTERED && original_state_ != VISIBLE_BOTTOM)
    SetState(VISIBLE_MINIMIZED);
  else if (state_ == VISIBLE_MINIMIZED)
    SetState(VISIBLE_CENTERED);
  return true;
}

aura::Window* HomeCardImpl::GetNativeWindow() {
  if (state_ == HIDDEN)
    return NULL;

  return home_card_widget_ ? home_card_widget_->GetNativeWindow() : NULL;
}

void HomeCardImpl::OnGestureEnded(State final_state) {
  home_card_view_->ClearGesture();
  if (state_ != final_state &&
      (state_ == VISIBLE_MINIMIZED || final_state == VISIBLE_MINIMIZED)) {
    WindowManager::GetInstance()->ToggleOverview();
  } else {
    HomeCard::State old_state = state_;
    state_ = final_state;
    home_card_view_->SetStateWithAnimation(old_state, final_state);
    layout_manager_->Layout();
  }
}

void HomeCardImpl::OnGestureProgressed(
    State from_state, State to_state, float progress) {
  home_card_view_->SetStateProgress(from_state, to_state, progress);

  gfx::Rect screen_bounds =
      home_card_widget_->GetNativeWindow()->GetRootWindow()->bounds();
  home_card_widget_->SetBounds(gfx::Tween::RectValueBetween(
      progress,
      GetBoundsForState(screen_bounds, from_state),
      GetBoundsForState(screen_bounds, to_state)));

  // TODO(mukai): signals the update to the window manager so that it shows the
  // intermediate visual state of overview mode.
}

void HomeCardImpl::OnOverviewModeEnter() {
  SetState(VISIBLE_BOTTOM);
}

void HomeCardImpl::OnOverviewModeExit() {
  SetState(VISIBLE_MINIMIZED);
}

void HomeCardImpl::OnWindowActivated(aura::Window* gained_active,
                                     aura::Window* lost_active) {
  if (state_ != HIDDEN &&
      gained_active != home_card_widget_->GetNativeWindow()) {
    SetState(VISIBLE_MINIMIZED);
  }
}

}  // namespace

// static
HomeCard* HomeCard::Create(AppModelBuilder* model_builder) {
  (new HomeCardImpl(model_builder))->Init();
  DCHECK(instance);
  return instance;
}

// static
void HomeCard::Shutdown() {
  DCHECK(instance);
  delete instance;
  instance = NULL;
}

// static
HomeCard* HomeCard::Get() {
  DCHECK(instance);
  return instance;
}

}  // namespace athena
