package com.fgodt.mixplayer;

import android.content.Context;
import android.content.res.Configuration;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.opengl.GLSurfaceView;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.FrameLayout;

import java.sql.Time;
import java.util.Arrays;
import java.util.Date;

import static java.lang.Thread.*;

/**
 * Created by rt-zl on 2019/2/15.
 */

public class Render extends VideoRender {



    static {
        System.loadLibrary("mixplayer");
    }

    private long handler = 0;

    private native int setRenderHandler(long handler);

    int asample, ach, abit;
    public int mixUpdateAudio(byte[] data, int size,double pts){
        playTime = pts;
        synchronized (audioBuf) {
            if (audioBufLen - audioHas < size) {
                return -1;
            }
            int len = audioBufLen - audioWPos;
            len = len > size ? size :len;
            System.arraycopy(data,0,audioBuf,audioWPos,len);
            audioWPos += len;
            audioHas +=len;
            if(audioWPos == audioBufLen){
                audioWPos = 0;
            }
            if(len<size){
                int les = size - len;
                System.arraycopy(data,len,audioBuf,audioWPos,les);
                audioWPos +=les;
                audioHas += les;
            }
            return 0;
        }
    }


    public int mixOpen(int vWidth,int vHeight,int asample, int ach, int abit){
        if(vWidth>0){
            Log.d("MIXOPEN","has video");
            nativeInit(getScreenWidth(),getScreenHeight());
            this.abit = abit;
            this.asample = asample;
            this.ach = ach;
            initAudioTrack();
            return  0;
        }
        return -1;
    }


    public void mixClose(){
        super.close();
    }

    public void renderClose(){
        play = false;
        if (audioTrack!=null){
            audioTrack.stop();
            totalAudioBuf = 0;
        }
    }

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

    public void init(long handler){
        this.handler = handler;
        setMixHander(handler);
        this.setRenderHandler(handler);
    }

    public double getPlaytime() {
        return  playTime;
    }

    AudioTrack audioTrack ;

    byte[] audioBuf ;
    long totalAudioBuf;
    int audioHas;
    int audioRPos, audioWPos;
    int audioBufLen = 4096*3;
    long silenceLen = 0;
    boolean play = false;
    double playTime = 0;
    byte[] silencBuf;
    private void initAudioTrack(){
        silencBuf = new byte[4096];
        audioBuf = new byte[audioBufLen];
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,asample,
                AudioFormat.CHANNEL_IN_STEREO,AudioFormat.ENCODING_PCM_16BIT,audioBufLen,AudioTrack.MODE_STREAM);
        play = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                int wsize = 1024;
                long posPre = 0;
                boolean needUpdate = false;
                int retryCount = 0;
                while (play) {
                    synchronized (audioBuf) {
                        long pos = audioTrack.getPlaybackHeadPosition();
                        // 16bit 2channels = 4 Byte
                        pos *= 4;
                        pos -= silenceLen;
                        if(posPre != pos){
                            posPre = pos;
                            retryCount = 0;
                        }else {
                            if(retryCount > 5)
                                needUpdate = true;
                            retryCount ++;
                        }
                        if (audioHas >= wsize && totalAudioBuf - pos < audioBufLen || pos <= 0 ||needUpdate ) {
                            needUpdate = false;
                            int len = audioBufLen - audioRPos;
                            len = len > wsize? wsize:len;
                            int ret = audioTrack.write(audioBuf, audioRPos, len);
                            audioRPos += ret;
                            audioHas -= ret;
                            totalAudioBuf+=ret;
                            if (audioRPos == audioBufLen) {
                                audioRPos = 0;
                            }
                        }else {
                        //    if (pos == totalAudioBuf && audioHas < wsize){
                        //        int c = audioTrack.write(silencBuf,0,2048);
                        //        silenceLen +=c;
                        //    }
                        }
                        if(ispause){
                            if(audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PAUSED) {
                                audioTrack.pause();
                                audioTrack.setVolume(0);
                            }
                        }else{
                            if(audioTrack.getPlayState()!=AudioTrack.PLAYSTATE_PLAYING) {
                                audioTrack.play();
                                audioTrack.setVolume(volume);
                            }
                        }
                    }
                    try {
                        sleep(3);
                    }catch (Exception ex){
                    }
                }
                Log.d("mixplayer","audio close");
            }
        }).start();
        audioTrack.play();
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        play = false;
        renderClose();
    }

}
