/*
 * 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.app;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v17.leanback.transition.TransitionHelper;
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.GuidanceStylist;
import android.support.v17.leanback.widget.GuidanceStylist.Guidance;
import android.support.v17.leanback.widget.GuidedAction;
import android.support.v17.leanback.widget.GuidedActionsStylist;
import android.support.v17.leanback.widget.VerticalGridView;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * A GuidedStepFragment is used to guide the user through a decision or series of decisions.
 * It is composed of a guidance view on the left and a view on the right containing a list of
 * possible actions.
 * <p>
 * <h3>Basic Usage</h3>
 * <p>
 * Clients of GuidedStepFragment must create a custom subclass to attach to their Activities.
 * This custom subclass provides the information necessary to construct the user interface and
 * respond to user actions. At a minimum, subclasses should override:
 * <ul>
 * <li>{@link #onCreateGuidance}, to provide instructions to the user</li>
 * <li>{@link #onCreateActions}, to provide a set of {@link GuidedAction}s the user can take</li>
 * <li>{@link #onGuidedActionClicked}, to respond to those actions</li>
 * </ul>
 * <p>
 * Clients use following helper functions to add GuidedStepFragment to Activity or FragmentManager:
 * <ul>
 * <li>{@link #addAsRoot(Activity, GuidedStepFragment, int)}, to be called during Activity onCreate,
 * adds GuidedStepFragment as the first Fragment in activity.</li>
 * <li>{@link #add(FragmentManager, GuidedStepFragment)} or {@link #add(FragmentManager,
 * GuidedStepFragment, int)}, to add GuidedStepFragment on top of existing Fragments or
 * replacing existing GuidedStepFragment when moving forward to next step.</li>
 * </ul>
 * <h3>Theming and Stylists</h3>
 * <p>
 * GuidedStepFragment delegates its visual styling to classes called stylists. The {@link
 * GuidanceStylist} is responsible for the left guidance view, while the {@link
 * GuidedActionsStylist} is responsible for the right actions view. The stylists use theme
 * attributes to derive values associated with the presentation, such as colors, animations, etc.
 * Most simple visual aspects of GuidanceStylist and GuidedActionsStylist can be customized
 * via theming; see their documentation for more information.
 * <p>
 * GuidedStepFragments must have access to an appropriate theme in order for the stylists to
 * function properly.  Specifically, the fragment must receive {@link
 * android.support.v17.leanback.R.style#Theme_Leanback_GuidedStep}, or a theme whose parent is
 * is set to that theme. Themes can be provided in one of three ways:
 * <ul>
 * <li>The simplest way is to set the theme for the host Activity to the GuidedStep theme or a
 * theme that derives from it.</li>
 * <li>If the Activity already has a theme and setting its parent theme is inconvenient, the
 * existing Activity theme can have an entry added for the attribute {@link
 * android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepTheme}. If present,
 * this theme will be used by GuidedStepFragment as an overlay to the Activity's theme.</li>
 * <li>Finally, custom subclasses of GuidedStepFragment may provide a theme through the {@link
 * #onProvideTheme} method. This can be useful if a subclass is used across multiple
 * Activities.</li>
 * </ul>
 * <p>
 * If the theme is provided in multiple ways, the onProvideTheme override has priority, followed by
 * the Activty's theme.  (Themes whose parent theme is already set to the guided step theme do not
 * need to set the guidedStepTheme attribute; if set, it will be ignored.)
 * <p>
 * If themes do not provide enough customizability, the stylists themselves may be subclassed and
 * provided to the GuidedStepFragment through the {@link #onCreateGuidanceStylist} and {@link
 * #onCreateActionsStylist} methods.  The stylists have simple hooks so that subclasses
 * may override layout files; subclasses may also have more complex logic to determine styling.
 * <p>
 * <h3>Guided sequences</h3>
 * <p>
 * GuidedStepFragments can be grouped together to provide a guided sequence. GuidedStepFragments
 * grouped as a sequence use custom animations provided by {@link GuidanceStylist} and
 * {@link GuidedActionsStylist} (or subclasses) during transitions between steps. Clients
 * should use {@link #add} to place subsequent GuidedFragments onto the fragment stack so that
 * custom animations are properly configured. (Custom animations are triggered automatically when
 * the fragment stack is subsequently popped by any normal mechanism.)
 * <p>
 * <i>Note: Currently GuidedStepFragments grouped in this way must all be defined programmatically,
 * rather than in XML. This restriction may be removed in the future.</i>
 *
 * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepTheme
 * @attr ref android.support.v17.leanback.R.styleable#LeanbackGuidedStepTheme_guidedStepBackground
 * @see GuidanceStylist
 * @see GuidanceStylist.Guidance
 * @see GuidedAction
 * @see GuidedActionsStylist
 */
