// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/system_window/system_window.h"

#include <algorithm>
#include <cmath>
#include <memory>

#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "cobalt/base/event_dispatcher.h"
#include "cobalt/system_window/input_event.h"
#include "starboard/double.h"
#include "starboard/system.h"

namespace cobalt {
namespace system_window {
namespace {

SystemWindow* g_the_window = NULL;

int Round(const float f) {
  double d(f + 0.5f);
  return static_cast<int>(SbDoubleFloor(d));
}

}  // namespace

SystemWindow::SystemWindow(base::EventDispatcher* event_dispatcher,
                           const base::Optional<math::Size>& window_size)
    : event_dispatcher_(event_dispatcher),
      window_(kSbWindowInvalid),
      key_down_(false) {
  if (!window_size) {
    window_ = SbWindowCreate(NULL);
  } else {
    SbWindowOptions options;
    SbWindowSetDefaultOptions(&options);
    options.size.width = window_size->width();
    options.size.height = window_size->height();
    window_ = SbWindowCreate(&options);
  }
  DCHECK(SbWindowIsValid(window_));
  DCHECK(!g_the_window) << "TODO: Support multiple SystemWindows.";
  g_the_window = this;
}

SystemWindow::~SystemWindow() {
  DCHECK_EQ(this, g_the_window);

  if (g_the_window == this) {
    g_the_window = NULL;
  }
  SbWindowDestroy(window_);
}

math::Size SystemWindow::GetWindowSize() const {
  SbWindowSize window_size;
  if (!SbWindowGetSize(window_, &window_size)) {
    DLOG(WARNING) << "SbWindowGetSize() failed.";
    return math::Size();
  }
  return math::Size(window_size.width, window_size.height);
}

float SystemWindow::GetDiagonalSizeInches() const {
#if SB_API_VERSION >= 11
  return SbWindowGetDiagonalSizeInInches(window_);
#else
  return 0.f;
#endif
}

float SystemWindow::GetDevicePixelRatio() const {
  SbWindowSize size;
  if (!SbWindowGetSize(window_, &size)) {
    DLOG(WARNING) << "SbWindowGetSize() failed.";
    return 1.0;
  }
  // A value of 0.0 for the video pixel ratio means that the ratio could not be
  // determined. In that case it should be assumed to be the same as the
  // graphics resolution, which corresponds to a device pixel ratio of 1.0.
  float device_pixel_ratio =
      (size.video_pixel_ratio == 0) ? 1.0f : size.video_pixel_ratio;
  return device_pixel_ratio;
}

math::Size SystemWindow::GetVideoOutputResolution() const {
  float ratio = GetDevicePixelRatio();
  math::Size size = GetWindowSize();
  return math::Size(Round(size.width() * ratio), Round(size.height() * ratio));
}

SbWindow SystemWindow::GetSbWindow() { return window_; }

void* SystemWindow::GetWindowHandle() {
  return SbWindowGetPlatformHandle(window_);
}

void SystemWindow::DispatchInputEvent(const SbInputData& data,
                                      InputEvent::Type type, bool is_repeat) {
  // Use the current time unless it was overridden.
  SbTimeMonotonic timestamp = 0;

  bool use_input_timestamp =
      SbSystemHasCapability(kSbSystemCapabilitySetsInputTimestamp);
  if (use_input_timestamp) {
    timestamp = data.timestamp;
  }

  if (timestamp == 0) {
    timestamp = SbTimeGetMonotonicNow();
  }

  // Starboard handily uses the Microsoft key mapping, which is also what Cobalt
  // uses.
  int key_code = static_cast<int>(data.key);
  float pressure = data.pressure;
  uint32 modifiers = data.key_modifiers;
  if (((data.device_type == kSbInputDeviceTypeTouchPad) ||
       (data.device_type == kSbInputDeviceTypeTouchScreen))) {
    switch (type) {
      case InputEvent::kPointerDown:
      case InputEvent::kPointerMove:
      case InputEvent::kTouchpadDown:
      case InputEvent::kTouchpadMove:
      case InputEvent::kTouchscreenDown:
      case InputEvent::kTouchscreenMove:
        // For touch contact input, ensure that the device button state is also
        // reported as pressed.
        //   https://www.w3.org/TR/2015/REC-pointerevents-20150224/#button-states
        key_code = kSbKeyMouse1;
        modifiers |= InputEvent::kLeftButton;
        if (!std::isnan(pressure)) {
          pressure = std::max(pressure, 0.5f);
        }
        break;
      case InputEvent::kKeyDown:
      case InputEvent::kKeyUp:
      case InputEvent::kKeyMove:
      case InputEvent::kInput:
      case InputEvent::kPointerUp:
      case InputEvent::kTouchpadUp:
      case InputEvent::kTouchscreenUp:
      case InputEvent::kWheel:
        break;
    }
  }

#if SB_API_VERSION >= 12 || SB_HAS(ON_SCREEN_KEYBOARD)
  std::unique_ptr<InputEvent> input_event(
      new InputEvent(timestamp, type, data.device_id, key_code, modifiers,
                     is_repeat, math::PointF(data.position.x, data.position.y),
                     math::PointF(data.delta.x, data.delta.y), pressure,
                     math::PointF(data.size.x, data.size.y),
                     math::PointF(data.tilt.x, data.tilt.y),
                     data.input_text ? data.input_text : "",
                     data.is_composing ? data.is_composing : false));
#else   // SB_API_VERSION >= 12 ||
  // SB_HAS(ON_SCREEN_KEYBOARD)
  std::unique_ptr<InputEvent> input_event(
      new InputEvent(timestamp, type, data.device_id, key_code, modifiers,
                     is_repeat, math::PointF(data.position.x, data.position.y),
                     math::PointF(data.delta.x, data.delta.y), pressure,
                     math::PointF(data.size.x, data.size.y),
                     math::PointF(data.tilt.x, data.tilt.y)));
#endif  // SB_API_VERSION >= 12 ||
        // SB_HAS(ON_SCREEN_KEYBOARD)
  event_dispatcher()->DispatchEvent(
      std::unique_ptr<base::Event>(input_event.release()));
}

void SystemWindow::HandlePointerInputEvent(const SbInputData& data) {
  InputEvent::Type input_event_type;
  switch (data.type) {
    case kSbInputEventTypePress: {
      if (data.device_type == kSbInputDeviceTypeTouchPad) {
        input_event_type = InputEvent::kTouchpadDown;
      } else if (data.device_type == kSbInputDeviceTypeTouchScreen) {
        input_event_type = InputEvent::kTouchscreenDown;
      } else {
        input_event_type = InputEvent::kPointerDown;
      }
      DispatchInputEvent(data, input_event_type, false /* is_repeat */);
      break;
    }
    case kSbInputEventTypeUnpress: {
      if (data.device_type == kSbInputDeviceTypeTouchPad) {
        input_event_type = InputEvent::kTouchpadUp;
      } else if (data.device_type == kSbInputDeviceTypeTouchScreen) {
        input_event_type = InputEvent::kTouchscreenUp;
      } else {
        input_event_type = InputEvent::kPointerUp;
      }
      DispatchInputEvent(data, input_event_type, false /* is_repeat */);
      break;
    }
    case kSbInputEventTypeWheel: {
      DispatchInputEvent(data, InputEvent::kWheel, false /* is_repeat */);
      break;
    }
    case kSbInputEventTypeMove: {
      if (data.device_type == kSbInputDeviceTypeTouchPad) {
        input_event_type = InputEvent::kTouchpadMove;
      } else if (data.device_type == kSbInputDeviceTypeTouchScreen) {
        input_event_type = InputEvent::kTouchscreenMove;
      } else {
        input_event_type = InputEvent::kPointerMove;
      }
      DispatchInputEvent(data, input_event_type, false /* is_repeat */);
      break;
    }
    default:
      SB_NOTREACHED();
      break;
  }
}

void SystemWindow::HandleInputEvent(const SbInputData& data) {
  DCHECK_EQ(window_, data.window);
  // Handle supported pointer device types.
  if ((kSbInputDeviceTypeMouse == data.device_type) ||
      (kSbInputDeviceTypeTouchScreen == data.device_type) ||
      (kSbInputDeviceTypeTouchPad == data.device_type)) {
    HandlePointerInputEvent(data);
    return;
  }

  // Handle all other input device types.
  switch (data.type) {
    case kSbInputEventTypePress: {
      DispatchInputEvent(data, InputEvent::kKeyDown, key_down_);
      key_down_ = true;
      break;
    }
    case kSbInputEventTypeUnpress: {
      DispatchInputEvent(data, InputEvent::kKeyUp, false /* is_repeat */);
      key_down_ = false;
      break;
    }
    case kSbInputEventTypeMove: {
      DispatchInputEvent(data, InputEvent::kKeyMove, false /* is_repeat */);
      break;
    }
#if SB_API_VERSION >= 12 || SB_HAS(ON_SCREEN_KEYBOARD)
    case kSbInputEventTypeInput: {
      DispatchInputEvent(data, InputEvent::kInput, false /* is_repeat */);
      break;
    }
#endif  // SB_API_VERSION >= 12 ||
        // SB_HAS(ON_SCREEN_KEYBOARD)
    default:
      break;
  }
}

SystemWindow* SystemWindow::PrimaryWindow() { return g_the_window; }

void HandleInputEvent(const SbEvent* event) {
  if (event->type != kSbEventTypeInput) {
    return;
  }

  DCHECK(g_the_window);
  DCHECK(event->data);
  SbInputData* data = reinterpret_cast<SbInputData*>(event->data);
  g_the_window->HandleInputEvent(*data);
  return;
}

}  // namespace system_window
}  // namespace cobalt
