/*
 * Copyright (C) 2014 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.deskclock.timer;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.viewpager.widget.ViewPager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.Button;
import android.widget.ImageView;

import com.android.deskclock.AnimatorUtils;
import com.android.deskclock.DeskClock;
import com.android.deskclock.DeskClockFragment;
import com.android.deskclock.R;
import com.android.deskclock.Utils;
import com.android.deskclock.data.DataModel;
import com.android.deskclock.data.Timer;
import com.android.deskclock.data.TimerListener;
import com.android.deskclock.data.TimerStringFormatter;
import com.android.deskclock.events.Events;
import com.android.deskclock.uidata.UiDataModel;

import java.io.Serializable;
import java.util.Arrays;

import static android.view.View.ALPHA;
import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
import static android.view.View.TRANSLATION_Y;
import static android.view.View.VISIBLE;
import static com.android.deskclock.uidata.UiDataModel.Tab.TIMERS;

/**
 * Displays a vertical list of timers in all states.
 */
public final class TimerFragment extends DeskClockFragment {

    private static final String EXTRA_TIMER_SETUP = "com.android.deskclock.action.TIMER_SETUP";

    private static final String KEY_TIMER_SETUP_STATE = "timer_setup_input";

    /** Notified when the user swipes vertically to change the visible timer. */
    private final TimerPageChangeListener mTimerPageChangeListener = new TimerPageChangeListener();

    /** Scheduled to update the timers while at least one is running. */
    private final Runnable mTimeUpdateRunnable = new TimeUpdateRunnable();

    /** Updates the {@link #mPageIndicators} in response to timers being added or removed. */
    private final TimerListener mTimerWatcher = new TimerWatcher();

    private TimerSetupView mCreateTimerView;
    private ViewPager mViewPager;
    private TimerPagerAdapter mAdapter;
    private View mTimersView;
    private View mCurrentView;
    private ImageView[] mPageIndicators;

    private Serializable mTimerSetupState;

    /** {@code true} while this fragment is creating a new timer; {@code false} otherwise. */
    private boolean mCreatingTimer;

    /**
     * @return an Intent that selects the timers tab with the setup screen for a new timer in place.
     */
    public static Intent createTimerSetupIntent(Context context) {
        return new Intent(context, DeskClock.class).putExtra(EXTRA_TIMER_SETUP, true);
    }

    /** The public no-arg constructor required by all fragments. */
    public TimerFragment() {
        super(TIMERS);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.timer_fragment, container, false);

        mAdapter = new TimerPagerAdapter(getFragmentManager());
        mViewPager = (ViewPager) view.findViewById(R.id.vertical_view_pager);
        mViewPager.setAdapter(mAdapter);
        mViewPager.addOnPageChangeListener(mTimerPageChangeListener);

        mTimersView = view.findViewById(R.id.timer_view);
        mCreateTimerView = (TimerSetupView) view.findViewById(R.id.timer_setup);
        mCreateTimerView.setFabContainer(this);
        mPageIndicators = new ImageView[] {
                (ImageView) view.findViewById(R.id.page_indicator0),
                (ImageView) view.findViewById(R.id.page_indicator1),
                (ImageView) view.findViewById(R.id.page_indicator2),
                (ImageView) view.findViewById(R.id.page_indicator3)
        };

        DataModel.getDataModel().addTimerListener(mAdapter);
        DataModel.getDataModel().addTimerListener(mTimerWatcher);

        // If timer setup state is present, retrieve it to be later honored.
        if (savedInstanceState != null) {
            mTimerSetupState = savedInstanceState.getSerializable(KEY_TIMER_SETUP_STATE);
        }

