/*
 * Copyright (C) 2015 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.support.v17.leanback.widget;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import android.support.v17.leanback.R;
import android.support.v4.content.ContextCompat;
import android.text.InputType;

import java.util.List;

/**
 * A data class which represents an action within a {@link
 * android.support.v17.leanback.app.GuidedStepFragment}. GuidedActions contain at minimum a title
 * and a description, and typically also an icon.
 * <p>
 * A GuidedAction typically represents a single action a user may take, but may also represent a
 * possible choice out of a group of mutually exclusive choices (similar to radio buttons), or an
 * information-only label (in which case the item cannot be clicked).
 * <p>
 * GuidedActions may optionally be checked. They may also indicate that they will request further
 * user input on selection, in which case they will be displayed with a chevron indicator.
 * <p>
 * GuidedAction recommends to use {@link Builder}. When application subclass GuidedAction, it
 * can subclass {@link BuilderBase}, implement its own builder() method where it should
 * call {@link BuilderBase#applyValues(GuidedAction)}.
 */
public class GuidedAction extends Action {

    private static final String TAG = "GuidedAction";

    /**
     * Special check set Id that is neither checkbox nor radio.
     */
    public static final int NO_CHECK_SET = 0;
    /**
     * Default checkset Id for radio.
     */
    public static final int DEFAULT_CHECK_SET_ID = 1;
    /**
     * Checkset Id for checkbox.
     */
    public static final int CHECKBOX_CHECK_SET_ID = -1;

    /**
     * When finishing editing, goes to next action.
     */
    public static final long ACTION_ID_NEXT = -2;
    /**
     * When finishing editing, stay on current action.
     */
    public static final long ACTION_ID_CURRENT = -3;

    /**
     * Id of standard OK action.
     */
    public static final long ACTION_ID_OK = -4;

    /**
     * Id of standard Cancel action.
     */
    public static final long ACTION_ID_CANCEL = -5;

    /**
     * Id of standard Finish action.
     */
    public static final long ACTION_ID_FINISH = -6;

    /**
     * Id of standard Finish action.
     */
    public static final long ACTION_ID_CONTINUE = -7;

    /**
     * Id of standard Yes action.
     */
    public static final long ACTION_ID_YES = -8;

    /**
     * Id of standard No action.
     */
    public static final long ACTION_ID_NO = -9;

    static final int EDITING_NONE = 0;
    static final int EDITING_TITLE = 1;
    static final int EDITING_DESCRIPTION = 2;
    static final int EDITING_ACTIVATOR_VIEW = 3;

    /**
     * Base builder class to build a {@link GuidedAction} object.  When subclass GuidedAction, you
     * can override this BuilderBase class, implements your build() method which should call
     * {@link #applyValues(GuidedAction)}.  When using GuidedAction directly, use {@link Builder}.
     */
    public abstract static class BuilderBase<B extends BuilderBase> {
        private Context mContext;
        private long mId;
        private CharSequence mTitle;
        private CharSequence mEditTitle;
        private CharSequence mDescription;
        private CharSequence mEditDescription;
        private Drawable mIcon;
        /**
         * The mActionFlags holds various action states such as whether title or description are
         * editable, or the action is focusable.
         *
         */
        private int mActionFlags;

        private int mEditable = EDITING_NONE;
        private int mInputType = InputType.TYPE_CLASS_TEXT;
        private int mDescriptionInputType = InputType.TYPE_CLASS_TEXT;
        private int mEditInputType = InputType.TYPE_CLASS_TEXT;
        private int mDescriptionEditInputType = InputType.TYPE_CLASS_TEXT;
        private int mCheckSetId = NO_CHECK_SET;
        private List<GuidedAction> mSubActions;
        private Intent mIntent;

        /**
         * Creates a BuilderBase for GuidedAction or its subclass.
         * @param context Context object used to build the GuidedAction.
         */
        public BuilderBase(Context context) {
            mContext = context;
            mActionFlags = PF_ENABLED | PF_FOCUSABLE | PF_AUTORESTORE;
        }

        /**
         * Returns Context of this Builder.
         * @return Context of this Builder.
         */
        public Context getContext() {
            return mContext;
        }

        private void setFlags(int flag, int mask) {
            mActionFlags = (mActionFlags & ~mask) | (flag & mask);
        }

