/*
 * Copyright 2017, Flávio Keglevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fkeglevich.rawdumper.controller.orientation;

import android.content.Context;
import android.hardware.SensorManager;
import android.view.OrientationEventListener;

import com.fkeglevich.rawdumper.camera.async.CameraContext;
import com.fkeglevich.rawdumper.raw.data.ImageOrientation;

import static android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT;

/**
 * Created by Flávio Keglevich on 27/08/2017.
 * TODO: Add a class header comment!
 */

public class OrientationManager
{
    private static final OrientationManager instance = new OrientationManager();

    public static OrientationManager getInstance()
    {
        return instance;
    }

    private OrientationEventListener orientationListener = null;
    private int lastDegrees = OrientationEventListener.ORIENTATION_UNKNOWN;

    void setup(Context context)
    {
        disable();
        orientationListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_UI)
        {
            @Override
            public void onOrientationChanged(int orientation)
            {
                lastDegrees = orientation;
            }
        };
        enable();
    }

    void disable()
    {
        if (orientationListener != null)
            orientationListener.disable();
    }

    void enable()
    {
        if (orientationListener != null)
            orientationListener.enable();
    }

    public ImageOrientation getImageOrientation(CameraContext cameraContext)
    {
        int cameraOrientation = cameraContext.getCameraInfo().getOrientation();
        int degrees;
        if (lastDegrees != OrientationEventListener.ORIENTATION_UNKNOWN)
            degrees = (lastDegrees + cameraOrientation) % 360;
        else
            degrees = cameraOrientation % 360;

        if (degrees >= 45 && degrees < 135)
            return ImageOrientation.RIGHTTOP;
        if (degrees >= 135 && degrees < 225)
            return ImageOrientation.BOTRIGHT;
        if (degrees >= 225 && degrees < 315)
            return ImageOrientation.LEFTBOT;
        else
            return ImageOrientation.TOPLEFT;
    }

    public int getCameraRotation(CameraContext cameraContext)
    {
        if (lastDegrees == OrientationEventListener.ORIENTATION_UNKNOWN)
            return 0;

        int orientation = (lastDegrees + 45) / 90 * 90;

        int facing = cameraContext.getCameraInfo().getFacing();
        int infoOrientation = cameraContext.getCameraInfo().getOrientation();

        if (facing == CAMERA_FACING_FRONT)
            return (infoOrientation - orientation + 360) % 360;
        else
            return (infoOrientation + orientation) % 360;
    }
}

@@ -744,16 +744,60 @@
 nager;%0D%0A
+import android.support.annotation.NonNull;%0D%0A
 import a
@@ -2264,24 +2264,91 @@
 ntation();%0D%0A
+        int facing = cameraContext.getCameraInfo().getFacing();%0D%0A%0D%0A
         int 
@@ -2358,35 +2358,49 @@
 rees;%0D%0A        i
-f (
+nt orientation = 
 lastDegrees != O
@@ -2446,48 +2446,244 @@
 NOWN
-)%0D%0A            degrees = (lastD
+ ? lastDegrees : 0;%0D%0A%0D%0A        if (facing == CAMERA_FACING_FRONT)%0D%0A        %7B%0D%0A            degrees = (cameraOrientation + orientation) %25 360;%0D%0A            degrees = (360 - degrees) %25 360;%0D%0A        %7D%0D%0A        else%0D%0A            d
 egrees 
-+ 
+= (
 came
@@ -2687,32 +2687,52 @@
 ameraOrientation
+ + orientation + 180
 ) %25 360;%0D%0A      
@@ -2721,32 +2721,34 @@
 80) %25 360;%0D%0A
+%0D%0A
         
 else%0D%0A      
@@ -2739,62 +2739,298 @@
     
-else%0D%0A            degrees = cameraOrientation %25 360;%0D%0A
+ImageOrientation result = degreesToOrientation(degrees, facing == CAMERA_FACING_FRONT);%0D%0A        //Log.i(%22OrientationManager%22, result.toString());%0D%0A        return result;%0D%0A    %7D%0D%0A%0D%0A    @NonNull%0D%0A    private ImageOrientation degreesToOrientation(int degrees, boolean flipHorizontally)%0D%0A    %7B
 %0D%0A  
@@ -3082,32 +3082,51 @@
           return
+ flipHorizontally ?
  ImageOrientatio
@@ -3132,19 +3132,46 @@
 on.RIGHT
-TOP
+BOT : ImageOrientation.LEFTBOT
 ;%0D%0A     
@@ -3221,32 +3221,51 @@
           return
+ flipHorizontally ?
  ImageOrientatio
@@ -3270,16 +3270,43 @@
 ion.
-BOT
+TOP
 RIGHT
+ : ImageOrientation.TOPLEFT
 ;%0D%0A 
@@ -3360,32 +3360,51 @@
           return
+ flipHorizontally ?
  ImageOrientatio
@@ -3401,35 +3401,63 @@
 Orientation.LEFT
-BOT
+TOP : ImageOrientation.RIGHTTOP
 ;%0D%0A        else%0D
@@ -3476,39 +3476,86 @@
  return 
-ImageOrientation.TOPLEF
+flipHorizontally ? ImageOrientation.BOTLEFT : ImageOrientation.BOTRIGH
 T;%0D%0A    

Fix orientation manager