// 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/touch/touch_transformer_controller.h"

#include "ash/display/display_controller.h"
#include "ash/display/display_manager.h"
#include "ash/host/ash_window_tree_host.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ui/aura/window_tree_host.h"
#include "ui/display/chromeos/display_configurator.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/events/devices/device_data_manager.h"

namespace ash {

namespace {

DisplayManager* GetDisplayManager() {
  return Shell::GetInstance()->display_manager();
}

ui::TouchscreenDevice FindTouchscreenById(unsigned int id) {
  const std::vector<ui::TouchscreenDevice>& touchscreens =
      ui::DeviceDataManager::GetInstance()->touchscreen_devices();
  for (const auto& touchscreen : touchscreens) {
    if (touchscreen.id == id)
      return touchscreen;
  }

  return ui::TouchscreenDevice();
}

}  // namespace

// This is to compute the scale ratio for the TouchEvent's radius. The
// configured resolution of the display is not always the same as the touch
// screen's reporting resolution, e.g. the display could be set as
// 1920x1080 while the touchscreen is reporting touch position range at
// 32767x32767. Touch radius is reported in the units the same as touch position
// so we need to scale the touch radius to be compatible with the display's
// resolution. We compute the scale as
// sqrt of (display_area / touchscreen_area)
double TouchTransformerController::GetTouchResolutionScale(
    const DisplayInfo& touch_display,
    const ui::TouchscreenDevice& touch_device) const {
  if (touch_device.id == ui::InputDevice::kInvalidId ||
      touch_device.size.IsEmpty() ||
      touch_display.bounds_in_native().size().IsEmpty())
    return 1.0;

  double display_area = touch_display.bounds_in_native().size().GetArea();
  double touch_area = touch_device.size.GetArea();
  double ratio = std::sqrt(display_area / touch_area);

  VLOG(2) << "Display size: "
          << touch_display.bounds_in_native().size().ToString()
          << ", Touchscreen size: " << touch_device.size.ToString()
          << ", Touch radius scale ratio: " << ratio;
  return ratio;
}

gfx::Transform TouchTransformerController::GetTouchTransform(
    const DisplayInfo& display,
    const DisplayInfo& touch_display,
    const ui::TouchscreenDevice& touchscreen,
    const gfx::Size& framebuffer_size) const {
  gfx::SizeF current_size = display.bounds_in_native().size();
  gfx::SizeF touch_native_size = touch_display.GetNativeModeSize();
#if defined(USE_OZONE)
  gfx::SizeF touch_area = touchscreen.size;
#elif defined(USE_X11)
  // On X11 touches are reported in the framebuffer coordinate space.
  gfx::SizeF touch_area = framebuffer_size;
#endif

  gfx::Transform ctm;

  if (current_size.IsEmpty() || touch_native_size.IsEmpty() ||
      touch_area.IsEmpty() || touchscreen.id == ui::InputDevice::kInvalidId)
    return ctm;

#if defined(USE_OZONE)
  // Translate the touch so that it falls within the display bounds.
  ctm.Translate(display.bounds_in_native().x(),
                display.bounds_in_native().y());
#endif

  // Take care of panel fitting only if supported. Panel fitting is emulated in
  // software mirroring mode (display != touch_display).
  // If panel fitting is enabled then the aspect ratio is preserved and the
  // display is scaled acordingly. In this case blank regions would be present
  // in order to center the displayed area.
  if (display.is_aspect_preserving_scaling() ||
      display.id() != touch_display.id()) {
    float touch_native_ar =
        touch_native_size.width() / touch_native_size.height();
    float current_ar = current_size.width() / current_size.height();

    if (current_ar > touch_native_ar) {  // Letterboxing
      ctm.Translate(
          0, (1 - current_ar / touch_native_ar) * 0.5 * current_size.height());
      ctm.Scale(1, current_ar / touch_native_ar);
    } else if (touch_native_ar > current_ar) {  // Pillarboxing
      ctm.Translate(
          (1 - touch_native_ar / current_ar) * 0.5 * current_size.width(), 0);
      ctm.Scale(touch_native_ar / current_ar, 1);
    }
  }

  // Take care of scaling between touchscreen area and display resolution.
  ctm.Scale(current_size.width() / touch_area.width(),
            current_size.height() / touch_area.height());
  return ctm;
}

TouchTransformerController::TouchTransformerController() {
  Shell::GetInstance()->display_controller()->AddObserver(this);
}

TouchTransformerController::~TouchTransformerController() {
  Shell::GetInstance()->display_controller()->RemoveObserver(this);
}

void TouchTransformerController::UpdateTouchTransformer() const {
  ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
  device_manager->ClearTouchTransformerRecord();

  // Display IDs and DisplayInfo for mirror or extended mode.
  int64 display1_id = gfx::Display::kInvalidDisplayID;
  int64 display2_id = gfx::Display::kInvalidDisplayID;
  DisplayInfo display1;
  DisplayInfo display2;
  // Display ID and DisplayInfo for single display mode.
  int64 single_display_id = gfx::Display::kInvalidDisplayID;
  DisplayInfo single_display;

  DisplayController* display_controller =
      Shell::GetInstance()->display_controller();
  ui::MultipleDisplayState display_state =
      Shell::GetInstance()->display_configurator()->display_state();
  if (display_state == ui::MULTIPLE_DISPLAY_STATE_INVALID ||
      display_state == ui::MULTIPLE_DISPLAY_STATE_HEADLESS) {
    return;
  } else if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR ||
             display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
    DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair();
    display1_id = id_pair.first;
    display2_id = id_pair.second;
    DCHECK(display1_id != gfx::Display::kInvalidDisplayID &&
           display2_id != gfx::Display::kInvalidDisplayID);
    display1 = GetDisplayManager()->GetDisplayInfo(display1_id);
    display2 = GetDisplayManager()->GetDisplayInfo(display2_id);
    device_manager->UpdateTouchRadiusScale(
        display1.touch_device_id(),
        GetTouchResolutionScale(
            display1,
            FindTouchscreenById(display1.touch_device_id())));
    device_manager->UpdateTouchRadiusScale(
        display2.touch_device_id(),
        GetTouchResolutionScale(
            display2,
            FindTouchscreenById(display2.touch_device_id())));
  } else {
    single_display_id = GetDisplayManager()->first_display_id();
    DCHECK(single_display_id != gfx::Display::kInvalidDisplayID);
    single_display = GetDisplayManager()->GetDisplayInfo(single_display_id);
    device_manager->UpdateTouchRadiusScale(
        single_display.touch_device_id(),
        GetTouchResolutionScale(
            single_display,
            FindTouchscreenById(single_display.touch_device_id())));
  }