        /**
         * Subclass of BuilderBase should call this function to apply values.
         * @param action GuidedAction to apply BuilderBase values.
         */
        protected final void applyValues(GuidedAction action) {
            // Base Action values
            action.setId(mId);
            action.setLabel1(mTitle);
            action.setEditTitle(mEditTitle);
            action.setLabel2(mDescription);
            action.setEditDescription(mEditDescription);
            action.setIcon(mIcon);

            // Subclass values
            action.mIntent = mIntent;
            action.mEditable = mEditable;
            action.mInputType = mInputType;
            action.mDescriptionInputType = mDescriptionInputType;
            action.mEditInputType = mEditInputType;
            action.mDescriptionEditInputType = mDescriptionEditInputType;
            action.mActionFlags = mActionFlags;
            action.mCheckSetId = mCheckSetId;
            action.mSubActions = mSubActions;
        }

        /**
         * Construct a clickable action with associated id and auto assign pre-defined title for the
         * action. If the id is not supported, the method simply does nothing.
         * @param id One of {@link GuidedAction#ACTION_ID_OK} {@link GuidedAction#ACTION_ID_CANCEL}
         * {@link GuidedAction#ACTION_ID_FINISH} {@link GuidedAction#ACTION_ID_CONTINUE}
         * {@link GuidedAction#ACTION_ID_YES} {@link GuidedAction#ACTION_ID_NO}.
         * @return The same BuilderBase object.
         */
        public B clickAction(long id) {
            if (id == ACTION_ID_OK) {
                mId = ACTION_ID_OK;
                mTitle = mContext.getString(android.R.string.ok);
            } else if (id == ACTION_ID_CANCEL) {
                mId = ACTION_ID_CANCEL;
                mTitle = mContext.getString(android.R.string.cancel);
            } else if (id == ACTION_ID_FINISH) {
                mId = ACTION_ID_FINISH;
                mTitle = mContext.getString(R.string.lb_guidedaction_finish_title);
            } else if (id == ACTION_ID_CONTINUE) {
                mId = ACTION_ID_CONTINUE;
                mTitle = mContext.getString(R.string.lb_guidedaction_continue_title);
            } else if (id == ACTION_ID_YES) {
                mId = ACTION_ID_YES;
                mTitle = mContext.getString(android.R.string.ok);
            } else if (id == ACTION_ID_NO) {
                mId = ACTION_ID_NO;
                mTitle = mContext.getString(android.R.string.cancel);
            }
            return (B) this;
        }

        /**
         * Sets the ID associated with this action.  The ID can be any value the client wishes;
         * it is typically used to determine what to do when an action is clicked.
         * @param id The ID to associate with this action.
         */
        public B id(long id) {
            mId = id;
            return (B) this;
        }

        /**
         * Sets the title for this action.  The title is typically a short string indicating the
         * action to be taken on click, e.g. "Continue" or "Cancel".
         * @param title The title for this action.
         */
        public B title(CharSequence title) {
            mTitle = title;
            return (B) this;
        }

        /**
         * Sets the title for this action.  The title is typically a short string indicating the
         * action to be taken on click, e.g. "Continue" or "Cancel".
         * @param titleResourceId The resource id of title for this action.
         */
        public B title(@StringRes int titleResourceId) {
            mTitle = getContext().getString(titleResourceId);
            return (B) this;
        }

        /**
         * Sets the optional title text to edit.  When TextView is activated, the edit title
         * replaces the string of title.
         * @param editTitle The optional title text to edit when TextView is activated.
         */
        public B editTitle(CharSequence editTitle) {
            mEditTitle = editTitle;
            return (B) this;
        }

        /**
         * Sets the optional title text to edit.  When TextView is activated, the edit title
         * replaces the string of title.
         * @param editTitleResourceId String resource id of the optional title text to edit when
         * TextView is activated.
         */
        public B editTitle(@StringRes int editTitleResourceId) {
            mEditTitle = getContext().getString(editTitleResourceId);
            return (B) this;
        }

        /**
         * Sets the description for this action.  The description is typically a longer string
         * providing extra information on what the action will do.
         * @param description The description for this action.
         */
        public B description(CharSequence description) {
            mDescription = description;
            return (B) this;
        }

