// 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 "ash/wm/default_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 {

// This specifies how much percent (30%) of a window rect
// must be visible when the window is added to the workspace.
const float kMinimumPercentOnScreenArea = 0.3f;

// When a window that has restore bounds at least as large as a work area is
// unmaximized, inset the bounds slightly so that they are not exactly the same.
// This makes it easier to resize the window.
const int kMaximizedWindowInset = 10;  // DIPs.

gfx::Size GetWindowMaximumSize(aura::Window* window) {
  return window->delegate() ? window->delegate()->GetMaximumSize()
                            : gfx::Size();
}

void MoveToDisplayForRestore(WindowState* window_state) {
  if (!window_state->HasRestoreBounds())
    return;
  const gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen();

  // Move only if the restore bounds is outside of
  // the display. There is no information about in which
  // display it should be restored, so this is best guess.
  // TODO(oshima): Restore information should contain the
  // work area information like WindowResizer does for the
  // last window location.
  gfx::Rect display_area = display::Screen::GetScreen()
                               ->GetDisplayNearestWindow(window_state->window())
                               .bounds();

  if (!display_area.Intersects(restore_bounds)) {
    const display::Display& display =
        display::Screen::GetScreen()->GetDisplayMatching(restore_bounds);
    RootWindowController* new_root_controller =
        Shell::Get()->GetRootWindowControllerWithDisplayId(display.id());
    if (new_root_controller->GetRootWindow() !=
        window_state->window()->GetRootWindow()) {
      aura::Window* new_container =
          new_root_controller->GetRootWindow()->GetChildById(
              window_state->window()->parent()->id());
      new_container->AddChild(window_state->window());
    }
  }
}

}  // namespace

DefaultState::DefaultState(mojom::WindowStateType initial_state_type)
    : BaseState(initial_state_type), stored_window_state_(nullptr) {}

DefaultState::~DefaultState() = default;

void DefaultState::AttachState(WindowState* window_state,
                               WindowState::State* state_in_previous_mode) {
  DCHECK_EQ(stored_window_state_, window_state);

  // If previous state is unminimized but window state is minimized, sync window
  // state to unminimized.
  if (window_state->IsMinimized() &&
      !IsMinimizedWindowStateType(state_in_previous_mode->GetType())) {
    aura::Window* window = window_state->window();
    window->SetProperty(
        aura::client::kShowStateKey,
        window->GetProperty(aura::client::kPreMinimizedShowStateKey));
  }

  ReenterToCurrentState(window_state, state_in_previous_mode);

  // If the display has changed while in the another mode,
  // we need to let windows know the change.
  display::Display current_display =
      display::Screen::GetScreen()->GetDisplayNearestWindow(
          window_state->window());
  if (stored_display_state_.bounds() != current_display.bounds()) {
    const WMEvent event(wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED);
    window_state->OnWMEvent(&event);
  } else if (stored_display_state_.work_area() != current_display.work_area()) {
    const WMEvent event(wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED);
    window_state->OnWMEvent(&event);
  }
}

void DefaultState::DetachState(WindowState* window_state) {
  stored_window_state_ = window_state;
  stored_bounds_ = window_state->window()->bounds();
  stored_restore_bounds_ = window_state->HasRestoreBounds()
                               ? window_state->GetRestoreBoundsInParent()
                               : gfx::Rect();
  // Remember the display state so that in case of the display change
  // while in the other mode, we can perform necessary action to
  // restore the window state to the proper state for the current
  // display.
  stored_display_state_ = display::Screen::GetScreen()->GetDisplayNearestWindow(
      window_state->window());
}

