/*
 * 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 android.text.style;

import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.text.ParcelableSpan;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;

import java.util.Arrays;
import java.util.Locale;

/**
 * Holds suggestion candidates for the text enclosed in this span.
 *
 * When such a span is edited in an EditText, double tapping on the text enclosed in this span will
 * display a popup dialog listing suggestion replacement for that text. The user can then replace
 * the original text by one of the suggestions.
 *
 * These spans should typically be created by the input method to provide correction and alternates
 * for the text.
 *
 * @see TextView#isSuggestionsEnabled()
 */
public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {

    private static final String TAG = "SuggestionSpan";

    /**
     * Sets this flag if the suggestions should be easily accessible with few interactions.
     * This flag should be set for every suggestions that the user is likely to use.
     */
    public static final int FLAG_EASY_CORRECT = 0x0001;

    /**
     * Sets this flag if the suggestions apply to a misspelled word/text. This type of suggestion is
     * rendered differently to highlight the error.
     */
    public static final int FLAG_MISSPELLED = 0x0002;

    /**
     * Sets this flag if the auto correction is about to be applied to a word/text
     * that the user is typing/composing. This type of suggestion is rendered differently
     * to indicate the auto correction is happening.
     */
    public static final int FLAG_AUTO_CORRECTION = 0x0004;

    /**
     * This action is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
     *
     * @deprecated For IMEs to receive this kind of user interaction signals, implement IMEs' own
     *             suggestion picker UI instead of relying on {@link SuggestionSpan}. To retrieve
     *             bounding boxes for each character of the composing text, use
     *             {@link android.view.inputmethod.CursorAnchorInfo}.
     */
    @Deprecated
    public static final String ACTION_SUGGESTION_PICKED = "android.text.style.SUGGESTION_PICKED";

    /**
     * This is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
     *
     * @deprecated See {@link #ACTION_SUGGESTION_PICKED}.
     */
    @Deprecated
    public static final String SUGGESTION_SPAN_PICKED_AFTER = "after";
    /**
     * This is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
     *
     * @deprecated See {@link #ACTION_SUGGESTION_PICKED}.
     */
    @Deprecated
    public static final String SUGGESTION_SPAN_PICKED_BEFORE = "before";
    /**
     * This is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
     *
     * @deprecated See {@link #ACTION_SUGGESTION_PICKED}.
     */
    @Deprecated
    public static final String SUGGESTION_SPAN_PICKED_HASHCODE = "hashcode";

    public static final int SUGGESTIONS_MAX_SIZE = 5;

    /*
     * TODO: Needs to check the validity and add a feature that TextView will change
     * the current IME to the other IME which is specified in SuggestionSpan.
     * An IME needs to set the span by specifying the target IME and Subtype of SuggestionSpan.
     * And the current IME might want to specify any IME as the target IME including other IMEs.
     */

    private int mFlags;
    private final String[] mSuggestions;
    /**
     * Kept for compatibility for apps that rely on invalid locale strings e.g.
     * {@code new Locale(" an ", " i n v a l i d ", "data")}, which cannot be handled by
     * {@link #mLanguageTag}.
     */
    @NonNull
    private final String mLocaleStringForCompatibility;
    @NonNull
    private final String mLanguageTag;
    private final int mHashCode;

    @UnsupportedAppUsage
    private float mEasyCorrectUnderlineThickness;
    @UnsupportedAppUsage
    private int mEasyCorrectUnderlineColor;

    private float mMisspelledUnderlineThickness;
    private int mMisspelledUnderlineColor;

    private float mAutoCorrectionUnderlineThickness;
    private int mAutoCorrectionUnderlineColor;

    /**
     * @param context Context for the application
     * @param suggestions Suggestions for the string under the span
     * @param flags Additional flags indicating how this span is handled in TextView
     */
    public SuggestionSpan(Context context, String[] suggestions, int flags) {
        this(context, null, suggestions, flags, null);
    }

    /**
     * @param locale Locale of the suggestions
     * @param suggestions Suggestions for the string under the span
     * @param flags Additional flags indicating how this span is handled in TextView
     */
    public SuggestionSpan(Locale locale, String[] suggestions, int flags) {
        this(null, locale, suggestions, flags, null);
    }

    /**
     * @param context Context for the application
     * @param locale locale Locale of the suggestions
     * @param suggestions Suggestions for the string under the span. Only the first up to
     * {@link SuggestionSpan#SUGGESTIONS_MAX_SIZE} will be considered. Null values not permitted.
     * @param flags Additional flags indicating how this span is handled in TextView
     * @param notificationTargetClass if not null, this class will get notified when the user
     *                                selects one of the suggestions.  On Android
     *                                {@link android.os.Build.VERSION_CODES#Q} and later this
     *                                parameter is always ignored.
     */
    public SuggestionSpan(Context context, Locale locale, String[] suggestions, int flags,
            Class<?> notificationTargetClass) {
        final int N = Math.min(SUGGESTIONS_MAX_SIZE, suggestions.length);
        mSuggestions = Arrays.copyOf(suggestions, N);
        mFlags = flags;
        final Locale sourceLocale;
        if (locale != null) {
            sourceLocale = locale;
        } else if (context != null) {
            // TODO: Consider to context.getResources().getResolvedLocale() instead.
            sourceLocale = context.getResources().getConfiguration().locale;
        } else {
            Log.e("SuggestionSpan", "No locale or context specified in SuggestionSpan constructor");
            sourceLocale = null;
        }
        mLocaleStringForCompatibility = sourceLocale == null ? "" : sourceLocale.toString();
        mLanguageTag = sourceLocale == null ? "" : sourceLocale.toLanguageTag();
        mHashCode = hashCodeInternal(mSuggestions, mLanguageTag, mLocaleStringForCompatibility);

        initStyle(context);
    }

    private void initStyle(Context context) {
        if (context == null) {
            mMisspelledUnderlineThickness = 0;
            mEasyCorrectUnderlineThickness = 0;
            mAutoCorrectionUnderlineThickness = 0;
            mMisspelledUnderlineColor = Color.BLACK;
            mEasyCorrectUnderlineColor = Color.BLACK;
            mAutoCorrectionUnderlineColor = Color.BLACK;
            return;
        }

        int defStyleAttr = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
        TypedArray typedArray = context.obtainStyledAttributes(
                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
        mMisspelledUnderlineThickness = typedArray.getDimension(
                com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
        mMisspelledUnderlineColor = typedArray.getColor(
                com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);

        defStyleAttr = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
        typedArray = context.obtainStyledAttributes(
                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
        mEasyCorrectUnderlineThickness = typedArray.getDimension(
                com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
        mEasyCorrectUnderlineColor = typedArray.getColor(
                com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);

        defStyleAttr = com.android.internal.R.attr.textAppearanceAutoCorrectionSuggestion;
        typedArray = context.obtainStyledAttributes(
                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
        mAutoCorrectionUnderlineThickness = typedArray.getDimension(
                com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
        mAutoCorrectionUnderlineColor = typedArray.getColor(
                com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
    }

    public SuggestionSpan(Parcel src) {
        mSuggestions = src.readStringArray();
        mFlags = src.readInt();
        mLocaleStringForCompatibility = src.readString();
        mLanguageTag = src.readString();
        mHashCode = src.readInt();
        mEasyCorrectUnderlineColor = src.readInt();
        mEasyCorrectUnderlineThickness = src.readFloat();
        mMisspelledUnderlineColor = src.readInt();
        mMisspelledUnderlineThickness = src.readFloat();
        mAutoCorrectionUnderlineColor = src.readInt();
        mAutoCorrectionUnderlineThickness = src.readFloat();
    }

    /**
     * @return an array of suggestion texts for this span
     */
    public String[] getSuggestions() {
        return mSuggestions;
    }

    /**
     * @deprecated use {@link #getLocaleObject()} instead.
     * @return the locale of the suggestions. An empty string is returned if no locale is specified.
     */
    @NonNull
    @Deprecated
    public String getLocale() {
        return mLocaleStringForCompatibility;
    }

    /**
     * Returns a well-formed BCP 47 language tag representation of the suggestions, as a
     * {@link Locale} object.
     *
     * <p><b>Caveat</b>: The returned object is guaranteed to be a  a well-formed BCP 47 language tag
     * representation.  For example, this method can return an empty locale rather than returning a
     * malformed data when this object is initialized with an malformed {@link Locale} object, e.g.
     * {@code new Locale(" a ", " b c d ", " "}.</p>
     *
     * @return the locale of the suggestions. {@code null} is returned if no locale is specified.
     */
    @Nullable
    public Locale getLocaleObject() {
        return mLanguageTag.isEmpty() ? null : Locale.forLanguageTag(mLanguageTag);
    }

    /**
     * @return {@code null}.
     *
     * @hide
     * @deprecated Do not use. Always returns {@code null}.
     */
    @Deprecated
    @UnsupportedAppUsage
    public String getNotificationTargetClassName() {
        return null;
    }

    public int getFlags() {
        return mFlags;
    }

    public void setFlags(int flags) {
        mFlags = flags;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        writeToParcelInternal(dest, flags);
    }

    /** @hide */
    public void writeToParcelInternal(Parcel dest, int flags) {
        dest.writeStringArray(mSuggestions);
        dest.writeInt(mFlags);
        dest.writeString(mLocaleStringForCompatibility);
        dest.writeString(mLanguageTag);
        dest.writeInt(mHashCode);
        dest.writeInt(mEasyCorrectUnderlineColor);
        dest.writeFloat(mEasyCorrectUnderlineThickness);
        dest.writeInt(mMisspelledUnderlineColor);
        dest.writeFloat(mMisspelledUnderlineThickness);
        dest.writeInt(mAutoCorrectionUnderlineColor);
        dest.writeFloat(mAutoCorrectionUnderlineThickness);
    }

    @Override
    public int getSpanTypeId() {
        return getSpanTypeIdInternal();
    }

    /** @hide */
    public int getSpanTypeIdInternal() {
        return TextUtils.SUGGESTION_SPAN;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof SuggestionSpan) {
            return ((SuggestionSpan)o).hashCode() == mHashCode;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return mHashCode;
    }

    private static int hashCodeInternal(String[] suggestions, @NonNull String languageTag,
            @NonNull String localeStringForCompatibility) {
        return Arrays.hashCode(new Object[] {Long.valueOf(SystemClock.uptimeMillis()), suggestions,
                languageTag, localeStringForCompatibility});
    }

    public static final @android.annotation.NonNull Parcelable.Creator<SuggestionSpan> CREATOR =
            new Parcelable.Creator<SuggestionSpan>() {
        @Override
        public SuggestionSpan createFromParcel(Parcel source) {
            return new SuggestionSpan(source);
        }

        @Override
        public SuggestionSpan[] newArray(int size) {
            return new SuggestionSpan[size];
        }
    };

    @Override
    public void updateDrawState(TextPaint tp) {
        final boolean misspelled = (mFlags & FLAG_MISSPELLED) != 0;
        final boolean easy = (mFlags & FLAG_EASY_CORRECT) != 0;
        final boolean autoCorrection = (mFlags & FLAG_AUTO_CORRECTION) != 0;
        if (easy) {
            if (!misspelled) {
                tp.setUnderlineText(mEasyCorrectUnderlineColor, mEasyCorrectUnderlineThickness);
            } else if (tp.underlineColor == 0) {
                // Spans are rendered in an arbitrary order. Since misspelled is less prioritary
                // than just easy, do not apply misspelled if an easy (or a mispelled) has been set
                tp.setUnderlineText(mMisspelledUnderlineColor, mMisspelledUnderlineThickness);
            }
        } else if (autoCorrection) {
            tp.setUnderlineText(mAutoCorrectionUnderlineColor, mAutoCorrectionUnderlineThickness);
        }
    }

    /**
     * @return The color of the underline for that span, or 0 if there is no underline
     */
    @ColorInt
    public int getUnderlineColor() {
        // The order here should match what is used in updateDrawState
        final boolean misspelled = (mFlags & FLAG_MISSPELLED) != 0;
        final boolean easy = (mFlags & FLAG_EASY_CORRECT) != 0;
        final boolean autoCorrection = (mFlags & FLAG_AUTO_CORRECTION) != 0;
        if (easy) {
            if (!misspelled) {
                return mEasyCorrectUnderlineColor;
            } else {
                return mMisspelledUnderlineColor;
            }
        } else if (autoCorrection) {
            return mAutoCorrectionUnderlineColor;
        }
        return 0;
    }

    /**
     * Does nothing.
     *
     * @deprecated this is deprecated in {@link android.os.Build.VERSION_CODES#Q}.
     * @hide
     */
    @UnsupportedAppUsage
    @Deprecated
    public void notifySelection(Context context, String original, int index) {
        Log.w(TAG, "notifySelection() is deprecated.  Does nothing.");
    }
}