        /**
         * Sets the description for this action.  The description is typically a longer string
         * providing extra information on what the action will do.
         * @param descriptionResourceId String resource id of the description for this action.
         */
        public B description(@StringRes int descriptionResourceId) {
            mDescription = getContext().getString(descriptionResourceId);
            return (B) this;
        }

        /**
         * Sets the optional description text to edit.  When TextView is activated, the edit
         * description replaces the string of description.
         * @param description The description to edit for this action.
         */
        public B editDescription(CharSequence description) {
            mEditDescription = description;
            return (B) this;
        }

        /**
         * Sets the optional description text to edit.  When TextView is activated, the edit
         * description replaces the string of description.
         * @param descriptionResourceId String resource id of the description to edit for this
         * action.
         */
        public B editDescription(@StringRes int descriptionResourceId) {
            mEditDescription = getContext().getString(descriptionResourceId);
            return (B) this;
        }

        /**
         * Sets the intent associated with this action.  Clients would typically fire this intent
         * directly when the action is clicked.
         * @param intent The intent associated with this action.
         */
        public B intent(Intent intent) {
            mIntent = intent;
            return (B) this;
        }

        /**
         * Sets the action's icon drawable.
         * @param icon The drawable for the icon associated with this action.
         */
        public B icon(Drawable icon) {
            mIcon = icon;
            return (B) this;
        }

        /**
         * Sets the action's icon drawable by retrieving it by resource ID from the specified
         * context. This is a convenience function that simply looks up the drawable and calls
         * {@link #icon(Drawable)}.
         * @param iconResourceId The resource ID for the icon associated with this action.
         * @param context The context whose resource ID should be retrieved.
         * @deprecated Use {@link #icon(int)}.
         */
        @Deprecated
        public B iconResourceId(@DrawableRes int iconResourceId, Context context) {
            return icon(ContextCompat.getDrawable(context, iconResourceId));
        }

        /**
         * Sets the action's icon drawable by retrieving it by resource ID from Builder's
         * context. This is a convenience function that simply looks up the drawable and calls
         * {@link #icon(Drawable)}.
         * @param iconResourceId The resource ID for the icon associated with this action.
         */
        public B icon(@DrawableRes int iconResourceId) {
            return icon(ContextCompat.getDrawable(getContext(), iconResourceId));
        }

        /**
         * Indicates whether this action title is editable. Note: Editable actions cannot also be
         * checked, or belong to a check set.
         * @param editable Whether this action is editable.
         */
        public B editable(boolean editable) {
            if (!editable) {
                if (mEditable == EDITING_TITLE) {
                    mEditable = EDITING_NONE;
                }
                return (B) this;
            }
            mEditable = EDITING_TITLE;
            if (isChecked() || mCheckSetId != NO_CHECK_SET) {
                throw new IllegalArgumentException("Editable actions cannot also be checked");
            }
            return (B) this;
        }

        /**
         * Indicates whether this action's description is editable
         * @param editable Whether this action description is editable.
         */
        public B descriptionEditable(boolean editable) {
            if (!editable) {
                if (mEditable == EDITING_DESCRIPTION) {
                    mEditable = EDITING_NONE;
                }
                return (B) this;
            }
            mEditable = EDITING_DESCRIPTION;
            if (isChecked() || mCheckSetId != NO_CHECK_SET) {
                throw new IllegalArgumentException("Editable actions cannot also be checked");
            }
            return (B) this;
        }

        /**
         * Indicates whether this action has a view can be activated to edit, e.g. a DatePicker.
         * @param editable Whether this action has view can be activated to edit.
         */
        public B hasEditableActivatorView(boolean editable) {
            if (!editable) {
                if (mEditable == EDITING_ACTIVATOR_VIEW) {
                    mEditable = EDITING_NONE;
                }
                return (B) this;
            }
            mEditable = EDITING_ACTIVATOR_VIEW;
            if (isChecked() || mCheckSetId != NO_CHECK_SET) {
                throw new IllegalArgumentException("Editable actions cannot also be checked");
            }
            return (B) this;
        }

        /**
         * Sets {@link InputType} of this action title not in editing.
         *
         * @param inputType InputType for the action title not in editing.
         */
        public B inputType(int inputType) {
            mInputType = inputType;
            return (B) this;
        }

