package com.kfzs.cfyl.media.activity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.SeekBar;

import com.kfzs.cfyl.media.BaseContainerActivity;
import com.kfzs.cfyl.media.R;
import com.kfzs.cfyl.media.api.Filterble;
import com.kfzs.cfyl.media.api.IFilter;
import com.kfzs.cfyl.media.api.Levelble;
import com.kfzs.cfyl.media.bean.BeautifyFilter;
import com.kfzs.cfyl.media.bean.Size;
import com.kfzs.cfyl.media.fragment.FgtChooseEditList;
import com.kfzs.cfyl.media.util.BitmapUtil;
import com.kfzs.cfyl.media.util.G;
import com.kfzs.cfyl.media.util.ViewUtil;
import com.kfzs.cfyl.share_library.util.LogUtil;
import com.sheep.gamegroup.model.entity.Video;

import org.wysaid.common.Common;
import org.wysaid.nativePort.CGEFFmpegNativeLibrary;
import org.wysaid.nativePort.CGENativeLibrary;
import org.wysaid.view.VideoPlayerGLSurfaceView;

import java.util.Locale;

import cn.finalteam.rxgalleryfinal.utils.MediaUtils;

/**
 * Created by realicing on 2018/11/9.
 * realicing@sina.com
 * 编辑视频
 */
public class ActEditVideo extends BaseContainerActivity implements Filterble, Levelble {

    @Override
    protected int getLayoutId() {
        return R.layout.media_act_edit_video;
    }

    VideoPlayerGLSurfaceView mPlayerView;

    private Video data;

    private String mCurrentConfig;//滤镜配置
    private float mIntensity = 1.0f;
    private int mBeautifyLevel = 0;//磨皮系数

    public static final int REQUEST_CODE_PICK_VIDEO = 1;