void DefaultState::HandleWorkspaceEvents(WindowState* window_state,
                                         const WMEvent* event) {
  switch (event->type()) {
    case WM_EVENT_ADDED_TO_WORKSPACE: {
      // When a window is dragged and dropped onto a different
      // root window, the bounds will be updated after they are added
      // to the root window.
      // If a window is opened as maximized or fullscreen, its bounds may be
      // empty, so update the bounds now before checking empty.
      if (window_state->is_dragged() ||
          window_state->allow_set_bounds_direct() ||
          SetMaximizedOrFullscreenBounds(window_state)) {
        return;
      }

      aura::Window* window = window_state->window();
      gfx::Rect bounds = window->bounds();
      // When window is added to a workspace, |bounds| may be not the original
      // not-changed-by-user bounds, for example a resized bounds truncated by
      // available workarea.
      if (window_state->pre_added_to_workspace_window_bounds())
        bounds = *window_state->pre_added_to_workspace_window_bounds();

      // Don't adjust window bounds if the bounds are empty as this
      // happens when a new views::Widget is created.
      if (bounds.IsEmpty())
        return;

      // Only windows of type WINDOW_TYPE_NORMAL or WINDOW_TYPE_PANEL need to be
      // adjusted to have minimum visibility, because they are positioned by the
      // user and user should always be able to interact with them. Other
      // windows are positioned programmatically.
      if (!window_state->IsUserPositionable())
        return;

      // Use entire display instead of workarea. The logic ensures 30%
      // visibility which should be enough to see where the window gets
      // moved.
      gfx::Rect display_area = screen_util::GetDisplayBoundsInParent(window);
      int min_width = bounds.width() * wm::kMinimumPercentOnScreenArea;
      int min_height = bounds.height() * wm::kMinimumPercentOnScreenArea;
      wm::AdjustBoundsToEnsureWindowVisibility(display_area, min_width,
                                               min_height, &bounds);
      window_state->AdjustSnappedBounds(&bounds);
      if (window->bounds() != bounds)
        window_state->SetBoundsConstrained(bounds);
      return;
    }
    case WM_EVENT_DISPLAY_BOUNDS_CHANGED: {
      if (window_state->is_dragged() ||
          window_state->allow_set_bounds_direct() ||
          SetMaximizedOrFullscreenBounds(window_state)) {
        return;
      }
      gfx::Rect work_area_in_parent =
          screen_util::GetDisplayWorkAreaBoundsInParent(window_state->window());
      gfx::Rect bounds = window_state->window()->GetTargetBounds();
      // When display bounds has changed, make sure the entire window is fully
      // visible.
      bounds.AdjustToFit(work_area_in_parent);
      window_state->AdjustSnappedBounds(&bounds);
      if (window_state->window()->GetTargetBounds() != bounds)
        window_state->SetBoundsDirectAnimated(bounds);
      return;
    }
    case WM_EVENT_WORKAREA_BOUNDS_CHANGED: {
      // Don't resize the maximized window when the desktop is covered
      // by fullscreen window. crbug.com/504299.
      bool in_fullscreen =
          RootWindowController::ForWindow(window_state->window())
              ->GetWorkspaceWindowState() == WORKSPACE_WINDOW_STATE_FULL_SCREEN;
      if (in_fullscreen && window_state->IsMaximized())
        return;

      if (window_state->is_dragged() ||
          window_state->allow_set_bounds_direct() ||
          SetMaximizedOrFullscreenBounds(window_state)) {
        return;
      }
      gfx::Rect work_area_in_parent =
          screen_util::GetDisplayWorkAreaBoundsInParent(window_state->window());
      gfx::Rect bounds = window_state->window()->GetTargetBounds();
      if (!::wm::GetTransientParent(window_state->window())) {
        wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_in_parent,
                                                        &bounds);
      }
      window_state->AdjustSnappedBounds(&bounds);
      if (window_state->window()->GetTargetBounds() != bounds)
        window_state->SetBoundsDirectAnimated(bounds);
      return;
    }
    case WM_EVENT_SYSTEM_UI_AREA_CHANGED:
      break;
    default:
      NOTREACHED() << "Unknown event:" << event->type();
  }
}

