// Copyright 2016 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 "ui/display/display_list.h"

#include "base/memory/ptr_util.h"
#include "ui/display/display_observer.h"

namespace display {

DisplayListObserverLock::~DisplayListObserverLock() {
  display_list_->DecrementObserverSuspendLockCount();
}

DisplayListObserverLock::DisplayListObserverLock(DisplayList* display_list)
    : display_list_(display_list) {
  display_list_->IncrementObserverSuspendLockCount();
}

DisplayList::DisplayList() {}

DisplayList::~DisplayList() {
  DCHECK_EQ(0, observer_suspend_lock_count_);
}

void DisplayList::AddObserver(DisplayObserver* observer) {
  observers_.AddObserver(observer);
}

void DisplayList::RemoveObserver(DisplayObserver* observer) {
  observers_.RemoveObserver(observer);
}

DisplayList::Displays::const_iterator DisplayList::FindDisplayById(
    int64_t id) const {
  for (auto iter = displays_.begin(); iter != displays_.end(); ++iter) {
    if (iter->id() == id)
      return iter;
  }
  return displays_.end();
}

DisplayList::Displays::const_iterator DisplayList::GetPrimaryDisplayIterator()
    const {
  return primary_display_index_ == -1
             ? displays_.end()
             : displays_.begin() + primary_display_index_;
}

std::unique_ptr<DisplayListObserverLock> DisplayList::SuspendObserverUpdates() {
  return base::WrapUnique(new DisplayListObserverLock(this));
}

void DisplayList::AddOrUpdateDisplay(const Display& display, Type type) {
  if (FindDisplayById(display.id()) == displays_.end())
    AddDisplay(display, type);
  else
    UpdateDisplay(display, type);
}

uint32_t DisplayList::UpdateDisplay(const Display& display) {
  return UpdateDisplay(display, GetTypeByDisplayId(display.id()));
}

uint32_t DisplayList::UpdateDisplay(const Display& display, Type type) {
  auto iter = FindDisplayByIdInternal(display.id());
  DCHECK(iter != displays_.end());

  Display* local_display = &(*iter);
  uint32_t changed_values = 0;
  if (type == Type::PRIMARY &&
      static_cast<int>(iter - displays_.begin()) !=
          static_cast<int>(GetPrimaryDisplayIterator() - displays_.begin())) {
    primary_display_index_ = static_cast<int>(iter - displays_.begin());
    // ash::DisplayManager only notifies for the Display gaining primary, not
    // the one losing it.
    changed_values |= DisplayObserver::DISPLAY_METRIC_PRIMARY;
  }
  if (local_display->bounds() != display.bounds()) {
    local_display->set_bounds(display.bounds());
    changed_values |= DisplayObserver::DISPLAY_METRIC_BOUNDS;
  }
  if (local_display->work_area() != display.work_area()) {
    local_display->set_work_area(display.work_area());
    changed_values |= DisplayObserver::DISPLAY_METRIC_WORK_AREA;
  }
  if (local_display->rotation() != display.rotation()) {
    local_display->set_rotation(display.rotation());
    changed_values |= DisplayObserver::DISPLAY_METRIC_ROTATION;
  }
  if (local_display->device_scale_factor() != display.device_scale_factor()) {
    local_display->set_device_scale_factor(display.device_scale_factor());
    changed_values |= DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
  }
  if (local_display->color_space() != display.color_space()) {
    local_display->set_color_space(display.color_space());
    changed_values |= DisplayObserver::DISPLAY_METRIC_COLOR_SPACE;
  }
  if (should_notify_observers()) {
    for (DisplayObserver& observer : observers_)
      observer.OnDisplayMetricsChanged(*local_display, changed_values);
  }
  return changed_values;
}

void DisplayList::AddDisplay(const Display& display, Type type) {
  DCHECK(displays_.end() == FindDisplayByIdInternal(display.id()));
  displays_.push_back(display);
  if (type == Type::PRIMARY)
    primary_display_index_ = static_cast<int>(displays_.size()) - 1;
  if (should_notify_observers()) {
    for (DisplayObserver& observer : observers_)
      observer.OnDisplayAdded(display);
  }
}

void DisplayList::RemoveDisplay(int64_t id) {
  auto iter = FindDisplayByIdInternal(id);
  DCHECK(displays_.end() != iter);
  if (primary_display_index_ == static_cast<int>(iter - displays_.begin())) {
    // The primary display can only be removed if it is the last display.
    // Users must choose a new primary before removing an old primary display.
    DCHECK_EQ(1u, displays_.size());
    primary_display_index_ = -1;
  } else if (primary_display_index_ >
             static_cast<int>(iter - displays_.begin())) {
    primary_display_index_--;
  }
  const Display display = *iter;
  displays_.erase(iter);
  if (should_notify_observers()) {
    for (DisplayObserver& observer : observers_)
      observer.OnDisplayRemoved(display);
  }
}

void DisplayList::IncrementObserverSuspendLockCount() {
  observer_suspend_lock_count_++;
}

void DisplayList::DecrementObserverSuspendLockCount() {
  DCHECK_GT(observer_suspend_lock_count_, 0);
  observer_suspend_lock_count_--;
}

DisplayList::Type DisplayList::GetTypeByDisplayId(int64_t display_id) const {
  if (primary_display_index_ == -1)
    return Type::NOT_PRIMARY;
  return (displays_[primary_display_index_].id() == display_id
              ? Type::PRIMARY
              : Type::NOT_PRIMARY);
}

DisplayList::Displays::iterator DisplayList::FindDisplayByIdInternal(
    int64_t id) {
  for (auto iter = displays_.begin(); iter != displays_.end(); ++iter) {
    if (iter->id() == id)
      return iter;
  }
  return displays_.end();
}

}  // namespace display
