// Copyright 2017 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 "starboard/shared/win32/application_win32.h"

#include <windows.h>   // NOLINT(build/include_order)
#include <windowsx.h>  // NOLINT(build/include_order)

#include <cstdio>
#include <string>

#include "starboard/input.h"
#include "starboard/key.h"
#include "starboard/shared/starboard/application.h"
#include "starboard/shared/win32/dialog.h"
#include "starboard/shared/win32/error_utils.h"
#include "starboard/shared/win32/minidump.h"
#include "starboard/shared/win32/thread_private.h"
#include "starboard/shared/win32/wchar_utils.h"
#include "starboard/shared/win32/window_internal.h"
#include "starboard/system.h"

using starboard::shared::starboard::Application;
using starboard::shared::starboard::CommandLine;
using starboard::shared::win32::ApplicationWin32;
using starboard::shared::win32::CStringToWString;
using starboard::shared::win32::DebugLogWinError;

namespace {

static const int kSbMouseDeviceId = 1;

static const TCHAR kWindowClassName[] = L"window_class_name";
const char kMiniDumpFilePath[] = "mini_dump_file_path";

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM w_param, LPARAM l_param) {
  return ApplicationWin32::Get()->WindowProcess(hWnd, msg, w_param, l_param);
}

bool RegisterWindowClass() {
  WNDCLASSEX window_class;
  window_class.cbSize = sizeof(WNDCLASSEX);
  // https://msdn.microsoft.com/en-us/library/windows/desktop/ff729176(v=vs.85).aspx
  window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  window_class.lpfnWndProc = WndProc;
  window_class.cbClsExtra = 0;
  window_class.cbWndExtra = 0;
  window_class.hInstance = GetModuleHandle(nullptr);
  // TODO: Add YouTube icon.
  window_class.hIcon = LoadIcon(window_class.hInstance, IDI_APPLICATION);
  window_class.hIconSm = LoadIcon(window_class.hInstance, IDI_APPLICATION);
  window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
  window_class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  window_class.lpszMenuName = NULL;
  window_class.lpszClassName = kWindowClassName;

  if (!::RegisterClassEx(&window_class)) {
    SB_LOG(ERROR) << "Failed to register window";
    DebugLogWinError();
    return false;
  }
  return true;
}

// Create a Windows window.
HWND CreateWindowInstance(const SbWindowOptions& options) {
  DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_CLIPSIBLINGS |
                  WS_CLIPCHILDREN | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
  if (options.windowed) {
    dwStyle |= WS_MAXIMIZE;
  }
  const std::wstring wide_window_name = CStringToWString(options.name);
  const HWND window = CreateWindow(
      kWindowClassName, wide_window_name.c_str(), dwStyle, CW_USEDEFAULT,
      CW_USEDEFAULT, options.size.width, options.size.height, nullptr, nullptr,
      GetModuleHandle(nullptr), nullptr);
  SetForegroundWindow(window);
  if (window == nullptr) {
    SB_LOG(ERROR) << "Failed to create window.";
    DebugLogWinError();
  }

  return window;
}

void AttachMiniDumpHandler(const CommandLine& cmd_line) {
  std::string file_path;
  if (cmd_line.HasSwitch(kMiniDumpFilePath)) {
    // If there is a mini dump file path then use that.
    file_path = cmd_line.GetSwitchValue(kMiniDumpFilePath);
  } else {
    // Otherwise use the file path and append ".dmp" to it.
    const auto& args = cmd_line.argv();
    if (!args.empty()) {
      file_path = args[0];
      file_path.append(".dmp");
    }
  }

  if (!file_path.empty()) {
    starboard::shared::win32::InitMiniDumpHandler(file_path.c_str());
  }
}

}  // namespace

