/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.inputmethod;

import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.textservice.SpellCheckerInfo;
import android.view.textservice.SpellCheckerSubtype;
import android.view.textservice.TextServicesManager;
import android.widget.Switch;

import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceScreen;

import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.widget.SwitchBar;
import com.android.settings.widget.SwitchBar.OnSwitchChangeListener;

public class SpellCheckersSettings extends SettingsPreferenceFragment
        implements OnSwitchChangeListener, OnPreferenceChangeListener {
    private static final String TAG = SpellCheckersSettings.class.getSimpleName();
    private static final boolean DBG = false;

    private static final String KEY_SPELL_CHECKER_LANGUAGE = "spellchecker_language";
    private static final String KEY_DEFAULT_SPELL_CHECKER = "default_spellchecker";
    private static final int ITEM_ID_USE_SYSTEM_LANGUAGE = 0;

    private SwitchBar mSwitchBar;
    private Preference mSpellCheckerLanaguagePref;
    private AlertDialog mDialog = null;
    private SpellCheckerInfo mCurrentSci;
    private SpellCheckerInfo[] mEnabledScis;
    private TextServicesManager mTsm;

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.INPUTMETHOD_SPELL_CHECKERS;
    }

    @Override
    public void onCreate(final Bundle icicle) {
        super.onCreate(icicle);

        addPreferencesFromResource(R.xml.spellchecker_prefs);
        mSpellCheckerLanaguagePref = findPreference(KEY_SPELL_CHECKER_LANGUAGE);

        mTsm = (TextServicesManager) getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
        mCurrentSci = mTsm.getCurrentSpellChecker();
        mEnabledScis = mTsm.getEnabledSpellCheckers();
        populatePreferenceScreen();
    }

    private void populatePreferenceScreen() {
        final SpellCheckerPreference pref = new SpellCheckerPreference(getPrefContext(),
                mEnabledScis);
        pref.setTitle(R.string.default_spell_checker);
        final int count = (mEnabledScis == null) ? 0 : mEnabledScis.length;
        if (count > 0) {
            pref.setSummary("%s");
        } else {
            pref.setSummary(R.string.spell_checker_not_selected);
        }
        pref.setKey(KEY_DEFAULT_SPELL_CHECKER);
        pref.setOnPreferenceChangeListener(this);
        getPreferenceScreen().addPreference(pref);
    }

    @Override
    public void onResume() {
        super.onResume();
        mSwitchBar = ((SettingsActivity) getActivity()).getSwitchBar();
        mSwitchBar.setSwitchBarText(
                R.string.spell_checker_master_switch_title,
                R.string.spell_checker_master_switch_title);
        mSwitchBar.show();
        mSwitchBar.addOnSwitchChangeListener(this);
        updatePreferenceScreen();
    }

    @Override
    public void onPause() {
        super.onPause();
        mSwitchBar.removeOnSwitchChangeListener(this);
    }

    @Override
    public void onSwitchChanged(final Switch switchView, final boolean isChecked) {
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.SPELL_CHECKER_ENABLED,
                isChecked ? 1 : 0);
        updatePreferenceScreen();
    }

    private void updatePreferenceScreen() {
        mCurrentSci = mTsm.getCurrentSpellChecker();
        final boolean isSpellCheckerEnabled = mTsm.isSpellCheckerEnabled();
        mSwitchBar.setChecked(isSpellCheckerEnabled);

        final SpellCheckerSubtype currentScs;
        if (mCurrentSci != null) {
            currentScs = mTsm.getCurrentSpellCheckerSubtype(
                    false /* allowImplicitlySelectedSubtype */);
        } else {
            currentScs = null;
        }
        mSpellCheckerLanaguagePref.setSummary(getSpellCheckerSubtypeLabel(mCurrentSci, currentScs));

        final PreferenceScreen screen = getPreferenceScreen();
        final int count = screen.getPreferenceCount();
        for (int index = 0; index < count; index++) {
            final Preference preference = screen.getPreference(index);
            preference.setEnabled(isSpellCheckerEnabled);
            if (preference instanceof SpellCheckerPreference) {
                final SpellCheckerPreference pref = (SpellCheckerPreference) preference;
                pref.setSelected(mCurrentSci);
            }
        }
        mSpellCheckerLanaguagePref.setEnabled(isSpellCheckerEnabled && mCurrentSci != null);
    }

    private CharSequence getSpellCheckerSubtypeLabel(final SpellCheckerInfo sci,
            final SpellCheckerSubtype subtype) {
        if (sci == null) {
            return getString(R.string.spell_checker_not_selected);
        }
        if (subtype == null) {
            return getString(R.string.use_system_language_to_select_input_method_subtypes);
        }
        return subtype.getDisplayName(
                getActivity(), sci.getPackageName(), sci.getServiceInfo().applicationInfo);
    }

    @Override
    public boolean onPreferenceTreeClick(Preference preference) {
        if (KEY_SPELL_CHECKER_LANGUAGE.equals(preference.getKey())) {
            writePreferenceClickMetric(preference);
            showChooseLanguageDialog();
            return true;
        }
        return super.onPreferenceTreeClick(preference);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        final SpellCheckerInfo sci = (SpellCheckerInfo) newValue;
        final boolean isSystemApp =
                (sci.getServiceInfo().applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
        if (isSystemApp) {
            changeCurrentSpellChecker(sci);
            return true;
        } else {
            showSecurityWarnDialog(sci);
            return false;
        }
    }

    private static int convertSubtypeIndexToDialogItemId(final int index) {
        return index + 1;
    }

    private static int convertDialogItemIdToSubtypeIndex(final int item) {
        return item - 1;
    }

    private void showChooseLanguageDialog() {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
        }
        final SpellCheckerInfo currentSci = mTsm.getCurrentSpellChecker();
        if (currentSci == null) {
            // This can happen in some situations.  One example is that the package that the current
            // spell checker belongs to was uninstalled or being in background.
            return;
        }
        final SpellCheckerSubtype currentScs = mTsm.getCurrentSpellCheckerSubtype(
                false /* allowImplicitlySelectedSubtype */);
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(R.string.phone_language);
        final int subtypeCount = currentSci.getSubtypeCount();
        final CharSequence[] items = new CharSequence[subtypeCount + 1 /* default */];
        items[ITEM_ID_USE_SYSTEM_LANGUAGE] = getSpellCheckerSubtypeLabel(currentSci, null);
        int checkedItemId = ITEM_ID_USE_SYSTEM_LANGUAGE;
        for (int index = 0; index < subtypeCount; ++index) {
            final SpellCheckerSubtype subtype = currentSci.getSubtypeAt(index);
            final int itemId = convertSubtypeIndexToDialogItemId(index);
            items[itemId] = getSpellCheckerSubtypeLabel(currentSci, subtype);
            if (subtype.equals(currentScs)) {
                checkedItemId = itemId;
            }
        }
        builder.setSingleChoiceItems(items, checkedItemId, new AlertDialog.OnClickListener() {
            @Override
            public void onClick(final DialogInterface dialog, final int item) {
                final int subtypeId;
                if (item == ITEM_ID_USE_SYSTEM_LANGUAGE) {
                    subtypeId = SpellCheckerSubtype.SUBTYPE_ID_NONE;
                } else {
                    final int index = convertDialogItemIdToSubtypeIndex(item);
                    subtypeId = currentSci.getSubtypeAt(index).hashCode();
                }

                Settings.Secure.putInt(getContentResolver(),
                        Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, subtypeId);

                if (DBG) {
                    final SpellCheckerSubtype subtype = mTsm.getCurrentSpellCheckerSubtype(
                            true /* allowImplicitlySelectedSubtype */);
                    Log.d(TAG, "Current spell check locale is "
                            + subtype == null ? "null" : subtype.getLocale());
                }
                dialog.dismiss();
                updatePreferenceScreen();
            }
        });
        mDialog = builder.create();
        mDialog.show();
    }

    private void showSecurityWarnDialog(final SpellCheckerInfo sci) {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
        }
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(android.R.string.dialog_alert_title);
        builder.setMessage(getString(R.string.spellchecker_security_warning,
                sci.loadLabel(getPackageManager())));
        builder.setCancelable(true);
        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(final DialogInterface dialog, final int which) {
                changeCurrentSpellChecker(sci);
            }
        });
        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(final DialogInterface dialog, final int which) {
            }
        });
        mDialog = builder.create();
        mDialog.show();
    }

    private void changeCurrentSpellChecker(final SpellCheckerInfo sci) {
        Settings.Secure.putString(getContentResolver(), Settings.Secure.SELECTED_SPELL_CHECKER,
                sci.getId());
        // Reset the spell checker subtype
        Settings.Secure.putInt(getContentResolver(), Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE,
                SpellCheckerSubtype.SUBTYPE_ID_NONE);
        if (DBG) {
            Log.d(TAG, "Current spell check is " + mTsm.getCurrentSpellChecker().getId());
        }
        updatePreferenceScreen();
    }
}
