package com.huawei.interactivebroadcastingwithcdnstreaming.screenlive.app;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.huawei.hwinteractivesdk.HWConstants;
import com.huawei.hwinteractivesdk.HWRtcEngine;
import com.huawei.hwinteractivesdk.HWRtcEngineEventHandler;
import com.huawei.hwinteractivesdk.HWVideoEncoderConfiguration;
import com.huawei.hwinteractivesdk.HWVideoFrame;
import com.huawei.interactivebroadcastingwithcdnstreaming.R;
import com.huawei.interactivebroadcastingwithcdnstreaming.screenlive.GLRender;
import com.huawei.interactivebroadcastingwithcdnstreaming.screenlive.ImgTexFrame;
import com.huawei.interactivebroadcastingwithcdnstreaming.screenlive.SinkConnector;
import com.huawei.interactivebroadcastingwithcdnstreaming.screenlive.capture.ScreenCapture;

import static com.huawei.hwinteractivesdk.HWVideoEncoderConfiguration.VD_1280x720;
import static com.huawei.interactivebroadcastingwithcdnstreaming.MainActivity.CLIENT_ROLE_BROADCASTER;

public class ScreenLiveActivity extends Activity {

    private static final String LOG_TAG = "ScreenLive";

    private static final int PERMISSION_REQ_ID_RECORD_AUDIO = 22;

    private ScreenCapture mScreenCapture;
    private GLRender mScreenGLRender;

    private HWRtcEngine mRtcEngine;

    private boolean mIsLandSpace = false;

    private String mChannelName;
    private String mPublishUrl = "";
    private String mAPPid = "";
    private String mTempToken;
    private String mUid;
    private int mRole;

    private void initModules() {
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);

        if (mScreenGLRender == null) {
            mScreenGLRender = new GLRender();
        }
        if (mScreenCapture == null) {
            mScreenCapture = new ScreenCapture(getApplicationContext(), mScreenGLRender, metrics.densityDpi);
        }

        mScreenCapture.mImgTexSrcConnector.connect(new SinkConnector<ImgTexFrame>() {
            @Override
            public void onFormatChanged(Object obj) {
                Log.d(LOG_TAG, "onFormatChanged " + obj.toString());
            }

            @Override
            public void onFrameAvailable(ImgTexFrame frame) {
                Log.d(LOG_TAG, "onFrameAvailable " + frame.toString());

                if (mRtcEngine == null) {
                    return;
                }

                HWVideoFrame vf = new HWVideoFrame();
                vf.format = HWVideoFrame.FORMAT_TEXTURE_OES;
                vf.timeStamp = frame.pts;
                vf.stride = frame.mFormat.mWidth;
                vf.height = frame.mFormat.mHeight;
                vf.textureID = frame.mTextureId;
                vf.syncMode = true;
                vf.eglContext14 = mScreenGLRender.getEGLContext();
                vf.transform = frame.mTexMatrix;

                mRtcEngine.pushExternalVideoFrame(vf);
            }
        });

        mScreenCapture.setOnScreenCaptureListener(new ScreenCapture.OnScreenCaptureListener() {
            @Override
            public void onStarted() {
                Log.d(LOG_TAG, "Screen Record Started");
            }

            @Override
            public void onError(int err) {
                Log.d(LOG_TAG, "onError " + err);
                switch (err) {
                    case ScreenCapture.SCREEN_ERROR_SYSTEM_UNSUPPORTED:
                        break;
                    case ScreenCapture.SCREEN_ERROR_PERMISSION_DENIED:
                        break;
                }
            }
        });

        WindowManager wm = (WindowManager) getApplicationContext()
                .getSystemService(Context.WINDOW_SERVICE);
        int screenWidth = wm.getDefaultDisplay().getWidth();
        int screenHeight = wm.getDefaultDisplay().getHeight();
        if ((mIsLandSpace && screenWidth < screenHeight) ||
                (!mIsLandSpace) && screenWidth > screenHeight) {
            screenWidth = wm.getDefaultDisplay().getHeight();
            screenHeight = wm.getDefaultDisplay().getWidth();
        }

        setOffscreenPreview(screenWidth, screenHeight);

        if (mRtcEngine == null) {
            try {
                mRtcEngine = HWRtcEngine.getInstance().create(this, getString(R.string.huawei_app_id), new HWRtcEngineEventHandler() {
                    @Override
                    public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
                        Log.d(LOG_TAG, "onJoinChannelSuccess " + channel + " " + elapsed);
                    }

                    @Override
                    public void onWarning(int warn) {
                        Log.d(LOG_TAG, "onWarning " + warn);
                    }

                    @Override
                    public void onError(int err) {
                        Log.d(LOG_TAG, "onError " + err);
                    }

                    @Override
                    public void onAudioRouteChanged(int routing) {
                        Log.d(LOG_TAG, "onAudioRouteChanged " + routing);
                    }
                });
            } catch (Exception e) {
                Log.e(LOG_TAG, Log.getStackTraceString(e));

                throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
            }