void DefaultState::HandleCompoundEvents(WindowState* window_state,
                                        const WMEvent* event) {
  aura::Window* window = window_state->window();

  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();
      }
      return;
    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();
      }
      return;
    case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE: {
      gfx::Rect work_area =
          screen_util::GetDisplayWorkAreaBoundsInParent(window);

      // Maximize vertically if:
      // - The window does not have a max height defined.
      // - The window has the normal state type. Snapped windows are excluded
      //   because they are already maximized vertically and reverting to the
      //   restored bounds looks weird.
      if (GetWindowMaximumSize(window).height() != 0 ||
          !window_state->IsNormalStateType()) {
        return;
      }
      if (window_state->HasRestoreBounds() &&
          (window->bounds().height() == work_area.height() &&
           window->bounds().y() == work_area.y())) {
        window_state->SetAndClearRestoreBounds();
      } else {
        window_state->SaveCurrentBoundsForRestore();
        window->SetBounds(gfx::Rect(window->bounds().x(), work_area.y(),
                                    window->bounds().width(),
                                    work_area.height()));
      }
      return;
    }
    case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE: {
      // Maximize horizontally if:
      // - The window does not have a max width defined.
      // - The window is snapped or has the normal state type.
      if (GetWindowMaximumSize(window).width() != 0)
        return;
      if (!window_state->IsNormalOrSnapped())
        return;
      gfx::Rect work_area =
          screen_util::GetDisplayWorkAreaBoundsInParent(window);
      if (window_state->IsNormalStateType() &&
          window_state->HasRestoreBounds() &&
          (window->bounds().width() == work_area.width() &&
           window->bounds().x() == work_area.x())) {
        window_state->SetAndClearRestoreBounds();
      } else {
        gfx::Rect new_bounds(work_area.x(), window->bounds().y(),
                             work_area.width(), window->bounds().height());

        gfx::Rect restore_bounds = window->bounds();
        if (window_state->IsSnapped()) {
          window_state->SetRestoreBoundsInParent(new_bounds);
          window_state->Restore();

          // The restore logic prevents a window from being restored to bounds
          // which match the workspace bounds exactly so it is necessary to set
          // the bounds again below.
        }

        window_state->SetRestoreBoundsInParent(restore_bounds);
        window->SetBounds(new_bounds);
      }
      return;
    }
    case WM_EVENT_TOGGLE_FULLSCREEN:
      ToggleFullScreen(window_state, window_state->delegate());
      return;
    case WM_EVENT_CYCLE_SNAP_LEFT:
    case WM_EVENT_CYCLE_SNAP_RIGHT:
      CycleSnap(window_state, event->type());
      return;
    default:
      NOTREACHED() << "Unknown event:" << event->type();
      break;
  }
}

void DefaultState::HandleBoundsEvents(WindowState* window_state,
                                      const WMEvent* event) {
  switch (event->type()) {
    case WM_EVENT_SET_BOUNDS: {
      const SetBoundsEvent* set_bounds_event =
          static_cast<const SetBoundsEvent*>(event);
      SetBounds(window_state, set_bounds_event);
    } break;
    case WM_EVENT_CENTER:
      CenterWindow(window_state);
      break;
    default:
      NOTREACHED() << "Unknown event:" << event->type();
      break;
  }
}

void DefaultState::HandleTransitionEvents(WindowState* window_state,
                                          const WMEvent* event) {
  mojom::WindowStateType current_state_type = window_state->GetStateType();
  mojom::WindowStateType next_state_type = GetStateForTransitionEvent(event);
  if (event->IsPinEvent()) {
    // If there already is a pinned window, it is not allowed to set it
    // to this window.
    // TODO(hidehiko): If a system modal window is openening, the pinning
    // probably should fail.
    if (Shell::Get()->screen_pinning_controller()->IsPinned()) {
      LOG(ERROR) << "An PIN event will be failed since another window is "
                 << "already in pinned mode.";
      next_state_type = current_state_type;
    }
  }

  if (next_state_type == current_state_type && window_state->IsSnapped()) {
    gfx::Rect snapped_bounds = GetSnappedWindowBoundsInParent(
        window_state->window(), event->type() == WM_EVENT_SNAP_LEFT
                                    ? mojom::WindowStateType::LEFT_SNAPPED
                                    : mojom::WindowStateType::RIGHT_SNAPPED);
    window_state->SetBoundsDirectAnimated(snapped_bounds);
    return;
  }

  if (event->type() == WM_EVENT_SNAP_LEFT ||
      event->type() == WM_EVENT_SNAP_RIGHT) {
    window_state->set_bounds_changed_by_user(true);
  }

  EnterToNextState(window_state, next_state_type);
}

