// 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 "ui/events/event_utils.h"

#include <Cocoa/Cocoa.h>

#import "base/mac/mac_util.h"
#import "base/mac/sdk_forward_declarations.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "ui/events/cocoa/cocoa_event_utils.h"
#include "ui/events/event_utils.h"
#import "ui/events/keycodes/keyboard_code_conversion_mac.h"
#include "ui/gfx/point.h"
#include "ui/gfx/vector2d.h"

namespace ui {

void UpdateDeviceList() {
  NOTIMPLEMENTED();
}

EventType EventTypeFromNative(const base::NativeEvent& native_event) {
  NSEventType type = [native_event type];
  switch (type) {
    case NSKeyDown:
      return ET_KEY_PRESSED;
    case NSKeyUp:
      return ET_KEY_RELEASED;
    case NSLeftMouseDown:
    case NSRightMouseDown:
    case NSOtherMouseDown:
      return ET_MOUSE_PRESSED;
    case NSLeftMouseUp:
    case NSRightMouseUp:
    case NSOtherMouseUp:
      return ET_MOUSE_RELEASED;
    case NSLeftMouseDragged:
    case NSRightMouseDragged:
    case NSOtherMouseDragged:
      return ET_MOUSE_DRAGGED;
    case NSMouseMoved:
      return ET_MOUSE_MOVED;
    case NSScrollWheel:
      return ET_MOUSEWHEEL;
    case NSMouseEntered:
      return ET_MOUSE_ENTERED;
    case NSMouseExited:
      return ET_MOUSE_EXITED;
    case NSEventTypeSwipe:
      return ET_SCROLL_FLING_START;
    case NSFlagsChanged:
    case NSAppKitDefined:
    case NSSystemDefined:
    case NSApplicationDefined:
    case NSPeriodic:
    case NSCursorUpdate:
    case NSTabletPoint:
    case NSTabletProximity:
    case NSEventTypeGesture:
    case NSEventTypeMagnify:
    case NSEventTypeRotate:
    case NSEventTypeBeginGesture:
    case NSEventTypeEndGesture:
      NOTIMPLEMENTED() << type;
      break;
    default:
      NOTIMPLEMENTED() << type;
      break;
  }
  return ET_UNKNOWN;
}

int EventFlagsFromNative(const base::NativeEvent& event) {
  NSUInteger modifiers = [event modifierFlags];
  return EventFlagsFromNSEventWithModifiers(event, modifiers);
}

base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) {
  NSTimeInterval since_system_startup = [native_event timestamp];
  // Truncate to extract seconds before doing floating point arithmetic.
  int64_t seconds = since_system_startup;
  since_system_startup -= seconds;
  int64_t microseconds = since_system_startup * 1000000;
  return base::TimeDelta::FromSeconds(seconds) +
      base::TimeDelta::FromMicroseconds(microseconds);
}

gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
  NSWindow* window = [native_event window];
  if (!window) {
    NOTIMPLEMENTED();  // Point will be in screen coordinates.
    return gfx::Point();
  }
  NSPoint location = [native_event locationInWindow];
  NSRect content_rect = [window contentRectForFrameRect:[window frame]];
  return gfx::Point(location.x, NSHeight(content_rect) - location.y);
}

gfx::Point EventSystemLocationFromNative(
    const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
  return gfx::Point();
}

int EventButtonFromNative(const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
  return 0;
}

int GetChangedMouseButtonFlagsFromNative(
    const base::NativeEvent& native_event) {
  NSEventType type = [native_event type];
  switch (type) {
    case NSLeftMouseDown:
    case NSLeftMouseUp:
    case NSLeftMouseDragged:
      return EF_LEFT_MOUSE_BUTTON;
    case NSRightMouseDown:
    case NSRightMouseUp:
    case NSRightMouseDragged:
      return EF_RIGHT_MOUSE_BUTTON;
    case NSOtherMouseDown:
    case NSOtherMouseUp:
    case NSOtherMouseDragged:
      return EF_MIDDLE_MOUSE_BUTTON;
  }
  return 0;
}

