package org.song.videoplayer;

import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;

import java.util.Arrays;
import java.util.List;

/**
 * Created by song on 2017/2/13.
 * Contact github.com/tohodog
 * UI界面由子类决定
 * edit on 2017/4/8.
 * 分离出QSVideoView,本类作为辅助类.
 * <p>
 * *1.提供播放器常见的ui的控制逻辑(播放按钮 进度条 时间等)
 * *2.提供手势支持
 * <p>
 * 减轻开发者工作量
 * 子类提供的xml按规定提供控件的id 本类即可完成该控件的逻辑
 */

public abstract class QSVideoViewHelp extends QSVideoView implements HandleTouchEvent.GestureEvent, SeekBar.OnSeekBarChangeListener {

    public static final int EVENT_CONTROL_VIEW = 1001;//控制view显示隐藏事件 extra[0]:0显示 1隐藏
    public static final int EVENT_SEEKBAR_START = 1002;//进度条拖动事件开始
    public static final int EVENT_SEEKBAR_TOUCHING = 1003;//拖动中 extra[0]进度 extra[1]总进度
    public static final int EVENT_SEEKBAR_END = 1004;//进度条拖动事件结束
    public static final int EVENT_CLICK_VIEW = 1005;//点击事件

    public int controlUIHideTime = 2500;//控制UI隐藏时间
    public boolean isDoneShowControlUI = false;//初始化完成/视频播放完成后,是否显示控制UI
    public boolean isWindowGesture = false;//是否非全屏下也可以手势调节进度

    protected ViewGroup controlContainer;//控制ui容器
    //提供辅助的控件
    protected TextView titleTextView;//标题
    protected TextView definitionTextView;//清晰度
    protected ImageView startButton, startButton2;//播放按钮
    protected SeekBar seekBar;//拖动条
    protected TextView currentTimeTextView, totalTimeTextView;//播放时间/视频长度
    protected ImageView fullscreenButton;//全屏按钮
    protected ProgressBar progressBar;//第二进度条
    protected View backView, floatCloseView, floatBackView;//返回
    protected final int progressMax = 1000;

    protected boolean isShowControlView;
    protected Handler mHandler;
    private HandleTouchEvent handleTouchEvent;
    private MyOnClickListener myOnClickListener;

    private List<QSVideo> qsVideos;
    private QSVideo nowPlayVideo;

    public QSVideoViewHelp(Context context) {
        this(context, null);
    }

