package com.excelliance.open;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;

import com.excelliance.lbui.R;
import com.excelliance.open.video.VideoView;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

@SuppressLint("NewApi")
public class NextChapter extends BaseActivity {
    private final String TAG = "NextChapter";
    private Parcelable nextChapterParcel = null;
    private String mPackageName;
    private Resources mResources;
    private Serializable detail = null;
    private Serializable localDetail = null;
    private String rGameId = null;
    private String rSavePath = null;
    private boolean rForceUpdate = false;
    private long rSize = 0;
    private boolean rPatch = false;
    private String notifyTitle = "";
    private String notifyMsg = "";

    private TextView textStatus;
    private TextView textProgress;
    private AdaptiveProgressBar mAdaptiveProgressBar;
    private TextView resStatus;
    private TextView mDownloadSpeed;

    private Dialog exitDialog = null;
    private Dialog notEnoughSpaceDialog = null;
    private Dialog dlWithoutWifiDialog = null;
    private Dialog unfinishedDlDialog = null;
    private Dialog updateWithoutWifiDialog = null;
    private Dialog dlBackgroundWithoutWifiDialog = null;
    private Dialog switchGPDialog = null;
    private Runnable runnable = null;
    private String strStatus = null;
    private int timer = 0;
    private boolean showProgressbar = true;
    private boolean patching = false;
    Thread mThread = null;
    private volatile boolean stopRequested;
    private View backgroundView;
    public static final String ACTION_NOTIFY = ".action.NextChapter.Notify";
    public static final String ACTION_DLOAD = ".action.NextChapter.Download";
    protected static final int STOP = 0x10000;
    protected static final int COMPUTE_DOWNLOAD_SPEED = 0x20000;
    private int iCount = 0;
    private String dlType = null;
    public static final String GAME_RUNNING = "gameRunning";
    private boolean gameRunning = false;
    private int mDownloadsType = 0;
    private int lastDlResNum = 1;
    private int mDlresZipType = 0;
    private Bundle resDlInfo = null;

    public static String GAMEID = null;
    public static String PROGRESS = null;
    public static String DOWNLOADED = null;
    public static String SIZE = null;
    public static String CURRRESNUM = null;
    public static String TOTALRESNUM = null;
    public static String ERROR = null;
    public static String ERRORTYPE = null;
    public static String DMD5 = null;
    public static String PROGRESS_INTENT = null;
    public static String DOWNLOADED_INTENT = null;
    public static String ERROR_INTENT = null;
    public static String EXTRACTED_INTENT = null;
    public static String MERGE = null;

    private int musicID;
    private MediaPlayer player;

    private VideoView videoView;