gfx::Vector2d GetMouseWheelOffset(const base::NativeEvent& event) {
  if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)] &&
      [event hasPreciseScrollingDeltas]) {
    // Handle continuous scrolling devices such as a Magic Mouse or a trackpad.
    // -scrollingDelta{X|Y} have float return types but they return values that
    // are already rounded to integers.
    // The values are the same as the values returned from calling
    // CGEventGetIntegerValueField(kCGScrollWheelEventPointDeltaAxis{1|2}).
    return gfx::Vector2d([event scrollingDeltaX], [event scrollingDeltaY]);
  } else {
    // Empirically, a value of 0.1 is typical for one mousewheel click. Positive
    // values when scrolling up or to the left. Scrolling quickly results in a
    // higher delta per click, up to about 15.0. (Quartz documentation suggests
    // +/-10).
    // Multiply by 1000 to vaguely approximate WHEEL_DELTA on Windows (120).
    const CGFloat kWheelDeltaMultiplier = 1000;
    return gfx::Vector2d(kWheelDeltaMultiplier * [event deltaX],
                         kWheelDeltaMultiplier * [event deltaY]);
  }
}

base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
  return [event copy];
}

void ReleaseCopiedNativeEvent(const base::NativeEvent& event) {
  [event release];
}

void IncrementTouchIdRefCount(const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
}

void ClearTouchIdIfReleased(const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
}

int GetTouchId(const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
  return 0;
}

float GetTouchRadiusX(const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
  return 0.f;
}

float GetTouchRadiusY(const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
  return 0.f;
}

float GetTouchAngle(const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
  return 0.f;
}

float GetTouchForce(const base::NativeEvent& native_event) {
  NOTIMPLEMENTED();
  return 0.f;
}

bool GetScrollOffsets(const base::NativeEvent& native_event,
                      float* x_offset,
                      float* y_offset,
                      float* x_offset_ordinal,
                      float* y_offset_ordinal,
                      int* finger_count) {
  NOTIMPLEMENTED();
  return false;
}

bool GetFlingData(const base::NativeEvent& native_event,
                  float* vx,
                  float* vy,
                  float* vx_ordinal,
                  float* vy_ordinal,
                  bool* is_cancel) {
  NOTIMPLEMENTED();
  return false;
}

KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) {
  return KeyboardCodeFromNSEvent(native_event);
}

const char* CodeFromNative(const base::NativeEvent& native_event) {
  return CodeFromNSEvent(native_event);
}

uint32 PlatformKeycodeFromNative(const base::NativeEvent& native_event) {
  return native_event.keyCode;
}

uint32 WindowsKeycodeFromNative(const base::NativeEvent& native_event) {
  return static_cast<uint32>(KeyboardCodeFromNSEvent(native_event));
}

uint16 TextFromNative(const base::NativeEvent& native_event) {
  NSString* text = @"";
  if ([native_event type] != NSFlagsChanged)
    text = [native_event characters];

  // These exceptions are based on WebInputEventFactoryMac.mm:
  uint32 windows_keycode = WindowsKeycodeFromNative(native_event);
  if (windows_keycode == '\r')
    text = @"\r";
  if ([text isEqualToString:@"\x7F"])
    text = @"\x8";
  if (windows_keycode == 9)
    text = @"\x9";

  uint16 return_value;
  [text getCharacters:&return_value];
  return return_value;
}

uint16 UnmodifiedTextFromNative(const base::NativeEvent& native_event) {
  NSString* text = @"";
  if ([native_event type] != NSFlagsChanged)
    text = [native_event charactersIgnoringModifiers];

  // These exceptions are based on WebInputEventFactoryMac.mm:
  uint32 windows_keycode = WindowsKeycodeFromNative(native_event);
  if (windows_keycode == '\r')
    text = @"\r";
  if ([text isEqualToString:@"\x7F"])
    text = @"\x8";
  if (windows_keycode == 9)
    text = @"\x9";

  uint16 return_value;
  [text getCharacters:&return_value];
  return return_value;
}

bool IsCharFromNative(const base::NativeEvent& native_event) {
  return false;
}

}  // namespace ui