        /**
         * Sets {@link InputType} of this action description not in editing.
         *
         * @param inputType InputType for the action description not in editing.
         */
        public B descriptionInputType(int inputType) {
            mDescriptionInputType = inputType;
            return (B) this;
        }


        /**
         * Sets {@link InputType} of this action title in editing.
         *
         * @param inputType InputType for the action title in editing.
         */
        public B editInputType(int inputType) {
            mEditInputType = inputType;
            return (B) this;
        }

        /**
         * Sets {@link InputType} of this action description in editing.
         *
         * @param inputType InputType for the action description in editing.
         */
        public B descriptionEditInputType(int inputType) {
            mDescriptionEditInputType = inputType;
            return (B) this;
        }


        private boolean isChecked() {
            return (mActionFlags & PF_CHECKED) == PF_CHECKED;
        }
        /**
         * Indicates whether this action is initially checked.
         * @param checked Whether this action is checked.
         */
        public B checked(boolean checked) {
            setFlags(checked ? PF_CHECKED : 0, PF_CHECKED);
            if (mEditable != EDITING_NONE) {
                throw new IllegalArgumentException("Editable actions cannot also be checked");
            }
            return (B) this;
        }

        /**
         * Indicates whether this action is part of a single-select group similar to radio buttons
         * or this action is a checkbox. When one item in a check set is checked, all others with
         * the same check set ID will be checked automatically.
         * @param checkSetId The check set ID, or {@link GuidedAction#NO_CHECK_SET} to indicate not
         * radio or checkbox, or {@link GuidedAction#CHECKBOX_CHECK_SET_ID} to indicate a checkbox.
         */
        public B checkSetId(int checkSetId) {
            mCheckSetId = checkSetId;
            if (mEditable != EDITING_NONE) {
                throw new IllegalArgumentException("Editable actions cannot also be in check sets");
            }
            return (B) this;
        }

        /**
         * Indicates whether the title and description are long, and should be displayed
         * appropriately.
         * @param multilineDescription Whether this action has a multiline description.
         */
        public B multilineDescription(boolean multilineDescription) {
            setFlags(multilineDescription ? PF_MULTI_lINE_DESCRIPTION : 0,
                    PF_MULTI_lINE_DESCRIPTION);
            return (B) this;
        }

        /**
         * Indicates whether this action has a next state and should display a chevron.
         * @param hasNext Whether this action has a next state.
         */
        public B hasNext(boolean hasNext) {
            setFlags(hasNext ? PF_HAS_NEXT : 0, PF_HAS_NEXT);
            return (B) this;
        }

        /**
         * Indicates whether this action is for information purposes only and cannot be clicked.
         * @param infoOnly Whether this action has a next state.
         */
        public B infoOnly(boolean infoOnly) {
            setFlags(infoOnly ? PF_INFO_ONLY : 0, PF_INFO_ONLY);
            return (B) this;
        }

        /**
         * Indicates whether this action is enabled.  If not enabled, an action cannot be clicked.
         * @param enabled Whether the action is enabled.
         */
        public B enabled(boolean enabled) {
            setFlags(enabled ? PF_ENABLED : 0, PF_ENABLED);
            return (B) this;
        }

        /**
         * Indicates whether this action can take focus.
         * @param focusable
         * @return The same BuilderBase object.
         */
        public B focusable(boolean focusable) {
            setFlags(focusable ? PF_FOCUSABLE : 0, PF_FOCUSABLE);
            return (B) this;
        }

        /**
         * Sets sub actions list.
         * @param subActions
         * @return The same BuilderBase object.
         */
        public B subActions(List<GuidedAction> subActions) {
            mSubActions = subActions;
            return (B) this;
        }

        /**
         * Explicitly sets auto restore feature on the GuidedAction.  It's by default true.
         * @param autoSaveRestoreEnabled True if turn on auto save/restore of GuidedAction content,
         *                                false otherwise.
         * @return The same BuilderBase object.
         * @see GuidedAction#isAutoSaveRestoreEnabled()
         */
        public B autoSaveRestoreEnabled(boolean autoSaveRestoreEnabled) {
            setFlags(autoSaveRestoreEnabled ? PF_AUTORESTORE : 0, PF_AUTORESTORE);
            return (B) this;
        }

    }

