package com.gensee.rtdemo;

import android.app.Activity;
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.gensee.callback.IRoomCallBack;
import com.gensee.callback.IVideoCallBack;
import com.gensee.common.RTSharedPref;
import com.gensee.common.ServiceType;
import com.gensee.demo.DemoConfig;
import com.gensee.demo.R;
import com.gensee.entity.LiveInfo;
import com.gensee.net.RtComp;
import com.gensee.room.RTRoom;
import com.gensee.room.RtSdk;
import com.gensee.routine.GSCountDownInfo;
import com.gensee.routine.GSResponderInfo;
import com.gensee.routine.LayoutInfo;
import com.gensee.routine.State;
import com.gensee.routine.UserInfo;
import com.gensee.taskret.OnTaskRet;
import com.gensee.utils.GenseeLog;
import com.gensee.videoparam.IVideoCoreInterface;
import com.gensee.videoparam.VideoParam;

import java.util.List;
import java.util.Map;

public class CustomCaptureActvity extends BaseActivity implements SurfaceHolder.Callback ,IRoomCallBack, IVideoCallBack {

    private static final String TAG = "CustomCaptureActvity";
    private SurfaceView surfaceView;
    private Camera camera;
    private RtSdk rtSdk;
    private IVideoCoreInterface videoSender;
    final int w = 640;
    final int h = 480;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_capture_actvity);


        surfaceView = findViewById(R.id.surfaceView);
        surfaceView.getHolder().addCallback(this);
        RTSharedPref.initPref(this);
        RTSharedPref.getIns().putInt("save.video.width", w);
        RTSharedPref.getIns().putInt("save.video.height", h);
        join();

    }



    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            //界面起来了可以先开始采集（如果直播中的尺寸受限制的话，需要在videoOpenCamera的时候重新设置一下这里的预览尺寸）

            int numberOfCameras = Camera.getNumberOfCameras();
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            for (int i = 0; i < numberOfCameras; i++) {
                Camera.getCameraInfo(i, cameraInfo);
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    camera = Camera.open(i);
                    break;
                }
            }
            if(camera != null){
                Camera.Parameters p = camera.getParameters();

                p.setPreviewSize(w,h);
                p.setPreviewFormat(ImageFormat.YV12);
                List<String> fms = p.getSupportedFocusModes();
                if(fms.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)){
                    p.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                }
                camera.setParameters(p);
                camera.setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        byte [] newData = new byte[data.length];
                        System.arraycopy(data,0,newData,0,data.length);
                        if(videoSender != null){
                            VideoParam vp = new VideoParam();
                            vp.fmt=16;
                            vp.width=w;
                            vp.height=h;
                            vp.rotate = 0;
                            videoSender.sendVideoData(newData,vp);
                        }
                    }
                });

                setCameraDisplayOrientation(this,cameraInfo,camera);
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void setCameraDisplayOrientation(Activity activity,
                                                   Camera.CameraInfo info, android.hardware.Camera camera) {

        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if(camera != null){
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    }


    private void join(){
        rtSdk = new RtSdk();
        rtSdk.setVideoCallBack(this);
//        rtSdk.setLocalVideoView(new IGSLocalVideoView() {
//            @Override
//            public void setGSLocalVideoViewType(IGSLocalVideoViewType igsLocalVideoViewType) {
//
//            }
//
//            @Override
//            public boolean isCameraSwitchEnable() {
//                return false;
//            }
//
//            @Override
//            public void doCameraSwitch() {
//
//            }
//
//            @Override
//            public int getOrientation() {
//                return ORIENTATION_PORTRAIT_UNCROP;
//            }
//
//            @Override
//            public void setOrientation(int i) {
//
//            }
//
//            @Override
//            public boolean isHolderCreated() {
//                return false;
//            }
//
//            @Override
//            public boolean close() {
//                return false;
//            }
//
//            @Override
//            public boolean open(Object o, IVideoCoreInterface iVideoCoreInterface) {
//                videoSender = iVideoCoreInterface;
//                return true;
//            }
//
//            @Override
//            public Camera getCamera() {
//                return null;
//            }
//
//            @Override
//            public void release() {
//                videoSender = null;
//            }
//
//            @Override
//            public void setHardEncode(boolean b) {
//
//            }
//
//            @Override
//            public boolean isVideoHardEncode() {
//                return false;
//            }
//
//            @Override
//            public void setVideoSize(int i, int i1) {
//
//            }
//
//            @Override
//            public void setOnCameraPermissionListener(OnCameraPermissionListener onCameraPermissionListener) {
//
//            }
//
//            @Override
//            public void setOnCameraInfoListener(OnCameraInfoListener onCameraInfoListener) {
//
//            }
//
//            @Override
//            public void setVideoCore(IVideoCoreInterface iVideoCoreInterface) {
//
//            }
//
//            @Override
//            public void setHardEncodeDataCallback(OnVideoHardEncodeDataCallback onVideoHardEncodeDataCallback) {
//
//            }
//
//            @Override
//            public void setFps(int i) {
//
//            }
//
//            @Override
//            public void setBitRate(int i) {
//
//            }
//
//            @Override
//            public void switchFlashOnOrOff(boolean b) {
//
//            }
//
//            @Override
//            public boolean isSupportFlashOnOrOff() {
//                return false;
//            }
//
//            @Override
//            public void focusOnTouch(double v, double v1, int i, int i1, int i2, int i3) {
//
//            }
//
//            @Override
//            public boolean isSupportFocusAuto() {
//                return false;
//            }
//
//            @Override
//            public void forceKeyFrame() {
//
//            }
//        });
        RtComp comp = new RtComp(this, new RtComp.Callback() {
            @Override
            public void onInited(String s) {
                rtSdk.initWithParam("", s, CustomCaptureActvity.this);
            }

            @Override
            public void onErr(int errCode) {
                GenseeLog.d(TAG, "onErr = " + errCode);
                switch (errCode) {
                    case ERR_DOMAIN:
                        toastMsg("domain不正确");
                        break;
                    case ERR_NUMBER_UNEXIST:
                        toastMsg("直播间不存在");
                        break;
                    case ERR_TOKEN:
                        toastMsg("口令错误");
                        break;
                    case ERR_SERVICE:
                        toastMsg("请选择正确服务类型（webcast meeting training）");
                        break;
                    case ERR_UN_NET:
                        toastMsg("请检查网络");
                        break;
                    case ERR_TIME_OUT:
                        toastMsg("连接超时，请重试");
                        break;
                    case ERR_PARAM:
                        toastMsg("initParam 为null 或 昵称为空");
                        break;
                    case ERR_THIRD_CERTIFICATION_AUTHORITY:
                        toastMsg("第三方认证失败");
                        break;
                    default:
                        toastMsg("初始化错误，错误码：" + errCode + ",请查对");
                        break;
                }
            }
        });
        comp.initWithGensee(DemoConfig.getIns().getInitParam());

    }

    /*-------------------------------------roomcallback---------------------------------------------*/

    @Override
    public void onInit(boolean b) {
        if(b){
            rtSdk.join(null);
        }
    }

    @Override
    public void onJoin(boolean b) {

    }

    @Override
    public void onRoomJoin(int result, UserInfo userInfo, boolean b) {
        GenseeLog.d(TAG, "onRoomJoin = " + result + " self " + userInfo);
        switch (result) {
            case JR_OK:
                toastMsg("加入成功");
                break;
            case JR_ERROR_HOST:
                toastMsg("组织者已经加入（老师已经加入）");
                break;
            case JR_ERROR_GETPARAM:
                toastMsg("加入参数错误");
                break;
            case JR_ERROR_LICENSE:
                toastMsg("人数已满");
                break;
            case JR_ERROR_LOCKED:
                toastMsg("直播间（课堂）被锁定");
                break;
            case JR_ERROR_CODEC:
                toastMsg("音频编码不匹配");
                break;

            default:
                break;
        }

        // 失败了请释放以便于重新加入
        if (result != JR_OK) {
            release();
        }
    }
    private void release() {
        // 释放房间实例，onTask响应之后才能重新加入
        rtSdk.release(new OnTaskRet() {

            @Override
            public void onTaskRet(boolean ret, int id, String desc) {
                // 房间从init-join-leave-release 到此结束
                toastMsg("释放完成，你可以重新加入");
                runOnUiThread(new Runnable() {
                    public void run() {
                        finish();
                    }
                });
                // app应该在此时关闭界面，至于触发退出到响应执行到此的时间间隔，app可以做一个对话框来增加交互的友好性
            }
        });

    }

    @Override
    public void onRoomLeave(int i) {
        release();
    }

    @Override
    public void onRoomReconnecting() {

    }

    @Override
    public void onRoomLock(boolean b) {

    }

    @Override
    public void onRoomUserJoin(UserInfo userInfo) {

    }

    @Override
    public void onRoomUserUpdate(UserInfo userInfo) {

    }

    @Override
    public void onRoomUserLeave(UserInfo userInfo) {

    }

    @Override
    public Context onGetContext() {
        return this;
    }

    @Override
    public ServiceType getServiceType() {
        return null;
    }

    @Override
    public void onRoomPublish(State state) {

    }

    @Override
    public void onRoomRecord(State state) {

    }

    @Override
    public void onRoomData(String s, long l) {

    }

    @Override
    public void onRoomBroadcastMsg(String s) {

    }

    @Override
    public void onRoomRollcall(int i) {

    }

    @Override
    public void onRoomRollcallAck(long l) {

    }

    @Override
    public void onRoomHandup(long l, String s) {

    }

    @Override
    public void onRoomHanddown(long l) {

    }

    @Override
    public void OnUpgradeNotify(String s) {

    }

    @Override
    public void onChatMode(int i) {

    }

    @Override
    public void onFreeMode(boolean b) {

    }

    @Override
    public void onLottery(byte b, String s) {

    }

    @Override
    public void onSettingSet(String s, int i) {

    }

    @Override
    public void onSettingSet(String s, String s1) {

    }

    @Override
    public int onSettingQuery(String s, int i) {
        if(RTSharedPref.KEY_VIDEO_W.equals(s)){
            return w;
        }
        else if(RTSharedPref.KEY_VIDEO_H.equals(s)){
            return  h;
        }
        return 0;
    }

    @Override
    public String onSettingQuery(String s) {
        return null;
    }

    @Override
    public void onNetworkReport(byte b) {

    }

    @Override
    public void onNetworkBandwidth(int i, int i1) {

    }

    @Override
    public void onRoomPhoneServiceStatus(boolean b) {

    }

    @Override
    public void onRoomPhoneCallingStatus(String s, int i, int i1) {

    }

    @Override
    public void onRoomWebLayoutChange(int i) {

    }

    @Override
    public void onLessonTimerPaused(boolean b) {

    }

    @Override
    public void onLessonTimerStart(long l) {

    }

    @Override
    public void onLiveInfo(LiveInfo liveInfo) {

    }

    /**********-----------------------IVideoCallback----------------------*******/

    @Override
    public void onVideoJoinConfirm(boolean b) {
        GenseeLog.i(TAG,"onVideoJoinConfirm " + b);
        if(b){
            rtSdk.videoOpenCamera(null);
        }
    }

    @Override
    public void onVideoCameraAvailiable(boolean b) {

    }

    @Override
    public void onVideoCameraOpened() {
        videoSender = (IVideoCoreInterface) RTRoom.getIns().getVideoEvent();
    }

    @Override
    public void onVideoCameraClosed() {
        videoSender = null;
    }

    @Override
    public void onVideoJoin(UserInfo userInfo) {

    }

    @Override
    public void onVideoLeave(long l) {

    }

    @Override
    public void onVideoActived(UserInfo userInfo, boolean b) {

    }

    @Override
    public void onVideoDisplay(UserInfo userInfo) {

    }

    @Override
    public void onVideoUndisplay(long l) {

    }

    @Override
    public void onVideoDataRender(long l, int i, int i1, int i2, float v, byte[] bytes) {

    }

    @Override
    public void onBackPressed() {
        rtSdk.leave(false,null);
    }

    @Override
    public void onRoomClassAlarm(int i) {

    }

    @Override
    public void onRoomBroadcastCmd(Map map) {

    }

    @Override
    public void onLayoutSync(LayoutInfo layoutInfo) {

    }

    @Override
    public void onRoomData(String s, String s1) {

    }

    @Override
    public void onRandomSelect(byte b, String s) {

    }

    @Override
    public void onRoomCountDown(GSCountDownInfo gsCountDownInfo) {

    }

    @Override
    public void onRoomPresentorChanged(long l) {

    }

    @Override
    public void onRoomResponsderInfo(GSResponderInfo gsResponderInfo) {

    }

    @Override
    public void onRoomNavigate(String s) {

    }

    @Override
    public void onRoomClassReuninCmd() {

    }

    @Override
    public void onRoomClassSeparateCmd() {

    }

    @Override
    public void onRoomSubClassUserNum(int i) {

    }

    @Override
    public void onRoomDBTDataPrepared() {

    }
}
