package com.yhao.floatwindow.utils;


import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

import com.yhao.floatwindow.interfaces.ISensorRotateChanged;

import java.lang.ref.WeakReference;

/**
 * @Copyright © 2019 sanbo Inc. All rights reserved.
 * @Description: 方向感应
 * @Version: 1.0
 * @Create: 2019-10-16 18:10:38
 * @author: sanbo
 */
public class RotateUtil {

    private SensorManager mSenserManger = null;
    private OrientationSensorListener mSensorListener = null;
    private Sensor mSensor = null;
    // 多次初始化
    private boolean isInit = false;
    // 是否中断, 默认不中断
    private boolean isInterrupt = false;
    // 默认是竖屏
    private boolean isLandscape = false;
    // 记录点击全屏后屏幕朝向是否改变,默认会自动切换
    private boolean isChangeOrientation = true;
    // 为了给页面传递方向改变
    private WeakReference<Activity> mActivityRef = null;
    // 变动时回调
    private ISensorRotateChanged mSensorRotateChanged = null;


    private RotateUtil() {
    }

    public static RotateUtil getInstance() {
        return HOLDER.INSTANCE;
    }

    public void start(Activity activity) {
        initSensorManager(activity.getApplicationContext());
        if (!isInit && mSenserManger != null) {
            mSenserManger.registerListener(mSensorListener, mSensor, SensorManager.SENSOR_DELAY_UI);
        }
        if (activity != null || mActivityRef.get() == null) {
            mActivityRef = new WeakReference<Activity>(activity);
        }
    }

    public void stop() {
        if (isInit && mSenserManger != null) {
            mSenserManger.unregisterListener(mSensorListener);
        }
        if (mActivityRef != null || mActivityRef.get() != null) {
            mActivityRef = null;
        }
    }

    /**
     * 初始化传感器
     *
     * @param context
     */
    private void initSensorManager(Context context) {
        // 初始化重力感应器
        if (mSenserManger == null) {
            mSenserManger = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        }
        if (mSensor == null) {
            mSensor = mSenserManger.getDefaultSensor(Sensor.TYPE_GRAVITY);
        }
        if (mSensorListener == null) {
            mSensorListener = new OrientationSensorListener();
        }
    }

    /**
     * 设置回调
     *
     * @param sensorRotateChanged
     */
    public void setRotateChanged(ISensorRotateChanged sensorRotateChanged) {
        if (sensorRotateChanged != null) {
            mSensorRotateChanged = sensorRotateChanged;
        }
    }

    /**
     * 当前屏幕朝向是否横屏
     *
     * @param orientation
     * @return
     */
    private boolean screenIsLandscape(int orientation) {
        return ((orientation > 45 && orientation <= 135) || (orientation > 225 && orientation <= 315));
    }

    /**
     * 当前屏幕朝向是否竖屏
     *
     * @param orientation
     * @return
     */
    private boolean screenIsPortrait(int orientation) {
        return (((orientation > 315 && orientation <= 360) || (orientation >= 0 && orientation <= 45))
                || (orientation > 135 && orientation <= 225));
    }

    private static class HOLDER {
        private static RotateUtil INSTANCE = new RotateUtil();
    }

    /**
     * 重力感应监听者
     */
    public class OrientationSensorListener implements SensorEventListener {
        public static final int ORIENTATION_UNKNOWN = -1;
        private static final int DATA_X = 0;
        private static final int DATA_Y = 1;
        private static final int DATA_Z = 2;
        //上次是否竖屏
        private boolean isLastLandscape = false;

        @Override
        public void onSensorChanged(SensorEvent event) {

            float[] values = event.values;
            int orientation = ORIENTATION_UNKNOWN;
            float X = -values[DATA_X];
            float Y = -values[DATA_Y];
            float Z = -values[DATA_Z];
            float magnitude = X * X + Y * Y;
            // Don't trust the angle if the magnitude is small compared to the y
            // value
            if (magnitude * 4 >= Z * Z) {
                // 屏幕旋转时
                float OneEightyOverPi = 57.29577957855f;
                float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi;
                orientation = 90 - Math.round(angle);
                // normalize to 0 - 359 range
                while (orientation >= 360) {
                    orientation -= 360;
                }
                while (orientation < 0) {
                    orientation += 360;
                }
            }

            //竖屏
            if (screenIsPortrait(orientation)) {
                //上次非竖屏,屏幕旋转
                if (!isLastLandscape) {
                    isChangeOrientation = true;
                    if (FwContent.isDebug) {
                        L.v("onSensorChanged: 横屏 ----> 竖屏");
                    }
                } else {
                    isChangeOrientation = false;
                    if (FwContent.isDebug) {
                        L.v("onSensorChanged: 竖屏 ----> 竖屏");
                    }
                }
                isLastLandscape = true;
                // 横屏处理
            } else if (screenIsLandscape(orientation)) {
                //上次竖屏,屏幕旋转
                if (isLastLandscape) {
                    isChangeOrientation = true;
                    if (FwContent.isDebug) {
                        L.v("onSensorChanged: 竖屏 ---->横屏");
                    }
                } else {
                    isChangeOrientation = false;
                    if (FwContent.isDebug) {
                        L.v("onSensorChanged: 横屏 ----> 横屏");
                    }
                }
                isLastLandscape = false;
            }

            // 页面变化,回调
            if (isChangeOrientation) {
                mSensorRotateChanged.onRotateChanged();
                isChangeOrientation = false;
            }

            // 不拦截时,对应页面也可以收到页面的改变

            if (!isInterrupt && mActivityRef != null && mActivityRef.get() != null) {
                // 根据手机屏幕的朝向角度,来设置内容的横竖屏,并且记录状态
                int requestedOrientation = 0;

                if (orientation > 45 && orientation < 135) {
                    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                } else if (orientation > 135 && orientation < 225) {
                    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                } else if (orientation > 225 && orientation < 315) {
                    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                } else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) {
                    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                }
                // 接收重力感应监听的结果,来改变屏幕朝向
                mActivityRef.get().setRequestedOrientation(requestedOrientation);
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }

    }

}