// Copyright 2017 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 "ash/wm/client_controlled_state.h"

#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_animation_types.h"
#include "ash/public/cpp/window_state_type.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/wm/screen_pinning_controller.h"
#include "ash/wm/window_parenting_utils.h"
#include "ash/wm/window_positioning_utils.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_state_delegate.h"
#include "ash/wm/window_state_util.h"
#include "ash/wm/wm_event.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/wm/core/window_util.h"

namespace ash {
namespace wm {

namespace {
// |kMinimumOnScreenArea + 1| is used to avoid adjusting loop.
constexpr int kClientControlledWindowMinimumOnScreenArea =
    kMinimumOnScreenArea + 1;
}  // namespace

// static
void ClientControlledState::AdjustBoundsForMinimumWindowVisibility(
    const gfx::Rect& display_bounds,
    gfx::Rect* bounds) {
  AdjustBoundsToEnsureWindowVisibility(
      display_bounds, kClientControlledWindowMinimumOnScreenArea,
      kClientControlledWindowMinimumOnScreenArea, bounds);
}

ClientControlledState::ClientControlledState(std::unique_ptr<Delegate> delegate)
    : BaseState(WindowStateType::kDefault), delegate_(std::move(delegate)) {}

ClientControlledState::~ClientControlledState() = default;

void ClientControlledState::HandleTransitionEvents(WindowState* window_state,
                                                   const WMEvent* event) {
  if (!delegate_)
    return;
  bool pin_transition = window_state->IsTrustedPinned() ||
                        window_state->IsPinned() || event->IsPinEvent();
  // Pinned State transition is handled on server side.
  if (pin_transition) {
    // Only one window can be pinned.
    if (event->IsPinEvent() &&
        Shell::Get()->screen_pinning_controller()->IsPinned()) {
      return;
    }
    WindowStateType next_state_type = GetStateForTransitionEvent(event);
    delegate_->HandleWindowStateRequest(window_state, next_state_type);
    WindowStateType old_state_type = state_type_;

    bool was_pinned = window_state->IsPinned();
    bool was_trusted_pinned = window_state->IsTrustedPinned();

    set_next_bounds_change_animation_type(kAnimationCrossFade);
    EnterNextState(window_state, next_state_type);

    VLOG(1) << "Processing Pinned Transtion: event=" << event->type()
            << ", state=" << old_state_type << "=>" << next_state_type
            << ", pinned=" << was_pinned << "=>" << window_state->IsPinned()
            << ", trusted pinned=" << was_trusted_pinned << "=>"
            << window_state->IsTrustedPinned();
    return;
  }

  switch (event->type()) {
    case WM_EVENT_NORMAL:
    case WM_EVENT_MAXIMIZE:
    case WM_EVENT_MINIMIZE:
    case WM_EVENT_FULLSCREEN: {
      // Reset window state
      window_state->UpdateWindowPropertiesFromStateType();
      WindowStateType next_state = GetStateForTransitionEvent(event);
      VLOG(1) << "Processing State Transtion: event=" << event->type()
              << ", state=" << state_type_ << ", next_state=" << next_state;
      // Then ask delegate to handle the window state change.
      delegate_->HandleWindowStateRequest(window_state, next_state);
      break;
    }
    case WM_EVENT_SNAP_LEFT:
    case WM_EVENT_SNAP_RIGHT: {
      if (window_state->CanSnap()) {
        // Get the desired window bounds for the snap state.
        gfx::Rect bounds = GetSnappedWindowBoundsInParent(
            window_state->window(), event->type() == WM_EVENT_SNAP_LEFT
                                        ? WindowStateType::kLeftSnapped
                                        : WindowStateType::kRightSnapped);
        window_state->set_bounds_changed_by_user(true);

        window_state->UpdateWindowPropertiesFromStateType();
        WindowStateType next_state = GetStateForTransitionEvent(event);
        VLOG(1) << "Processing State Transtion: event=" << event->type()
                << ", state=" << state_type_ << ", next_state=" << next_state;

        // Then ask delegate to set the desired bounds for the snap state.
        delegate_->HandleBoundsRequest(window_state, next_state, bounds,
                                       window_state->GetDisplay().id());
      }
      break;
    }
    case WM_EVENT_SHOW_INACTIVE:
      NOTREACHED();
      break;
    default:
      NOTREACHED() << "Unknown event :" << event->type();
  }
}

void ClientControlledState::AttachState(
    WindowState* window_state,
    WindowState::State* state_in_previous_mode) {}

void ClientControlledState::DetachState(WindowState* window_state) {}

void ClientControlledState::HandleWorkspaceEvents(WindowState* window_state,
                                                  const WMEvent* event) {
  // Client is responsible for adjusting bounds after workspace bounds change.
  if (window_state->IsSnapped()) {
    gfx::Rect bounds = GetSnappedWindowBoundsInParent(
        window_state->window(), window_state->GetStateType());
    // Then ask delegate to set the desired bounds for the snap state.
    delegate_->HandleBoundsRequest(window_state, window_state->GetStateType(),
                                   bounds, window_state->GetDisplay().id());
  } else if (event->type() == WM_EVENT_ADDED_TO_WORKSPACE) {
    aura::Window* window = window_state->window();
    gfx::Rect bounds = window->bounds();
    AdjustBoundsForMinimumWindowVisibility(window->GetRootWindow()->bounds(),
                                           &bounds);

    if (window->bounds() != bounds)
      window_state->SetBoundsConstrained(bounds);
  }
}

void ClientControlledState::HandleCompoundEvents(WindowState* window_state,
                                                 const WMEvent* event) {
  if (!delegate_)
    return;
  switch (event->type()) {
    case WM_EVENT_TOGGLE_MAXIMIZE_CAPTION:
      if (window_state->IsFullscreen()) {
        const wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
        window_state->OnWMEvent(&event);
      } else if (window_state->IsMaximized()) {
        window_state->Restore();
      } else if (window_state->IsNormalOrSnapped()) {
        if (window_state->CanMaximize())
          window_state->Maximize();
      }
      break;
    case WM_EVENT_TOGGLE_MAXIMIZE:
      if (window_state->IsFullscreen()) {
        const wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
        window_state->OnWMEvent(&event);
      } else if (window_state->IsMaximized()) {
        window_state->Restore();
      } else if (window_state->CanMaximize()) {
        window_state->Maximize();
      }
      break;
    case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
      // TODO(oshima): Implement this.
      break;
    case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
      // TODO(oshima): Implement this.
      break;
    case WM_EVENT_TOGGLE_FULLSCREEN:
      ToggleFullScreen(window_state, window_state->delegate());
      break;
    case WM_EVENT_CYCLE_SNAP_LEFT:
    case WM_EVENT_CYCLE_SNAP_RIGHT:
      CycleSnap(window_state, event->type());
      break;
    default:
      NOTREACHED() << "Invalid event :" << event->type();
      break;
  }
}

void ClientControlledState::HandleBoundsEvents(WindowState* window_state,
                                               const WMEvent* event) {
  if (!delegate_)
    return;
  switch (event->type()) {
    case WM_EVENT_SET_BOUNDS: {
      const auto* set_bounds_event = static_cast<const SetBoundsEvent*>(event);
      const gfx::Rect& bounds = set_bounds_event->requested_bounds();
      if (set_bounds_locally_) {
        switch (next_bounds_change_animation_type_) {
          case kAnimationNone:
            window_state->SetBoundsDirect(bounds);
            break;
          case kAnimationCrossFade:
            window_state->SetBoundsDirectCrossFade(bounds);
            break;
          case kAnimationAnimated:
            window_state->SetBoundsDirectAnimated(
                bounds, bounds_change_animation_duration_);
            break;
        }
        next_bounds_change_animation_type_ = kAnimationNone;
      } else if (!window_state->IsPinned()) {
        // TODO(oshima): Define behavior for pinned app.
        bounds_change_animation_duration_ = set_bounds_event->duration();
        int64_t display_id = set_bounds_event->display_id();
        auto* window = window_state->window();
        if (display_id == display::kInvalidDisplayId) {
          display_id = display::Screen::GetScreen()
                           ->GetDisplayNearestWindow(window)
                           .id();
        }
#if DCHECK_IS_ON()
        gfx::Rect bounds_in_display(bounds);
        // The coordinates of the WindowState's parent must be same as display
        // coordinates. The following code is only to verify this condition.
        const aura::Window* root = window->GetRootWindow();
        aura::Window::ConvertRectToTarget(window->parent(), root,
                                          &bounds_in_display);
        DCHECK_EQ(bounds_in_display.x(), bounds.x());
        DCHECK_EQ(bounds_in_display.y(), bounds.y());
#endif
        delegate_->HandleBoundsRequest(
            window_state, window_state->GetStateType(), bounds, display_id);
      }
      break;
    }
    case WM_EVENT_CENTER:
      CenterWindow(window_state);
      break;
    default:
      NOTREACHED() << "Unknown event:" << event->type();
  }
}

void ClientControlledState::OnWindowDestroying(WindowState* window_state) {
  delegate_.reset();
}

bool ClientControlledState::EnterNextState(WindowState* window_state,
                                           WindowStateType next_state_type) {
  // Do nothing if  we're already in the same state, or delegate has already
  // been deleted.
  if (state_type_ == next_state_type || !delegate_)
    return false;
  WindowStateType previous_state_type = state_type_;
  state_type_ = next_state_type;

  window_state->UpdateWindowPropertiesFromStateType();
  window_state->NotifyPreStateTypeChange(previous_state_type);

  // Don't update the window if the window is detached from parent.
  // This can happen during dragging.
  // TODO(oshima): This was added for DOCKED windows. Investigate if
  // we still need this.
  if (window_state->window()->parent())
    UpdateMinimizedState(window_state, previous_state_type);

  window_state->NotifyPostStateTypeChange(previous_state_type);

  if (next_state_type == WindowStateType::kPinned ||
      previous_state_type == WindowStateType::kPinned ||
      next_state_type == WindowStateType::kTrustedPinned ||
      previous_state_type == WindowStateType::kTrustedPinned) {
    Shell::Get()->screen_pinning_controller()->SetPinnedWindow(
        window_state->window());
  }

  return true;
}

}  // namespace wm
}  // namespace ash