    private long mPreDownloadSize;
    private long mPreComputeSpeedTime;
    //间隔2秒计算下载速度
    private static final int COMPUTE_TIME = 2000;
    //间隔3秒检查速度是否更新
    private static final int CHECK_TIME = 3000;
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case STOP:
                    Thread.currentThread().interrupt();
                    break;
                    //计算下载速度
                case COMPUTE_DOWNLOAD_SPEED:
                    long downloadSize = (long)msg.obj;
                    if(mPreDownloadSize == 0){
                        mPreDownloadSize = downloadSize;
                    }
                    if(mPreComputeSpeedTime == 0){
                        mPreComputeSpeedTime = SystemClock.elapsedRealtime();
                    }
                    long time = SystemClock.elapsedRealtime() - mPreComputeSpeedTime;
                    if(time > COMPUTE_TIME){
                        long size = downloadSize - mPreDownloadSize;
                        long speed  = size/time;
                        String strSpeed = speed + "KB/s";
                        if (speed >= 1024) {
                            strSpeed = String.format("%.2fMB/s", ((float) (speed)) / 1024.0f);
                        }

                        // 防止speed是负值
                        if (speed >= 0) {
                            mDownloadSpeed.setText(strSpeed);
                        }
                        mPreComputeSpeedTime = SystemClock.elapsedRealtime();
                        mPreDownloadSize = downloadSize;
                    }
                    handler.removeMessages(COMPUTE_DOWNLOAD_SPEED);
                    Message message = Message.obtain();
                    message.what = COMPUTE_DOWNLOAD_SPEED;
                    message.obj = msg.obj;
                    handler.sendMessageDelayed(message,CHECK_TIME);
                    break;
            }
        }
    };

    //download information receiver
    private BroadcastReceiver myReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            callNextChapterParcel("onReceive", new Class[]{Context.class, Intent.class}, new Object[]{context, intent});
            String action = intent.getAction();
            String packageName = getPackageName();
            int resId = 0;
            int resId2 = 0;
            String gameId = intent.getStringExtra(GAMEID);
            boolean merge = intent.getBooleanExtra(MERGE,false);
            if ((mDownloadsType == 1 && gameId == null) || (mDownloadsType == 2 && gameId != null)) {
                Log.d(TAG, "bc mismatch");
                return;
            }

            if (action.equals(packageName + ERROR_INTENT)) {//download error
                String error = intent.getStringExtra(ERROR);
                int errType = intent.getIntExtra(ERRORTYPE, -1);
                Log.d(TAG, "gameId=" + gameId + " error=" + error + " detail=" + detail + " errType = " + errType);
                showProgressbar = true;
                if (mDownloadsType == 1 && (detail == null || rGameId == null || gameId == null || !gameId.equals(rGameId))){
                    return;
                }
                stopRequested = true;
                strStatus = error;
                handler.removeCallbacks(runnable);
                textStatus.setText(strStatus);
                if (errType != -1) {
                    String dmd5 = intent.getStringExtra(DMD5);
                    callNextChapterParcel("errorCommit", new Class[]{String.class, String.class}, new Object[]{String.valueOf(errType), dmd5});
                }
            } else if (action.equals(PROGRESS_INTENT)) {//download progress
                Log.d(TAG, "action PROGRESS_INTENT");
                int progress = intent.getIntExtra(PROGRESS, 0);
                Log.d(TAG, "gameId=" + gameId + " progress=" + progress + " detail=" + detail);
                if (mDownloadsType == 1 && (detail == null || rGameId == null || gameId == null || !gameId.equals(rGameId))){
                    return;
                }

                if (progress == -2) {
                    return;
                }

                if (progress == -1) {
                    handler.removeCallbacks(runnable);
                    strStatus = getResources().getString(R.string.lebian_dl_dl_failed);
                    textStatus.setText(strStatus);
                    showProgressbar = true;
                    return;
                }
                if (dlWithoutWifiDialog != null && dlWithoutWifiDialog.isShowing()) {
                    dlWithoutWifiDialog.dismiss();
                }
                if (unfinishedDlDialog != null && unfinishedDlDialog.isShowing()) {
                    unfinishedDlDialog.dismiss();
                }
                if (updateWithoutWifiDialog != null && updateWithoutWifiDialog.isShowing()) {
                    updateWithoutWifiDialog.dismiss();
                }

                if (progress == 100 && (mDownloadsType != 1 || detail != null)) {
                    handler.removeCallbacks(downloadCallBack);
                    stopRequested = true;
                    Thread tmpThread = mThread;
                    mThread = null;
                    if (tmpThread != null) {
                        tmpThread.interrupt();
                    }
                }

                mAdaptiveProgressBar.setProgress(progress);
                if (progress < 5) {
                    mAdaptiveProgressBar.setProgress(5);
                }

                int pro = progress;
                boolean mergeApk = intent.getBooleanExtra("mergeApk",false);
                if (progress == 99 && (rPatch || mDownloadsType == 2)||mergeApk) {
                    patching = true;
                    stopRequested = false;
                    pro = 100;
                    strStatus = getResources().getString(R.string.lebian_dl_status_extract);
                    handler.removeCallbacks(runnable);
                    handler.postDelayed(runnable, 800);
                    textProgress.setVisibility(View.GONE);
                    mDownloadSpeed.setVisibility(View.GONE);
                    if (resStatus != null) {
                        resStatus.setVisibility(View.INVISIBLE);
                    }
                    mAdaptiveProgressBar.setProgress(0);
                }

                if (progress == 100 && (mDownloadsType != 1 || detail != null)) {
                    showProgressbar = true;
                    if(merge){
                        strStatus = getResources().getString(R.string.lebian_merge_finish_restart);
                    }else {
                        strStatus = getResources().getString(R.string.lebian_dl_status_downloaded);
                        textProgress.setText(String.format("%.2fMB/%.2fMB", ((float) (rSize)) / (1024.0f * 1024.0f), ((float) (rSize)) / (1024.0f * 1024.0f)));
                    }
                }
            } else if (action.equals(packageName + DOWNLOADED_INTENT)) {//downloaded size
                long downloaded = intent.getLongExtra(DOWNLOADED, 0L);
                long size = intent.getLongExtra(SIZE, 0L);
                int currResNum = intent.getIntExtra(CURRRESNUM, 1);
                int totalResNum = intent.getIntExtra(TOTALRESNUM, 1);
                if (lastDlResNum != currResNum) {
                    showProgressbar = true;
                    lastDlResNum = currResNum;
                    mPreDownloadSize = 0;
                    mPreComputeSpeedTime = 0;
                }
                Message message = Message.obtain();
                message.what = COMPUTE_DOWNLOAD_SPEED;
                message.obj = downloaded;
                handler.sendMessage(message);
                if (size > 0 && rSize != size) {
                    Log.d(TAG, "size change rSize:" + rSize);
                    rSize = size;
                }
                if (mDownloadsType == 1 && (detail == null || rGameId == null || gameId == null || !gameId.equals(rGameId))){
                    return;
                }
                if (showProgressbar && downloaded > 0) {
                    strStatus = getResources().getString((dlType != null && dlType.equals("update")) ? R.string.lebian_dl_status_updating : R.string.lebian_dl_status_downloading);
                    textStatus.setText(strStatus);
                    handler.removeCallbacks(runnable);
                    handler.postDelayed(runnable, 800);
                    mAdaptiveProgressBar.setVisibility(View.VISIBLE);
                    textProgress.setVisibility(View.VISIBLE);
                    if (totalResNum > 1 && resStatus != null) {
                        resStatus.setVisibility(View.VISIBLE);
                        resStatus.setText(currResNum + "/" + totalResNum);
                    }
                    showProgressbar = false;

                    Log.d(TAG, "PROGRESS_INTENT start downloadCallBack");
                    handler.removeCallbacks(downloadCallBack);
                    handler.postDelayed(downloadCallBack, 10000);
                }
                textProgress.setText(String.format("%.2fMB/%.2fMB", ((float) (downloaded)) / (1024.0f * 1024.0f) * 0.9f, ((float) (rSize)) / (1024.0f * 1024.0f)));
            } else if (action.equals(packageName + ACTION_NOTIFY)) {//network not available
                Log.d(TAG, "network not available");
                handler.removeCallbacks(runnable);
                strStatus = getResources().getString(R.string.lebian_dl_status_no_network);
                textStatus.setText(strStatus);
            } else if (action.equals(packageName + EXTRACTED_INTENT)) {//extracted size
                int progress = intent.getIntExtra(PROGRESS, 0);
                if(progress > 100){
                    Log.i(TAG,"progress is over " + progress);
                    progress = 100;
                }
                mAdaptiveProgressBar.setProgress(progress);
                if (showProgressbar) {
                    showProgressbar = false;
                    strStatus = getResources().getString(R.string.lebian_dl_status_extract);
                }
                if(progress == 100) {
                    if(resId != 0){
                        strStatus = getResources().getString(R.string.lebian_merge_finish_restart);
                    }
                }
            }
        }
    };

    @Override
    public int getLBTheme() {
        return R.style.LebianNextChapterTheme;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG,"onCreate");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            getWindow().setAttributes(lp);
        }
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            nextChapterParcel = savedInstanceState.getParcelable("nextChapterParcel");
        }
        if (nextChapterParcel == null) {
            try {
                Class clazz = BwbxUI.getClass("main.NextChapterParcel");
                Constructor cons = clazz.getDeclaredConstructor(Parcel.class);
                cons.setAccessible(true);
                nextChapterParcel = (Parcelable) cons.newInstance((Parcel) null);
            } catch (Exception e) {
                Log.d(TAG, "no NextChapterParcel");
                e.printStackTrace();
            }
        }

        GAMEID = (String) callNextChapterParcel("getGAMEID", null, null);
        PROGRESS = (String) callNextChapterParcel("getPROGRESS", null, null);
        DOWNLOADED = (String) callNextChapterParcel("getDOWNLOADED", null, null);
        SIZE = (String) callNextChapterParcel("getSIZE", null, null);
        CURRRESNUM = (String) callNextChapterParcel("getCURRRESNUM", null, null);
        TOTALRESNUM = (String) callNextChapterParcel("getTOTALRESNUM", null, null);
        ERROR = (String) callNextChapterParcel("getERROR", null, null);
        ERRORTYPE = (String) callNextChapterParcel("getERRORTYPE", null, null);
        DMD5 = (String) callNextChapterParcel("getDMD5", null, null);
        PROGRESS_INTENT = (String) callNextChapterParcel("getPROGRESS_INTENT", null, null);
        DOWNLOADED_INTENT = (String) callNextChapterParcel("getDOWNLOADED_INTENT", null, null);
        ERROR_INTENT = (String) callNextChapterParcel("getERROR_INTENT", null, null);
        EXTRACTED_INTENT = (String) callNextChapterParcel("getEXTRACTED_INTENT", null, null);
        MERGE = (String) callNextChapterParcel("getMERGE", null, null);

        IntentFilter filter = new IntentFilter();
        String packageName = getPackageName();
        filter.addAction(packageName + ACTION_NOTIFY);
        filter.addAction(PROGRESS_INTENT);
        filter.addAction(packageName + DOWNLOADED_INTENT);
        filter.addAction(packageName + ERROR_INTENT);
        filter.addAction(packageName + EXTRACTED_INTENT);
        LBContextCompat.registerReceiver(this,myReceiver,filter);

        if (nextChapterParcel != null) {
            callNextChapterParcel("init", new Class[]{Activity.class, Handler.class, Bundle.class}, new Object[]{this, handler, savedInstanceState});
        }


        gameRunning = getIntent().getBooleanExtra(GAME_RUNNING, false);
        mPackageName = getPackageName();
        mResources = getResources();
        setContentView(R.layout.lebian_next_chapter);
        backgroundView = findViewById(R.id.background_view);
        if (backgroundView instanceof VideoView){
            videoView = (VideoView) backgroundView;
        }
        textStatus = (TextView) findViewById(R.id.lebian_text_status);
        textProgress = (TextView) findViewById(R.id.lebian_text_progress);

        //初始化进度条
        mAdaptiveProgressBar = findViewById(R.id.lebian_progressBar);
        Drawable progressDrawable = mResources.getDrawable(R.drawable.lebian_barcolor);
        mAdaptiveProgressBar.setProgressDrawable(progressDrawable);
        mAdaptiveProgressBar.setLayoutParams(new FrameLayout.LayoutParams(LbUiWindowManager.getInstance(this).getScreenWidth(this), dip2px(this, 14)));
        mAdaptiveProgressBar.updateLayoutParams(0.8, 1);

        //添加背景音乐
        musicID = 0;
        if(musicID != 0){
            if(player==null) {
                player = MediaPlayer.create(this,musicID);
            }
            player.setLooping(true);
        }

        resStatus = (TextView) findViewById(R.id.lebian_resource_status);

        mDownloadSpeed = findViewById(R.id.lebian_download_speed);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        runnable = new Runnable() {
            @Override
            public void run() {
                if (timer >= 4){
                    timer = 0;
                }
                switch (timer) {
                    case 0:
                        textStatus.setText(strStatus);
                        break;
                    case 1:
                        textStatus.setText(strStatus + ".");
                        break;
                    case 2:
                        textStatus.setText(strStatus + "..");
                        break;
                    case 3:
                        textStatus.setText(strStatus + "...");
                        break;
                }
                timer++;
                handler.postDelayed(this, 800);
            }
        };

        Intent intent = getIntent();
        strStatus = getResources().getString(R.string.lebian_dl_status_connecting);
        mAdaptiveProgressBar.setVisibility(View.VISIBLE);
        if (resStatus != null) {
            resStatus.setVisibility(View.INVISIBLE);
        }
        handler.removeCallbacks(runnable);
        handler.postDelayed(runnable, 800);
        handler.removeCallbacks(downloadCallBack);
        handler.postDelayed(downloadCallBack, 10000);
        mDownloadsType = intent.getIntExtra("dlsType", 1);
        if (mDownloadsType == 1) {
            detail = intent.getSerializableExtra("detail");
            localDetail = intent.getSerializableExtra("localDetail");
            dlType = intent.getStringExtra("dlType");
            rGameId = intent.getStringExtra("gameId");
            rSavePath = intent.getStringExtra("savePath");
            rForceUpdate = intent.getBooleanExtra("forceUpdate",false);
            rSize = intent.getLongExtra("size", 0) + intent.getLongExtra("expsize", 0)+intent.getLongExtra("tsize",0);
            int patch = intent.getIntExtra("patch", -1);
            int expPatch = intent.getIntExtra("exppatch", -1);
            rPatch = (patch > 0) || (expPatch > 0);
            String mainActivity = intent.getStringExtra("mainActivity");
            notifyTitle = intent.getStringExtra("notifyTitle");
            notifyMsg = intent.getStringExtra("notifyMsg");
            if (detail != null) {
                Log.d(TAG, "gameId:" + rGameId + ", savePath:" + rSavePath);
                if (rSavePath == null) {
                    Log.d(TAG, "space not enough");
                    showNotEnoughSpaceDialog();
                } else {
                    Log.d(TAG, "action.NextChapterBC savePath != null");
                    boolean rmAutoDl = ((Boolean) callNextChapterParcel("getREMOVE_AUTO_DOWNLOAD", null, null)).booleanValue();
                    if ((rmAutoDl || !BwbxUI.isWifi(NextChapter.this)) && !gameRunning) {
                        boolean updatePrompt = PreferencesHelper.getBoolean(NextChapter.this, PreferencesHelper.MODULE_PROMPT, "gameUpdate", false);
                        if (dlType != null && dlType.equals("update")) {
                            if (!updatePrompt && localDetail != null) {
                                showUpdateWithoutWifiDialog(detail, localDetail, !BwbxUI.isWifi(NextChapter.this));
                            } else if (localDetail != null) {
                                mAdaptiveProgressBar.setVisibility(View.GONE);
                                textProgress.setVisibility(View.GONE);
                                textStatus.setVisibility(View.INVISIBLE);
                            }
                        } else {
                            if (!updatePrompt) {
                                showDlWithoutWifiDialog(detail, mainActivity, !BwbxUI.isWifi(NextChapter.this));
                            } else {
                                mAdaptiveProgressBar.setVisibility(View.GONE);
                                textProgress.setVisibility(View.GONE);
                                textStatus.setVisibility(View.INVISIBLE);
                            }
                        }
                        return;
                    }
                }
            }
        } else if (mDownloadsType == 2) { //download bwbx full res
            mDlresZipType = intent.getIntExtra("dlsZipType", 1);
            resDlInfo = intent.getExtras();
        }

        // android 13 back gesture 兼容
        if (Build.VERSION.SDK_INT >= 33) {
            getOnBackInvokedDispatcher().registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, new OnBackInvokedCallback() {
                @Override
                public void onBackInvoked() {
                    onBackPressedInternal();
                }
            });
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
        if(musicID != 0 && !player.isPlaying()){
            playMusic();
        }
        if (!BwbxUI.isConnected(this) && !patching) {
            showProgressbar = true;
            handler.removeCallbacks(runnable);
            strStatus = getResources().getString(R.string.lebian_dl_status_no_network);
            textStatus.setText(strStatus);
        }
        boolean isGp = (Boolean) callNextChapterParcel("isGP", null, null);
        if (isGp) {
            //二次加载的时候，收到了跳转GP更新，会走到这里
            showSwitchGPDialog();
        }
        callNextChapterParcel("onResume", null, null);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "onRestart enter");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (nextChapterParcel != null) {
            callNextChapterParcel("onSaveInstanceState", new Class[]{Bundle.class}, new Object[]{outState});
            outState.putParcelable("nextChapterParcel", nextChapterParcel);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        callNextChapterParcel("onPause", null, null);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(musicID != 0){
            pauseMusic();
        }
        if (videoView != null) {
            videoView.onStop();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(musicID != 0){
            stopMusic();
        }
        if (videoView != null) {
            videoView.onDestroy();
        }
        LBContextCompat.unregisterReceiver(this,myReceiver);
        callNextChapterParcel("onDestroy", null, null);
    }

    private final Runnable downloadCallBack = new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "downloadCallBack enter");
            boolean showUnfinishedDialog = (Boolean) callNextChapterParcel("getPopUnfinishedDialog", null, null);
            if (showUnfinishedDialog){
                showProgressbar = true;
                handler.removeCallbacks(runnable);
                strStatus = getResources().getString(R.string.lebian_dl_dl_failed);
                textStatus.setText(strStatus);
                showUnfinishedDlDialog();
            }
            handler.postDelayed(downloadCallBack, 10000);
        }
    };

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            onBackPressedInternal();
        }
        return false;
    }

    private void showExitDialog() {
        if (exitDialog == null) {
            Builder builder = new Builder(this);
            builder.setMessage(getResources().getString(R.string.lebian_exit_dialog_titile));

            builder.setTitle(getResources().getString(R.string.lebian_hint));

            builder.setPositiveButton(getResources().getString(R.string.lebian_button_ok), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    finish();
                    if (gameRunning){
                        quitGame();
                    }
                }
            });

            builder.setNegativeButton(getResources().getString(R.string.lebian_button_cancel), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    dialog.dismiss();
                    exitDialog = null;
                }
            });
            exitDialog = builder.create();
            exitDialog.setCancelable(false);
            exitDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
        }
        if (!exitDialog.isShowing() && !isFinishing()) {
            exitDialog.show();
        }
    }

    private void showDlWithoutWifiDialog(final Serializable detail, final String mainActivity, final boolean dataConnection) {
        if (dlWithoutWifiDialog == null) {
            final boolean forceUpdate = rForceUpdate;
            CustomDialog.Builder builder = new CustomDialog.Builder(this);
            int resId = R.string.lebian_dl_update_without_wifi;
            int resId2 = R.string.lebian_dl_update_wifi;
            builder.setMessage(String.format(getResources().getString(dataConnection ? resId : resId2), ((float) (rSize)) / (1024.0f * 1024.0f)));

            builder.setTitle(getResources().getString(R.string.lebian_hint));

            if (!forceUpdate) {
                builder.setCheckBox(getResources().getString(R.string.lebian_next_no_prompt), false, new OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        PreferencesHelper.putBoolean(NextChapter.this, PreferencesHelper.MODULE_PROMPT, "gameUpdate", isChecked);
                    }
                });
            }

            builder.setPositiveButton(getResources().getString(R.string.lebian_button_ok), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    callNextChapterParcel("downloadComponent", new Class[]{Serializable.class}, new Object[]{detail});
                    dlWithoutWifiDialog = null;
                    PreferencesHelper.putBoolean(NextChapter.this, PreferencesHelper.MODULE_PROMPT, "gameUpdate", false);
                }
            });

            resId = forceUpdate ? R.string.lebian_quit_game : R.string.lebian_no_update;
            if (!forceUpdate) {
                builder.setNegativeButton(getResources().getString(resId), new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        dlWithoutWifiDialog = null;
                        if (mainActivity == null || mainActivity.length() <= 0){
                            finish();
                        } else {
                            callNextChapterParcel("startMainActivity", new Class[]{String.class}, new Object[]{mainActivity});
                        }
                    }
                });
            }  else if (BwbxUI.getGlobalBoolean(NextChapter.this, "ENABLE_EXIT_BUTTON", false)) {
                builder.setNegativeButton(getResources().getString(resId), new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        dlWithoutWifiDialog = null;
                        finish();
                    }
                });
            }

            dlWithoutWifiDialog = builder.create();
            dlWithoutWifiDialog.setCancelable(false);
            dlWithoutWifiDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
        }
        if (!dlWithoutWifiDialog.isShowing() && !isFinishing()) {
            dlWithoutWifiDialog.show();
        }
    }

    private void showUnfinishedDlDialog() {
        Log.d(TAG, "showUnfinishedDialog enter, type:" + mDownloadsType);
        if (unfinishedDlDialog == null) {
            CustomDialog.Builder builder = new CustomDialog.Builder(this);
            builder.setMessage(getResources().getString(R.string.lebian_dl_unfinished_dl_without_wifi));
            builder.setTitle(getResources().getString(R.string.lebian_hint));
            builder.setPositiveButton(getResources().getString(R.string.lebian_button_ok), new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    if (detail != null || mDownloadsType == 2) {
                        if (mDownloadsType == 1) {
                            callNextChapterParcel("downloadComponent", new Class[]{Serializable.class}, new Object[]{detail});
                        }
                        else if (mDownloadsType == 2) {
                            callNextChapterParcel("downloadFullRes", new Class[]{int.class, Bundle.class}, new Object[]{mDlresZipType, resDlInfo});
                        }
                        strStatus = getResources().getString(R.string.lebian_dl_status_connecting);
                        handler.removeCallbacks(runnable);
                        handler.postDelayed(runnable, 800);
                    } else {
                        Log.d(TAG, "showUnfinishedDlDialog detail==null");
                    }
                }
            });
            if (BwbxUI.getGlobalBoolean(NextChapter.this, "ENABLE_EXIT_BUTTON", false)) {
                builder.setNegativeButton(getResources().getString(R.string.lebian_quit_game), new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        finish();
                        if (gameRunning){
                            quitGame();
                        }
                    }
                });
            }
            unfinishedDlDialog = builder.create();
            unfinishedDlDialog.setCancelable(false);
            unfinishedDlDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
        }
        if (!unfinishedDlDialog.isShowing() && !isFinishing()) {
            unfinishedDlDialog.show();
        }
    }

    private void showUpdateWithoutWifiDialog(final Serializable detail, final Serializable localDetail, final boolean dataConnection) {
        if (updateWithoutWifiDialog == null) {
            final boolean forceUpdate = rForceUpdate;
            CustomDialog.Builder builder = new CustomDialog.Builder(this);
            builder.setMessage(String.format(getResources().getString(dataConnection ? R.string.lebian_dl_update_without_wifi : R.string.lebian_dl_update_wifi), ((float) (rSize)) / (1024.0f * 1024.0f)));

            builder.setTitle(getResources().getString(R.string.lebian_hint));
            if (!forceUpdate) {
                builder.setCheckBox(getResources().getString(R.string.lebian_next_no_prompt), false, new OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        PreferencesHelper.putBoolean(NextChapter.this, PreferencesHelper.MODULE_PROMPT, "gameUpdate", isChecked);
                    }
                });
            }
            builder.setPositiveButton(getResources().getString(R.string.lebian_button_ok), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    callNextChapterParcel("downloadComponent", new Class[]{Serializable.class}, new Object[]{detail});
                    PreferencesHelper.putBoolean(NextChapter.this, PreferencesHelper.MODULE_PROMPT, "gameUpdate", false);
                }
            });

            int resId = forceUpdate ? R.string.lebian_quit_game:R.string.lebian_no_update;
            if (!forceUpdate) {
                builder.setNegativeButton(getResources().getString(resId), new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        updateWithoutWifiDialog = null;
                        callNextChapterParcel("startGame", new Class[]{Serializable.class, Boolean.class}, new Object[]{localDetail, false});

                    }
                });
            } else if (BwbxUI.getGlobalBoolean(NextChapter.this, "ENABLE_EXIT_BUTTON", false)) {
                builder.setNegativeButton(getResources().getString(resId), new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        updateWithoutWifiDialog = null;
                        finish();
                    }
                });
            }

            updateWithoutWifiDialog = builder.create();
            updateWithoutWifiDialog.setCancelable(false);
            updateWithoutWifiDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
        }
        if (!updateWithoutWifiDialog.isShowing() && !isFinishing()) {
            updateWithoutWifiDialog.show();
        }
    }

    private void showDlBackgroundWithoutWifiDialog() {
        Log.d(TAG, "showDlBackgroundWithoutWifiDialog enter");
        if (dlBackgroundWithoutWifiDialog == null) {
            CustomDialog.Builder builder = new CustomDialog.Builder(this);
            builder.setMessage(getResources().getString(R.string.lebian_dl_dl_without_wifi_background));
            builder.setTitle(getResources().getString(R.string.lebian_hint));
            builder.setPositiveButton(getResources().getString(R.string.lebian_dl_dl_background), new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    finish();
                    if (gameRunning){
                        quitGame();
                    }
                }
            });
            if (BwbxUI.getGlobalBoolean(NextChapter.this, "ENABLE_EXIT_BUTTON", false)) {
                builder.setNegativeButton(getResources().getString(R.string.lebian_quit_game), new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        callNextChapterParcel("quitDownloadBg", null, null);
                        dialog.dismiss();
                        finish();
                        if (gameRunning){
                            quitGame();
                        }
                    }
                });
            }
            dlBackgroundWithoutWifiDialog = builder.create();
            dlBackgroundWithoutWifiDialog.setCancelable(false);
            dlBackgroundWithoutWifiDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
        }
        if (!dlBackgroundWithoutWifiDialog.isShowing() && !isFinishing()) {
            dlBackgroundWithoutWifiDialog.show();
        }
    }

    private void showNotEnoughSpaceDialog() {
        if (notEnoughSpaceDialog == null) {
            boolean hasSD = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
            CustomDialog.Builder builder = new CustomDialog.Builder(this);
            builder.setTitle(getResources().getString(R.string.lebian_not_enought_space));
            long requiredSize = rSize;
            if (!hasSD){
                requiredSize += (20 << 20);
            }
            String body = String.format(getResources().getString(R.string.lebian_storage_space_requirement_dload), requiredSize / (float) (1024 * 1024), hasSD ? getResources().getString(R.string.lebian_storage_sd) : getResources().getString(R.string.lebian_storage_phone));
            builder.setMessage(body);

            builder.setPositiveButton(getResources().getString(R.string.lebian_button_ok), new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    if (!gameRunning) {
                        if (localDetail == null || rForceUpdate){
                            finish();
                        }
                        else {
                            callNextChapterParcel("startGame", new Class[]{Serializable.class, Boolean.class}, new Object[]{localDetail, false});
                        }
                    } else {
                        finish();
                        if (rForceUpdate){
                            quitGame();
                        }
                    }
                }
            });
            notEnoughSpaceDialog = builder.create();
            notEnoughSpaceDialog.setCancelable(false);
            notEnoughSpaceDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
        }
        if (!notEnoughSpaceDialog.isShowing() && !isFinishing()) {
            notEnoughSpaceDialog.show();
        }
    }

    private void showSwitchGPDialog() {
        if (switchGPDialog == null) {
            boolean hasSD = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
            CustomDialog.Builder builder = new CustomDialog.Builder(this);
            builder.setTitle(getResources().getString(R.string.lebian_hint));
            builder.setMessage(R.string.lebian_dl_update_with_google_play);

            builder.setPositiveButton(getResources().getString(R.string.lebian_button_ok), new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    callNextChapterParcel("switchToGP", null, null);                }
            });
            switchGPDialog = builder.create();
            switchGPDialog.setCancelable(false);
            switchGPDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                @Override
                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                        return true;
                    } else {
                        return false;
                    }
                }
            });
        }
        if (!switchGPDialog.isShowing() && !isFinishing()) {
            switchGPDialog.show();
        }
    }


    private Object callNextChapterParcel(String name, Class[] type, Object[] args) {
        try {
            Class clazz = BwbxUI.getClass("main.NextChapterParcel");
            Method method = clazz.getDeclaredMethod(name, type);
            method.setAccessible(true);
            return method.invoke(nextChapterParcel, args);
        } catch (Exception e) {
            Log.d(TAG, "no NextChapterParcel:"+name);
            e.printStackTrace();
        }

        return null;
    }

    public void quitGame() {
        Log.d(TAG, "quit enter");
        LBContextCompat.unregisterReceiver(this,myReceiver);
        callNextChapterParcel("quitGame", null, null);
    }

    private void pauseMusic() {
        if(player!=null && player.isPlaying()) {
            player.pause();
        }
    }

    private void stopMusic() {
        if(player!=null) {
            player.stop();//停止
            player.reset();//重置
            player.release();//释放资源
            player = null;//赋空
        }
    }

    private void playMusic() {
        player.start();
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d(TAG,"onConfigurationChanged");
        mAdaptiveProgressBar.onConfigurationChanged(newConfig);
        backgroundView.dispatchConfigurationChanged(newConfig);
    }

    private void onBackPressedInternal() {
        if (!BwbxUI.isConnected(this) || BwbxUI.isWifi(this) || showProgressbar){
            showExitDialog();
        }
        else{
            showDlBackgroundWithoutWifiDialog();
        }
    }
}