        return view;
    }

    @Override
    public void onStart() {
        super.onStart();

        // Initialize the page indicators.
        updatePageIndicators();

        boolean createTimer = false;
        int showTimerId = -1;

        // Examine the intent of the parent activity to determine which view to display.
        final Intent intent = getActivity().getIntent();
        if (intent != null) {
            // These extras are single-use; remove them after honoring them.
            createTimer = intent.getBooleanExtra(EXTRA_TIMER_SETUP, false);
            intent.removeExtra(EXTRA_TIMER_SETUP);

            showTimerId = intent.getIntExtra(TimerService.EXTRA_TIMER_ID, -1);
            intent.removeExtra(TimerService.EXTRA_TIMER_ID);
        }

        // Choose the view to display in this fragment.
        if (showTimerId != -1) {
            // A specific timer must be shown; show the list of timers.
            showTimersView(FAB_AND_BUTTONS_IMMEDIATE);
        } else if (!hasTimers() || createTimer || mTimerSetupState != null) {
            // No timers exist, a timer is being created, or the last view was timer setup;
            // show the timer setup view.
            showCreateTimerView(FAB_AND_BUTTONS_IMMEDIATE);

            if (mTimerSetupState != null) {
                mCreateTimerView.setState(mTimerSetupState);
                mTimerSetupState = null;
            }
        } else {
            // Otherwise, default to showing the list of timers.
            showTimersView(FAB_AND_BUTTONS_IMMEDIATE);
        }

        // If the intent did not specify a timer to show, show the last timer that expired.
        if (showTimerId == -1) {
            final Timer timer = DataModel.getDataModel().getMostRecentExpiredTimer();
            showTimerId = timer == null ? -1 : timer.getId();
        }

        // If a specific timer should be displayed, display the corresponding timer tab.
        if (showTimerId != -1) {
            final Timer timer = DataModel.getDataModel().getTimer(showTimerId);
            if (timer != null) {
                final int index = DataModel.getDataModel().getTimers().indexOf(timer);
                mViewPager.setCurrentItem(index);
            }
        }
    }

    @Override
    public void onResume() {
        super.onResume();

        // We may have received a new intent while paused.
        final Intent intent = getActivity().getIntent();
        if (intent != null && intent.hasExtra(TimerService.EXTRA_TIMER_ID)) {
            // This extra is single-use; remove after honoring it.
            final int showTimerId = intent.getIntExtra(TimerService.EXTRA_TIMER_ID, -1);
            intent.removeExtra(TimerService.EXTRA_TIMER_ID);

            final Timer timer = DataModel.getDataModel().getTimer(showTimerId);
            if (timer != null) {
                // A specific timer must be shown; show the list of timers.
                final int index = DataModel.getDataModel().getTimers().indexOf(timer);
                mViewPager.setCurrentItem(index);

                animateToView(mTimersView, null, false);
            }
        }
    }

    @Override
    public void onStop() {
        super.onStop();

        // Stop updating the timers when this fragment is no longer visible.
        stopUpdatingTime();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        DataModel.getDataModel().removeTimerListener(mAdapter);
        DataModel.getDataModel().removeTimerListener(mTimerWatcher);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        // If the timer creation view is visible, store the input for later restoration.
        if (mCurrentView == mCreateTimerView) {
            mTimerSetupState = mCreateTimerView.getState();
            outState.putSerializable(KEY_TIMER_SETUP_STATE, mTimerSetupState);
        }
    }

    private void updateFab(@NonNull ImageView fab, boolean animate) {
        if (mCurrentView == mTimersView) {
            final Timer timer = getTimer();
            if (timer == null) {
                fab.setVisibility(INVISIBLE);
                return;
            }

            fab.setVisibility(VISIBLE);
            switch (timer.getState()) {
                case RUNNING:
                    if (animate) {
                        fab.setImageResource(R.drawable.ic_play_pause_animation);
                    } else {
                        fab.setImageResource(R.drawable.ic_play_pause);
                    }
                    fab.setContentDescription(fab.getResources().getString(R.string.timer_stop));
                    break;
                case RESET:
                    if (animate) {
                        fab.setImageResource(R.drawable.ic_stop_play_animation);
                    } else {
                        fab.setImageResource(R.drawable.ic_pause_play);
                    }
                    fab.setContentDescription(fab.getResources().getString(R.string.timer_start));
                    break;
                case PAUSED:
                    if (animate) {
                        fab.setImageResource(R.drawable.ic_pause_play_animation);
                    } else {
                        fab.setImageResource(R.drawable.ic_pause_play);
                    }
                    fab.setContentDescription(fab.getResources().getString(R.string.timer_start));
                    break;
                case MISSED:
                case EXPIRED:
                    fab.setImageResource(R.drawable.ic_stop_white_24dp);
                    fab.setContentDescription(fab.getResources().getString(R.string.timer_stop));
                    break;
            }
        } else if (mCurrentView == mCreateTimerView) {
            if (mCreateTimerView.hasValidInput()) {
                fab.setImageResource(R.drawable.ic_start_white_24dp);
                fab.setContentDescription(fab.getResources().getString(R.string.timer_start));
                fab.setVisibility(VISIBLE);
            } else {
                fab.setContentDescription(null);
                fab.setVisibility(INVISIBLE);
            }
        }
    }

    @Override
    public void onUpdateFab(@NonNull ImageView fab) {
        updateFab(fab, false);
    }

    @Override
    public void onMorphFab(@NonNull ImageView fab) {
        // Update the fab's drawable to match the current timer state.
        updateFab(fab, Utils.isNOrLater());
        // Animate the drawable.
        AnimatorUtils.startDrawableAnimation(fab);
    }

    @Override
    public void onUpdateFabButtons(@NonNull Button left, @NonNull Button right) {
        if (mCurrentView == mTimersView) {
            left.setClickable(true);
            left.setText(R.string.timer_delete);
            left.setContentDescription(left.getResources().getString(R.string.timer_delete));
            left.setVisibility(VISIBLE);

            right.setClickable(true);
            right.setText(R.string.timer_add_timer);
            right.setContentDescription(right.getResources().getString(R.string.timer_add_timer));
            right.setVisibility(VISIBLE);

        } else if (mCurrentView == mCreateTimerView) {
            left.setClickable(true);
            left.setText(R.string.timer_cancel);
            left.setContentDescription(left.getResources().getString(R.string.timer_cancel));
            // If no timers yet exist, the user is forced to create the first one.
            left.setVisibility(hasTimers() ? VISIBLE : INVISIBLE);

            right.setVisibility(INVISIBLE);
        }
    }

    @Override
    public void onFabClick(@NonNull ImageView fab) {
        if (mCurrentView == mTimersView) {
            final Timer timer = getTimer();

            // If no timer is currently showing a fab action is meaningless.
            if (timer == null) {
                return;
            }

            final Context context = fab.getContext();
            final long currentTime = timer.getRemainingTime();

            switch (timer.getState()) {
                case RUNNING:
                    DataModel.getDataModel().pauseTimer(timer);
                    Events.sendTimerEvent(R.string.action_stop, R.string.label_deskclock);
                    if (currentTime > 0) {
                        mTimersView.announceForAccessibility(TimerStringFormatter.formatString(
                                context, R.string.timer_accessibility_stopped, currentTime, true));
                    }
                    break;
                case PAUSED:
                case RESET:
                    DataModel.getDataModel().startTimer(timer);
                    Events.sendTimerEvent(R.string.action_start, R.string.label_deskclock);
                    if (currentTime > 0) {
                        mTimersView.announceForAccessibility(TimerStringFormatter.formatString(
                                context, R.string.timer_accessibility_started, currentTime, true));
                    }
                    break;
                case MISSED:
                case EXPIRED:
                    DataModel.getDataModel().resetOrDeleteTimer(timer, R.string.label_deskclock);
                    break;
            }

        } else if (mCurrentView == mCreateTimerView) {
            mCreatingTimer = true;
            try {
                // Create the new timer.
                final long timerLength = mCreateTimerView.getTimeInMillis();
                final Timer timer = DataModel.getDataModel().addTimer(timerLength, "", false);
                Events.sendTimerEvent(R.string.action_create, R.string.label_deskclock);

                // Start the new timer.
                DataModel.getDataModel().startTimer(timer);
                Events.sendTimerEvent(R.string.action_start, R.string.label_deskclock);

                // Display the freshly created timer view.
                mViewPager.setCurrentItem(0);
            } finally {
                mCreatingTimer = false;
            }

            // Return to the list of timers.
            animateToView(mTimersView, null, true);
        }
    }

    @Override
    public void onLeftButtonClick(@NonNull Button left) {
        if (mCurrentView == mTimersView) {
            // Clicking the "delete" button.
            final Timer timer = getTimer();
            if (timer == null) {
                return;
            }

            if (mAdapter.getCount() > 1) {
                animateTimerRemove(timer);
            } else {
                animateToView(mCreateTimerView, timer, false);
            }

            left.announceForAccessibility(getActivity().getString(R.string.timer_deleted));
        } else if (mCurrentView == mCreateTimerView) {
            // Clicking the "cancel" button on the timer creation page returns to the timers list.
            mCreateTimerView.reset();

            animateToView(mTimersView, null, false);

            left.announceForAccessibility(getActivity().getString(R.string.timer_canceled));
        }
    }

    @Override
    public void onRightButtonClick(@NonNull Button right) {
        if (mCurrentView != mCreateTimerView) {
            animateToView(mCreateTimerView, null, true);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (mCurrentView == mCreateTimerView) {
            return mCreateTimerView.onKeyDown(keyCode, event);
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * Updates the state of the page indicators so they reflect the selected page in the context of
     * all pages.
     */
    private void updatePageIndicators() {
        final int page = mViewPager.getCurrentItem();
        final int pageIndicatorCount = mPageIndicators.length;
        final int pageCount = mAdapter.getCount();

        final int[] states = computePageIndicatorStates(page, pageIndicatorCount, pageCount);
        for (int i = 0; i < states.length; i++) {
            final int state = states[i];
            final ImageView pageIndicator = mPageIndicators[i];
            if (state == 0) {
                pageIndicator.setVisibility(GONE);
            } else {
                pageIndicator.setVisibility(VISIBLE);
                pageIndicator.setImageResource(state);
            }
        }
    }

    /**
     * @param page the selected page; value between 0 and {@code pageCount}
     * @param pageIndicatorCount the number of indicators displaying the {@code page} location
     * @param pageCount the number of pages that exist
     * @return an array of length {@code pageIndicatorCount} specifying which image to display for
     *      each page indicator or 0 if the page indicator should be hidden
     */
    @VisibleForTesting
    static int[] computePageIndicatorStates(int page, int pageIndicatorCount, int pageCount) {
        // Compute the number of page indicators that will be visible.
        final int rangeSize = Math.min(pageIndicatorCount, pageCount);

        // Compute the inclusive range of pages to indicate centered around the selected page.
        int rangeStart = page - (rangeSize / 2);
        int rangeEnd = rangeStart + rangeSize - 1;

        // Clamp the range of pages if they extend beyond the last page.
        if (rangeEnd >= pageCount) {
            rangeEnd = pageCount - 1;
            rangeStart = rangeEnd - rangeSize + 1;
        }

        // Clamp the range of pages if they extend beyond the first page.
        if (rangeStart < 0) {
            rangeStart = 0;
            rangeEnd = rangeSize - 1;
        }

        // Build the result with all page indicators initially hidden.
        final int[] states = new int[pageIndicatorCount];
        Arrays.fill(states, 0);

        // If 0 or 1 total pages exist, all page indicators must remain hidden.
        if (rangeSize < 2) {
            return states;
        }

        // Initialize the visible page indicators to be dark.
        Arrays.fill(states, 0, rangeSize, R.drawable.ic_swipe_circle_dark);

        // If more pages exist before the first page indicator, make it a fade-in gradient.
        if (rangeStart > 0) {
            states[0] = R.drawable.ic_swipe_circle_top;
        }

        // If more pages exist after the last page indicator, make it a fade-out gradient.
        if (rangeEnd < pageCount - 1) {
            states[rangeSize - 1] = R.drawable.ic_swipe_circle_bottom;
        }

        // Set the indicator of the selected page to be light.
        states[page - rangeStart] = R.drawable.ic_swipe_circle_light;

        return states;
    }

    /**
     * Display the view that creates a new timer.
     */
    private void showCreateTimerView(int updateTypes) {
        // Stop animating the timers.
        stopUpdatingTime();

        // Show the creation view; hide the timer view.
        mTimersView.setVisibility(GONE);
        mCreateTimerView.setVisibility(VISIBLE);

        // Record the fact that the create view is visible.
        mCurrentView = mCreateTimerView;

        // Update the fab and buttons.
        updateFab(updateTypes);
    }

    /**
     * Display the view that lists all existing timers.
     */
    private void showTimersView(int updateTypes) {
        // Clear any defunct timer creation state; the next timer creation starts fresh.
        mTimerSetupState = null;

        // Show the timer view; hide the creation view.
        mTimersView.setVisibility(VISIBLE);
        mCreateTimerView.setVisibility(GONE);

        // Record the fact that the create view is visible.
        mCurrentView = mTimersView;

        // Update the fab and buttons.
        updateFab(updateTypes);

        // Start animating the timers.
        startUpdatingTime();
    }

    /**
     * @param timerToRemove the timer to be removed during the animation
     */
    private void animateTimerRemove(final Timer timerToRemove) {
        final long duration = UiDataModel.getUiDataModel().getShortAnimationDuration();

        final Animator fadeOut = ObjectAnimator.ofFloat(mViewPager, ALPHA, 1, 0);
        fadeOut.setDuration(duration);
        fadeOut.setInterpolator(new DecelerateInterpolator());
        fadeOut.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                DataModel.getDataModel().removeTimer(timerToRemove);
                Events.sendTimerEvent(R.string.action_delete, R.string.label_deskclock);
            }
        });

        final Animator fadeIn = ObjectAnimator.ofFloat(mViewPager, ALPHA, 0, 1);
        fadeIn.setDuration(duration);
        fadeIn.setInterpolator(new AccelerateInterpolator());

        final AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(fadeOut).before(fadeIn);
        animatorSet.start();
    }

    /**
     * @param toView one of {@link #mTimersView} or {@link #mCreateTimerView}
     * @param timerToRemove the timer to be removed during the animation; {@code null} if no timer
     *      should be removed
     * @param animateDown {@code true} if the views should animate upwards, otherwise downwards
     */
    private void animateToView(final View toView, final Timer timerToRemove,
            final boolean animateDown) {
        if (mCurrentView == toView) {
            return;
        }

        final boolean toTimers = toView == mTimersView;
        if (toTimers) {
            mTimersView.setVisibility(VISIBLE);
        } else {
            mCreateTimerView.setVisibility(VISIBLE);
        }
        // Avoid double-taps by enabling/disabling the set of buttons active on the new view.
        updateFab(BUTTONS_DISABLE);

        final long animationDuration = UiDataModel.getUiDataModel().getLongAnimationDuration();

        final ViewTreeObserver viewTreeObserver = toView.getViewTreeObserver();
        viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                if (viewTreeObserver.isAlive()) {
                    viewTreeObserver.removeOnPreDrawListener(this);
                }

                final View view = mTimersView.findViewById(R.id.timer_time);
                final float distanceY = view != null ? view.getHeight() + view.getY() : 0;
                final float translationDistance = animateDown ? distanceY : -distanceY;

                toView.setTranslationY(-translationDistance);
                mCurrentView.setTranslationY(0f);
                toView.setAlpha(0f);
                mCurrentView.setAlpha(1f);

                final Animator translateCurrent = ObjectAnimator.ofFloat(mCurrentView,
                        TRANSLATION_Y, translationDistance);
                final Animator translateNew = ObjectAnimator.ofFloat(toView, TRANSLATION_Y, 0f);
                final AnimatorSet translationAnimatorSet = new AnimatorSet();
                translationAnimatorSet.playTogether(translateCurrent, translateNew);
                translationAnimatorSet.setDuration(animationDuration);
                translationAnimatorSet.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN);

                final Animator fadeOutAnimator = ObjectAnimator.ofFloat(mCurrentView, ALPHA, 0f);
                fadeOutAnimator.setDuration(animationDuration / 2);
                fadeOutAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        super.onAnimationStart(animation);

                        // The fade-out animation and fab-shrinking animation should run together.
                        updateFab(FAB_AND_BUTTONS_SHRINK);
                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        if (toTimers) {
                            showTimersView(FAB_AND_BUTTONS_EXPAND);

                            // Reset the state of the create view.
                            mCreateTimerView.reset();
                        } else {
                            showCreateTimerView(FAB_AND_BUTTONS_EXPAND);
                        }

                        if (timerToRemove != null) {
                            DataModel.getDataModel().removeTimer(timerToRemove);
                            Events.sendTimerEvent(R.string.action_delete, R.string.label_deskclock);
                        }

                        // Update the fab and button states now that the correct view is visible and
                        // before the animation to expand the fab and buttons starts.
                        updateFab(FAB_AND_BUTTONS_IMMEDIATE);
                    }
                });

                final Animator fadeInAnimator = ObjectAnimator.ofFloat(toView, ALPHA, 1f);
                fadeInAnimator.setDuration(animationDuration / 2);
                fadeInAnimator.setStartDelay(animationDuration / 2);

                final AnimatorSet animatorSet = new AnimatorSet();
                animatorSet.playTogether(fadeOutAnimator, fadeInAnimator, translationAnimatorSet);
                animatorSet.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        mTimersView.setTranslationY(0f);
                        mCreateTimerView.setTranslationY(0f);
                        mTimersView.setAlpha(1f);
                        mCreateTimerView.setAlpha(1f);
                    }
                });
                animatorSet.start();

                return true;
            }
        });
    }

    private boolean hasTimers() {
        return mAdapter.getCount() > 0;
    }

    private Timer getTimer() {
        if (mViewPager == null) {
            return null;
        }

        return mAdapter.getCount() == 0 ? null : mAdapter.getTimer(mViewPager.getCurrentItem());
    }

    private void startUpdatingTime() {
        // Ensure only one copy of the runnable is ever scheduled by first stopping updates.
        stopUpdatingTime();
        mViewPager.post(mTimeUpdateRunnable);
    }

    private void stopUpdatingTime() {
        mViewPager.removeCallbacks(mTimeUpdateRunnable);
    }

    /**
     * Periodically refreshes the state of each timer.
     */
    private class TimeUpdateRunnable implements Runnable {
        @Override
        public void run() {
            final long startTime = SystemClock.elapsedRealtime();
            // If no timers require continuous updates, avoid scheduling the next update.
            if (!mAdapter.updateTime()) {
                return;
            }
            final long endTime = SystemClock.elapsedRealtime();

            // Try to maintain a consistent period of time between redraws.
            final long delay = Math.max(0, startTime + 20 - endTime);
            mTimersView.postDelayed(this, delay);
        }
    }

    /**
     * Update the page indicators and fab in response to a new timer becoming visible.
     */
    private class TimerPageChangeListener extends ViewPager.SimpleOnPageChangeListener {
        @Override
        public void onPageSelected(int position) {
            updatePageIndicators();
            updateFab(FAB_AND_BUTTONS_IMMEDIATE);

            // Showing a new timer page may introduce a timer requiring continuous updates.
            startUpdatingTime();
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            // Teasing a neighboring timer may introduce a timer requiring continuous updates.
            if (state == ViewPager.SCROLL_STATE_DRAGGING) {
                startUpdatingTime();
            }
        }
    }

    /**
     * Update the page indicators in response to timers being added or removed.
     * Update the fab in response to the visible timer changing.
     */
    private class TimerWatcher implements TimerListener {
        @Override
        public void timerAdded(Timer timer) {
            updatePageIndicators();
            // If the timer is being created via this fragment avoid adjusting the fab.
            // Timer setup view is about to be animated away in response to this timer creation.
            // Changes to the fab immediately preceding that animation are jarring.
            if (!mCreatingTimer) {
                updateFab(FAB_AND_BUTTONS_IMMEDIATE);
            }
        }

        @Override
        public void timerUpdated(Timer before, Timer after) {
            // If the timer started, animate the timers.
            if (before.isReset() && !after.isReset()) {
                startUpdatingTime();
            }

            // Fetch the index of the change.
            final int index = DataModel.getDataModel().getTimers().indexOf(after);

            // If the timer just expired but is not displayed, display it now.
            if (!before.isExpired() && after.isExpired() && index != mViewPager.getCurrentItem()) {
                mViewPager.setCurrentItem(index, true);

            } else if (mCurrentView == mTimersView && index == mViewPager.getCurrentItem()) {
                // Morph the fab from its old state to new state if necessary.
                if (before.getState() != after.getState()
                        && !(before.isPaused() && after.isReset())) {
                    updateFab(FAB_MORPH);
                }
            }
        }

        @Override
        public void timerRemoved(Timer timer) {
            updatePageIndicators();
            updateFab(FAB_AND_BUTTONS_IMMEDIATE);

            if (mCurrentView == mTimersView && mAdapter.getCount() == 0) {
                animateToView(mCreateTimerView, null, false);
            }
        }
    }
}