namespace starboard {
namespace shared {
namespace win32 {

#if SB_MODULAR_BUILD
ApplicationWin32::ApplicationWin32(
    SbEventHandleCallback sb_event_handle_callback)
    : localized_strings_(SbSystemGetLocaleId()),
      QueueApplication(sb_event_handle_callback) {}
#else
ApplicationWin32::ApplicationWin32()
    : localized_strings_(SbSystemGetLocaleId()) {}
#endif  // SB_MODULAR_BUILD
ApplicationWin32::~ApplicationWin32() {}

SbWindow ApplicationWin32::CreateWindowForWin32(
    const SbWindowOptions* options) {
  if (SbWindowIsValid(window_.get())) {
    SB_LOG(WARNING) << "Returning existing window instance.";
    return window_.get();
  }

  RegisterWindowClass();
  HWND window;
  if (options) {
    window = CreateWindowInstance(*options);
    window_.reset(new SbWindowPrivate(options, window));
  } else {
    SbWindowOptions default_options;
    SbWindowSetDefaultOptions(&default_options);
    window = CreateWindowInstance(default_options);
    window_.reset(new SbWindowPrivate(&default_options, window));
  }
  ShowWindow(window, SW_SHOW);
  UpdateWindow(window);
  return window_.get();
}

bool ApplicationWin32::DestroyWindow(SbWindow window) {
  if (!SbWindowIsValid(window) || window != window_.get()) {
    return false;
  }

  HWND window_handle = window_->GetWindowHandle();
  window_.reset();

  if (!::DestroyWindow(window_handle)) {
    SB_LOG(WARNING) << "Unable to destroy window";
  }

  if (!::UnregisterClass(kWindowClassName, NULL)) {
    SB_LOG(ERROR) << "Failed to unregister window class.";
    DebugLogWinError();
  }

  return true;
}

bool ApplicationWin32::OnSbSystemRaisePlatformError(
    SbSystemPlatformErrorType type,
    SbSystemPlatformErrorCallback callback,
    void* user_data) {
  // This was never being deleted, but it should be.
  if (type != kSbSystemPlatformErrorTypeConnectionError)
    SB_NOTREACHED();

  ApplicationWin32* app = ApplicationWin32::Get();
  const bool created_dialog = ShowOkCancelDialog(
      app->GetCoreWindow()->GetWindowHandle(),
      "",  // No title.
      app->GetLocalizedString("UNABLE_TO_CONTACT_YOUTUBE_1",
                              "Sorry, could not connect to YouTube."),
      app->GetLocalizedString("RETRY_BUTTON", "Retry"),
      [this, callback, user_data]() {
        callback(kSbSystemPlatformErrorResponsePositive, user_data);
      },
      app->GetLocalizedString("EXIT_BUTTON", "Exit"),
      [this, callback, user_data]() {
        callback(kSbSystemPlatformErrorResponseNegative, user_data);
      });
  SB_DCHECK(!created_dialog);
  if (!created_dialog) {
    SB_LOG(ERROR) << "Failed to create dialog!";
  }
  return true;
}

Application::Event* ApplicationWin32::WaitForSystemEventWithTimeout(
    SbTime time) {
  ProcessNextSystemMessage();
  if (pending_event_) {
    Event* out = pending_event_;
    pending_event_ = nullptr;
    return out;
  }

  ScopedLock lock(stop_waiting_for_system_events_mutex_);
  if (time <= SbTimeGetMonotonicNow() || stop_waiting_for_system_events_) {
    stop_waiting_for_system_events_ = false;
    return nullptr;
  }

  return WaitForSystemEventWithTimeout(time);
}

LRESULT ApplicationWin32::WindowProcess(HWND hWnd,
                                        UINT msg,
                                        WPARAM w_param,
                                        LPARAM l_param) {
  switch (msg) {
    // Input message handling.
    case WM_MBUTTONDOWN:
    case WM_LBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_MBUTTONUP:
    case WM_LBUTTONUP:
    case WM_RBUTTONUP:
    case WM_MOUSEMOVE:
    case WM_MOUSEWHEEL:
      pending_event_ =
          ProcessWinMouseEvent(GetCoreWindow(), msg, w_param, l_param);
      break;
    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
    case WM_KEYUP:
    case WM_SYSKEYUP:
      pending_event_ =
          ProcessWinKeyEvent(GetCoreWindow(), msg, w_param, l_param);
      break;
    case WM_DESTROY:
      if (window_.get()) {
        // Freeze the application first so we can do some cleanup before the
        // window is destroyed (e.g. stopping rasterization).
        InjectAndProcess(kSbEventTypeFreeze, /* checkSystemEvents */ false);
        PostQuitMessage(0);
      }
      break;
    default:
      return DefWindowProcW(hWnd, msg, w_param, l_param);
  }
  return 0;
}

int ApplicationWin32::Run(int argc, char** argv) {
  CommandLine cmd_line(argc, argv);
  AttachMiniDumpHandler(cmd_line);
  int return_val = Application::Run(argc, argv);
  return return_val;
}

void ApplicationWin32::ProcessNextSystemMessage() {
  MSG msg;
  BOOL peek_message_return = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
  if (peek_message_return == 0) {  // 0 indicates no messages available.
    return;
  }

  if (!DialogHandleMessage(&msg)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  if (msg.message == WM_QUIT) {
    SB_LOG(INFO) << "Received Quit message; stopping application";
    SbSystemRequestStop(msg.wParam);
  }
}

Application::Event* ApplicationWin32::ProcessWinMouseEvent(SbWindow window,
                                                           UINT msg,
                                                           WPARAM w_param,
                                                           LPARAM l_param) {
  SbInputData* data = new SbInputData();
  memset(data, 0, sizeof(*data));

  data->window = window;
  data->device_type = kSbInputDeviceTypeMouse;
  data->device_id = kSbMouseDeviceId;
  switch (msg) {
    case WM_LBUTTONDOWN:
      data->key = kSbKeyMouse1;
      data->type = kSbInputEventTypePress;
      break;
    case WM_RBUTTONDOWN:
      data->key = kSbKeyMouse2;
      data->type = kSbInputEventTypePress;
      break;
    case WM_MBUTTONDOWN:
      data->key = kSbKeyMouse3;
      data->type = kSbInputEventTypePress;
      break;
    case WM_LBUTTONUP:
      data->key = kSbKeyMouse1;
      data->type = kSbInputEventTypeUnpress;
      break;
    case WM_RBUTTONUP:
      data->key = kSbKeyMouse2;
      data->type = kSbInputEventTypeUnpress;
      break;
    case WM_MBUTTONUP:
      data->key = kSbKeyMouse3;
      data->type = kSbInputEventTypeUnpress;
      break;
    case WM_MOUSEMOVE:
      data->type = kSbInputEventTypeMove;
      break;
    case WM_MOUSEWHEEL: {
      data->type = kSbInputEventTypeWheel;
      int wheel_delta = GET_WHEEL_DELTA_WPARAM(w_param);
      // Per MSFT, standard mouse wheel increments are multiples of 120. For
      // smooth scrolling, this may be less.
      // https://msdn.microsoft.com/en-us/library/windows/desktop/ms645617(v=vs.85).aspx
      data->delta.y = wheel_delta / 120.0f;
    } break;
    default:
      SB_LOG(WARNING) << "Received unrecognized MSG code " << msg;
      return nullptr;
  }

  data->pressure = NAN;
  data->size = {NAN, NAN};
  data->tilt = {NAN, NAN};
  data->position.x = GET_X_LPARAM(l_param);
  data->position.y = GET_Y_LPARAM(l_param);

  return new Application::Event(kSbEventTypeInput, data,
                                &Application::DeleteDestructor<SbInputData>);
}

}  // namespace win32
}  // namespace shared
}  // namespace starboard
