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    /**
50     * Bind to a contact cursor in the contact list.
51     */
52    public void bind(final Cursor cursor, final String alphabetHeader) {
53        final long dataId = cursor.getLong(ContactUtil.INDEX_DATA_ID);
54        final long contactId = cursor.getLong(ContactUtil.INDEX_CONTACT_ID);
55        final String lookupKey = cursor.getString(ContactUtil.INDEX_LOOKUP_KEY);
56        final String displayName = cursor.getString(ContactUtil.INDEX_DISPLAY_NAME);
57        final String photoThumbnailUri = cursor.getString(ContactUtil.INDEX_PHOTO_URI);
58        final String destination = cursor.getString(ContactUtil.INDEX_PHONE_EMAIL);
59        final int destinationType = cursor.getInt(ContactUtil.INDEX_PHONE_EMAIL_TYPE);
60        final String destinationLabel = cursor.getString(ContactUtil.INDEX_PHONE_EMAIL_LABEL);
61        mStyledName = null;
62        mStyledDestination = null;
63        mAlphabetHeader = alphabetHeader;
64        mSingleRecipient = false;
65
66        // Check whether this contact is first level (i.e. whether it's the first entry of this
67        // contact in the contact list).
68        boolean isFirstLevel = true;
69        if (!cursor.isFirst() && cursor.moveToPrevious()) {
70            final long contactIdPrevious = cursor.getLong(ContactUtil.INDEX_CONTACT_ID);
71            if (contactId == contactIdPrevious) {
72                isFirstLevel = false;
73            }
74            cursor.moveToNext();
75        }
76
77        mRecipientEntry = ContactUtil.createRecipientEntry(displayName,
78                DisplayNameSources.STRUCTURED_NAME, destination, destinationType, destinationLabel,
79                contactId, lookupKey, dataId, photoThumbnailUri, isFirstLevel);
80    }
81
82    /**
83     * Bind to a RecipientEntry produced by the chips text view in the search drop down, plus
84     * optional styled name & destination for showing bold search match.
85     */
86    public void bind(final RecipientEntry entry, final CharSequence styledName,
87            final CharSequence styledDestination, final boolean singleRecipient) {
88        Assert.isTrue(entry.isValid());
89        mRecipientEntry = entry;
90        mStyledName = styledName;
91        mStyledDestination = styledDestination;
92        mAlphabetHeader = null;
93        mSingleRecipient = singleRecipient;
94    }
95
96    public CharSequence getDisplayName() {
97        final CharSequence displayName = mStyledName != null ? mStyledName :
98            ContactRecipientEntryUtils.getDisplayNameForContactList(mRecipientEntry);
99        return displayName == null ? "" : displayName;
100    }
101
102    public Uri getPhotoThumbnailUri() {
103        return mRecipientEntry.getPhotoThumbnailUri() == null ? null :
104            mRecipientEntry.getPhotoThumbnailUri();
105    }
106
107    public CharSequence getDestination() {
108        final CharSequence destination = mStyledDestination != null ?
109                mStyledDestination : ContactRecipientEntryUtils.formatDestination(mRecipientEntry);
110        return destination == null ? "" : destination;
111    }
112
113    public int getDestinationType() {
114        return mRecipientEntry.getDestinationType();
115    }
116
117    public String getDestinationLabel() {
118        return mRecipientEntry.getDestinationLabel();
119    }
120
121    public long getContactId() {
122        return mRecipientEntry.getContactId();
123    }
124
125    public String getLookupKey() {
126        return mRecipientEntry.getLookupKey();
127    }
128
129    /**
130     * Returns if this item is "first-level," i.e. whether it's the first entry of the contact
131     * that it represents in the list. For example, if John Smith has 3 different phone numbers,
132     * then the first number is considered first-level, while the other two are considered
133     * second-level.
134     */
135    public boolean getIsFirstLevel() {
136        // Treat the item as first level if it's a top-level recipient entry, or if it's the only
137        // item in the list.
138        return mRecipientEntry.isFirstLevel() || mSingleRecipient;
139    }
140
141    /**
142     * Returns if this item is simple, i.e. it has only avatar and a display name with phone number
143     * embedded so we can hide everything else.
144     */
145    public boolean getIsSimpleContactItem() {
146        return ContactRecipientEntryUtils.isAvatarAndNumberOnlyContact(mRecipientEntry) ||
147                ContactRecipientEntryUtils.isSendToDestinationContact(mRecipientEntry);
148    }
149
150    public String getAlphabetHeader() {
151        return mAlphabetHeader;
152    }
153
154    /**
155     * Returns a RecipientEntry instance readily usable by the RecipientEditTextView.
156     */
157    public RecipientEntry getRecipientEntry() {
158        return mRecipientEntry;
159    }
160}
161