    public QSVideoViewHelp(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public QSVideoViewHelp(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initHelpView(context);
    }

    public void setUp(String url, String title) {
        setUp(QSVideo.Build(url).title(title).build());
    }

    public void setUp(QSVideo... qsVideos) {
        setUp(Arrays.asList(qsVideos));
    }

    public void setUp(List<QSVideo> qsVideos) {
        this.qsVideos = qsVideos;
        switchVideo(0);
    }

    //切视频
    protected void switchVideo(int index) {
        if (qsVideos != null && qsVideos.size() > index) {
            if (qsVideos.indexOf(nowPlayVideo) == index)
                return;

            int position = getPosition();
            boolean isPlaying = isPlaying();
            boolean checkReady = checkReady();

            nowPlayVideo = qsVideos.get(index);
            super.setUp(nowPlayVideo.url(), nowPlayVideo.headers(), nowPlayVideo.option());
            if (titleTextView != null) titleTextView.setText(nowPlayVideo.title());
            //开启清晰度
            if (definitionTextView != null) {
                if (nowPlayVideo.definition() != null) {
                    definitionTextView.setVisibility(VISIBLE);
                    definitionTextView.setText(nowPlayVideo.definition());
                } else {
                    definitionTextView.setVisibility(GONE);
                }
            }

            if (checkReady) {
                seekTo(position);
                if (isPlaying) play();
                else prePlay();
            }
        }
    }

    public int getNowPlayIndex() {
        return qsVideos == null ? -1 : qsVideos.indexOf(nowPlayVideo);
    }

    protected void initHelpView(Context context) {
        myOnClickListener = new MyOnClickListener();
        mHandler = new Handler(Looper.getMainLooper());
        handleTouchEvent = new HandleTouchEvent(this);
        audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);

        controlContainer = (ViewGroup) View.inflate(context, getLayoutId(), null);
        videoView.addView(controlContainer, new LayoutParams(-1, -1));
        videoView.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return handleTouchEvent.handleEvent(v, event);
            }
        });

        titleTextView = (TextView) findViewById(R.id.help_title);
        startButton = (ImageView) findViewById(R.id.help_start);
        startButton2 = (ImageView) findViewById(R.id.help_start2);
        fullscreenButton = (ImageView) findViewById(R.id.help_fullscreen);
        seekBar = (SeekBar) findViewById(R.id.help_seekbar);
        progressBar = (ProgressBar) findViewById(R.id.help_progress);
        currentTimeTextView = (TextView) findViewById(R.id.help_current);
        totalTimeTextView = (TextView) findViewById(R.id.help_total);
        backView = findViewById(R.id.help_back);
        floatCloseView = findViewById(R.id.help_float_close);
        floatBackView = findViewById(R.id.help_float_goback);
        definitionTextView = findViewById(R.id.help_definition);
        if (seekBar != null) {
            seekBar.setOnSeekBarChangeListener(this);
            seekBar.setMax(progressMax);
        }
        if (progressBar != null)
            progressBar.setMax(progressMax);
        setClick(videoView, startButton, startButton2, fullscreenButton, backView, floatCloseView, floatBackView, definitionTextView);

    }

    //-----------ui监听start-----------------
    private void setClick(View... vs) {
        for (View v : vs) {
            if (v != null)
                v.setOnClickListener(myOnClickListener);
        }
    }

    private class MyOnClickListener implements OnClickListener {
        @Override
        public void onClick(View view) {
            int i = view.getId();

            //播放按钮
            if (i == R.id.help_start || i == R.id.help_start2) {
                clickPlay();
            }
            //全屏按钮
            if (i == R.id.help_fullscreen) {
                clickFull();
            }
            //退出按钮
            if (i == R.id.help_back) {
                if (currentMode != MODE_WINDOW_NORMAL)
                    quitWindowFullscreen();
                else
                    Util.scanForActivity(getContext()).finish();
            }
            //退出悬浮窗按钮
            if (i == R.id.help_float_close) {
                if (isSystemFloatMode())
                    release();
                else
                    pause();
                quitWindowFloat();

            }
            //退出悬浮窗按钮
            if (i == R.id.help_float_goback) {
                if (isSystemFloatMode()) {
                    try {
                        Intent intent = new Intent(getContext(), Util.scanForActivity(getContext()).getClass());
                        //intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                        getContext().getApplicationContext().startActivity(intent);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                quitWindowFloat();
            }
            //点击空白处
            if (view == videoView) {
                if (currentState == STATE_NORMAL || currentState == STATE_ERROR)
                    clickPlay();
                else if (currentState == STATE_PLAYING ||
                        currentState == STATE_PAUSE ||
                        currentState == STATE_AUTO_COMPLETE) {
                    isShowControlView = !isShowControlView;
                    setUIWithStateAndMode(currentState, currentMode);
                }
            }

            //清晰度按钮
            if (i == R.id.help_definition) {
                popDefinition(definitionTextView, qsVideos, getNowPlayIndex());
            }

            //点击事件
            handlePlayListener.onEvent(EVENT_CLICK_VIEW, i);
        }
    }

    protected void clickFull() {
        if (currentMode == MODE_WINDOW_FULLSCREEN) {
            quitWindowFullscreen();
        } else {
            enterWindowFullscreen();
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (getDuration() > 1) {
            int time = seekBar.getProgress() * (getDuration() / progressMax);
            if (currentTimeTextView != null)
                currentTimeTextView.setText(Util.stringForTime(time));
        }
        handlePlayListener.onEvent(EVENT_SEEKBAR_TOUCHING, progress, progressMax);
        //Log.i(TAG, "onProgressChanged " + Util.stringForTime(time));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        cancelProgressTimer();
        cancelDismissControlViewTimer();
        handlePlayListener.onEvent(EVENT_SEEKBAR_START);
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if (getDuration() > 1) {
            int time = seekBar.getProgress() * (getDuration() / progressMax);
            seekTo(time);
        }
        startProgressTimer();
        if (currentState == STATE_PLAYING)
            startDismissControlViewTimer(1314);
        handlePlayListener.onEvent(EVENT_SEEKBAR_END);
    }
    //-----------ui监听end-----------------


    //-----------设置UI数据start-----------------
    @Override//覆盖父类监听播放器状态//todo 父类这个方法后面考虑改成final,子类从监听里获取状态,事件
    protected void setUIWithStateAndMode(final int status, final int mode) {
        cancelDismissControlViewTimer();
        cancelProgressTimer();
        switch (status) {
            case STATE_NORMAL:
            case STATE_PREPARING:
                resetProgressAndTime();
                onBuffering(false);
                isShowControlView = false;
                break;
            case STATE_PLAYING:
                startDismissControlViewTimer();
                startProgressTimer();
                if (currentState == STATE_PREPARING)//加载完成显示下控制UI
                    if (isDoneShowControlUI) isShowControlView = true;
                break;
            case STATE_PAUSE:
                startProgressTimer();
                if (currentState == STATE_PREPARING)//加载完成显示下控制UI
                    isShowControlView = true;
                break;
            case STATE_ERROR:
                onBuffering(false);
                isShowControlView = false;
                break;
            case STATE_AUTO_COMPLETE:
                if (isDoneShowControlUI) isShowControlView = true;
                setCompleProgressAndTime();
                onBuffering(false);
                break;
        }
        changeUiWithStateAndMode(status, mode);
        if ((status == STATE_PLAYING || status == STATE_PAUSE || status == STATE_AUTO_COMPLETE)
                & !isShowControlView)
            dismissControlView(status, mode);
        //调用父类...
        super.setUIWithStateAndMode(status, mode);
        //状态改变监听回调永远放在最后
        handlePlayListener.onEvent(EVENT_CONTROL_VIEW, isShowControlView ? 0 : 1);
    }

    //缓冲进度
    @Override
    protected void setBufferProgress(float bufferProgress) {
        if (seekBar != null)
            seekBar.setSecondaryProgress((int) (bufferProgress * progressMax));
        if (progressBar != null)
            progressBar.setSecondaryProgress((int) (bufferProgress * progressMax));
    }

    //设置进度和时间
    protected void setProgressAndText() {
        int position = getPosition();
        int duration = getDuration();
        if (position < 0)
            position = 0;
        if (duration <= 0)
            duration = 1;
        int progress = (int) (((long) position * progressMax) / duration);
        if (progress < 0 || progress > progressMax)//防止溢出
            progress = progressMax;
        setProgressBar(progress, seekBar, progressBar);
        if (currentTimeTextView != null)
            currentTimeTextView.setText(Util.stringForTime(position));
        if (totalTimeTextView != null)
            if (duration > 1)
                totalTimeTextView.setText(Util.stringForTime(duration));
            else
                totalTimeTextView.setText(R.string.online);
    }

    //初始化进度和时间
    protected void resetProgressAndTime() {
        setProgressBar(0, seekBar, progressBar);
        if (currentTimeTextView != null)
            currentTimeTextView.setText(Util.stringForTime(0));
        if (totalTimeTextView != null)
            totalTimeTextView.setText(Util.stringForTime(0));
    }

    //播放完成进度和时间
    protected void setCompleProgressAndTime() {
        setProgressBar(progressMax, seekBar, progressBar);
        if (currentTimeTextView != null)
            currentTimeTextView.setText(Util.stringForTime(getDuration()));
    }

    private void setProgressBar(int pro, ProgressBar... ps) {
        for (ProgressBar p : ps)
            if (p != null)
                p.setProgress(pro);

    }
    //-----------设置数据end-----------------


    //-----------定时任务更新进度start-----------------
    protected void startProgressTimer() {
        cancelProgressTimer();
        mHandler.post(updateProgress);
    }

    protected void cancelProgressTimer() {
        mHandler.removeCallbacks(updateProgress);
    }

    private Runnable updateProgress = new Runnable() {
        @Override
        public void run() {
            mHandler.postDelayed(updateProgress, 500);
            setProgressAndText();
        }
    };
    //-----------定时任务更新进度end-----------------


    //-----------定时任务隐藏控制栏start-----------------
    protected void startDismissControlViewTimer() {
        startDismissControlViewTimer(controlUIHideTime);
    }

    protected void startDismissControlViewTimer(int delayed) {
        cancelDismissControlViewTimer();
        mHandler.postDelayed(dismissControlViewTimerRunnable, delayed);
    }

    protected void cancelDismissControlViewTimer() {
        mHandler.removeCallbacks(dismissControlViewTimerRunnable);
    }

    private Runnable dismissControlViewTimerRunnable = new Runnable() {
        @Override
        public void run() {
            isShowControlView = false;
            dismissControlView(currentState, currentMode);
            handlePlayListener.onEvent(EVENT_CONTROL_VIEW, isShowControlView ? 0 : 1);
        }
    };
    //-----------定时任务隐藏控制栏end-----------------


    /**
     * =========================================
     * -------子类需要实现的重要的方法------------
     * ========================================
     */
    protected abstract int getLayoutId();//id见ids.xml

    protected abstract void changeUiWithStateAndMode(int status, int mode);//根据状态设置ui显示/隐藏

    protected abstract void dismissControlView(int status, int mode);//播放时定时隐藏的控制ui

    protected abstract void onBuffering(boolean isBuffering);//缓冲


    //==============================================================================================
    //-------------------------------------以下为手势逻辑--------------------------------------------
    //==============================================================================================
    @Override
    public void onGestureBegin(int type) {
        if (!isWindowGesture & currentMode != MODE_WINDOW_FULLSCREEN)
            return;

        //进度
        if (type == HandleTouchEvent.GestureEvent.TOUCH_FULL_X & checkReady())
            tempPosition = getPosition();
        //亮度
        if (type == HandleTouchEvent.GestureEvent.TOUCH_LEFT_Y) {
            tempBrightness = (int) (Util.scanForActivity(getContext()).getWindow().getAttributes().screenBrightness * 255);
            if (tempBrightness < 0)
                try {//系统亮度 不能activity取
                    tempBrightness = Settings.System.getInt(getContext().getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
                } catch (Settings.SettingNotFoundException e) {
                    e.printStackTrace();
                    tempBrightness = 0;
                }
        }
        //音量
        if (type == HandleTouchEvent.GestureEvent.TOUCH_RIGHT_Y)
            tempVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

    }

    //调节前的值 亮度退出全屏应原样
    private int tempPosition;
    private int tempBrightness;
    private int tempVolume;
    protected AudioManager audioManager;

    @Override
    public void onGestureChange(int type, float level) {
        if (!isWindowGesture & currentMode != MODE_WINDOW_FULLSCREEN)
            return;
        //进度
        if (type == HandleTouchEvent.GestureEvent.TOUCH_FULL_X & checkReady()) {
            int duration = getDuration();
            if (duration <= 1)
                return;
            //拖动开始慢 后面快
            int delta = (int) (level * Math.abs(level) * duration);
            if (delta < -tempPosition)
                delta = -tempPosition;
            if (delta > duration - tempPosition)
                delta = duration - tempPosition;
            if (showProgressDialog(delta, tempPosition, duration)) {
                //pause();
            }
        }
        //亮度
        if (type == HandleTouchEvent.GestureEvent.TOUCH_LEFT_Y) {
            WindowManager.LayoutParams params = Util.scanForActivity(getContext()).getWindow().getAttributes();
            int delta = (int) (level * 255);
            int nowBrightness = tempBrightness + delta;
            if (nowBrightness < 0)
                nowBrightness = 0;
            if (nowBrightness > 255)
                nowBrightness = 255;
            float b = nowBrightness / 255.0f;
            if (showBrightnessDialog((int) (b * 100), 100)) {
                params.screenBrightness = b;
                Util.scanForActivity(getContext()).getWindow().setAttributes(params);
            }
        }
        //音量
        if (type == HandleTouchEvent.GestureEvent.TOUCH_RIGHT_Y) {
            int max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            int deltaV = (int) (max * level);
            int nowVolume = tempVolume + deltaV;
            if (nowVolume < 0)
                nowVolume = 0;
            if (nowVolume > max)
                nowVolume = max;
            if (showVolumeDialog(nowVolume, max))
                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, nowVolume, 0);
        }
    }

    @Override
    public void onGestureEnd(int type, float level) {
        //双击
        if (type == HandleTouchEvent.GestureEvent.TOUCH_DOUBLE_C)
            doubleClick();

        if (!isWindowGesture & currentMode != MODE_WINDOW_FULLSCREEN)
            return;
        //进度
        if (type == HandleTouchEvent.GestureEvent.TOUCH_FULL_X & checkReady()) {
            int duration = getDuration();
            if (duration <= 0)
                return;
            if (!dismissProgressDialog()) return;

            int delta = (int) (level * Math.abs(level) * duration);
            tempPosition += delta;
            if (tempPosition > duration)
                tempPosition = duration;
            if (tempPosition < 0)
                tempPosition = 0;
            seekTo(tempPosition);
            tempPosition = 0;
            //play();
        }
        //亮度
        if (type == HandleTouchEvent.GestureEvent.TOUCH_LEFT_Y) {
            dismissBrightnessDialog();
        }
        //音量
        if (type == HandleTouchEvent.GestureEvent.TOUCH_RIGHT_Y) {
            dismissVolumeDialog();
        }

        if (currentMode == MODE_WINDOW_FULLSCREEN) {
            Util.showNavigationBar(getContext(), false);
        }
    }

    //-----------各种手势ui实现start-----------
    //子类写了实现 就返回true
    protected abstract boolean showWifiDialog();//要弹出非wifi提示框覆盖return true即可

    protected abstract void doubleClick();

    protected abstract void popDefinition(View view, List<QSVideo> qsVideos, int index);//弹出清晰度

    protected abstract boolean showProgressDialog(int delay, int position, int duration);

    protected abstract boolean dismissProgressDialog();

    protected abstract boolean showVolumeDialog(int nowVolume, int maxVolume);

    protected abstract boolean dismissVolumeDialog();

    protected abstract boolean showBrightnessDialog(int nowBrightness, int maxBrightness);

    protected abstract boolean dismissBrightnessDialog();
    //-----------各种调节弹窗end-----------

}