// Copyright (c) 2012 The Chromium OS 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 "gestures/include/finger_metrics.h"

namespace gestures {

Vector2 Add(const Vector2& left, const Vector2& right) {
  return Vector2(left).Add(right);
}

Vector2 Sub(const Vector2& left, const Vector2& right) {
  return Vector2(left).Sub(right);
}

float Dot(const Vector2& left, const Vector2& right) {
  return left.x * right.x +  left.y * right.y;
}

MetricsProperties::MetricsProperties(PropRegistry* prop_reg)
    : two_finger_close_horizontal_distance_thresh(
          prop_reg,
          "Two Finger Horizontal Close Distance Thresh",
          50.0),
      two_finger_close_vertical_distance_thresh(
          prop_reg,
          "Two Finger Vertical Close Distance Thresh",
          45.0) {}

FingerMetrics::FingerMetrics()
    : tracking_id_(-1) {}

FingerMetrics::FingerMetrics(short tracking_id)
    : tracking_id_(tracking_id) {}

FingerMetrics::FingerMetrics(const FingerState& state,
                             stime_t timestamp)
    : tracking_id_(state.tracking_id),
      position_(state.position_x, state.position_y),
      origin_position_(state.position_x, state.position_y),
      origin_time_(timestamp) {}

void FingerMetrics::Update(const FingerState& state, stime_t timestamp,
                           bool gesture_start) {
  Vector2 new_position = Vector2(state.position_x, state.position_y);
  delta_ = Sub(new_position, position_);
  position_ = new_position;

  if (gesture_start) {
    start_position_ = position_;
    start_time_ = timestamp;
  }
}

bool Metrics::CloseEnoughToGesture(const Vector2& pos_a,
                                   const Vector2& pos_b) const {
  float horiz_axis_sq =
      properties_->two_finger_close_horizontal_distance_thresh.val_ *
      properties_->two_finger_close_horizontal_distance_thresh.val_;
  float vert_axis_sq =
      properties_->two_finger_close_vertical_distance_thresh.val_ *
      properties_->two_finger_close_vertical_distance_thresh.val_;
  Vector2 delta = Sub(pos_a, pos_b);
  // Equation of ellipse:
  //    ,.--+--..
  //  ,'   V|    `.   x^2   y^2
  // |      +------|  --- + --- < 1
  //  \        H  /   H^2   V^2
  //   `-..__,,.-'
  return vert_axis_sq * delta.x * delta.x + horiz_axis_sq * delta.y * delta.y
         < vert_axis_sq * horiz_axis_sq;
}

Metrics::Metrics(MetricsProperties* properties) : properties_(properties) {}

const FingerMetrics* Metrics::GetFinger(short tracking_id) const {
  auto iter = fingers_.find(FingerMetrics(tracking_id));
  if (iter != fingers_.end())
    return iter;
  else
    return NULL;
}

const FingerMetrics* Metrics::GetFinger(const FingerState& state) const {
  return GetFinger(state.tracking_id);
}

void Metrics::Update(const HardwareState& hwstate) {
  int previous_count = fingers_.size();
  int existing_count = 0;
  int new_count = 0;

  // create metrics for new fingers
  for (int i=0; i<hwstate.finger_cnt; ++i) {
    const FingerState& state = hwstate.fingers[i];
    auto iter = fingers_.find(FingerMetrics(state.tracking_id));
    if (iter == fingers_.end()) {
      fingers_.push_back(FingerMetrics(state,
                                       hwstate.timestamp));
      ++new_count;
    } else {
      ++existing_count;
    }
  }

  // remove metrics for lifted fingers
  if (existing_count != previous_count) {
    auto iter = fingers_.begin();
    while (iter != fingers_.end()) {
      if (!hwstate.GetFingerState(iter->tracking_id()))
        iter = fingers_.erase(iter);
      else
        ++iter;
    }
  }

  // when a new finger has been added or a finger has been removed
  // we consider this to be a new gesture starting
  bool gesture_start = (existing_count != previous_count) || new_count > 0;
  for (FingerMetrics& finger: fingers_) {
    const FingerState* fs = hwstate.GetFingerState(finger.tracking_id());
    if (!fs) {
      Err("Unexpected missing finger state!");
      continue;
    }
    finger.Update(*fs, hwstate.timestamp, gesture_start);
  }
}

void Metrics::Clear() {
  fingers_.clear();
}

}  // namespace gestures
