package com.sensetime.demo.view;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;

import androidx.annotation.NonNull;

import com.blankj.utilcode.util.LogUtils;
import com.sensetime.demo.SenseTimeMtc;

import org.jetbrains.annotations.NotNull;

public class UVCCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    public static final String TAG = "UVCCameraSurfaceView";

    private final Object mSyncSurface = new Object();

    private boolean mDrawFlag = true;

    private double mRequestedAspect = -1.0;

    public UVCCameraSurfaceView(final Context context) {
        this(context, null, 0);
    }

    public UVCCameraSurfaceView(final Context context, final AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public UVCCameraSurfaceView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setAspectRatio(final double aspectRatio) {
        if (aspectRatio < 0) {
            throw new IllegalArgumentException();
        }
        if (mRequestedAspect != aspectRatio) {
            mRequestedAspect = aspectRatio;
            requestLayout();
        }
    }

    public void setAspectRatio(final int width, final int height) {
        setAspectRatio(width / (double) height);
    }

    // include virtual menu's height
    public static int getRealHeight(@NotNull Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        assert wm != null;
        Display display = wm.getDefaultDisplay();
        int screenHeight = 0;
        {
            DisplayMetrics dm = new DisplayMetrics();
            display.getRealMetrics(dm);
            screenHeight = dm.heightPixels;
        }
        return screenHeight;
    }

    public static int getRealWidth(@NotNull Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        assert wm != null;
        wm.getDefaultDisplay().getRealMetrics(dm);
        return dm.widthPixels;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        LogUtils.dTag(TAG, "surfaceCreated");
        Canvas canvas = holder.lockCanvas();
        //绘制之前先对画布进行翻转
        canvas.scale(-1, 1, getWidth() / 2, getHeight() / 2);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        LogUtils.dTag(TAG, "tracking view:" + visibility);
        synchronized (mSyncSurface) {
            if (visibility == VISIBLE) {
                mDrawFlag = true;
            } else {
                mDrawFlag = false;
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        LogUtils.dTag(TAG, "surfaceDestroyed");
        synchronized (mSyncSurface) {
            mDrawFlag = false;
        }
    }

    public Object getmSyncSurface() {
        return mSyncSurface;
    }

    public boolean ismDrawFlag() {
        return mDrawFlag;
    }

    public void setmDrawFlag(boolean mDrawFlag) {
        this.mDrawFlag = mDrawFlag;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        float screenWidth = getRealWidth(getContext());
        float screenHeight = getRealHeight(getContext());
        SenseTimeMtc senseTimeMtc = SenseTimeMtc.getInstance();
        int CAMERA_W, CAMERA_H;
        if (senseTimeMtc.getmM10_L_P() == SenseTimeMtc.LANDSCAPE_0 || senseTimeMtc.getmM10_L_P() == senseTimeMtc.LANDSCAPE_180) {
            CAMERA_W = senseTimeMtc.getCameraWidth();
            CAMERA_H = senseTimeMtc.getCameraHeight();
        } else {//竖屏状态
            CAMERA_W = senseTimeMtc.getCameraHeight();
            CAMERA_H = senseTimeMtc.getCameraWidth();
        }

        if (screenWidth > screenHeight) { // screen landscape
            if (CAMERA_H < CAMERA_W) {//camera landscape
                if (senseTimeMtc.ismScaleHeight()) {//Adjust width according to height
                    senseTimeMtc.setPreviewWidth((int) (screenHeight / mRequestedAspect));
                    senseTimeMtc.setPreviewHeight((int) screenHeight);
                } else {//Adjust height according to width
                    senseTimeMtc.setPreviewWidth((int) screenWidth);
                    senseTimeMtc.setPreviewHeight((int) (screenWidth * mRequestedAspect));//M10
                }
            } else {//camera portrait
                senseTimeMtc.setPreviewWidth((int) (screenHeight * mRequestedAspect));
                senseTimeMtc.setPreviewHeight((int) screenHeight);
            }
        } else { // screen portrait
            if (CAMERA_H < CAMERA_W) { // camera landscape
                senseTimeMtc.setPreviewWidth((int) (screenWidth / mRequestedAspect));
                senseTimeMtc.setPreviewHeight((int) screenWidth);
            } else { // camera portrait
                if (senseTimeMtc.ismScaleHeight()) {//Adjust width according to height
                    senseTimeMtc.setPreviewWidth((int) (screenHeight * mRequestedAspect));
                    senseTimeMtc.setPreviewHeight((int) screenHeight);
                } else {//Adjust height according to width
                    senseTimeMtc.setPreviewWidth((int) screenWidth);
                    senseTimeMtc.setPreviewHeight((int) (screenWidth / mRequestedAspect));
                }
            }
        }
        LogUtils.dTag(TAG, "senseTimeMtc.mPreviewWidth = " + senseTimeMtc.getPreviewWidth() + ",senseTimeMtc.mPreviewHeight = " + senseTimeMtc.getPreviewHeight() + ",requestAspect = " + mRequestedAspect);
        setMeasuredDimension(senseTimeMtc.getPreviewWidth(), senseTimeMtc.getPreviewHeight());
    }
}
