// Copyright 2019 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.

package io.flutter.plugins.camera;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.hardware.SensorManager;
import android.provider.Settings;
import android.view.Display;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.WindowManager;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;

class DeviceOrientationManager {

  private static final IntentFilter orientationIntentFilter =
      new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);

  private final Activity activity;
  private final DartMessenger messenger;
  private final boolean isFrontFacing;
  private final int sensorOrientation;
  private PlatformChannel.DeviceOrientation lastOrientation;
  private OrientationEventListener orientationEventListener;
  private BroadcastReceiver broadcastReceiver;

  public DeviceOrientationManager(
      Activity activity, DartMessenger messenger, boolean isFrontFacing, int sensorOrientation) {
    this.activity = activity;
    this.messenger = messenger;
    this.isFrontFacing = isFrontFacing;
    this.sensorOrientation = sensorOrientation;
  }

  public void start() {
    startSensorListener();
    startUIListener();
  }

  public void stop() {
    stopSensorListener();
    stopUIListener();
  }

  public int getMediaOrientation() {
    return this.getMediaOrientation(this.lastOrientation);
  }

  public int getMediaOrientation(PlatformChannel.DeviceOrientation orientation) {
    int angle = 0;
    switch (orientation) {
      case PORTRAIT_UP:
        angle = 0;
        break;
      case PORTRAIT_DOWN:
        angle = 180;
        break;
      case LANDSCAPE_LEFT:
        angle = 90;
        break;
      case LANDSCAPE_RIGHT:
        angle = 270;
        break;
    }
    if (isFrontFacing) angle *= -1;
    return (angle + sensorOrientation + 360) % 360;
  }

  private void startSensorListener() {
    if (orientationEventListener != null) return;
    orientationEventListener =
        new OrientationEventListener(activity, SensorManager.SENSOR_DELAY_NORMAL) {
          @Override
          public void onOrientationChanged(int angle) {
            if (!isSystemAutoRotationLocked()) {
              PlatformChannel.DeviceOrientation newOrientation = calculateSensorOrientation(angle);
              if (!newOrientation.equals(lastOrientation)) {
                lastOrientation = newOrientation;
                messenger.sendDeviceOrientationChangeEvent(newOrientation);
              }
            }
          }
        };
    if (orientationEventListener.canDetectOrientation()) {
      orientationEventListener.enable();
    }
  }

  private void startUIListener() {
    if (broadcastReceiver != null) return;
    broadcastReceiver =
        new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
            if (isSystemAutoRotationLocked()) {
              PlatformChannel.DeviceOrientation orientation = getUIOrientation();
              if (!orientation.equals(lastOrientation)) {
                lastOrientation = orientation;
                messenger.sendDeviceOrientationChangeEvent(orientation);
              }
            }
          }
        };
    activity.registerReceiver(broadcastReceiver, orientationIntentFilter);
    broadcastReceiver.onReceive(activity, null);
  }

  private void stopSensorListener() {
    if (orientationEventListener == null) return;
    orientationEventListener.disable();
    orientationEventListener = null;
  }

  private void stopUIListener() {
    if (broadcastReceiver == null) return;
    activity.unregisterReceiver(broadcastReceiver);
    broadcastReceiver = null;
  }

  private boolean isSystemAutoRotationLocked() {
    return android.provider.Settings.System.getInt(
            activity.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0)
        != 1;
  }

  private PlatformChannel.DeviceOrientation getUIOrientation() {
    final int rotation = getDisplay().getRotation();
    final int orientation = activity.getResources().getConfiguration().orientation;

    switch (orientation) {
      case Configuration.ORIENTATION_PORTRAIT:
        if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
          return PlatformChannel.DeviceOrientation.PORTRAIT_UP;
        } else {
          return PlatformChannel.DeviceOrientation.PORTRAIT_DOWN;
        }
      case Configuration.ORIENTATION_LANDSCAPE:
        if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
          return PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT;
        } else {
          return PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT;
        }
      default:
        return PlatformChannel.DeviceOrientation.PORTRAIT_UP;
    }
  }

  private PlatformChannel.DeviceOrientation calculateSensorOrientation(int angle) {
    final int tolerance = 45;
    angle += tolerance;

    // Orientation is 0 in the default orientation mode. This is portait-mode for phones
    // and landscape for tablets. We have to compensate for this by calculating the default
    // orientation, and apply an offset accordingly.
    int defaultDeviceOrientation = getDeviceDefaultOrientation();
    if (defaultDeviceOrientation == Configuration.ORIENTATION_LANDSCAPE) {
      angle += 90;
    }
    // Determine the orientation
    angle = angle % 360;
    return new PlatformChannel.DeviceOrientation[] {
          PlatformChannel.DeviceOrientation.PORTRAIT_UP,
          PlatformChannel.DeviceOrientation.LANDSCAPE_LEFT,
          PlatformChannel.DeviceOrientation.PORTRAIT_DOWN,
          PlatformChannel.DeviceOrientation.LANDSCAPE_RIGHT,
        }
        [angle / 90];
  }

  private int getDeviceDefaultOrientation() {
    Configuration config = activity.getResources().getConfiguration();
    int rotation = getDisplay().getRotation();
    if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180)
            && config.orientation == Configuration.ORIENTATION_LANDSCAPE)
        || ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270)
            && config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
      return Configuration.ORIENTATION_LANDSCAPE;
    } else {
      return Configuration.ORIENTATION_PORTRAIT;
    }
  }

  @SuppressWarnings("deprecation")
  private Display getDisplay() {
    return ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
  }
}