            mRtcEngine.enableVideo();

            if (mRtcEngine.isTextureEncodeSupported()) {
                mRtcEngine.setExternalVideoSource(true, true);
            } else {
                throw new RuntimeException("Can not work on device do not supporting texture" + mRtcEngine.isTextureEncodeSupported());
            }

//            mRtcEngine.setVideoProfile(Constants.VIDEO_PROFILE_360P, true);

            HWVideoEncoderConfiguration hwVideoEncoderConfiguration = new HWVideoEncoderConfiguration();
            hwVideoEncoderConfiguration.bitrate = 2260;
            hwVideoEncoderConfiguration.dimensions = VD_1280x720;
            mRtcEngine.setVideoEncoderConfiguration(hwVideoEncoderConfiguration);

            mRtcEngine.setClientRole(HWConstants.CLIENT_ROLE_BROADCASTER);
        }
    }

    private void deInitModules() {
        if(mRtcEngine!=null){
            mRtcEngine.release();
            mRtcEngine = null;
        }

        if (mScreenCapture != null) {
            mScreenCapture.release();
            mScreenCapture = null;
        }

        if (mScreenGLRender != null) {
            mScreenGLRender.quit();
            mScreenGLRender = null;
        }
    }

    /**
     * Set offscreen preview.
     *
     * @param width  offscreen width
     * @param height offscreen height
     * @throws IllegalArgumentException
     */
    public void setOffscreenPreview(int width, int height) throws IllegalArgumentException {
        if (width <= 0 || height <= 0) {
            throw new IllegalArgumentException("Invalid offscreen resolution");
        }

        mScreenGLRender.init(width, height);
    }

    private void startCapture() {
        mScreenCapture.start();
    }

    private void stopCapture() {
        mScreenCapture.stop();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen_live);

        checkSelfPermission(Manifest.permission.RECORD_AUDIO, PERMISSION_REQ_ID_RECORD_AUDIO);

        Intent i = getIntent();
        mChannelName = i.getStringExtra("CHANNEL");
        mPublishUrl = i.getStringExtra("URL");
        mAPPid = i.getStringExtra("APPID");
        mTempToken = i.getStringExtra("TOKEN");
        mUid = i.getStringExtra("UID");
        mRole = i.getIntExtra("ROLE",CLIENT_ROLE_BROADCASTER);
    }

    public void onLiveSharingScreenClicked(View view) {
        if (!checkSelfPermission(Manifest.permission.RECORD_AUDIO, PERMISSION_REQ_ID_RECORD_AUDIO)) {
            return;
        }

        Button button = (Button) view;
        boolean selected = button.isSelected();
        button.setSelected(!selected);

        if (button.isSelected()) {
            initModules();
            startCapture();

//            String channel = "ss_test" + System.currentTimeMillis();
//            channel = "ss_test";

            TextView tv = (TextView) findViewById(R.id.channel_name_info);
            tv.setText(getString(R.string.label_channel_info, mChannelName));

            button.setText(R.string.label_stop_sharing_your_screen);
            mRtcEngine.muteAllRemoteAudioStreams(true);
            mRtcEngine.muteAllRemoteVideoStreams(true);
            mRtcEngine.joinChannel(mTempToken, mChannelName, "", mUid,"", mRole);
        } else {
            TextView tv = (TextView) findViewById(R.id.channel_name_info);
//            tv.setText("请点击开始录屏直播");

            button.setText(R.string.label_start_sharing_your_screen);

            mRtcEngine.leaveChannel();

            stopCapture();
        }
    }

//    mChannelName = i.getStringExtra("CHANNEL");
//    mPublishUrl = i.getStringExtra("URL");
//    mAPPid = i.getStringExtra("APPID");
//    mTempToken = i.getStringExtra("TOKEN");
//    mUid = i.getStringExtra("UID");
//    mRole = i.getIntExtra("ROLE",CLIENT_ROLE_BROADCASTER);

    public boolean checkSelfPermission(String permission, int requestCode) {
        Log.i(LOG_TAG, "checkSelfPermission " + permission + " " + requestCode);
        if (ContextCompat.checkSelfPermission(this,
                permission)
                != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this,
                    new String[]{permission},
                    requestCode);
            return false;
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[], @NonNull int[] grantResults) {
        Log.i(LOG_TAG, "onRequestPermissionsResult " + grantResults[0] + " " + requestCode);

        switch (requestCode) {
            case PERMISSION_REQ_ID_RECORD_AUDIO: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                } else {
                    showLongToast("No permission for " + Manifest.permission.RECORD_AUDIO);
                    finish();
                }
                break;
            }
        }
    }

    public final void showLongToast(final String msg) {
        this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
            }
        });
    }

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

        deInitModules();
    }
}