// static
bool DefaultState::SetMaximizedOrFullscreenBounds(WindowState* window_state) {
  DCHECK(!window_state->is_dragged());
  DCHECK(!window_state->allow_set_bounds_direct());
  if (window_state->IsMaximized()) {
    window_state->SetBoundsDirect(
        screen_util::GetMaximizedWindowBoundsInParent(window_state->window()));
    return true;
  }
  if (window_state->IsFullscreen()) {
    window_state->SetBoundsDirect(
        screen_util::GetDisplayBoundsInParent(window_state->window()));
    return true;
  }
  return false;
}

// static
void DefaultState::SetBounds(WindowState* window_state,
                             const SetBoundsEvent* event) {
  if (window_state->is_dragged() || window_state->allow_set_bounds_direct()) {
    // TODO(oshima|varkha): Is this still needed? crbug.com/485612.
    window_state->SetBoundsDirect(event->requested_bounds());
  } else if (!SetMaximizedOrFullscreenBounds(window_state)) {
    if (event->animate()) {
      window_state->SetBoundsDirectAnimated(event->requested_bounds(),
                                            event->duration());
    } else {
      window_state->SetBoundsConstrained(event->requested_bounds());
    }
  }
}

void DefaultState::EnterToNextState(WindowState* window_state,
                                    mojom::WindowStateType next_state_type) {
  // Do nothing if  we're already in the same state.
  if (state_type_ == next_state_type)
    return;

  mojom::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()) {
    if (!window_state->HasRestoreBounds() &&
        (previous_state_type == mojom::WindowStateType::DEFAULT ||
         previous_state_type == mojom::WindowStateType::NORMAL) &&
        !window_state->IsMinimized() && !window_state->IsNormalStateType()) {
      window_state->SaveCurrentBoundsForRestore();
    }

    // When restoring from a minimized state, we want to restore to the
    // previous bounds. However, we want to maintain the restore bounds.
    // (The restore bounds are set if a user maximized the window in one
    // axis by double clicking the window border for example).
    gfx::Rect restore_bounds_in_screen;
    if (previous_state_type == mojom::WindowStateType::MINIMIZED &&
        window_state->IsNormalStateType() && window_state->HasRestoreBounds() &&
        !window_state->unminimize_to_restore_bounds()) {
      restore_bounds_in_screen = window_state->GetRestoreBoundsInScreen();
      window_state->SaveCurrentBoundsForRestore();
    }

    if (window_state->IsMaximizedOrFullscreenOrPinned())
      MoveToDisplayForRestore(window_state);

    UpdateBoundsFromState(window_state, previous_state_type);
    UpdateMinimizedState(window_state, previous_state_type);

    // Normal state should have no restore bounds unless it's
    // unminimized.
    if (!restore_bounds_in_screen.IsEmpty())
      window_state->SetRestoreBoundsInScreen(restore_bounds_in_screen);
    else if (window_state->IsNormalStateType())
      window_state->ClearRestoreBounds();
  }
  window_state->NotifyPostStateTypeChange(previous_state_type);

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

  window_state->UpdatePipState();
}

void DefaultState::ReenterToCurrentState(
    WindowState* window_state,
    WindowState::State* state_in_previous_mode) {
  mojom::WindowStateType previous_state_type =
      state_in_previous_mode->GetType();

  // A state change should not move a window into or out of full screen or
  // pinned since these are "special mode" the user wanted to be in and
  // should be respected as such.
  if (previous_state_type == mojom::WindowStateType::FULLSCREEN ||
      previous_state_type == mojom::WindowStateType::PINNED ||
      previous_state_type == mojom::WindowStateType::TRUSTED_PINNED) {
    state_type_ = previous_state_type;
  } else if (state_type_ == mojom::WindowStateType::FULLSCREEN ||
             state_type_ == mojom::WindowStateType::PINNED ||
             state_type_ == mojom::WindowStateType::TRUSTED_PINNED) {
    state_type_ = previous_state_type;
  }

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

  if ((state_type_ == mojom::WindowStateType::NORMAL ||
       state_type_ == mojom::WindowStateType::DEFAULT) &&
      !stored_bounds_.IsEmpty()) {
    // Use the restore mechanism to set the bounds for
    // the window in normal state. This also covers unminimize case.
    window_state->SetRestoreBoundsInParent(stored_bounds_);
  }

  UpdateBoundsFromState(window_state, state_in_previous_mode->GetType());
  UpdateMinimizedState(window_state, state_in_previous_mode->GetType());

  // Then restore the restore bounds to their previous value.
  if (!stored_restore_bounds_.IsEmpty())
    window_state->SetRestoreBoundsInParent(stored_restore_bounds_);
  else
    window_state->ClearRestoreBounds();

  window_state->NotifyPostStateTypeChange(previous_state_type);
}