    /**
     * Builds a {@link GuidedAction} object.
     */
    public static class Builder extends BuilderBase<Builder> {

        /**
         * @deprecated Use {@link GuidedAction.Builder#GuidedAction.Builder(Context)}.
         */
        @Deprecated
        public Builder() {
            super(null);
        }

        /**
         * Creates a Builder for GuidedAction.
         * @param context Context to build GuidedAction.
         */
        public Builder(Context context) {
            super(context);
        }

        /**
         * Builds the GuidedAction corresponding to this Builder.
         * @return The GuidedAction as configured through this Builder.
         */
        public GuidedAction build() {
            GuidedAction action = new GuidedAction();
            applyValues(action);
            return action;
        }

    }

    static final int PF_CHECKED = 0x00000001;
    static final int PF_MULTI_lINE_DESCRIPTION = 0x00000002;
    static final int PF_HAS_NEXT = 0x00000004;
    static final int PF_INFO_ONLY = 0x00000008;
    static final int PF_ENABLED = 0x00000010;
    static final int PF_FOCUSABLE = 0x00000020;
    static final int PF_AUTORESTORE = 0x00000040;
    int mActionFlags;

    private CharSequence mEditTitle;
    private CharSequence mEditDescription;
    int mEditable;
    int mInputType;
    int mDescriptionInputType;
    int mEditInputType;
    int mDescriptionEditInputType;

    int mCheckSetId;

    List<GuidedAction> mSubActions;

    Intent mIntent;

    protected GuidedAction() {
        super(0);
    }

    private void setFlags(int flag, int mask) {
        mActionFlags = (mActionFlags & ~mask) | (flag & mask);
    }

    /**
     * Returns the title of this action.
     * @return The title set when this action was built.
     */
    public CharSequence getTitle() {
        return getLabel1();
    }

    /**
     * Sets the title of this action.
     * @param title The title set when this action was built.
     */
    public void setTitle(CharSequence title) {
        setLabel1(title);
    }

    /**
     * Returns the optional title text to edit.  When not null, it is being edited instead of
     * {@link #getTitle()}.
     * @return Optional title text to edit instead of {@link #getTitle()}.
     */
    public CharSequence getEditTitle() {
        return mEditTitle;
    }

    /**
     * Sets the optional title text to edit instead of {@link #setTitle(CharSequence)}.
     * @param editTitle Optional title text to edit instead of {@link #setTitle(CharSequence)}.
     */
    public void setEditTitle(CharSequence editTitle) {
        mEditTitle = editTitle;
    }

    /**
     * Returns the optional description text to edit.  When not null, it is being edited instead of
     * {@link #getDescription()}.
     * @return Optional description text to edit instead of {@link #getDescription()}.
     */
    public CharSequence getEditDescription() {
        return mEditDescription;
    }

    /**
     * Sets the optional description text to edit instead of {@link #setDescription(CharSequence)}.
     * @param editDescription Optional description text to edit instead of
     * {@link #setDescription(CharSequence)}.
     */
    public void setEditDescription(CharSequence editDescription) {
        mEditDescription = editDescription;
    }

    /**
     * Returns true if {@link #getEditTitle()} is not null.  When true, the {@link #getEditTitle()}
     * is being edited instead of {@link #getTitle()}.
     * @return true if {@link #getEditTitle()} is not null.
     */
    public boolean isEditTitleUsed() {
        return mEditTitle != null;
    }

    /**
     * Returns the description of this action.
     * @return The description of this action.
     */
    public CharSequence getDescription() {
        return getLabel2();
    }

    /**
     * Sets the description of this action.
     * @param description The description of the action.
     */
    public void setDescription(CharSequence description) {
        setLabel2(description);
    }

    /**
     * Returns the intent associated with this action.
     * @return The intent set when this action was built.
     */
    public Intent getIntent() {
        return mIntent;
    }

    /**
     * Sets the intent of this action.
     * @param intent New intent to set on this action.
     */
    public void setIntent(Intent intent) {
        mIntent = intent;
    }

    /**
     * Returns whether this action title is editable.
     * @return true if the action title is editable, false otherwise.
     */
    public boolean isEditable() {
        return mEditable == EDITING_TITLE;
    }

    /**
     * Returns whether this action description is editable.
     * @return true if the action description is editable, false otherwise.
     */
    public boolean isDescriptionEditable() {
        return mEditable == EDITING_DESCRIPTION;
    }

