package com.huawei.pushpuresdkdemo;

import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.params.MeteringRectangle;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.Toast;

import com.github.faucamp.simplertmp.RtmpHandler;
import com.huawei.publishsdk.HWVideoFrame;
import com.huawei.publishsdk.HwCamera2View;
import com.huawei.publishsdk.HwEncodeHandler;
import com.huawei.publishsdk.HwPublisher;
import com.huawei.publishsdk.HwRecordHandler;

import java.io.IOException;
import java.net.SocketException;

import static android.widget.Toast.LENGTH_SHORT;
import static com.huawei.publishsdk.HwPublisher.NV21;

public class Main3Activity extends AppCompatActivity implements HwEncodeHandler.HwEncodeListener, RtmpHandler.RtmpListener, HwRecordHandler.HwRecordListener {
    private static final String TAG = "Main3Activity";
    private HwCamera2View mCameraView;
    private Button btnSwitchCamera;
    private SeekBar sbZoom;
    private ScaleGestureDetector mScaleDetector;
    private int mScaleFactor = 1;
    public boolean mIsFocus;
    private FocusImageView mFocusImageView;
    private Button btnSwitchEncoder;
    private String codecString = "video/hevc";
    private Button btnPublish;
    private Button btnMediaType;
    private HwPublisher mPublisher;
    private EditText etUrl;
    //对于HEVC编码推流，需要源站支持才行。
    private String rtmpUrl = "rtmp://114.116.233.229/live/5g?vhost=live.myhwclouds.com.cn";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);

        Window window = this.getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        mCameraView = (HwCamera2View) findViewById(R.id.camera_view);
        btnSwitchCamera = (Button) findViewById(R.id.swCam);
        sbZoom = (SeekBar) findViewById(R.id.sb_zoom);
        mScaleDetector = new ScaleGestureDetector(this, new ScaleListener());
        mFocusImageView = (FocusImageView) findViewById(R.id.focusImageView);
        btnSwitchEncoder = (Button) findViewById(R.id.swEnc);
        btnMediaType = (Button) findViewById(R.id.MediaType);
        btnPublish = (Button) findViewById(R.id.publish);
        etUrl = (EditText)findViewById(R.id.url);

        etUrl.setText(rtmpUrl);

        btnSwitchCamera.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onClick(View v) {
                if (mCameraView != null) {

                    if(mCameraView.getCameraId().equals("0"))
                        mCameraView.switchCamera("1");
                    else {
                        mCameraView.switchCamera("0");
                    }

                    if(mCameraView!=null){
                        mCameraView.setPreviewResolution(3840,2160);
                        int[] res =  mCameraView.getPreviewResolution();
                        Log.e(TAG, "onClick getPreviewResolution: "+ res[0]+"*"+res[1]);
                        if(mPublisher!=null){
                            mPublisher.reSetEncoderResolution(res[0],res[1]);
                        }
                    }
                }
            }
        });

        sbZoom.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                Log.e(TAG, "当前进度值:" + progress + "  / 100 ");