    private VideoPlayerGLSurfaceView.PlayCompletionCallback playCompletionCallback = new VideoPlayerGLSurfaceView.PlayCompletionCallback() {
        @Override
        public void playComplete(MediaPlayer player) {
            Log.i(Common.LOG_TAG, "The video playing is over, restart...");
            player.start();
        }

        @Override
        public boolean playFailed(MediaPlayer player, final int what, final int extra) {
            G.showToast(getApplicationContext(), "播放出错，请稍候重试");
            return true;
        }
    };
    @Override
    public void initView() {
        if (this instanceof BaseContainerActivity) {
            super.initView();
        }
        mPlayerView = findViewById(R.id.videoGLSurfaceView);
        data = (Video) getIntent().getSerializableExtra(Video.class.getSimpleName());
        mPlayerView.setZOrderOnTop(false);
        mPlayerView.setZOrderMediaOverlay(true);


        mPlayerView.setPlayerInitializeCallback(new VideoPlayerGLSurfaceView.PlayerInitializeCallback() {
            @Override
            public void initPlayer(final MediaPlayer player) {
                //针对网络视频进行进度检查
                player.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
                    @Override
                    public void onBufferingUpdate(MediaPlayer mp, int percent) {
                        Log.i(Common.LOG_TAG, "Buffer update: " + percent);
                        if (percent == 100) {
                            Log.i(Common.LOG_TAG, "缓冲完毕!");
                            player.setOnBufferingUpdateListener(null);
                        }
                    }
                });
            }
        });

        mPlayerView.setVideoUri(Uri.parse(data.getFilePath()), new VideoPlayerGLSurfaceView.PlayPreparedCallback() {
            @Override
            public void playPrepared(MediaPlayer player) {
                Log.i(Common.LOG_TAG, "The video is prepared to play");
                player.start();
            }
        }, playCompletionCallback);

        seekBarLl = findViewById(R.id.seekBarLl);
        if (ViewUtil.isVisible(seekBarLl)) {
            loadTest();
        }
    }

    //点击完成
    public void onClickCommit(View view) {
        if(TextUtils.isEmpty(mCurrentConfig)){
            setResultAndFinish();
            return;
        }
        showProgress().getTextView().setText("编辑视频中");
        new Thread(new Runnable() {
            @Override
            public void run() {
                final String filePath = tryGenerateVideoWithFilter();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + filePath)));
                        data.setFilePath(filePath);
                        hideProgress();
                        G.showToast(getApplicationContext(), "编辑完成");
                        setResultAndFinish();
                    }
                });
            }
        }).start();
    }

    private void setResultAndFinish() {
        Intent intent = new Intent();
        intent.putExtra(Video.class.getSimpleName(), data);
        setResult(RESULT_OK, intent);
        ActEditVideo.this.finish();
    }

    private String tryGenerateVideoWithFilter() {
        String srcFilPath = data.getFilePath();
        String outputFilename = String.format(Locale.CHINA, "%s_%d_%f.mp4", srcFilPath.substring(0, srcFilPath.lastIndexOf(".")), mCurrentConfig.hashCode(), mIntensity);
        Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.media_sheep_logo_3);
        //left 30px top 60px width 750
        Bitmap logo = data.getOrientation() / 90 % 2 == 0 ?
            BitmapUtil.createBigLogo(bmp, new Size().setWidth(data.getWidth()).setHeight(data.getHeight()).setX(data.getWidth() * 30 / 750).setY(data.getWidth() * 60 / 750)) :
            BitmapUtil.createBigLogo(bmp, new Size().setWidth(data.getHeight()).setHeight(data.getWidth()).setX(data.getHeight() * 30 / 750).setY(data.getHeight() * 60 / 750));
        Bitmap rotateBmp = data.getOrientation() != 0 ? MediaUtils.rotateBimap(360 - data.getOrientation(), logo) : logo;
        if(logo != rotateBmp)
            logo.recycle();
        bmp.recycle();

        CGEFFmpegNativeLibrary.generateVideoWithFilter(outputFilename, srcFilPath, mCurrentConfig, mIntensity, rotateBmp, CGENativeLibrary.TextureBlendMode.CGE_BLEND_ADDREV, 1.0f, false);
        rotateBmp.recycle();
        LogUtil.println(ActEditVideo.class.getSimpleName(), "Done! The file is generated at: " + outputFilename);
        return outputFilename;
    }

    private IFilter filter;
    //设置滤镜
    @Override
    public void setFilter(IFilter filter) {
        if (mPlayerView != null && filter != null && filter.getConfig() != null) {
            this.filter = filter;
            initCurrentConfig();
        }
    }
    private void initCurrentConfig(){
        StringBuilder config = new StringBuilder();
        String filterConfig = "";
        if(filter != null){
            filterConfig = filter.getConfig();
            config.append(filterConfig);
            config.append(" ");
        }
        if(mBeautifyLevel > 0){
            config.append(BeautifyFilter.getConfig(mBeautifyLevel, G.WIDTH, G.HEIGHT));
        }
        mCurrentConfig = config.toString().trim();
        LogUtil.println("initCurrentConfig", mCurrentConfig, filterConfig, mBeautifyLevel);
        mPlayerView.setFilterWithConfig(mCurrentConfig);
    }

    @Override
    public void setFilterIntensity(float intensity) {
        if (mPlayerView != null) {
            mIntensity = intensity;
            mPlayerView.setFilterIntensity(mIntensity);
        }
    }
    @Override
    public void setLevel(int level) {
        LogUtil.println(ActEditVideo.class.getSimpleName(), "setLevel", level);
        if (mPlayerView != null) {
            mBeautifyLevel = level;
            initCurrentConfig();
        }
    }

    //下面为测试代码

    private void loadTest() {

        for (int i = 0; i < 6; i++) {
            SeekBar sb = new SeekBar(getApplicationContext());
            sb.setMax(100);
            sb.setProgress(50);
            seekBarLl.addView(sb);
            final int finalI = i;
            sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
                    onSeek(finalI, progress);
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                }
            });
        }
    }

    LinearLayout seekBarLl;

    private int[] progresses = {50, 50, 50, 50, 50, 50};

    private float getPercent(int index) {
        return (progresses[index] - 50) / 50.0f;
    }

    private int getPercent(int index, int max) {
        return progresses[index] * max / 100;
    }

    private void onSeekHsv(int index, int progress) {
        progresses[index] = progress;//色调（H），饱和度（S），明度（V）
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@adjust hsv %.2f %.2f %.2f %.2f %.2f %.2f", getPercent(i++), getPercent(i++), getPercent(i++), getPercent(i++), getPercent(i++), getPercent(i)));
    }

    private void onSeekHsl(int index, int progress) {
        progresses[index] = progress;//0,0,0 色相(H)、饱和度(S)、明度(L)
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@adjust hsl %.2f %.2f %.2f", getPercent(i++), getPercent(i++), getPercent(i)));
    }

    private void onSeekRgb(int index, int progress) {
        progresses[index] = progress;//0,0,255,255 黑<白、反光<亮度
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@curve RGB(%d, %d)(%d, %d)", getPercent(i++, 255), getPercent(i++, 255), getPercent(i++, 255), getPercent(i, 255)));
    }

    private void onSeekLevel(int index, int progress) {
        progresses[index] = progress;//0,1,1
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@adjust level %.2f %.2f %.2f ", getPercent(i++), getPercent(i++), getPercent(i)));
    }

    private void onSeekSaturation(int index, int progress) {
        progresses[index] = progress;//1 饱和度
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@adjust saturation %.2f ", getPercent(0)));
    }

    private void onSeek/*ColorBalance*/(int index, int progress) {
        progresses[index] = progress;//0,0,0 红绿蓝
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@adjust colorbalance %.2f %.2f %.2f ", getPercent(i++), getPercent(i++), getPercent(i)));
    }

    private void onSeekHaze(int index, int progress) {
        progresses[index] = progress;
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@style haze %.2f %.2f %.2f %.2f %.2f ", getPercent(i++), getPercent(i++), getPercent(i++), getPercent(i++), getPercent(i)));
    }

    private static String[] TYPES = {"overlay", "colordodge", "pinlight", "ol", "screen"};

    private void onSeekPixBlend(int index, int progress) {
        progresses[index] = progress;
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@adjust saturation %.2f @pixblend %s %.2f %.2f %.2f %d ", getPercent(i++), TYPES[progresses[1] / 20 % TYPES.length], getPercent(i++), getPercent(i++), getPercent(i++), getPercent(i, 40)));
    }

    private void onSeekCurve(int index, int progress) {
        progresses[index] = progress;
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@curve R(%d, %d)(%d, %d)(%d, %d) ", getPercent(i++, 255), getPercent(i++, 255), getPercent(i++, 255), getPercent(i++, 255), getPercent(i++, 255), getPercent(i++, 255)));
    }

    private void onSeekBeautify(int index, int progress) {
        progresses[index] = progress;
        int i = 0;
        mPlayerView.setFilterWithConfig(String.format(Locale.CHINA, "@beautify face %d %d, %d ", getPercent(i++, 2), getPercent(i++, 1000), getPercent(i++, 1000)));
    }

    View.OnClickListener galleryBtnClickListener = new View.OnClickListener() {

        @Override
        public void onClick(final View view) {
            Intent videoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
            videoPickerIntent.setType("video/*");
            startActivityForResult(videoPickerIntent, REQUEST_CODE_PICK_VIDEO);
        }
    };

    @Override
    public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        switch (requestCode) {
            case REQUEST_CODE_PICK_VIDEO:
                if (resultCode == RESULT_OK) {

                    mPlayerView.setVideoUri(data.getData(), new VideoPlayerGLSurfaceView.PlayPreparedCallback() {
                        @Override
                        public void playPrepared(MediaPlayer player) {
                            Log.i(Common.LOG_TAG, "The video is prepared to play");
                            player.start();
                        }
                    }, playCompletionCallback);
                }
            default:
                break;
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.i(VideoPlayerGLSurfaceView.LOG_TAG, "activity onPause...");
        mPlayerView.release();
        mPlayerView.onPause();
    }

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

        mPlayerView.onResume();
    }

    @Override
    protected Fragment initFragment() {
        return new FgtChooseEditList();
    }

}
