1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.messaging.ui.conversation;
17
18import android.os.Bundle;
19import android.support.v7.app.ActionBar;
20
21/**
22 * The base class for a method of user input, e.g. media picker.
23 */
24public abstract class ConversationInput {
25    /**
26     * The host component where all input components are contained. This is typically the
27     * conversation fragment but may be mocked in test code.
28     */
29    public interface ConversationInputBase {
30        boolean showHideInternal(final ConversationInput target, final boolean show,
31                final boolean animate);
32        String getInputStateKey(final ConversationInput input);
33        void beginUpdate();
34        void handleOnShow(final ConversationInput target);
35        void endUpdate();
36    }
37
38    protected boolean mShowing;
39    protected ConversationInputBase mConversationInputBase;
40
41    public abstract boolean show(boolean animate);
42    public abstract boolean hide(boolean animate);
43
44    public ConversationInput(ConversationInputBase baseHost, final boolean isShowing) {
45        mConversationInputBase = baseHost;
46        mShowing = isShowing;
47    }
48
49    public boolean onBackPressed() {
50        if (mShowing) {
51            mConversationInputBase.showHideInternal(this, false /* show */, true /* animate */);
52            return true;
53        }
54        return false;
55    }
56
57    public boolean onNavigationUpPressed() {
58        return false;
59    }
60
61    /**
62     * Toggle the visibility of this view.
63     * @param animate
64     * @return true if the view is now shown, false if it now hidden
65     */
66    public boolean toggle(final boolean animate) {
67        mConversationInputBase.showHideInternal(this, !mShowing /* show */, true /* animate */);
68        return mShowing;
69    }
70
71    public void saveState(final Bundle savedState) {
72        savedState.putBoolean(mConversationInputBase.getInputStateKey(this), mShowing);
73    }
74
75    public void restoreState(final Bundle savedState) {
76        // Things are hidden by default, so only handle show.
77        if (savedState.getBoolean(mConversationInputBase.getInputStateKey(this))) {
78            mConversationInputBase.showHideInternal(this, true /* show */, false /* animate */);
79        }
80    }
81
82    public boolean updateActionBar(final ActionBar actionBar) {
83        return false;
84    }
85
86    /**
87     * Update our visibility flag in response to visibility change, both for actions
88     * initiated by this class (through the show/hide methods), and for external changes
89     * tracked by event listeners (e.g. ImeStateObserver, MediaPickerListener). As part of
90     * handling an input showing, we will hide all other inputs to ensure they are mutually
91     * exclusive.
92     */
93    protected void onVisibilityChanged(final boolean visible) {
94        if (mShowing != visible) {
95            mConversationInputBase.beginUpdate();
96            mShowing = visible;
97            if (visible) {
98                mConversationInputBase.handleOnShow(this);
99            }
100            mConversationInputBase.endUpdate();
101        }
102    }
103}
104