package com.hand.face.ui;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.RectF;
import android.hardware.Camera;
import android.hardware.Camera.Face;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.hand.face.common.Config;
import com.hand.face.common.LoadingDialog;
import com.hand.face.myinterface.CameraInterface;
import com.hand.face.utils.DisplayUtil;
import com.hand.face.utils.EventUtil;
import com.hand.face.utils.FileUtil;
import com.hand.face.utils.GoogleFaceDetect;
import com.hand.face.utils.NotifyMessageManager;
import com.hand.face.utils.Utils;
import com.hand.face.view.CameraSurfaceView;
import com.hand.face.view.FaceView;
import com.hand.face.view.MaskView;
import com.youtu.Youtu;

import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.ref.WeakReference;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by xiang.wang on 2016/12/8.
 * 视频流获取检测到人脸的那一帧视频
 */
public class FaceCompareActivity extends Activity {
    private String endpoint = "http://oss-cn-shanghai.aliyuncs.com";
    private String nameSapce = "http://handbk.oss-cn-shanghai.aliyuncs.com";
    private OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider("LTAIf20TU2Tdb8jz", "7f2vPdAYXeImOg80I6y43huIvu171i");
    private OSS oss;
    private static final int CAMERA_PERMISSION_REQUEST = 1;
    private static final String TAG = "FaceCompareActivity";
    CameraSurfaceView surfaceView = null;
    FaceView faceView;
    float previewRate = -1f;
    private MainHandler mMainHandler = null;
    GoogleFaceDetect googleFaceDetect = null;
    ImageButton switchBtn;
    //视频检测到人脸的次数
    private int times = 0;
//    private ImageView img;
    private MaskView mask;
    private String APP_ID = "";
    private String SECRET_ID = "";
    private String SECRET_KEY = "";
    private Youtu faceYoutu;
    private LoadingDialog loadingDialog;
    private boolean pictureLock = true;
    private ExecutorService mImageThreadPool = Executors.newFixedThreadPool(3);
    private MyHandler handler;
    private Matrix mMatrix = new Matrix();
    private RectF mRect = new RectF();
    //人脸矩形的左右左边范围
    private int faceLeft=0;
    private int faceRight=0;
    //人脸矩形的上下范围
    private int faceTop=0;
    private int faceBottom=0;
    private TextView textv_face_info;
    private NotifyMessageManager notify;
    //屏幕宽度
    private int w_screen;
    private Timer timer;
    public static void actionStart(Context context){
        Intent intent = new Intent(context,FaceCompareActivity.class);
        context.startActivity(intent);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(Utils.getResourceId(FaceCompareActivity.this, "activity_video", "layout"));
        ClientConfiguration conf = new ClientConfiguration();
        conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
        conf.setSocketTimeout(20 * 1000); // socket超时,默认15秒
        conf.setMaxConcurrentRequest(5); // 最大并发请求书,默认5个
        conf.setMaxErrorRetry(2); // 失败后最大重试次数,默认2次
        oss = new OSSClient(FaceCompareActivity.this, endpoint, credentialProvider,conf);
        //运行时权限检测
        if (ContextCompat.checkSelfPermission(FaceCompareActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
        {
            //不具有camera权限 申请权限
            ActivityCompat.requestPermissions(FaceCompareActivity.this, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST);
        }else{
        init();}
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case CAMERA_PERMISSION_REQUEST: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    init();
                } else {
                }
                return;
            }
        }
    }
    private void init(){
        initUI();
        initViewParams();
        //计算测量范围
        initWH();
        notify = NotifyMessageManager.getInstance();
        handler = new MyHandler(FaceCompareActivity.this);
        timer = new Timer(true);
        APP_ID = Config.APP_ID;
        SECRET_ID = Config.SECRET_ID;
        SECRET_KEY = Config.SECRET_KEY;
        faceYoutu = new Youtu(APP_ID, SECRET_ID, SECRET_KEY, Youtu.API_YOUTU_END_POINT);
        loadingDialog = new LoadingDialog(FaceCompareActivity.this);
        mMainHandler = new MainHandler();
        googleFaceDetect = new GoogleFaceDetect(getApplicationContext(), mMainHandler);
        mMainHandler.sendEmptyMessageDelayed(EventUtil.CAMERA_HAS_STARTED_PREVIEW, 1500);
    }
    private void initWH(){
        DisplayMetrics dm = getResources().getDisplayMetrics();
        w_screen = dm.widthPixels;
        int h_screen = dm.heightPixels;
        //获取屏幕的百分之九十的一半作为半径 根据圆内最大正方形的左上角坐标计算left
        faceLeft = w_screen * 9 / 20 * 2 / 10;
        faceRight = w_screen-faceLeft;
        faceTop = h_screen/2 -  w_screen*9/20 + 20;
        faceBottom = h_screen/2 +  w_screen*9/20 + 20;
        boolean isMirror = false;
        int Id = CameraInterface.getInstance().getCameraId();
        if(Id == Camera.CameraInfo.CAMERA_FACING_BACK){
            isMirror = false; //后置Camera无需mirror
        }else if(Id == Camera.CameraInfo.CAMERA_FACING_FRONT){
            isMirror = true;  //前置Camera需要mirror
        }
        Utils.prepareMatrix(mMatrix, isMirror, 90, w_screen, h_screen);
        mMatrix.postRotate(0);
    }
    private void initUI(){
        surfaceView = (CameraSurfaceView)findViewById(Utils.getResourceId(FaceCompareActivity.this, "camera_surfaceview", "id"));
        faceView = (FaceView)findViewById(Utils.getResourceId(FaceCompareActivity.this, "face_view", "id"));
        textv_face_info = (TextView) findViewById(Utils.getResourceId(FaceCompareActivity.this, "textv_face_info", "id"));
        switchBtn = (ImageButton) findViewById(Utils.getResourceId(FaceCompareActivity.this, "btn_switch", "id"));
        mask = (MaskView) findViewById(Utils.getResourceId(FaceCompareActivity.this, "mask", "id"));
        switchBtn.setVisibility(View.GONE);
//        img = (ImageView) findViewById(R.id.img);
//        switchBtn.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                 //切换摄像头
//                stopGoogleFaceDetect();
//                int newId = (CameraInterface.getInstance().getCameraId() + 1)%2;
//                CameraInterface.getInstance().doStopCamera();
//                //人脸登录默认前置摄像头
//                CameraInterface.getInstance().doOpenCamera(null,newId);
//                CameraInterface.getInstance().doStartPreview(surfaceView.getSurfaceHolder(), previewRate);
//                mMainHandler.sendEmptyMessageDelayed(EventUtil.CAMERA_HAS_STARTED_PREVIEW, 1500);
//            }
//        });
    }
    private void initViewParams(){
        LayoutParams params = surfaceView.getLayoutParams();
        Point p = DisplayUtil.getScreenMetrics(this);
        params.width = p.x;
        params.height = p.y;
        previewRate = DisplayUtil.getScreenRate(this); //默认全屏的比例预览
        surfaceView.setLayoutParams(params);
    }



