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 */
16
17package com.android.messaging.datamodel.data;
18
19import android.database.Cursor;
20import android.net.Uri;
21import android.provider.ContactsContract.DisplayNameSources;
22
23import com.android.ex.chips.RecipientEntry;
24
25import com.android.messaging.util.Assert;
26import com.android.messaging.util.ContactRecipientEntryUtils;
27import com.android.messaging.util.ContactUtil;
28
29/**
30 * Data model object used to power ContactListItemViews, which may be displayed either in
31 * our contact list, or in the chips UI search drop down presented by ContactDropdownLayouter.
32 */
33public class ContactListItemData {
34    // Keeps the contact data in the form of RecipientEntry that RecipientEditTextView can
35    // directly use.
36    private RecipientEntry mRecipientEntry;
37
38    private CharSequence mStyledName;
39    private CharSequence mStyledDestination;
40
41    // If this contact is the first in the list for its first letter, then this will be the
42    // first letter, otherwise this is null.
43    private String mAlphabetHeader;
44
45    // Is the contact the only item in the list (happens when the user clicks on an
46    // existing chip for which we show full contact detail for the selected contact).
47    private boolean mSingleRecipient;
48
49    // Is the contact in managed profile.
50    private boolean mIsWorkContact;
51
52    /**
53     * Bind to a contact cursor in the contact list.
54     */
55    public void bind(final Cursor cursor, final String alphabetHeader) {
56        final long dataId = cursor.getLong(ContactUtil.INDEX_DATA_ID);
57        final long contactId = cursor.getLong(ContactUtil.INDEX_CONTACT_ID);
58        final String lookupKey = cursor.getString(ContactUtil.INDEX_LOOKUP_KEY);
59        final String displayName = cursor.getString(ContactUtil.INDEX_DISPLAY_NAME);
60        final String photoThumbnailUri = cursor.getString(ContactUtil.INDEX_PHOTO_URI);
61        final String destination = cursor.getString(ContactUtil.INDEX_PHONE_EMAIL);
62        final int destinationType = cursor.getInt(ContactUtil.INDEX_PHONE_EMAIL_TYPE);
63        final String destinationLabel = cursor.getString(ContactUtil.INDEX_PHONE_EMAIL_LABEL);
64        mStyledName = null;
65        mStyledDestination = null;
66        mAlphabetHeader = alphabetHeader;
67        mSingleRecipient = false;
68
69        // Check whether this contact is first level (i.e. whether it's the first entry of this
70        // contact in the contact list).
71        boolean isFirstLevel = true;
72        if (!cursor.isFirst() && cursor.moveToPrevious()) {
73            final long contactIdPrevious = cursor.getLong(ContactUtil.INDEX_CONTACT_ID);
74            if (contactId == contactIdPrevious) {
75                isFirstLevel = false;
76            }
77            cursor.moveToNext();
78        }
79
80        mRecipientEntry = ContactUtil.createRecipientEntry(displayName,
81                DisplayNameSources.STRUCTURED_NAME, destination, destinationType, destinationLabel,
82                contactId, lookupKey, dataId, photoThumbnailUri, isFirstLevel);
83
84        mIsWorkContact = ContactUtil.isEnterpriseContactId(contactId);
85    }
86
87    /**
88     * Bind to a RecipientEntry produced by the chips text view in the search drop down, plus
89     * optional styled name & destination for showing bold search match.
90     */
91    public void bind(final RecipientEntry entry, final CharSequence styledName,
92                     final CharSequence styledDestination, final boolean singleRecipient,
93                     final boolean isWorkContact) {
94        Assert.isTrue(entry.isValid());
95        mRecipientEntry = entry;
96        mStyledName = styledName;
97        mStyledDestination = styledDestination;
98        mAlphabetHeader = null;
99        mSingleRecipient = singleRecipient;
100        mIsWorkContact = isWorkContact;
101    }
102
103    public CharSequence getDisplayName() {
104        final CharSequence displayName = mStyledName != null ? mStyledName :
105            ContactRecipientEntryUtils.getDisplayNameForContactList(mRecipientEntry);
106        return displayName == null ? "" : displayName;
107    }
108
109    public Uri getPhotoThumbnailUri() {
110        return mRecipientEntry.getPhotoThumbnailUri() == null ? null :
111            mRecipientEntry.getPhotoThumbnailUri();
112    }
113
114    public CharSequence getDestination() {
115        final CharSequence destination = mStyledDestination != null ?
116                mStyledDestination : ContactRecipientEntryUtils.formatDestination(mRecipientEntry);
117        return destination == null ? "" : destination;
118    }
119
120    public int getDestinationType() {
121        return mRecipientEntry.getDestinationType();
122    }
123
124    public String getDestinationLabel() {
125        return mRecipientEntry.getDestinationLabel();
126    }
127
128    public long getContactId() {
129        return mRecipientEntry.getContactId();
130    }
131
132    public String getLookupKey() {
133        return mRecipientEntry.getLookupKey();
134    }
135
136    /**
137     * Returns if this item is "first-level," i.e. whether it's the first entry of the contact
138     * that it represents in the list. For example, if John Smith has 3 different phone numbers,
139     * then the first number is considered first-level, while the other two are considered
140     * second-level.
141     */
142    public boolean getIsFirstLevel() {
143        // Treat the item as first level if it's a top-level recipient entry, or if it's the only
144        // item in the list.
145        return mRecipientEntry.isFirstLevel() || mSingleRecipient;
146    }
147
148    /**
149     * Returns if this item is simple, i.e. it has only avatar and a display name with phone number
150     * embedded so we can hide everything else.
151     */
152    public boolean getIsSimpleContactItem() {
153        return ContactRecipientEntryUtils.isAvatarAndNumberOnlyContact(mRecipientEntry) ||
154                ContactRecipientEntryUtils.isSendToDestinationContact(mRecipientEntry);
155    }
156
157    public String getAlphabetHeader() {
158        return mAlphabetHeader;
159    }
160
161    /**
162     * Returns a RecipientEntry instance readily usable by the RecipientEditTextView.
163     */
164    public RecipientEntry getRecipientEntry() {
165        return mRecipientEntry;
166    }
167
168    /**
169     * @return whether the contact is in managed profile.
170     */
171    public boolean getIsWorkContact() {
172        return mIsWorkContact;
173    }
174}
175