package com.sheep.gamegroup.module.find.activity;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.AppCompatButton;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.SeekBar;

import com.kfzs.duanduan.utils.StatusBarUtils;
import com.sheep.gamegroup.absBase.AbsObserver;
import com.sheep.gamegroup.absBase.BaseContainerActivity;
import com.sheep.gamegroup.module.find.util.Filterble;
import com.sheep.gamegroup.module.find.util.IFilter;
import com.sheep.gamegroup.module.find.bean.Size;
import com.sheep.gamegroup.module.find.fragment.FgtChooseEditList;
import com.sheep.gamegroup.model.entity.Video;
import com.sheep.gamegroup.util.BitmapUtil;
import com.sheep.gamegroup.util.DataUtil;
import com.sheep.gamegroup.util.LogUtil;
import com.sheep.gamegroup.util.TestUtil;
import com.sheep.gamegroup.util.ViewUtil;
import com.sheep.gamegroup.util.viewHelper.CacheImageUtil;
import com.sheep.jiuyan.samllsheep.R;
import com.sheep.jiuyan.samllsheep.SheepApp;
import com.sheep.jiuyan.samllsheep.utils.G;

import org.greenrobot.eventbus.EventBus;
import org.wysaid.common.Common;
import org.wysaid.myUtils.ImageUtil;
import org.wysaid.nativePort.CGEFFmpegNativeLibrary;
import org.wysaid.nativePort.CGEFrameRenderer;
import org.wysaid.nativePort.CGENativeLibrary;
import org.wysaid.view.VideoPlayerGLSurfaceView;

import java.io.File;
import java.util.Locale;

