//================================================================================================================================
//
// Copyright (c) 2015-2022 VisionStar Information Technology (Shanghai) Co., Ltd. All Rights Reserved.
// EasyAR is the registered trademark or trademark of VisionStar Information Technology (Shanghai) Co., Ltd in China
// and other countries for the augmented reality technology developed by VisionStar Information Technology (Shanghai) Co., Ltd.
//
//================================================================================================================================

package cn.easyar.samples.helloarmotiontracking;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.ContextThemeWrapper;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Locale;

// only the following application markets supported:
// Google PlayStore
// Xiaomi app store (小米应用商店)
// Huawei Apps Gallery (华为应用商店)
// OPPO APP Market (OPPO 软件商店)
// Samsung Galaxy Store (三星应用商店)
// V-Appstore (vivo应用商店)
//
// add to <manifest> in AndroidManifest.xml
//     <queries>
//         <intent>
//             <action android:name="android.intent.action.VIEW" />
//             <category android:name="android.intent.category.BROWSABLE" />
//             <data android:scheme="https" />
//         </intent>
//
//         <package android:name="com.google.ar.core" /> <!-- only needed when using ARCore < v1.19.0 -->
//
//         <!-- only needed for Huawei devices with Android 11+ -->
//         <package android:name="com.huawei.browser" />
//
//         <!-- only needed for OPPO devices with Android 11+ -->
//         <package android:name="com.oppo.market" />
//         <package android:name="com.heytap.market" />
//         <package android:name="com.heytap.browser" />
//
//         <!-- only needed for Samsung devices with Android 11+ -->
//         <package android:name="com.sec.android.app.samsungapps" />
//     </queries>

public class ARCoreInstaller {
    public static String getCurrentVersion(Context context) {
        try {
            PackageInfo pInfo = context.getPackageManager().getPackageInfo("com.google.ar.core", PackageManager.GET_META_DATA);
            return pInfo.versionName;
        } catch (PackageManager.NameNotFoundException e1) {
            return null;
        }
    }
    private static boolean isGoodVersion(String version) {
        return version.matches("\\d+\\.\\d+\\.\\d+");
    }
    private static boolean isVersionGreaterOrEqual(String left, String right) {
        String[] l = left.split("\\.");
        String[] r = right.split("\\.");
        if (l.length != r.length) { throw new RuntimeException("VersionSchemeNotMatch"); }
        for (int k = 0; k < l.length; k += 1) {
            int lPart = Integer.parseInt(l[k]);
            int rPart = Integer.parseInt(r[k]);
            if (lPart > rPart) { return true; }
            if (lPart < rPart) { return false; }
        }
        return true;
    }
    public interface InstallCallback {
        void invoke(boolean isInstalledAndSupportedVersion, boolean needContinue);
    }

