1/*
2 * Copyright (C) 2012 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 */
16
17package com.android.mail.widget;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.graphics.Bitmap;
22import android.graphics.BitmapFactory;
23import android.graphics.Typeface;
24import android.text.Spannable;
25import android.text.SpannableStringBuilder;
26import android.text.style.AbsoluteSizeSpan;
27import android.text.style.CharacterStyle;
28import android.text.style.ForegroundColorSpan;
29import android.text.style.StyleSpan;
30import android.view.View;
31import android.widget.RemoteViews;
32
33import com.android.mail.R;
34import com.android.mail.providers.Conversation;
35import com.android.mail.providers.Folder;
36import com.android.mail.ui.FolderDisplayer;
37import com.android.mail.utils.FolderUri;
38
39public class WidgetConversationListItemViewBuilder {
40    // Static colors
41    private static int SUBJECT_TEXT_COLOR_READ;
42    private static int SUBJECT_TEXT_COLOR_UNREAD;
43    private static int SNIPPET_TEXT_COLOR;
44    private static int DATE_TEXT_COLOR_READ;
45    private static int DATE_TEXT_COLOR_UNREAD;
46
47    // Static bitmap
48    private static Bitmap ATTACHMENT;
49
50    private WidgetFolderDisplayer mFolderDisplayer;
51
52    /**
53     * Label Displayer for Widget
54     */
55    protected static class WidgetFolderDisplayer extends FolderDisplayer {
56        public WidgetFolderDisplayer(Context context) {
57            super(context);
58        }
59
60        // Maximum number of folders we want to display
61        private static final int MAX_DISPLAYED_FOLDERS_COUNT = 3;
62
63        /*
64         * Load Conversation Labels
65         */
66        @Override
67        public void loadConversationFolders(Conversation conv, final FolderUri ignoreFolderUri,
68                final int ignoreFolderType) {
69            super.loadConversationFolders(conv, ignoreFolderUri, ignoreFolderType);
70        }
71
72        private static int getFolderViewId(int position) {
73            switch (position) {
74                case 0:
75                    return R.id.widget_folder_0;
76                case 1:
77                    return R.id.widget_folder_1;
78                case 2:
79                    return R.id.widget_folder_2;
80            }
81            return 0;
82        }
83
84        /**
85         * Display folders
86         */
87        public void displayFolders(RemoteViews remoteViews) {
88            int displayedFolder = 0;
89            for (Folder folderValues : mFoldersSortedSet) {
90                int viewId = getFolderViewId(displayedFolder);
91                if (viewId == 0) {
92                    continue;
93                }
94                remoteViews.setViewVisibility(viewId, View.VISIBLE);
95                int color[] = new int[] {folderValues.getBackgroundColor(mDefaultBgColor)};
96                Bitmap bitmap = Bitmap.createBitmap(color, 1, 1, Bitmap.Config.RGB_565);
97                remoteViews.setImageViewBitmap(viewId, bitmap);
98
99                if (++displayedFolder == MAX_DISPLAYED_FOLDERS_COUNT) {
100                    break;
101                }
102            }
103
104            for (int i = displayedFolder; i < MAX_DISPLAYED_FOLDERS_COUNT; i++) {
105                remoteViews.setViewVisibility(getFolderViewId(i), View.GONE);
106            }
107        }
108    }
109
110    /*
111     * Get font sizes and bitmaps from Resources
112     */
113    public WidgetConversationListItemViewBuilder(Context context) {
114        final Resources res = context.getResources();
115
116        // Initialize colors
117        SUBJECT_TEXT_COLOR_READ = res.getColor(R.color.subject_text_color_read);
118        SUBJECT_TEXT_COLOR_UNREAD = res.getColor(R.color.subject_text_color_unread);
119        SNIPPET_TEXT_COLOR = res.getColor(R.color.snippet_text_color);
120        DATE_TEXT_COLOR_READ = res.getColor(R.color.date_text_color_read);
121        DATE_TEXT_COLOR_UNREAD = res.getColor(R.color.date_text_color_unread);
122
123        // Initialize Bitmap
124        ATTACHMENT = BitmapFactory.decodeResource(res, R.drawable.ic_attach_file_20dp);
125    }
126
127    /*
128     * Add size, color and style to a given text
129     */
130    private static CharSequence addStyle(CharSequence text, int size, int color) {
131        SpannableStringBuilder builder = new SpannableStringBuilder(text);
132        builder.setSpan(
133                new AbsoluteSizeSpan(size), 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
134        if (color != 0) {
135            builder.setSpan(new ForegroundColorSpan(color), 0, text.length(),
136                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
137        }
138        return builder;
139    }
140
141    /*
142     * Return the full View
143     */
144    public RemoteViews getStyledView(final Context context, final CharSequence date,
145            final Conversation conversation, final FolderUri folderUri, final int ignoreFolderType,
146            final SpannableStringBuilder senders, String subject) {
147
148        final boolean isUnread = !conversation.read;
149        final String snippet = conversation.getSnippet();
150        final boolean hasAttachments = conversation.hasAttachments;
151        final Resources res = context.getResources();
152        final int dateFontSize = res.getDimensionPixelSize(R.dimen.widget_date_font_size);
153        final int subjectFontSize = res.getDimensionPixelSize(R.dimen.widget_subject_font_size);
154
155        // Add style to date
156        final int dateColor = isUnread ? DATE_TEXT_COLOR_UNREAD : DATE_TEXT_COLOR_READ;
157        final CharSequence styledDate = addStyle(date, dateFontSize, dateColor);
158
159        subject = Conversation.getSubjectForDisplay(context, null /* badgeText */, subject);
160        final SpannableStringBuilder subjectBuilder = new SpannableStringBuilder(subject);
161        if (isUnread) {
162            subjectBuilder.setSpan(new StyleSpan(Typeface.BOLD), 0, subject.length(),
163                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
164        }
165        final CharacterStyle subjectStyle = new ForegroundColorSpan(
166                isUnread ? SUBJECT_TEXT_COLOR_UNREAD : SUBJECT_TEXT_COLOR_READ);
167        subjectBuilder.setSpan(subjectStyle, 0, subjectBuilder.length(),
168                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
169        final CharSequence styledSubject = addStyle(subjectBuilder, subjectFontSize, 0);
170
171        final SpannableStringBuilder snippetBuilder = new SpannableStringBuilder(snippet);
172        snippetBuilder.setSpan(new ForegroundColorSpan(SNIPPET_TEXT_COLOR), 0,
173                snippetBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
174        final CharSequence styledSnippet = addStyle(snippetBuilder, subjectFontSize, 0);
175
176        // Paper clip for attachment
177        Bitmap paperclipBitmap = null;
178        if (hasAttachments) {
179            paperclipBitmap = ATTACHMENT;
180        }
181
182        // Inflate and fill out the remote view
183        final RemoteViews remoteViews = new RemoteViews(
184                context.getPackageName(), R.layout.widget_conversation_list_item);
185        remoteViews.setTextViewText(R.id.widget_senders, senders);
186        remoteViews.setTextViewText(R.id.widget_date, styledDate);
187        remoteViews.setTextViewText(R.id.widget_subject, styledSubject);
188        remoteViews.setTextViewText(R.id.widget_snippet, styledSnippet);
189        if (paperclipBitmap != null) {
190            remoteViews.setViewVisibility(R.id.widget_attachment, View.VISIBLE);
191            remoteViews.setImageViewBitmap(R.id.widget_attachment, paperclipBitmap);
192        } else {
193            remoteViews.setViewVisibility(R.id.widget_attachment, View.GONE);
194        }
195        if (isUnread) {
196            remoteViews.setViewVisibility(R.id.widget_unread_background, View.VISIBLE);
197            remoteViews.setViewVisibility(R.id.widget_read_background, View.GONE);
198        } else {
199            remoteViews.setViewVisibility(R.id.widget_unread_background, View.GONE);
200            remoteViews.setViewVisibility(R.id.widget_read_background, View.VISIBLE);
201        }
202        if (context.getResources().getBoolean(R.bool.display_folder_colors_in_widget)) {
203            mFolderDisplayer = new WidgetFolderDisplayer(context);
204            mFolderDisplayer.loadConversationFolders(conversation, folderUri, ignoreFolderType);
205            mFolderDisplayer.displayFolders(remoteViews);
206        }
207
208        return remoteViews;
209    }
210}
211