import butterknife.BindView;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import rx.functions.Action1;

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

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        StatusBarUtils.setTranslucent(this);
        super.onCreate(savedInstanceState);
    }

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

    @BindView(R.id.videoGLSurfaceView)
    VideoPlayerGLSurfaceView mPlayerView;

    private Video data;

    private String mCurrentConfig;
    private float mIntensity = 1.0f;

    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) {
            if (TestUtil.isDev())
                G.showToast(String.format(Locale.CHINA, "播放出错！错误码: %d, %d", what, extra));
            else
                G.showToast("播放出错，请稍候重试");
            return true;
        }
    };

    @Override
    public void initView() {
        if (this instanceof BaseContainerActivity) {
            super.initView();
        }
        data = DataUtil.getObject(getIntent(), Video.class);
        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);

        LinearLayout menuLayout = findViewById(R.id.menuLinearLayout);
        if (ViewUtil.isVisible(menuLayout)) {
            loadTest(menuLayout);
        }
    }

    //点击完成
    public void onClickCommit(View view) {
        showProgress(false);
        CacheImageUtil.cacheAndLoadImg(ViewUtil.getNetImgByName("sheep_logo_3"), new Action1<File>() {
            @Override
            public void call(final File file) {
                Observable.create(new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                        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.decodeFile(file.getAbsolutePath());
                        //left 30px top 60px width 750
                        Bitmap logo = BitmapUtil.createBigLogo(bmp, new Size().setWidth(G.WIDTH).setHeight(G.HEIGHT).setX(G.WIDTH * 30 / 750).setY(G.WIDTH * 60 / 750));
                        bmp.recycle();
                        CGEFFmpegNativeLibrary.generateVideoWithFilter(outputFilename, srcFilPath, mCurrentConfig, mIntensity, logo, CGENativeLibrary.TextureBlendMode.CGE_BLEND_ADDREV, 1.0f, false);

                        LogUtil.println(ActEditVideo.class.getSimpleName(), "Done! The file is generated at: " + outputFilename);
                        emitter.onNext(outputFilename);
                    }
                }).subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new AbsObserver<String>() {
                            @Override
                            public void onNext(String filePath) {
                                sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + filePath)));
                                data.setFilePath(filePath);
                                EventBus.getDefault().post(data);
                                ActEditVideo.this.finish();
                            }

                            @Override
                            public void onError(Throwable e) {
                                G.showToast(e.getMessage());
                            }

                            @Override
                            public void onComplete() {
                                hideProgress();
                            }
                        });
            }
        });
    }

    //设置滤镜
    @Override
    public void setFilter(IFilter filter) {
        if (mPlayerView != null && filter != null && filter.getConfig() != null) {
            mCurrentConfig = filter.getConfig();
            mPlayerView.setFilterWithConfig(mCurrentConfig);
        }
    }

    @Override
    public void setFilterIntensity(float intensity) {
        if (mPlayerView != null) {
            mIntensity = intensity;
            mPlayerView.setFilterIntensity(mIntensity);
        }
    }

    //下面为测试代码

    private void loadTest(LinearLayout menuLayout) {

        mShapeBtn = findViewById(R.id.switchShapeBtn);

        mShapeBtn.setOnClickListener(new View.OnClickListener() {

            private boolean useMask = false;
            Bitmap bmp;

            @Override
            public void onClick(View v) {
                useMask = !useMask;
                if (useMask) {
                    if (bmp == null)
                        bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);

                    if (bmp != null) {
                        mPlayerView.setMaskBitmap(bmp, false, new VideoPlayerGLSurfaceView.SetMaskBitmapCallback() {
                            @Override
                            public void setMaskOK(CGEFrameRenderer renderer) {
//                                if(mPlayerView.isUsingMask()) {
//                                    renderer.setMaskFlipScale(1.0f, -1.0f);
//                                }
                                Log.i(Common.LOG_TAG, "enable mask!");
                            }
                        });
                    }
                } else {
                    mPlayerView.setMaskBitmap(null, false);
                }

            }
        });

        mTakeshotBtn = findViewById(R.id.takeShotBtn);

        mTakeshotBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPlayerView.takeShot(new VideoPlayerGLSurfaceView.TakeShotCallback() {
                    @Override
                    public void takeShotOK(Bitmap bmp) {
                        if (bmp != null) {
                            String s = ImageUtil.saveBitmap(bmp);
                            ActEditVideo.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + s)));
                        } else {
                            Log.e(Common.LOG_TAG, "take shot failed!");
                        }
                    }
                });
            }
        });


        {
            Button btn = new Button(this);
            menuLayout.addView(btn);
            btn.setAllCaps(false);
            btn.setText("Last Recorded Video");
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

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

        String[] filePaths = {
                data.getFilePath(),
                "http://wge.wysaid.org/res/video/1.mp4",
                "http://wysaid.org/p/test.mp4",
        };

        for (int i = 0; i != filePaths.length; ++i) {
            MyVideoButton btn = new MyVideoButton(this);
            btn.setText("Video" + i);
            btn.videoUri = Uri.parse(filePaths[i]);
            btn.videoView = mPlayerView;
            btn.setOnClickListener(btn);
            menuLayout.addView(btn);
        }

        mGalleryBtn = findViewById(R.id.galleryBtn);
        mGalleryBtn.setOnClickListener(galleryBtnClickListener);

        Button fitViewBtn = findViewById(R.id.fitViewBtn);
        fitViewBtn.setOnClickListener(new View.OnClickListener() {
            boolean shouldFit = false;

            @Override
            public void onClick(View v) {
                shouldFit = !shouldFit;
                mPlayerView.setFitFullView(shouldFit);
            }
        });

        seekBarLl = findViewById(R.id.seekBarLl);
        for (int i = 0; i < 6; i++) {
            SeekBar sb = new SeekBar(SheepApp.getInstance());
            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) {

                }
            });
        }
    }

    Button mShapeBtn;
    Button mTakeshotBtn;
    Button mGalleryBtn;
    LinearLayout seekBarLl;

    class MyVideoButton extends AppCompatButton implements View.OnClickListener {

        Uri videoUri;
        VideoPlayerGLSurfaceView videoView;

        public MyVideoButton(Context context) {
            super(context);
        }

        @Override
        public void onClick(View v) {

            G.showToast("loading video: " + videoUri.getHost() + videoUri.getPath() + " If the video is from the internet, you may wait a while...");

            videoView.setVideoUri(videoUri, new VideoPlayerGLSurfaceView.PlayPreparedCallback() {
                @Override
                public void playPrepared(MediaPlayer player) {
                    mPlayerView.post(new Runnable() {
                        @Override
                        public void run() {
                            G.showToast("Start playing " + videoUri.getHost() + videoUri.getPath());
                        }
                    });

                    player.start();
                }
            }, playCompletionCallback);
        }
    }

    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)));
    }

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

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

    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();
    }
}
