// 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/ozone/evdev/libgestures_glue/gesture_timer_provider.h"

#include <gestures/gestures.h>

#include "base/timer/timer.h"

// libgestures requires that this be in the top level namespace.
struct GesturesTimer {
 public:
  GesturesTimer() {}
  ~GesturesTimer() {}

  void Set(stime_t delay, GesturesTimerCallback callback, void* callback_data) {
    callback_ = callback;
    callback_data_ = callback_data;
    timer_.Start(FROM_HERE,
                 base::TimeDelta::FromMicroseconds(
                     delay * base::Time::kMicrosecondsPerSecond),
                 this,
                 &GesturesTimer::OnTimerExpired);
  }

  void Cancel() { timer_.Stop(); }

 private:
  void OnTimerExpired() {
    // Run the callback and reschedule the next run if requested.
    stime_t next_delay = callback_(ui::StimeNow(), callback_data_);
    if (next_delay >= 0) {
      timer_.Start(FROM_HERE,
                   base::TimeDelta::FromMicroseconds(
                       next_delay * base::Time::kMicrosecondsPerSecond),
                   this,
                   &GesturesTimer::OnTimerExpired);
    }
  }

  GesturesTimerCallback callback_ = nullptr;
  void* callback_data_ = nullptr;
  base::OneShotTimer timer_;
};

namespace ui {

namespace {

GesturesTimer* GesturesTimerCreate(void* data) { return new GesturesTimer; }

void GesturesTimerSet(void* data,
                      GesturesTimer* timer,
                      stime_t delay,
                      GesturesTimerCallback callback,
                      void* callback_data) {
  timer->Set(delay, callback, callback_data);
}

void GesturesTimerCancel(void* data, GesturesTimer* timer) { timer->Cancel(); }

void GesturesTimerFree(void* data, GesturesTimer* timer) { delete timer; }

}  // namespace

stime_t StimeNow() {
  struct timespec ts;

  if (clock_gettime(CLOCK_MONOTONIC, &ts))
    PLOG(FATAL) << "clock_gettime";

  return StimeFromTimespec(&ts);
}

const GesturesTimerProvider kGestureTimerProvider = {
    GesturesTimerCreate, GesturesTimerSet, GesturesTimerCancel,
    GesturesTimerFree};

}  // namespace ui