    /**
     * Returns if this action has editable title or editable description.
     * @return True if this action has editable title or editable description, false otherwise.
     */
    public boolean hasTextEditable() {
        return mEditable == EDITING_TITLE || mEditable == EDITING_DESCRIPTION;
    }

    /**
     * Returns whether this action can be activated to edit, e.g. a DatePicker.
     * @return true if the action can be activated to edit.
     */
    public boolean hasEditableActivatorView() {
        return mEditable == EDITING_ACTIVATOR_VIEW;
    }

    /**
     * Returns InputType of action title in editing; only valid when {@link #isEditable()} is true.
     * @return InputType of action title in editing.
     */
    public int getEditInputType() {
        return mEditInputType;
    }

    /**
     * Returns InputType of action description in editing; only valid when
     * {@link #isDescriptionEditable()} is true.
     * @return InputType of action description in editing.
     */
    public int getDescriptionEditInputType() {
        return mDescriptionEditInputType;
    }

    /**
     * Returns InputType of action title not in editing.
     * @return InputType of action title not in editing.
     */
    public int getInputType() {
        return mInputType;
    }

    /**
     * Returns InputType of action description not in editing.
     * @return InputType of action description not in editing.
     */
    public int getDescriptionInputType() {
        return mDescriptionInputType;
    }

    /**
     * Returns whether this action is checked.
     * @return true if the action is currently checked, false otherwise.
     */
    public boolean isChecked() {
        return (mActionFlags & PF_CHECKED) == PF_CHECKED;
    }

    /**
     * Sets whether this action is checked.
     * @param checked Whether this action should be checked.
     */
    public void setChecked(boolean checked) {
        setFlags(checked ? PF_CHECKED : 0, PF_CHECKED);
    }

    /**
     * Returns the check set id this action is a part of. All actions in the same list with the same
     * check set id are considered linked. When one of the actions within that set is selected, that
     * action becomes checked, while all the other actions become unchecked.
     *
     * @return an integer representing the check set this action is a part of, or
     *         {@link #CHECKBOX_CHECK_SET_ID} if this is a checkbox, or {@link #NO_CHECK_SET} if
     *         this action is not a checkbox or radiobutton.
     */
    public int getCheckSetId() {
        return mCheckSetId;
    }

    /**
     * Returns whether this action is has a multiline description.
     * @return true if the action was constructed as having a multiline description, false
     * otherwise.
     */
    public boolean hasMultilineDescription() {
        return (mActionFlags & PF_MULTI_lINE_DESCRIPTION) == PF_MULTI_lINE_DESCRIPTION;
    }

    /**
     * Returns whether this action is enabled.
     * @return true if the action is currently enabled, false otherwise.
     */
    public boolean isEnabled() {
        return (mActionFlags & PF_ENABLED) == PF_ENABLED;
    }

    /**
     * Sets whether this action is enabled.
     * @param enabled Whether this action should be enabled.
     */
    public void setEnabled(boolean enabled) {
        setFlags(enabled ? PF_ENABLED : 0, PF_ENABLED);
    }

    /**
     * Returns whether this action is focusable.
     * @return true if the action is currently focusable, false otherwise.
     */
    public boolean isFocusable() {
        return (mActionFlags & PF_FOCUSABLE) == PF_FOCUSABLE;
    }

    /**
     * Sets whether this action is focusable.
     * @param focusable Whether this action should be focusable.
     */
    public void setFocusable(boolean focusable) {
        setFlags(focusable ? PF_FOCUSABLE : 0, PF_FOCUSABLE);
    }

    /**
     * Returns whether this action will request further user input when selected, such as showing
     * another GuidedStepFragment or launching a new activity. Configured during construction.
     * @return true if the action will request further user input when selected, false otherwise.
     */
    public boolean hasNext() {
        return (mActionFlags & PF_HAS_NEXT) == PF_HAS_NEXT;
    }

    /**
     * Returns whether the action will only display information and is thus not clickable. If both
     * this and {@link #hasNext()} are true, infoOnly takes precedence. The default is false. For
     * example, this might represent e.g. the amount of storage a document uses, or the cost of an
     * app.
     * @return true if will only display information, false otherwise.
     */
    public boolean infoOnly() {
        return (mActionFlags & PF_INFO_ONLY) == PF_INFO_ONLY;
    }

