// Copyright 2015 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 "remoting/client/touch_input_scaler.h"

#include "base/logging.h"
#include "remoting/proto/event.pb.h"

namespace remoting {

using protocol::TouchEvent;
using protocol::TouchEventPoint;

namespace {

// |value| is the number to be scaled. |output_max| is the output desktop's max
// height or width. |input_max| is the input desktop's max height or width.
float Scale(float value, int output_max, int input_max) {
  DCHECK_GT(output_max, 0);
  DCHECK_GT(input_max, 0);
  value *= output_max;
  value /= input_max;
  return value;
}

// Same as Scale() but |value| will be scaled and clamped using |output_max| and
// |input_max|.
float ScaleAndClamp(float value, int output_max, int input_max) {
  value = Scale(value, output_max, input_max);
  return std::max(0.0f, std::min(static_cast<float>(output_max), value));
}

}  // namespace

TouchInputScaler::TouchInputScaler(InputStub* input_stub)
    : InputFilter(input_stub) {}

TouchInputScaler::~TouchInputScaler() {}

void TouchInputScaler::InjectTouchEvent(const TouchEvent& event) {
  if (input_size_.is_empty() || output_size_.is_empty())
    return;

  // We scale based on the maximum input & output coordinates, rather than the
  // input and output sizes, so that it's possible to reach the edge of the
  // output when up-scaling.  We also take care to round up or down correctly,
  // which is important when down-scaling.
  TouchEvent out_event(event);
  for (int i = 0; i < out_event.touch_points().size(); ++i) {
    TouchEventPoint* point = out_event.mutable_touch_points(i);
    if (point->has_x() || point->has_y()) {
      DCHECK(point->has_x() && point->has_y());
      point->set_x(
          ScaleAndClamp(point->x(), output_size_.width(), input_size_.width()));
      point->set_y(ScaleAndClamp(point->y(), output_size_.height(),
                                 input_size_.height()));
    }

    // Also scale the touch size. Without scaling, the size on the host will not
    // be right.
    // For example
    // Suppose:
    //  - No size scaling.
    //  - Client is a HiDPI Chromebook device.
    //  - Host is running on a HiDPI Windows device.
    // With the configuration above, the client will send the logical touch
    // size to the host, therefore it will be smaller on the host.
    // This is because a HiDPI Chromebook device (e.g. Pixel) has 2 by 2
    // physical pixel mapped to a logical pixel.
    // With scaling, the size would be the same.
    // Note that there's no need to clamp the touch point size. For example on
    // a Nexus4 device, part of the touch circle falls outside the screen on
    // edges but still functions correctly.
    if (point->has_radius_x() || point->has_radius_y()) {
      DCHECK(point->has_radius_x() && point->has_radius_y());
      point->set_radius_x(
          Scale(point->radius_x(), output_size_.width(), input_size_.width()));
      point->set_radius_y(Scale(point->radius_y(), output_size_.height(),
                                input_size_.height()));
    }
  }

  InputFilter::InjectTouchEvent(out_event);
}

}  // namespace remoting