public class GuidedStepFragment extends Fragment implements GuidedActionAdapter.ClickListener,
        GuidedActionAdapter.FocusListener {

    private static final String TAG_LEAN_BACK_ACTIONS_FRAGMENT = "leanBackGuidedStepFragment";
    private static final String EXTRA_ACTION_SELECTED_INDEX = "selectedIndex";

    private static final boolean IS_FRAMEWORK_FRAGMENT = true;

    /**
     * Fragment argument name for UI style.  The argument value is persisted in fragment state.
     * The value is initially {@link #UI_STYLE_DEFAULT} and might be changed in one of the three
     * helper functions:
     * <ul>
     * <li>{@link #addAsRoot(Activity, GuidedStepFragment, int)}</li>
     * <li>{@link #add(FragmentManager, GuidedStepFragment)} or {@link #add(FragmentManager,
     * GuidedStepFragment, int)}</li>
     * </ul>
     * <p>
     * Argument value can be either:
     * <ul>
     * <li>{@link #UI_STYLE_DEFAULT}</li>
     * <li>{@link #UI_STYLE_ENTRANCE}</li>
     * <li>{@link #UI_STYLE_ACTIVITY_ROOT}</li>
     * </ul>
     */
    public static final String EXTRA_UI_STYLE = "uiStyle";

    /**
     * Default value for argument {@link #EXTRA_UI_STYLE}.  The default value is assigned
     * in GuidedStepFragment constructor.  This is the case that we use GuidedStepFragment to
     * replace another existing GuidedStepFragment when moving forward to next step. Default
     * behavior of this style is:
     * <ul>
     * <li> Enter transition slides in from END(right), exit transition slide out to START(left).
     * </li>
     * <li> No background, see {@link #onProvideBackgroundFragment()}.</li>
     * </ul>
     */
    public static final int UI_STYLE_DEFAULT = 0;

    /**
     * One possible value of argument {@link #EXTRA_UI_STYLE}.  This is the case that we show
     * GuidedStepFragment on top of other content.  The default behavior of this style:
     * <ul>
     * <li>Enter transition slides in from two sides, exit transition is inherited from
     * {@link #UI_STYLE_DEFAULT}.  Note: Changing exit transition by UI style is not working because
     * fragment transition asks for exit transition before UI style is restored in Fragment
     * .onCreate().</li>
     * <li> {@link #onProvideBackgroundFragment()} will create {@link GuidedStepBackgroundFragment}
     * to covering underneath content. The activity must provide a container to host background
     * fragment and override {@link #getContainerIdForBackground()}</li>
     * </ul>
     */
    public static final int UI_STYLE_ENTRANCE = 1;

    /**
     * One possible value of argument {@link #EXTRA_UI_STYLE}.  This is the case that we show first
     * GuidedStepFragment in a separate activity.  The default behavior of this style:
     * <ul>
     * <li> Enter transition is assigned null (will rely on activity transition), exit transition is
     * same as {@link #UI_STYLE_DEFAULT}.  Note: Changing exit transition by UI style is not working
     * because fragment transition asks for exit transition before UI style is restored in
     * Fragment.onCreate().</li>
     * <li> No background, see {@link #onProvideBackgroundFragment()}.
     * </ul>
     */
    public static final int UI_STYLE_ACTIVITY_ROOT = 2;

    private static final String TAG = "GuidedStepFragment";
    private static final boolean DEBUG = false;

    private int mTheme;
    private ContextThemeWrapper mThemeWrapper;
    private GuidanceStylist mGuidanceStylist;
    private GuidedActionsStylist mActionsStylist;
    private GuidedActionAdapter mAdapter;
    private VerticalGridView mListView;
    private List<GuidedAction> mActions = new ArrayList<GuidedAction>();
    private int mSelectedIndex = -1;

    public GuidedStepFragment() {
        // We need to supply the theme before any potential call to onInflate in order
        // for the defaulting to work properly.
        mTheme = onProvideTheme();
        mGuidanceStylist = onCreateGuidanceStylist();
        mActionsStylist = onCreateActionsStylist();
        onProvideFragmentTransitions();
    }

    /**
     * Creates the presenter used to style the guidance panel. The default implementation returns
     * a basic GuidanceStylist.
     * @return The GuidanceStylist used in this fragment.
     */
    public GuidanceStylist onCreateGuidanceStylist() {
        return new GuidanceStylist();
    }

    /**
     * Creates the presenter used to style the guided actions panel. The default implementation
     * returns a basic GuidedActionsStylist.
     * @return The GuidedActionsStylist used in this fragment.
     */
    public GuidedActionsStylist onCreateActionsStylist() {
        return new GuidedActionsStylist();
    }

    /**
     * Returns the theme used for styling the fragment. The default returns -1, indicating that the
     * host Activity's theme should be used.
     * @return The theme resource ID of the theme to use in this fragment, or -1 to use the
     * host Activity's theme.
     */
    public int onProvideTheme() {
        return -1;
    }

    /**
     * Returns the information required to provide guidance to the user. This hook is called during
     * {@link #onCreateView}.  May be overridden to return a custom subclass of {@link
     * GuidanceStylist.Guidance} for use in a subclass of {@link GuidanceStylist}. The default
     * returns a Guidance object with empty fields; subclasses should override.
     * @param savedInstanceState The saved instance state from onCreateView.
     * @return The Guidance object representing the information used to guide the user.
     */
    public @NonNull Guidance onCreateGuidance(Bundle savedInstanceState) {
        return new Guidance("", "", "", null);
    }

    /**
     * Fills out the set of actions available to the user. This hook is called during {@link
     * #onCreate}. The default leaves the list of actions empty; subclasses should override.
     * @param actions A non-null, empty list ready to be populated.
     * @param savedInstanceState The saved instance state from onCreate.
     */
    public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
    }

    /**
     * Callback invoked when an action is taken by the user. Subclasses should override in
     * order to act on the user's decisions.
     * @param action The chosen action.
     */
    @Override
    public void onGuidedActionClicked(GuidedAction action) {
    }

    /**
     * Callback invoked when an action is focused (made to be the current selection) by the user.
     */
    @Override
    public void onGuidedActionFocused(GuidedAction action) {
    }

    /**
     * Callback invoked when an action's title has been edited.
     */
    public void onGuidedActionEdited(GuidedAction action) {
    }

    /**
     * Adds the specified GuidedStepFragment to the fragment stack, replacing any existing
     * GuidedStepFragments in the stack, and configuring the fragment-to-fragment custom
     * transitions.  A backstack entry is added, so the fragment will be dismissed when BACK key
     * is pressed.
     * <li>If current fragment on stack is GuidedStepFragment: assign {@link #UI_STYLE_DEFAULT}
     * <li>If current fragment on stack is not GuidedStepFragment: assign {@link #UI_STYLE_ENTRANCE}
     * <p>
     * Note: currently fragments added using this method must be created programmatically rather
     * than via XML.
     * @param fragmentManager The FragmentManager to be used in the transaction.
     * @param fragment The GuidedStepFragment to be inserted into the fragment stack.
     * @return The ID returned by the call FragmentTransaction.replace.
     */
    public static int add(FragmentManager fragmentManager, GuidedStepFragment fragment) {
        return add(fragmentManager, fragment, android.R.id.content);
    }

    /**
     * Adds the specified GuidedStepFragment to the fragment stack, replacing any existing
     * GuidedStepFragments in the stack, and configuring the fragment-to-fragment custom
     * transitions.  A backstack entry is added, so the fragment will be dismissed when BACK key
     * is pressed.
     * <li>If current fragment on stack is GuidedStepFragment: assign {@link #UI_STYLE_DEFAULT}
     * <li>If current fragment on stack is not GuidedStepFragment: assign {@link #UI_STYLE_ENTRANCE}
     * <p>
     * Note: currently fragments added using this method must be created programmatically rather
     * than via XML.
     * @param fragmentManager The FragmentManager to be used in the transaction.
     * @param fragment The GuidedStepFragment to be inserted into the fragment stack.
     * @param id The id of container to add GuidedStepFragment, can be android.R.id.content.
     * @return The ID returned by the call FragmentTransaction.replace.
     */
    public static int add(FragmentManager fragmentManager, GuidedStepFragment fragment, int id) {
        boolean inGuidedStep = getCurrentGuidedStepFragment(fragmentManager) != null;
        if (IS_FRAMEWORK_FRAGMENT && Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 23
                && !inGuidedStep && fragment.getContainerIdForBackground() != View.NO_ID) {
            // workaround b/22631964 for framework fragment
            fragmentManager.beginTransaction()
                .replace(id, new DummyFragment(), TAG_LEAN_BACK_ACTIONS_FRAGMENT)
                .replace(fragment.getContainerIdForBackground(), new DummyFragment())
                .commit();
        }
        FragmentTransaction ft = fragmentManager.beginTransaction();

        ft.addToBackStack(null);
        fragment.setUiStyle(inGuidedStep ? UI_STYLE_DEFAULT : UI_STYLE_ENTRANCE);
        initialBackground(fragment, id, ft);
        return ft.replace(id, fragment, TAG_LEAN_BACK_ACTIONS_FRAGMENT).commit();
    }

    /**
     * Adds the specified GuidedStepFragment as content of Activity; no backstack entry is added so
     * the activity will be dismissed when BACK key is pressed.
     * {@link #UI_STYLE_ACTIVITY_ROOT} is assigned.
     *
     * Note: currently fragments added using this method must be created programmatically rather
     * than via XML.
     * @param activity The Activity to be used to insert GuidedstepFragment.
     * @param fragment The GuidedStepFragment to be inserted into the fragment stack.
     * @param id The id of container to add GuidedStepFragment, can be android.R.id.content.
     * @return The ID returned by the call FragmentTransaction.replace.
     */
    public static int addAsRoot(Activity activity, GuidedStepFragment fragment, int id) {
        // Workaround b/23764120: call getDecorView() to force requestFeature of ActivityTransition.
        activity.getWindow().getDecorView();

        FragmentManager fragmentManager = activity.getFragmentManager();
        FragmentTransaction ft = fragmentManager.beginTransaction();
        fragment.setUiStyle(UI_STYLE_ACTIVITY_ROOT);
        initialBackground(fragment, id, ft);
        return ft.replace(id, fragment, TAG_LEAN_BACK_ACTIONS_FRAGMENT).commit();
    }

    static void initialBackground(GuidedStepFragment fragment, int id, FragmentTransaction ft) {
        if (fragment.getContainerIdForBackground() != View.NO_ID) {
            Fragment backgroundFragment = fragment.onProvideBackgroundFragment();
            if (backgroundFragment != null) {
                ft.replace(fragment.getContainerIdForBackground(), backgroundFragment);
            }
        }
    }

    /**
     * Returns the current GuidedStepFragment on the fragment transaction stack.
     * @return The current GuidedStepFragment, if any, on the fragment transaction stack.
     */
    public static GuidedStepFragment getCurrentGuidedStepFragment(FragmentManager fm) {
        Fragment f = fm.findFragmentByTag(TAG_LEAN_BACK_ACTIONS_FRAGMENT);
        if (f instanceof GuidedStepFragment) {
            return (GuidedStepFragment) f;
        }
        return null;
    }

    /**
     * @hide
     */
    public static class DummyFragment extends Fragment {

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            final View v = new View(inflater.getContext());
            v.setVisibility(View.GONE);
            return v;
        }
    }

    /**
     * Returns the GuidanceStylist that displays guidance information for the user.
     * @return The GuidanceStylist for this fragment.
     */
    public GuidanceStylist getGuidanceStylist() {
        return mGuidanceStylist;
    }

    /**
     * Returns the GuidedActionsStylist that displays the actions the user may take.
     * @return The GuidedActionsStylist for this fragment.
     */
    public GuidedActionsStylist getGuidedActionsStylist() {
        return mActionsStylist;
    }

    /**
     * Returns the list of GuidedActions that the user may take in this fragment.
     * @return The list of GuidedActions for this fragment.
     */
    public List<GuidedAction> getActions() {
        return mActions;
    }

    /**
     * Sets the list of GuidedActions that the user may take in this fragment.
     * @param actions The list of GuidedActions for this fragment.
     */
    public void setActions(List<GuidedAction> actions) {
        mActions = actions;
        if (mAdapter != null) {
            mAdapter.setActions(mActions);
        }
    }

    /**
     * Returns the view corresponding to the action at the indicated position in the list of
     * actions for this fragment.
     * @param position The integer position of the action of interest.
     * @return The View corresponding to the action at the indicated position, or null if that
     * action is not currently onscreen.
     */
    public View getActionItemView(int position) {
        return mListView.findViewHolderForPosition(position).itemView;
    }

    /**
     * Scrolls the action list to the position indicated, selecting that action's view.
     * @param position The integer position of the action of interest.
     */
    public void setSelectedActionPosition(int position) {
        mListView.setSelectedPosition(position);
    }

    /**
     * Returns the position if the currently selected GuidedAction.
     * @return position The integer position of the currently selected action.
     */
    public int getSelectedActionPosition() {
        return mListView.getSelectedPosition();
    }

    /**
     * Called by Constructor to provide fragment transitions.  Default implementation creates
     * a short slide and fade transition in code for {@link #UI_STYLE_DEFAULT} for both enter and
     * exit transition.  When using style {@link #UI_STYLE_ENTRANCE}, enter transition is set
     * to slide from both sides.  When using style {@link #UI_STYLE_ACTIVITY_ROOT}, enter
     * transition is set to null and you should rely on activity transition.
     * <p>
     * Subclass may override and set its own fragment transition.  Note that because Context is not
     * available when onProvideFragmentTransitions() is called, subclass will need use a cached
     * static application context to load transition from xml.  Because the fragment view is
     * removed during fragment transition, in general app cannot use two Visibility transition
     * together.  Workaround is to create your own Visibility transition that controls multiple
     * animators (e.g. slide and fade animation in one Transition class).
     */
    protected void onProvideFragmentTransitions() {
        if (Build.VERSION.SDK_INT >= 21) {
            TransitionHelper helper = TransitionHelper.getInstance();
            if (getUiStyle() == UI_STYLE_DEFAULT) {
                Object enterTransition = helper.createFadeAndShortSlide(Gravity.END);
                helper.exclude(enterTransition, R.id.guidedactions_background, true);
                helper.exclude(enterTransition, R.id.guidedactions_selector, true);
                TransitionHelper.getInstance().setEnterTransition(this, enterTransition);
                Object exitTransition = helper.createFadeAndShortSlide(Gravity.START);
                helper.exclude(exitTransition, R.id.guidedactions_background, true);
                helper.exclude(exitTransition, R.id.guidedactions_selector, true);
                TransitionHelper.getInstance().setExitTransition(this, exitTransition);
            } else if (getUiStyle() == UI_STYLE_ENTRANCE) {
                Object enterTransition = helper.createFadeAndShortSlide(Gravity.END |
                        Gravity.START);
                helper.include(enterTransition, R.id.content_fragment);
                helper.include(enterTransition, R.id.action_fragment);
                TransitionHelper.getInstance().setEnterTransition(this, enterTransition);
                // exit transition is unchanged, same as UI_STYLE_DEFAULT
            } else if (getUiStyle() == UI_STYLE_ACTIVITY_ROOT) {
                // for Activity root, we dont need enter transition, use activity transition
                TransitionHelper.getInstance().setEnterTransition(this, null);
                // exit transition is unchanged, same as UI_STYLE_DEFAULT
            }
        }
    }

    /**
     * Default implementation of background for covering content below GuidedStepFragment.
     * It uses current theme attribute guidedStepBackground which by default is read from
     * android:windowBackground.
     */
    public static class GuidedStepBackgroundFragment extends Fragment {
        public GuidedStepBackgroundFragment() {
            onProvideFragmentTransitions();
        }

        /**
         * Sets fragment transitions for GuidedStepBackgroundFragment.  Can be overridden.
         */
        protected void onProvideFragmentTransitions() {
            if (Build.VERSION.SDK_INT >= 21) {
                TransitionHelper helper = TransitionHelper.getInstance();
                Object enterTransition = helper.createFadeTransition(
                        TransitionHelper.FADE_IN|TransitionHelper.FADE_OUT);
                TransitionHelper.getInstance().setEnterTransition(this, enterTransition);
            }
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            Activity activity = getActivity();
            Context themedContext = null;
            if (!isGuidedStepTheme(activity)) {
                // Look up the guidedStepTheme in the activity's currently specified theme.  If it
                // exists, replace the theme with its value.
                int resId = R.attr.guidedStepTheme;
                TypedValue typedValue = new TypedValue();
                boolean found = activity.getTheme().resolveAttribute(resId, typedValue, true);
                if (DEBUG) Log.v(TAG, "Found guided step theme reference? " + found);
                if (found) {
                    ContextThemeWrapper themeWrapper =
                            new ContextThemeWrapper(activity, typedValue.resourceId);
                    if (isGuidedStepTheme(themeWrapper)) {
                        themedContext = themeWrapper;
                    }
                }
                if (!found) {
                    Log.e(TAG, "GuidedStepFragment does not have an appropriate theme set.");
                }
            }

            if (themedContext != null) {
                inflater = inflater.cloneInContext(themedContext);
            }

            return inflater.inflate(R.layout.lb_guidedstep_background, container, false);
        }
    }

    /**
     * Creates a background fragment for {@link #UI_STYLE_ENTRANCE}, returns null for other cases.
     * Subclass may override the default behavior, e.g. provide different backgrounds
     * for {@link #UI_STYLE_DEFAULT}.  Background fragment will be inserted in {@link
     * #getContainerIdForBackground()}.
     *
     * @return fragment that will be inserted below GuidedStepFragment.
     */
    protected Fragment onProvideBackgroundFragment() {
        if (getUiStyle() == UI_STYLE_ENTRANCE) {
            return new GuidedStepBackgroundFragment();
        }
        return null;
    }

    /**
     * Returns container id for inserting {@link #onProvideBackgroundFragment()}.  The id should be
     * different than container id for inserting GuidedStepFragment.
     * Default value is {@link View#NO_ID}.  Subclass must override to host background fragment.
     * @return container id for inserting {@link #onProvideBackgroundFragment()}
     */
    protected int getContainerIdForBackground() {
        return View.NO_ID;
    }


    /**
     * Set UI style to fragment arguments,  UI style cannot be changed after initialization.
     * @param style {@link #UI_STYLE_ACTIVITY_ROOT} {@link #UI_STYLE_DEFAULT} or
     * {@link #UI_STYLE_ENTRANCE}.
     */
    public void setUiStyle(int style) {
        int oldStyle = getUiStyle();
        Bundle arguments = getArguments();
        if (arguments == null) {
            arguments = new Bundle();
        }
        arguments.putInt(EXTRA_UI_STYLE, style);
        // call setArgument() will validate if the fragment is already added.
        setArguments(arguments);
        if (style != oldStyle) {
            onProvideFragmentTransitions();
        }
    }

    /**
     * Read UI style from fragment arguments.
     *
     * @return {@link #UI_STYLE_ACTIVITY_ROOT} {@link #UI_STYLE_DEFAULT} or
     * {@link #UI_STYLE_ENTRANCE}.
     */
    public int getUiStyle() {
        Bundle b = getArguments();
        if (b == null) return UI_STYLE_DEFAULT;
        return b.getInt(EXTRA_UI_STYLE, UI_STYLE_DEFAULT);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (DEBUG) Log.v(TAG, "onCreate");
        // Set correct transition from saved arguments.
        onProvideFragmentTransitions();
        Bundle state = (savedInstanceState != null) ? savedInstanceState : getArguments();
        if (state != null) {
            if (mSelectedIndex == -1) {
                mSelectedIndex = state.getInt(EXTRA_ACTION_SELECTED_INDEX, -1);
            }
        }
        mActions.clear();
        onCreateActions(mActions, savedInstanceState);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (DEBUG) Log.v(TAG, "onCreateView");

        resolveTheme();
        inflater = getThemeInflater(inflater);

        View v = inflater.inflate(R.layout.lb_guidedstep_fragment, container, false);
        ViewGroup guidanceContainer = (ViewGroup) v.findViewById(R.id.content_fragment);
        ViewGroup actionContainer = (ViewGroup) v.findViewById(R.id.action_fragment);

        Guidance guidance = onCreateGuidance(savedInstanceState);
        View guidanceView = mGuidanceStylist.onCreateView(inflater, guidanceContainer, guidance);
        guidanceContainer.addView(guidanceView);

        View actionsView = mActionsStylist.onCreateView(inflater, actionContainer);
        actionContainer.addView(actionsView);

        GuidedActionAdapter.EditListener editListener = new GuidedActionAdapter.EditListener() {
                @Override
                public void onGuidedActionEdited(GuidedAction action, boolean entering) {
                    runImeAnimations(entering);
                    if (!entering) {
                        GuidedStepFragment.this.onGuidedActionEdited(action);
                    }
                }
        };

        mAdapter = new GuidedActionAdapter(mActions, this, this, editListener, mActionsStylist);

        mListView = mActionsStylist.getActionsGridView();
        mListView.setAdapter(mAdapter);
        int pos = (mSelectedIndex >= 0 && mSelectedIndex < mActions.size()) ?
                mSelectedIndex : getFirstCheckedAction();
        mListView.setSelectedPosition(pos);

        return v;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(EXTRA_ACTION_SELECTED_INDEX,
                (mListView != null) ? getSelectedActionPosition() : mSelectedIndex);
    }

    private static boolean isGuidedStepTheme(Context context) {
        int resId = R.attr.guidedStepThemeFlag;
        TypedValue typedValue = new TypedValue();
        boolean found = context.getTheme().resolveAttribute(resId, typedValue, true);
        if (DEBUG) Log.v(TAG, "Found guided step theme flag? " + found);
        return found && typedValue.type == TypedValue.TYPE_INT_BOOLEAN && typedValue.data != 0;
    }

    private void resolveTheme() {
        // Look up the guidedStepTheme in the currently specified theme.  If it exists,
        // replace the theme with its value.
        Activity activity = getActivity();
        if (mTheme == -1 && !isGuidedStepTheme(activity)) {
            // Look up the guidedStepTheme in the activity's currently specified theme.  If it
            // exists, replace the theme with its value.
            int resId = R.attr.guidedStepTheme;
            TypedValue typedValue = new TypedValue();
            boolean found = activity.getTheme().resolveAttribute(resId, typedValue, true);
            if (DEBUG) Log.v(TAG, "Found guided step theme reference? " + found);
            if (found) {
                ContextThemeWrapper themeWrapper =
                        new ContextThemeWrapper(activity, typedValue.resourceId);
                if (isGuidedStepTheme(themeWrapper)) {
                    mTheme = typedValue.resourceId;
                    mThemeWrapper = themeWrapper;
                } else {
                    found = false;
                    mThemeWrapper = null;
                }
            }
            if (!found) {
                Log.e(TAG, "GuidedStepFragment does not have an appropriate theme set.");
            }
        } else if (mTheme != -1) {
            mThemeWrapper = new ContextThemeWrapper(activity, mTheme);
        }
    }

    private LayoutInflater getThemeInflater(LayoutInflater inflater) {
        if (mTheme == -1) {
            return inflater;
        } else {
            return inflater.cloneInContext(mThemeWrapper);
        }
    }

    private int getFirstCheckedAction() {
        for (int i = 0, size = mActions.size(); i < size; i++) {
            if (mActions.get(i).isChecked()) {
                return i;
            }
        }
        return 0;
    }

    private void runImeAnimations(boolean entering) {
        ArrayList<Animator> animators = new ArrayList<Animator>();
        if (entering) {
            mGuidanceStylist.onImeAppearing(animators);
            mActionsStylist.onImeAppearing(animators);
        } else {
            mGuidanceStylist.onImeDisappearing(animators);
            mActionsStylist.onImeDisappearing(animators);
        }
        AnimatorSet set = new AnimatorSet();
        set.playTogether(animators);
        set.start();
    }

}