    private static boolean isNewVersionIgnored = false;
    private static int dpToPx(Context context, int dp) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
    }

    public static boolean isInstalled(Activity activity) {
        String currentVersion = getCurrentVersion(activity);
        boolean isInstalledValue = (currentVersion != null) && isGoodVersion(currentVersion);
        return isInstalledValue;
    }

    public static void tryInstallOrUpdate(Activity activity, String minimumSupportedVersion, String knownLatestVersion, InstallCallback callback) {
        String currentVersion = getCurrentVersion(activity);
        boolean isInstalled = (currentVersion != null) && isGoodVersion(currentVersion);
        boolean isSupportedVersion = isInstalled && isVersionGreaterOrEqual(currentVersion, minimumSupportedVersion);
        boolean isLatesetVersion = isInstalled && isVersionGreaterOrEqual(currentVersion, knownLatestVersion);
        boolean isZh = Locale.getDefault().getLanguage() == "zh";

        if (isInstalled && isLatesetVersion) {
            callback.invoke(true, true);
            return;
        }
        if (isInstalled && isSupportedVersion && isNewVersionIgnored) {
            callback.invoke(true, true);
            return;
        }

        int DialogStyle = Build.VERSION.SDK_INT >= 22 ? android.R.style.Theme_DeviceDefault_Dialog_Alert : android.R.style.Theme_Dialog;
        AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(activity, DialogStyle));

        ArrayList<Pair<String, DialogInterface.OnClickListener>> selections = new ArrayList<>();
        {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("market://details?id=com.google.ar.core"));
            if (intent.resolveActivityInfo(activity.getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {
                selections.add(Pair.create(isZh ? "应用商店" : "Application Market", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        activity.startActivity(intent);
                    }
                }));
            }
        }
        {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("mimarket://details?id=com.google.ar.core"));
            if (intent.resolveActivityInfo(activity.getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {
                selections.add(Pair.create(isZh ? "小米应用商店" : "Xiaomi App Store", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        activity.startActivity(intent);
                    }
                }));
            }
        }
        {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("appmarket://details?id=com.google.ar.core"));
            if (intent.resolveActivityInfo(activity.getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {
                selections.add(Pair.create(isZh ? "华为应用商店" : "Huawei Apps Gallery", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        activity.startActivity(intent);
                    }
                }));
            }
        }
        {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("oppomarket://details?packagename=com.google.ar.core"));
            if (intent.resolveActivityInfo(activity.getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {
                selections.add(Pair.create(isZh ? "OPPO应用商店" : "OPPO APP Market", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        activity.startActivity(intent);
                    }
                }));
            }
        }
        {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("samsungapps://ProductDetail/com.google.ar.core"));
            if (intent.resolveActivityInfo(activity.getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {
                selections.add(Pair.create(isZh ? "三星应用商店" : "Samsung Galaxy Store", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        activity.startActivity(intent);
                    }
                }));
            }
        }
        {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("vivomarket://details?id=com.google.ar.core"));
            if (intent.resolveActivityInfo(activity.getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {
                selections.add(Pair.create(isZh ? "VIVO应用商店" : "V-Appstore", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        activity.startActivity(intent);
                    }
                }));
            }
        }
        {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("https://github.com/google-ar/arcore-android-sdk/releases"));
            if (intent.resolveActivityInfo(activity.getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {
                selections.add(Pair.create("GitHub", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        activity.startActivity(intent);
                    }
                }));
            }
        }

        String[] selectionTitles = new String[selections.size()];
        for (int k = 0; k < selections.size(); k += 1) {
            selectionTitles[k] = selections.get(k).first;
        }

        String titleText;
        if (!isInstalled) {
            titleText = isZh ? "请安装Google Play Services for AR以继续" : "Please install Google Play Services for AR to continue.";
        } else {
            if (isSupportedVersion) {
                titleText = isZh ? "似乎可更新Google Play Services for AR\n当前版本：" + currentVersion + "\n较新版本：" + knownLatestVersion : "It seems that Google Play Services for AR can be updated.\nCurrent version: " + currentVersion + "\nNewer version: " + knownLatestVersion;
            } else {
                titleText = isZh ? "请更新Google Play Services for AR以继续\n当前版本：" + currentVersion + "\n较新版本：" + knownLatestVersion : "Please update Google Play Services for AR to continue.\nCurrent version: " + currentVersion + "\nNewer version: " + knownLatestVersion;
            }
        }

        TextView title = new TextView(activity);
        title.setText(titleText);
        title.setTextAppearance(activity, android.R.style.TextAppearance_DeviceDefault_DialogWindowTitle);
        int dx = dpToPx(activity, 20);
        title.setPadding(dx, dx, dx, dx);
        builder.setCustomTitle(title);

        builder.setItems(selectionTitles, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                selections.get(which).second.onClick(dialog, 0);
                String currentVersion = getCurrentVersion(activity);
                boolean isInstalled = (currentVersion != null) && isGoodVersion(currentVersion);
                boolean isSupportedVersion = isInstalled && isVersionGreaterOrEqual(currentVersion, minimumSupportedVersion);
                callback.invoke(isInstalled && isSupportedVersion, isInstalled && isSupportedVersion);
            }
        });

        if (isInstalled && isSupportedVersion) {
            builder.setPositiveButton(isZh ? "忽略" : "Ignore", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String currentVersion = getCurrentVersion(activity);
                    boolean isInstalled = (currentVersion != null) && isGoodVersion(currentVersion);
                    boolean isSupportedVersion = isInstalled && isVersionGreaterOrEqual(currentVersion, minimumSupportedVersion);
                    callback.invoke(isInstalled && isSupportedVersion, isInstalled && isSupportedVersion);
                }
            });
            builder.setNeutralButton(isZh ? "始终忽略" : "Always Ignore", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String currentVersion = getCurrentVersion(activity);
                    boolean isInstalled = (currentVersion != null) && isGoodVersion(currentVersion);
                    boolean isSupportedVersion = isInstalled && isVersionGreaterOrEqual(currentVersion, minimumSupportedVersion);
                    isNewVersionIgnored = true;
                    callback.invoke(isInstalled && isSupportedVersion, isInstalled && isSupportedVersion);
                }
            });
        }

        builder.setNegativeButton(isZh ? "返回" : "Return", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String currentVersion = getCurrentVersion(activity);
                boolean isInstalled = (currentVersion != null) && isGoodVersion(currentVersion);
                boolean isSupportedVersion = isInstalled && isVersionGreaterOrEqual(currentVersion, minimumSupportedVersion);
                callback.invoke(isInstalled && isSupportedVersion, false);
            }
        });
        builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                String currentVersion = getCurrentVersion(activity);
                boolean isInstalled = (currentVersion != null) && isGoodVersion(currentVersion);
                boolean isSupportedVersion = isInstalled && isVersionGreaterOrEqual(currentVersion, minimumSupportedVersion);
                callback.invoke(isInstalled && isSupportedVersion, false);
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
    }
}