  gfx::Size fb_size =
      Shell::GetInstance()->display_configurator()->framebuffer_size();

  if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) {
    // In mirror mode, both displays share the same root window so
    // both display ids are associated with the root window.
    aura::Window* root = display_controller->GetPrimaryRootWindow();
    RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
        display1_id, display2_id);
    device_manager->UpdateTouchInfoForDisplay(
        display1_id, display1.touch_device_id(),
        GetTouchTransform(display1, display1,
                          FindTouchscreenById(display1.touch_device_id()),
                          fb_size));
    device_manager->UpdateTouchInfoForDisplay(
        display2_id, display2.touch_device_id(),
        GetTouchTransform(display2, display2,
                          FindTouchscreenById(display2.touch_device_id()),
                          fb_size));
    return;
  }

  if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
    // In extended but software mirroring mode, ther is only one X root window
    // that associates with both displays.
    if (GetDisplayManager()->software_mirroring_enabled())  {
      aura::Window* root = display_controller->GetPrimaryRootWindow();
      RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
          display1_id, display2_id);
      DisplayInfo source_display =
          gfx::Display::InternalDisplayId() == display1_id ?
          display1 : display2;
      // Mapping from framebuffer size to the source display's native
      // resolution.
      device_manager->UpdateTouchInfoForDisplay(
          display1_id, display1.touch_device_id(),
          GetTouchTransform(source_display, display1,
                            FindTouchscreenById(display1.touch_device_id()),
                            fb_size));
      device_manager->UpdateTouchInfoForDisplay(
          display2_id, display2.touch_device_id(),
          GetTouchTransform(source_display, display2,
                            FindTouchscreenById(display2.touch_device_id()),
                            fb_size));
    } else {
      // In actual extended mode, each display is associated with one root
      // window.
      aura::Window* root1 =
          display_controller->GetRootWindowForDisplayId(display1_id);
      aura::Window* root2 =
          display_controller->GetRootWindowForDisplayId(display2_id);
      RootWindowController::ForWindow(root1)->ash_host()->UpdateDisplayID(
          display1_id, gfx::Display::kInvalidDisplayID);
      RootWindowController::ForWindow(root2)->ash_host()->UpdateDisplayID(
          display2_id, gfx::Display::kInvalidDisplayID);
      // Mapping from framebuffer size to each display's native resolution.
      device_manager->UpdateTouchInfoForDisplay(
          display1_id, display1.touch_device_id(),
          GetTouchTransform(display1, display1,
                            FindTouchscreenById(display1.touch_device_id()),
                            fb_size));
      device_manager->UpdateTouchInfoForDisplay(
          display2_id, display2.touch_device_id(),
          GetTouchTransform(display2, display2,
                            FindTouchscreenById(display2.touch_device_id()),
                            fb_size));
    }
    return;
  }

  // Single display mode. The root window has one associated display id.
  aura::Window* root =
      display_controller->GetRootWindowForDisplayId(single_display.id());
  RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
      single_display.id(), gfx::Display::kInvalidDisplayID);
  device_manager->UpdateTouchInfoForDisplay(
      single_display_id, single_display.touch_device_id(),
      GetTouchTransform(single_display, single_display,
                        FindTouchscreenById(single_display.touch_device_id()),
                        fb_size));
}

void TouchTransformerController::OnDisplaysInitialized() {
  UpdateTouchTransformer();
}

void TouchTransformerController::OnDisplayConfigurationChanged() {
  UpdateTouchTransformer();
}

}  // namespace ash