//    @Override
//    public void onClick(View v) {
//
//        switch (v.getId()){
//
//            case R.id.btn_switch:
//                //切换摄像头
//                stopGoogleFaceDetect();
//                int newId = (CameraInterface.getInstance().getCameraId() + 1)%2;
//                CameraInterface.getInstance().doStopCamera();
//                //人脸登录默认前置摄像头
//                CameraInterface.getInstance().doOpenCamera(null,newId);
//                CameraInterface.getInstance().doStartPreview(surfaceView.getSurfaceHolder(), previewRate);
//                mMainHandler.sendEmptyMessageDelayed(EventUtil.CAMERA_HAS_STARTED_PREVIEW, 1500);
////                startGoogleFaceDetect();
//                break;
//        }
//    }

    private  class MainHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            switch (msg.what){
                case EventUtil.UPDATE_FACE_RECT:
                    Face[] faces = (Face[]) msg.obj;
//                    //当检测到人脸
                    if(faces.length>0){
                        Log.i(TAG,String.valueOf(times));
                        mRect.set(faces[0].rect);
                        mMatrix.mapRect(mRect);
                        //加范围控制 给范围四周加一些误差 左右20 上下40
                        if(mRect.left>=(faceLeft-20) && mRect.right<=(faceRight+20) && mRect.top >= (faceTop-40) && mRect.bottom <=(faceBottom+40)){
                            textv_face_info.setText("请保持不动");
                            times++;
                        }else{
                            textv_face_info.setText("请将人脸放入圆圈内");
                            times = 0;
                        }
                    }else{
                        times = 0;
                        textv_face_info.setText("未检测到人脸");
                    }
                    if(times>=10 && pictureLock){
                        textv_face_info.setVisibility(View.GONE);
                        //检测
                        try {
                            detect();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    //停止画框功能
//                    faceView.setFaces(faces);
                    break;
                case EventUtil.CAMERA_HAS_STARTED_PREVIEW:
                    try {
                        startGoogleFaceDetect();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
            }
            super.handleMessage(msg);
        }

    }
    private void detect() throws Exception{
        pictureLock = false;
        if(loadingDialog!=null) {
            loadingDialog.setText("正在检测人脸,请等待...");
            loadingDialog.show();}
        if(faceYoutu!=null){
            mImageThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Bitmap mImage = surfaceView.getPicture();
                    //保存图片
                    String path = getFilesDir().getPath();
                    FileUtil.saveBitmap(FileUtil.centerSquareScaleBitmap(mImage, (faceRight - faceLeft) * mImage.getWidth() / w_screen + 20), path);
                    if (mImage != null) {
                        try {
                            JSONObject respose = faceYoutu.DetectFace(mImage, 1);
                            Message msg = new Message();
                            msg.what = 0x100;
                            Bundle bundle = new Bundle();
                            bundle.putString("respose", respose.toString());
                            msg.setData(bundle);
                            handler.sendMessage(msg);
                        } catch (Exception e) {
							Message msg = new Message();
							handler.sendEmptyMessage(0x101);
                            e.printStackTrace();
                        }
                    } else {
                        Message msg = new Message();
                        handler.sendEmptyMessage(0x101);
                    }
                }
            });
        }
    }
    private void startGoogleFaceDetect() throws Exception{
        Camera.Parameters params = CameraInterface.getInstance().getCameraParams();
        String phoneName = android.os.Build.MODEL;
        if(phoneName!=null && !phoneName.isEmpty() && phoneName.contains("HUAWEI")){
            //开启定时器进行获取视频流图片检测
            textv_face_info.setText("请将人脸放入圆圈内");
            TimerTask task = new TimerTask(){
                public void run() {
                    Message message = new Message();
                    message.what = 0x103;
                    handler.sendMessage(message);
                }
            };
            if(timer!=null){
                timer.schedule(task, 3000, 3000);
            }
        }else if(phoneName!=null && !phoneName.isEmpty() && phoneName.contains("X800")){
            //开启定时器进行获取视频流图片检测
            textv_face_info.setText("请将人脸放入圆圈内");
            TimerTask task = new TimerTask(){
                public void run() {
                    Message message = new Message();
                    message.what = 0x103;
                    handler.sendMessage(message);
                }
            };
            if(timer!=null){
                timer.schedule(task, 3000, 3000);
            }
        }else if(phoneName!=null && !phoneName.isEmpty() && phoneName.contains("vivo X7Plus")){
            //开启定时器进行获取视频流图片检测
            textv_face_info.setText("请将人脸放入圆圈内");
            TimerTask task = new TimerTask(){
                public void run() {
                    Message message = new Message();
                    message.what = 0x103;
                    handler.sendMessage(message);
                }
            };
            if(timer!=null){
                timer.schedule(task, 3000, 3000);
            }
        }else if(params.getMaxNumDetectedFaces() > 0){
            if(faceView != null){
                faceView.clearFaces();
                faceView.setVisibility(View.VISIBLE);
            }
            CameraInterface.getInstance().getCameraDevice().setFaceDetectionListener(googleFaceDetect);
            CameraInterface.getInstance().getCameraDevice().startFaceDetection();
        }else{
            //开启定时器进行获取视频流图片检测
            textv_face_info.setText("请将人脸放入圆圈内");
            TimerTask task = new TimerTask(){
                public void run() {
                    Message message = new Message();
                    message.what = 0x103;
                    handler.sendMessage(message);
                }
            };
            if(timer!=null){
                timer.schedule(task, 3000, 3000);
            }
        }
    }
    private void stopGoogleFaceDetect(){
        Camera.Parameters params = CameraInterface.getInstance().getCameraParams();
        if(params!=null  && params.getMaxNumDetectedFaces() > 0){
            CameraInterface.getInstance().getCameraDevice().setFaceDetectionListener(null);
            CameraInterface.getInstance().getCameraDevice().stopFaceDetection();
            faceView.clearFaces();
        }
    }
    public interface NV21ImgCallBack{
        public void getImgBuffer(byte[] nv21);
    }
    // 防止handler出现内存泄露 写成静态类
    static class MyHandler extends Handler {
        // 持有当前activity的弱引用
        WeakReference<FaceCompareActivity> myActivity;

        public MyHandler(FaceCompareActivity act) {
            myActivity = new WeakReference<FaceCompareActivity>(act);
        }
        @Override
        public void handleMessage(Message msg) {
            FaceCompareActivity myAct = myActivity.get();
            switch (msg.what) {
                case 0x100:
                    //图片检测返回
                    if(myAct.loadingDialog!=null && myAct.loadingDialog.isShowing())  myAct.loadingDialog.dismiss();
                    String respose = msg.getData().getString("respose");
                    try {
                        JSONObject face = new JSONObject(respose);
                        //错误码和错误编号
                        String errorcode = face.getString("errorcode");
                        String errormsg = face.getString("errormsg");
                        if(!"0".equals(errorcode)){
                            myAct.times = 0;
                            myAct.pictureLock = true;
                            myAct.textv_face_info.setVisibility(View.VISIBLE);
                            Toast.makeText(myAct, "图片校验失败,请重新检测人脸照片", Toast.LENGTH_SHORT).show();
                        }else{
                            JSONArray jsonArr = face.getJSONArray("face");
                            JSONObject faceObj = jsonArr.getJSONObject(0);
                            //获取保存的图片路径
                            String imgPath = FileUtil.getSavePath();
                            faceObj.put("imgPath", imgPath);
                            myAct.uploadImage(imgPath,faceObj);
//                            myAct.notify.sendNotifyMessage(faceObj.toString());
                            if(myAct.timer!=null){
                                myAct.timer.cancel();
                            }
//                            myAct.finish();
                        }
                    }catch (JSONException e) {
                        //打开检测锁 重置检测次数
                        myAct.times = 0;
                        myAct.pictureLock = true;
                        myAct.textv_face_info.setVisibility(View.VISIBLE);
                        Toast.makeText(myAct, "图片校验失败,请重新检测人脸照片", Toast.LENGTH_SHORT).show();
                        e.printStackTrace();
                    }
                    break;
                case 0x101:
                    if(myAct.loadingDialog!=null && myAct.loadingDialog.isShowing()) myAct.loadingDialog.dismiss();
                    myAct. times = 0;
                    myAct.pictureLock = true;
                    myAct.textv_face_info.setVisibility(View.VISIBLE);
                    break;
                case 0x103:
                    if(myAct.pictureLock){
                        try {
                            myAct.detect();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    break;
                default:
                    break;
            }
        }

    }

    @Override
    protected void onDestroy() {
        //关闭人脸识别
        stopGoogleFaceDetect();
        //关闭摄像头
        CameraInterface.getInstance().doStopCamera();
        if(timer!=null){
            timer.cancel();
        }
        super.onDestroy();
    }
    private void uploadImage(String url,final JSONObject obj){
        if(loadingDialog!=null) {
            loadingDialog.setText("正在上传图片,请等待...");
            loadingDialog.show();}
        final String time = System.currentTimeMillis()+"";
        // 构造上传请求
        PutObjectRequest put = new PutObjectRequest("handbk",time+".jpg", url);
        // 异步上传时可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
            }
        });
        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                Log.d("PutObject", "UploadSuccess");
                try {
                    obj.put("aliyunPath", nameSapce+"/"+time+".jpg");
                    Log.d("PutObject", obj.toString());
                    notify.sendNotifyMessage(obj.toString());
                    if(loadingDialog!=null && loadingDialog.isShowing()) loadingDialog.dismiss();
                    FaceCompareActivity.this.finish();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
//                Toast.makeText(FaceCompareActivity.this,"上传成功"+result.toString(),Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                }
                if(loadingDialog!=null && loadingDialog.isShowing()) loadingDialog.dismiss();
                FaceCompareActivity.this.finish();
                Toast.makeText(FaceCompareActivity.this,"图片上传失败",Toast.LENGTH_SHORT).show();
            }
        });
        // task.cancel(); // 可以取消任务
        // task.waitUntilFinished(); // 可以等待任务完成
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(timer!=null){
            timer.cancel();
        }
        return super.onKeyDown(keyCode, event);
    }
}