package com.idata.ocr.iocr;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Size;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import com.idata.ocr.Predictor;

public class CameraActivity extends AppCompatActivity implements View.OnClickListener{

    private String[] REQUIRE_PERMISSIONS = {"android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.READ_EXTERNAL_STORAGE", "android.permission.READ_PHONE_STATE", "android.permission.INTERNET" };

    private CameraSurfaceView mPreviewView = null;
    private TextView mValidRect = null;
    private Predictor mPredictor = Predictor.getInstance();

    private static boolean activate = false;

    private AlertDialog mWaitingDialog = null;

    private float mWidthRatio = 0.9f;
    private float mHeightRatio = 0.2f;


    private final int MSG_UNACTVE = 0;
    private final int MSG_CANCEL_WAITING_DIALOG = 1;
    private final int MSG_SHOW_TOAST = 2;
    private Handler mHandler = new Handler(Looper.myLooper()){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch(msg.what) {
                case MSG_UNACTVE:
                    showAlert();
                    break;
                case MSG_CANCEL_WAITING_DIALOG:
                    cancelWaitingDialog();
                    break;
                case MSG_SHOW_TOAST:
                    Toast.makeText(CameraActivity.this, (String)msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mValidRect = findViewById(R.id.validRect);
        mPreviewView = (CameraSurfaceView) findViewById(R.id.previewView);
        mPreviewView.setOnStateListener(new CameraSurfaceView.OnStateListener() {
            @Override
            public void onSizeChanged(Size size) {
                adjustedValidZone(size, mWidthRatio, mHeightRatio);
            }

            @Override
            public void onSizeNotChanged(Size size) {
                adjustedValidZone(size, mWidthRatio, mHeightRatio);
            }
        });

        Button bt = (Button)findViewById(R.id.btTakePic);
        bt.setOnClickListener(this);

        bt = (Button)findViewById(R.id.btSmall);
        bt.setOnClickListener(this);

        bt = (Button)findViewById(R.id.btMedium);
        bt.setOnClickListener(this);

        bt = (Button)findViewById(R.id.btFull);
        bt.setOnClickListener(this);


        new Thread(new Runnable() {
            @Override
            public void run() {
                activate  = mPredictor.initModel(getApplicationContext());
                if(!activate) {
                    mHandler.sendEmptyMessage(MSG_UNACTVE);
                }
            }
        }).start();
    }

    @Override
    protected void onResume() {
        super.onResume();

        if(mPreviewView.getHolder() != null)
            mPreviewView.openCamera(mPreviewView.getHolder());
    }

    @Override
    protected void onPause() {
        super.onPause();

        mPreviewView.releaseCamera();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mPredictor.releaseModel();
    }

    protected boolean checkPermissionsGranted(String[] neededPermissions)
    {
        if(neededPermissions == null || neededPermissions.length == 0)
            return true;

        boolean allGranted = true;
        for(String permission : neededPermissions)
        {
            allGranted &= ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED;
        }
        return allGranted;
    }

    @Override
    public void onRequestPermissionsResult(final int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        boolean isAllGranted = true;
        String deniedPermission = null;
        for(int i=0; i<grantResults.length; i++) {
            int grantResult = grantResults[i];
            if(grantResult == PackageManager.PERMISSION_DENIED)
            {
                isAllGranted = false;
                deniedPermission = permissions[i];
                break;
            }
        }

        if(isAllGranted == false)
        {
            Toast.makeText(this, R.string.right_not_enough, Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @Override
    public void onClick(View v) {
        switch(v.getId())
        {
            case R.id.btTakePic:
                takePicture();
                break;
            case R.id.btSmall:
                if(mWaitingDialog != null && mWaitingDialog.isShowing())
                    return;

                adjustedValidZone(0.9f, 0.2f);
                break;
            case R.id.btMedium:
                if(mWaitingDialog != null && mWaitingDialog.isShowing())
                    return;

                adjustedValidZone(0.9f, 0.5f);
                break;
            case R.id.btFull:
                if(mWaitingDialog != null && mWaitingDialog.isShowing())
                    return;

                adjustedValidZone(1f, 1f);
                break;
        }
    }

    public void takePicture() {

        if(!activate) {
            mHandler.sendEmptyMessage(MSG_UNACTVE);
            return;
        }

        if(mWaitingDialog != null && mWaitingDialog.isShowing())
            return;

        mPreviewView.stopPreview();

        showWaitingDialog();

        mPreviewView.takePicture(new CameraSurfaceView.OnTakePicListener() {
            @Override
            public void onTakePic(Bitmap bitmap) {
                if(bitmap != null) {
                    ShowActivity.mImage = bitmap;

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Intent intent = new Intent(CameraActivity.this, ShowActivity.class);
                            startActivity(intent);
                        }
                    });
                }
                else
                {
                    mHandler.sendMessage(mHandler.obtainMessage(MSG_SHOW_TOAST, getString(R.string.fails_to_fetch_image)));
                }
                mHandler.sendEmptyMessage(MSG_CANCEL_WAITING_DIALOG);
            }
        });
    }

    private void showAlert(){
        TextView title = new TextView(CameraActivity.this);
        title.setText(R.string.prompt);
        title.setGravity(Gravity.CENTER);
        title.setTextColor(0xFFFF0000);
        title.setTextSize(20);
        AlertDialog alertDialog = new AlertDialog.Builder(CameraActivity.this).
                //setTitle("未激活").
                        setCustomTitle(title).
                        setMessage(R.string.prompt_invalid_account).
                        setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // TODO Auto-generated method stub
                            }
                        }).create();
        alertDialog.show();
    }

    private void showWaitingDialog()
    {
        if(mWaitingDialog == null) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(R.string.taking_pic);
            mWaitingDialog = builder.create();
            mWaitingDialog.setCancelable(false);
            mWaitingDialog.setCanceledOnTouchOutside(false);
        }
        if(mWaitingDialog.isShowing() == false)
            mWaitingDialog.show();
    }

    private void cancelWaitingDialog()
    {
        if(mWaitingDialog != null && mWaitingDialog.isShowing())
            mWaitingDialog.dismiss();
    }

    private void adjustedValidZone(float widthRatio, float heightRatio)
    {
        if(mPreviewView != null)
            adjustedValidZone(new Size(mPreviewView.getWidth(), mPreviewView.getHeight()), widthRatio, heightRatio);
    }

    private void adjustedValidZone(Size size, float widthRatio, float heightRatio)
    {
        if(mValidRect != null && mPreviewView != null)
        {
            mWidthRatio = widthRatio;
            mHeightRatio = heightRatio;

            mPreviewView.setValidZoneRatio(widthRatio, heightRatio);
            if(widthRatio == 1f && heightRatio == 1f)
            {
                mValidRect.setVisibility(View.GONE);
            }
            else {
                int width = size.getWidth();
                int height = size.getHeight();

                FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mValidRect.getLayoutParams();
                layoutParams.width = (int)(width * widthRatio);
                layoutParams.height = (int)(height * heightRatio);
                layoutParams.topMargin = (height - layoutParams.height) / 2;

                mValidRect.setLayoutParams(layoutParams);
                mValidRect.setVisibility(View.VISIBLE);
            }
        }
    }
}
