/*
 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.appspot.apprtc;

import android.widget.SeekBar;
import android.widget.TextView;

import org.webrtc.CameraEnumerationAndroid.CaptureFormat;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Control capture format based on a seekbar listener.
 */
public class CaptureQualityController implements SeekBar.OnSeekBarChangeListener {
  private final List<CaptureFormat> formats =
      Arrays.asList(new CaptureFormat(1280, 720, 0, 30000), new CaptureFormat(960, 540, 0, 30000),
          new CaptureFormat(640, 480, 0, 30000), new CaptureFormat(480, 360, 0, 30000),
          new CaptureFormat(320, 240, 0, 30000), new CaptureFormat(256, 144, 0, 30000));
  // Prioritize framerate below this threshold and resolution above the threshold.
  private static final int FRAMERATE_THRESHOLD = 15;
  private TextView captureFormatText;
  private CallFragment.OnCallEvents callEvents;
  private int width = 0;
  private int height = 0;
  private int framerate = 0;
  private double targetBandwidth = 0;

  public CaptureQualityController(
      TextView captureFormatText, CallFragment.OnCallEvents callEvents) {
    this.captureFormatText = captureFormatText;
    this.callEvents = callEvents;
  }

  private final Comparator<CaptureFormat> compareFormats = new Comparator<CaptureFormat>() {
    @Override
    public int compare(CaptureFormat first, CaptureFormat second) {
      int firstFps = calculateFramerate(targetBandwidth, first);
      int secondFps = calculateFramerate(targetBandwidth, second);

      if (firstFps >= FRAMERATE_THRESHOLD && secondFps >= FRAMERATE_THRESHOLD
          || firstFps == secondFps) {
        // Compare resolution.
        return first.width * first.height - second.width * second.height;
      } else {
        // Compare fps.
        return firstFps - secondFps;
      }
    }
  };

  @Override
  public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    if (progress == 0) {
      width = 0;
      height = 0;
      framerate = 0;
      captureFormatText.setText(R.string.muted);
      return;
    }

    // Extract max bandwidth (in millipixels / second).
    long maxCaptureBandwidth = java.lang.Long.MIN_VALUE;
    for (CaptureFormat format : formats) {
      maxCaptureBandwidth =
          Math.max(maxCaptureBandwidth, (long) format.width * format.height * format.framerate.max);
    }

    // Fraction between 0 and 1.
    double bandwidthFraction = (double) progress / 100.0;
    // Make a log-scale transformation, still between 0 and 1.
    final double kExpConstant = 3.0;
    bandwidthFraction =
        (Math.exp(kExpConstant * bandwidthFraction) - 1) / (Math.exp(kExpConstant) - 1);
    targetBandwidth = bandwidthFraction * maxCaptureBandwidth;

    // Choose the best format given a target bandwidth.
    final CaptureFormat bestFormat = Collections.max(formats, compareFormats);
    width = bestFormat.width;
    height = bestFormat.height;
    framerate = calculateFramerate(targetBandwidth, bestFormat);
    captureFormatText.setText(width + "x" + height + " @ " + framerate + "fps");
  }

  @Override
  public void onStartTrackingTouch(SeekBar seekBar) {}

  @Override
  public void onStopTrackingTouch(SeekBar seekBar) {
    callEvents.onCaptureFormatChange(width, height, framerate);
  }

  // Return the highest frame rate possible based on bandwidth and format.
  private int calculateFramerate(double bandwidth, CaptureFormat format) {
    return (int) Math.round(
        Math.min(format.framerate.max, (int) Math.round(bandwidth / (format.width * format.height)))
        / 1000.0);
  }
}
