// Copyright (c) 2012 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 <vector>

#include "ui/events/event.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"

namespace ui {

namespace {
int g_custom_event_types = ET_LAST;
}  // namespace

scoped_ptr<Event> EventFromNative(const base::NativeEvent& native_event) {
  scoped_ptr<Event> event;
  EventType type = EventTypeFromNative(native_event);
  switch(type) {
    case ET_KEY_PRESSED:
    case ET_KEY_RELEASED:
      event.reset(new KeyEvent(native_event, false));
      break;

    case ET_TRANSLATED_KEY_PRESS:
    case ET_TRANSLATED_KEY_RELEASE:
      // These should not be generated by native events.
      NOTREACHED();
      break;

    case ET_MOUSE_PRESSED:
    case ET_MOUSE_DRAGGED:
    case ET_MOUSE_RELEASED:
    case ET_MOUSE_MOVED:
    case ET_MOUSE_ENTERED:
    case ET_MOUSE_EXITED:
      event.reset(new MouseEvent(native_event));
      break;

    case ET_MOUSEWHEEL:
      event.reset(new MouseWheelEvent(native_event));
      break;

    case ET_SCROLL_FLING_START:
    case ET_SCROLL_FLING_CANCEL:
    case ET_SCROLL:
      event.reset(new ScrollEvent(native_event));
      break;

    case ET_TOUCH_RELEASED:
    case ET_TOUCH_PRESSED:
    case ET_TOUCH_MOVED:
    case ET_TOUCH_CANCELLED:
      event.reset(new TouchEvent(native_event));
      break;

    default:
      break;
  }
  return event.Pass();
}

int RegisterCustomEventType() {
  return ++g_custom_event_types;
}

base::TimeDelta EventTimeForNow() {
  return base::TimeDelta::FromInternalValue(
      base::TimeTicks::Now().ToInternalValue());
}

bool ShouldDefaultToNaturalScroll() {
  return GetInternalDisplayTouchSupport() ==
      gfx::Display::TOUCH_SUPPORT_AVAILABLE;
}

gfx::Display::TouchSupport GetInternalDisplayTouchSupport() {
  gfx::Screen* screen = gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE);
  // No screen in some unit tests.
  if (!screen)
    return gfx::Display::TOUCH_SUPPORT_UNKNOWN;
  const std::vector<gfx::Display>& displays = screen->GetAllDisplays();
  for (std::vector<gfx::Display>::const_iterator it = displays.begin();
       it != displays.end(); ++it) {
    if (it->IsInternal())
      return it->touch_support();
  }
  return gfx::Display::TOUCH_SUPPORT_UNAVAILABLE;
}

}  // namespace ui
