1/*
2 * Copyright (C) 2012 Google Inc.
3 * Licensed to The Android Open Source Project.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mail.browse;
19
20import android.content.Context;
21import android.util.AttributeSet;
22import android.view.View;
23import android.view.View.OnClickListener;
24import android.view.ViewGroup;
25import android.widget.LinearLayout;
26
27import com.android.mail.R;
28import com.android.mail.browse.ConversationViewAdapter.ConversationHeaderItem;
29import com.android.mail.providers.Conversation;
30import com.android.mail.providers.UIProvider;
31import com.android.mail.ui.ConversationUpdater;
32import com.android.mail.utils.LogTag;
33import com.android.mail.utils.LogUtils;
34import com.android.mail.utils.Utils;
35
36/**
37 * A view for the subject and folders in the conversation view. This container
38 * makes an attempt to combine subject and folders on the same horizontal line if
39 * there is enough room to fit both without wrapping. If they overlap, it
40 * adjusts the layout to position the folders below the subject.
41 */
42public class ConversationViewHeader extends LinearLayout implements OnClickListener {
43
44    public interface ConversationViewHeaderCallbacks {
45        /**
46         * Called in response to a click on the folders region.
47         */
48        void onFoldersClicked();
49
50        /**
51         * Called when the height of the {@link ConversationViewHeader} changes.
52         *
53         * @param newHeight the new height in px
54         */
55        void onConversationViewHeaderHeightChange(int newHeight);
56    }
57
58    private static final String LOG_TAG = LogTag.getLogTag();
59    private SubjectAndFolderView mSubjectAndFolderView;
60    private StarView mStarView;
61    private ConversationViewHeaderCallbacks mCallbacks;
62    private ConversationAccountController mAccountController;
63    private ConversationUpdater mConversationUpdater;
64    private ConversationHeaderItem mHeaderItem;
65    private Conversation mConversation;
66
67    /**
68     * Instantiated from this layout: conversation_view_header.xml
69     * @param context
70     */
71    public ConversationViewHeader(Context context) {
72        this(context, null);
73    }
74
75    public ConversationViewHeader(Context context, AttributeSet attrs) {
76        super(context, attrs);
77    }
78
79    @Override
80    protected void onFinishInflate() {
81        super.onFinishInflate();
82
83        mSubjectAndFolderView =
84                (SubjectAndFolderView) findViewById(R.id.subject_and_folder_view);
85        mStarView = (StarView) findViewById(R.id.conversation_header_star);
86        mStarView.setOnClickListener(this);
87    }
88
89    public void setCallbacks(ConversationViewHeaderCallbacks callbacks,
90            ConversationAccountController accountController,
91            ConversationUpdater conversationUpdater) {
92        mCallbacks = callbacks;
93        mAccountController = accountController;
94        mConversationUpdater = conversationUpdater;
95    }
96
97    public void setSubject(final String subject) {
98        mSubjectAndFolderView.setSubject(subject);
99    }
100
101    public void setFolders(Conversation conv) {
102        mSubjectAndFolderView.setFolders(mCallbacks, mAccountController.getAccount(), conv);
103    }
104
105    public void setStarred(boolean isStarred) {
106        mStarView.setStarred(isStarred);
107        mStarView.setVisibility(View.VISIBLE);
108    }
109
110    public void bind(ConversationHeaderItem headerItem) {
111        mHeaderItem = headerItem;
112        mConversation = mHeaderItem.mConversation;
113        if (mSubjectAndFolderView != null) {
114            mSubjectAndFolderView.bind(headerItem);
115        }
116        mStarView.setVisibility(mConversation != null ? View.VISIBLE : View.INVISIBLE);
117    }
118
119    private int measureHeight() {
120        ViewGroup parent = (ViewGroup) getParent();
121        if (parent == null) {
122            LogUtils.e(LOG_TAG, "Unable to measure height of conversation header");
123            return getHeight();
124        }
125        final int h = Utils.measureViewHeight(this, parent);
126        return h;
127    }
128
129    /**
130     * Update the conversation view header to reflect the updated conversation.
131     */
132    public void onConversationUpdated(Conversation conv) {
133        // The only things we have to worry about when the conversation changes
134        // in the conversation header are the folders, priority indicators, and starred state.
135        // Updating these will resize the space for the header.
136        mConversation = conv;
137        setSubject(conv.subject);
138        setFolders(conv);
139        setStarred(conv.starred);
140        if (mHeaderItem != null) {
141            final int h = measureHeight();
142            if (mHeaderItem.setHeight(h)) {
143                mCallbacks.onConversationViewHeaderHeightChange(h);
144            }
145        }
146    }
147
148    @Override
149    public void onClick(View v) {
150        final int id = v.getId();
151        if (mConversation != null && id == R.id.conversation_header_star) {
152            mConversation.starred = !mConversation.starred;
153            setStarred(mConversation.starred);
154            mConversationUpdater.updateConversation(Conversation.listOf(mConversation),
155                    UIProvider.ConversationColumns.STARRED, mConversation.starred);
156        }
157
158    }
159}
160