//                mPublisher.setFocusMode(FOCUS_MODE_AUTO);
                if((mCameraView!=null)){
                    mCameraView.setZoom(progress);
//                    mCameraView.startAutoFocus();
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.e(TAG, "触碰SeekBar:");
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.e(TAG, "放开SeekBar:");
            }
        });

        btnSwitchEncoder.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onClick(View v) {
                if (btnSwitchEncoder.getText().toString().contentEquals("HEVC encoder")) {
                    codecString = "video/avc";
                    btnSwitchEncoder.setText("H.264 encoder");
                } else if (btnSwitchEncoder.getText().toString().contentEquals("H.264 encoder")) {
                    codecString = "video/hevc";
                    btnSwitchEncoder.setText("HEVC encoder");
                }
            }
        });

        btnPublish.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onClick(View v) {
                if (btnPublish.getText().toString().contentEquals("publish")) {
                    //这里回调根据需要使用，不需要摄像头数据回调时，可以设置为null
                    mPublisher = new HwPublisher(Main3Activity.this, mCameraView, new HwPublisher.HwPreviewCallback() {
                        @Override
                        public void onGetHwVideoFrame(HWVideoFrame hwVideoFrame) {
                            //回调摄像头采集原始数据，格式 NV21
                            //mPublisher.pushExternVideoFrame(hwVideoFrame);
                        }
                    }, false);

                    mPublisher.setEncodeHandler(new HwEncodeHandler(Main3Activity.this),codecString);
                    mPublisher.setRtmpHandler(new RtmpHandler(Main3Activity.this),codecString);
                    mPublisher.setRecordHandler(new HwRecordHandler(Main3Activity.this));

                    if(!mPublisher.isEncodeEnabled())
                    {
                        Toast.makeText(Main3Activity.this,"不支持编码器："+codecString,LENGTH_SHORT);
                        return;
                    }

                    mCameraView.setPreviewResolution(3840, 2160);
                    mCameraView.setPreviewFps(30);

                    mPublisher.setOutputResolution(3840, 2160);
                    mPublisher.setVfps(30);
                    mPublisher.switchToHardEncoder();
                    mPublisher.setVBitrate(8*1000*1000);

                    mPublisher.setStatisticEnable(true);
                    mPublisher.startAudioRecord();
                    mPublisher.startPublish(etUrl.getText().toString());
                    btnPublish.setText("stop");
                    btnSwitchEncoder.setEnabled(false);
                } else if (btnPublish.getText().toString().contentEquals("stop")) {
                    Log.e(TAG, "onClick: 1111111");
                    if(mPublisher!=null){
                        mPublisher.stopAudioRecord();
                        Log.e(TAG, "onClick: 222222");
                        mPublisher.stopPublish();
                        mPublisher.release();
                        Log.e(TAG, "onClick: 33333");
                        mPublisher = null;
                    }
                    Log.e(TAG, "onClick: 44444");
                    btnPublish.setText("publish");
                    btnSwitchEncoder.setEnabled(true);
                }
            }
        });

        btnMediaType.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mPublisher==null)
                    return;
                if(btnMediaType.getText().toString().equals("AUDIO+VIDEO")){

                    mPublisher.setSendType(HwPublisher.sendAudioOnly);
                    mPublisher.stopCamera();
                    btnMediaType.setText("AUDIO");
                }else if(btnMediaType.getText().toString().equals("AUDIO")){
                    mPublisher.setSendType(HwPublisher.sendVideoOnly);
                    mPublisher.startCamera();
                    btnMediaType.setText("VIDEO");
                }
                else{
                    mPublisher.setSendType(HwPublisher.sendAudioVideoBoth);
                    mPublisher.startCamera();
                    btnMediaType.setText("AUDIO+VIDEO");
                }
            }
        });
    }

    @Override
    public void onNetworkWeak() {

    }

    @Override
    public void onNetworkResume() {

    }

    @Override
    public void onEncodeIllegalArgumentException(IllegalArgumentException e) {

    }

    @Override
    public void onRtmpConnecting(String s) {

    }

    @Override
    public void onRtmpConnected(String s) {

    }

    @Override
    public void onRtmpVideoStreaming() {

    }

    @Override
    public void onRtmpAudioStreaming() {

    }

    @Override
    public void onRtmpStopped() {

    }

    @Override
    public void onRtmpDisconnected() {

    }

    @Override
    public void onRtmpVideoFpsChanged(double v) {

    }

    @Override
    public void onRtmpVideoBitrateChanged(double v) {

    }

    @Override
    public void onRtmpAudioBitrateChanged(double v) {

    }

    @Override
    public void onRtmpSocketException(SocketException e) {

    }

    @Override
    public void onRtmpIOException(IOException e) {

    }

    @Override
    public void onRtmpIllegalArgumentException(IllegalArgumentException e) {

    }

    @Override
    public void onRtmpIllegalStateException(IllegalStateException e) {

    }

    @Override
    public void onRecordPause() {

    }

    @Override
    public void onRecordResume() {

    }

    @Override
    public void onRecordStarted(String s) {

    }

    @Override
    public void onRecordFinished(String s) {

    }

    @Override
    public void onRecordIllegalArgumentException(IllegalArgumentException e) {

    }

    @Override
    public void onRecordIOException(IOException e) {

    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFactor = (int) detector.getScaleFactor();
            if (mCameraView != null) {
                try {
                    setZoom();
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }
            return true;
        }
    }
    private static final int ZOOM_OUT = 0;
    private static final int ZOOM_IN = 1;
    private static final int ZOOM_DELTA = 2;
//setPreviewBuilderFocusRegion(MeteringRectangle[] meteringRectangleArr)
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void setZoom() throws CameraAccessException {
        int zoom = mCameraView.getZoom();
        if (mScaleFactor == ZOOM_IN) {
            if (zoom < mCameraView.getMaxZoom()) zoom += ZOOM_DELTA;
        } else if (mScaleFactor == ZOOM_OUT) {
            if (zoom > 0) zoom -= ZOOM_DELTA;
        }
        mCameraView.setZoom(zoom);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e(TAG, "onTouchEvent getZoom: " +mCameraView.getZoom());
        if(mScaleDetector!=null){
            Log.e(TAG, "dispatchTouchEvent mScaleDetector is not null! ");
            mScaleDetector.onTouchEvent(event);
        }

        switch (event.getAction()& MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_DOWN! ");
                mIsFocus = true;
                break;
            case MotionEvent.ACTION_UP:
                Point pointFocus =new Point((int)event.getX(),(int)event.getY());
                Rect maxRect =  mCameraView.getMaxRect();
                if(pointFocus.x-100<0||pointFocus.y-100<0)
                    return super.onTouchEvent(event);
                MeteringRectangle rectangle = new MeteringRectangle(pointFocus.x-100,pointFocus.y-100,200,200,MeteringRectangle.METERING_WEIGHT_DONT_CARE);
                Log.e(TAG, "dispatchTouchEvent ACTION_UP! ");
                if(rectangle.getX()<0||rectangle.getX()>maxRect.right||rectangle.getY()<0||rectangle.getY()>maxRect.right||(rectangle.getX()+200)>maxRect.right||(rectangle.getY()+200)>maxRect.bottom)
                    return super.onTouchEvent(event);
                Log.e(TAG, "onTouchEvent x: "+rectangle.getX()+" Y: " +rectangle.getY());
                if (mIsFocus) {
                    mFocusImageView.startFocus(pointFocus);
                    if ( mCameraView != null) {
//                        mCameraView.setPreviewBuilderUnlockfocus();
                        //setPreviewBuilderFocusRegion(MeteringRectangle[] meteringRectangleArr)
                        mCameraView.setPreviewBuilderFocusTrigger();
                        mCameraView.setPreviewBuilderFocusRegion(new MeteringRectangle[]{rectangle});
//                        mCameraView.setPreviewBuilderLockfocus();
                    }
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                Log.e(TAG, "dispatchTouchEvent ACTION_POINTER_DOWN! ");
                mIsFocus = false;
                break;
        }
        return super.onTouchEvent(event);
    }
}