    /**
     * Change sub actions list.
     * @param actions Sub actions list to set on this action.  Sets null to disable sub actions.
     */
    public void setSubActions(List<GuidedAction> actions) {
        mSubActions = actions;
    }

    /**
     * @return List of sub actions or null if sub actions list is not enabled.
     */
    public List<GuidedAction> getSubActions() {
        return mSubActions;
    }

    /**
     * @return True if has sub actions list, even it's currently empty.
     */
    public boolean hasSubActions() {
        return mSubActions != null;
    }

    /**
     * Returns true if Action will be saved to instanceState and restored later, false otherwise.
     * The default value is true.  When isAutoSaveRestoreEnabled() is true and {@link #getId()} is
     * not {@link #NO_ID}:
     * <li>{@link #isEditable()} is true: save text of {@link #getTitle()}</li>
     * <li>{@link #isDescriptionEditable()} is true: save text of {@link #getDescription()}</li>
     * <li>{@link #getCheckSetId()} is not {@link #NO_CHECK_SET}: save {@link #isChecked()}}</li>
     * <li>{@link GuidedDatePickerAction} will be saved</li>
     * App may explicitly disable auto restore and handle by itself. App should override Fragment
     * onSaveInstanceState() and onCreateActions()
     * @return True if Action will be saved to instanceState and restored later, false otherwise.
     */
    public final boolean isAutoSaveRestoreEnabled() {
        return (mActionFlags & PF_AUTORESTORE) == PF_AUTORESTORE;
    }

    /**
     * Save action into a bundle using a given key. When isAutoRestoreEna() is true:
     * <li>{@link #isEditable()} is true: save text of {@link #getTitle()}</li>
     * <li>{@link #isDescriptionEditable()} is true: save text of {@link #getDescription()}</li>
     * <li>{@link #getCheckSetId()} is not {@link #NO_CHECK_SET}: save {@link #isChecked()}}</li>
     * <li>{@link GuidedDatePickerAction} will be saved</li>
     * Subclass may override this method.
     * @param bundle  Bundle to save the Action.
     * @param key Key used to save the Action.
     */
    public void onSaveInstanceState(Bundle bundle, String key) {
        if (needAutoSaveTitle() && getTitle() != null) {
            bundle.putString(key, getTitle().toString());
        } else if (needAutoSaveDescription() && getDescription() != null) {
            bundle.putString(key, getDescription().toString());
        } else if (getCheckSetId() != NO_CHECK_SET) {
            bundle.putBoolean(key, isChecked());
        }
    }

    /**
     * Restore action from a bundle using a given key. When isAutoRestore() is true:
     * <li>{@link #isEditable()} is true: save text of {@link #getTitle()}</li>
     * <li>{@link #isDescriptionEditable()} is true: save text of {@link #getDescription()}</li>
     * <li>{@link #getCheckSetId()} is not {@link #NO_CHECK_SET}: save {@link #isChecked()}}</li>
     * <li>{@link GuidedDatePickerAction} will be saved</li>
     * Subclass may override this method.
     * @param bundle  Bundle to restore the Action from.
     * @param key Key used to restore the Action.
     */
    public void onRestoreInstanceState(Bundle bundle, String key) {
        if (needAutoSaveTitle()) {
            String title = bundle.getString(key);
            if (title != null) {
                setTitle(title);
            }
        } else if (needAutoSaveDescription()) {
            String description = bundle.getString(key);
            if (description != null) {
                setDescription(description);
            }
        } else if (getCheckSetId() != NO_CHECK_SET) {
            setChecked(bundle.getBoolean(key, isChecked()));
        }
    }

    final static boolean isPasswordVariant(int inputType) {
        final int variation = inputType & InputType.TYPE_MASK_VARIATION;
        return variation == InputType.TYPE_TEXT_VARIATION_PASSWORD
                || variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
                || variation == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD;
    }

    final boolean needAutoSaveTitle() {
        return isEditable() && !isPasswordVariant(getEditInputType());
    }

    final boolean needAutoSaveDescription() {
        return isDescriptionEditable() && !isPasswordVariant(getDescriptionEditInputType());
    }

}