void DefaultState::UpdateBoundsFromState(
    WindowState* window_state,
    mojom::WindowStateType previous_state_type) {
  aura::Window* window = window_state->window();
  gfx::Rect bounds_in_parent;
  switch (state_type_) {
    case mojom::WindowStateType::LEFT_SNAPPED:
    case mojom::WindowStateType::RIGHT_SNAPPED:
      bounds_in_parent =
          GetSnappedWindowBoundsInParent(window_state->window(), state_type_);
      break;

    case mojom::WindowStateType::DEFAULT:
    case mojom::WindowStateType::NORMAL: {
      gfx::Rect work_area_in_parent =
          screen_util::GetDisplayWorkAreaBoundsInParent(window);
      if (window_state->HasRestoreBounds()) {
        bounds_in_parent = window_state->GetRestoreBoundsInParent();
        // Check if the |window|'s restored size is bigger than the working area
        // This may happen if a window was resized to maximized bounds or if the
        // display resolution changed while the window was maximized.
        if (previous_state_type == mojom::WindowStateType::MAXIMIZED &&
            bounds_in_parent.width() >= work_area_in_parent.width() &&
            bounds_in_parent.height() >= work_area_in_parent.height()) {
          bounds_in_parent = work_area_in_parent;
          bounds_in_parent.Inset(kMaximizedWindowInset, kMaximizedWindowInset,
                                 kMaximizedWindowInset, kMaximizedWindowInset);
        }
      } else {
        bounds_in_parent = window->bounds();
      }
      // Make sure that part of the window is always visible.
      if (!window_state->is_dragged()) {
        // Avoid doing this while the window is being dragged as its root
        // window hasn't been updated yet in the case of dragging to another
        // display. crbug.com/666836.
        wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_in_parent,
                                                        &bounds_in_parent);
      }
      break;
    }
    case mojom::WindowStateType::MAXIMIZED:
      bounds_in_parent = screen_util::GetMaximizedWindowBoundsInParent(window);
      break;

    case mojom::WindowStateType::FULLSCREEN:
    case mojom::WindowStateType::PINNED:
    case mojom::WindowStateType::TRUSTED_PINNED:
      bounds_in_parent = screen_util::GetDisplayBoundsInParent(window);
      break;

    case mojom::WindowStateType::MINIMIZED:
      break;
    case mojom::WindowStateType::INACTIVE:
    case mojom::WindowStateType::AUTO_POSITIONED:
    case mojom::WindowStateType::PIP:
      return;
  }

  if (!window_state->IsMinimized()) {
    if (IsMinimizedWindowStateType(previous_state_type) ||
        window_state->IsFullscreen() || window_state->IsPinned()) {
      window_state->SetBoundsDirect(bounds_in_parent);
    } else if (window_state->IsMaximized() ||
               IsMaximizedOrFullscreenOrPinnedWindowStateType(
                   previous_state_type)) {
      window_state->SetBoundsDirectCrossFade(bounds_in_parent);
    } else if (window_state->is_dragged()) {
      // SetBoundsDirectAnimated does not work when the window gets reparented.
      // TODO(oshima): Consider fixing it and reenable the animation.
      window_state->SetBoundsDirect(bounds_in_parent);
    } else {
      window_state->SetBoundsDirectAnimated(bounds_in_parent);
    }
  }
}

}  // namespace wm
}  // namespace ash
