1/*
2 * Copyright (C) 2010 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.contacts.list;
17
18import android.content.Context;
19import android.content.CursorLoader;
20import android.database.Cursor;
21import android.net.Uri;
22import android.net.Uri.Builder;
23import android.provider.ContactsContract;
24import android.provider.ContactsContract.Contacts;
25import android.provider.ContactsContract.Contacts.AggregationSuggestions;
26import android.provider.ContactsContract.Directory;
27import android.text.TextUtils;
28import android.view.LayoutInflater;
29import android.view.View;
30import android.view.ViewGroup;
31import android.widget.TextView;
32
33import com.android.contacts.R;
34import com.android.contacts.common.list.ContactListAdapter;
35import com.android.contacts.common.list.ContactListItemView;
36import com.android.contacts.common.list.DirectoryListLoader;
37
38public class JoinContactListAdapter extends ContactListAdapter {
39
40    /** Maximum number of suggestions shown for joining aggregates */
41    private static final int MAX_SUGGESTIONS = 4;
42
43    public static final int PARTITION_SUGGESTIONS = 0;
44    public static final int PARTITION_ALL_CONTACTS = 1;
45
46    private long mTargetContactId;
47
48    public JoinContactListAdapter(Context context) {
49        super(context);
50        setPinnedPartitionHeadersEnabled(true);
51        setSectionHeaderDisplayEnabled(true);
52        setIndexedPartition(PARTITION_ALL_CONTACTS);
53        setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_NONE);
54    }
55
56    @Override
57    protected void addPartitions() {
58        // Partition 0: suggestions
59        addPartition(false, true);
60
61        // Partition 1: All contacts
62        addPartition(createDefaultDirectoryPartition());
63    }
64
65    public void setTargetContactId(long targetContactId) {
66        this.mTargetContactId = targetContactId;
67    }
68
69    @Override
70    public void configureLoader(CursorLoader cursorLoader, long directoryId) {
71        JoinContactLoader loader = (JoinContactLoader) cursorLoader;
72
73        final Builder builder = Contacts.CONTENT_URI.buildUpon();
74        builder.appendEncodedPath(String.valueOf(mTargetContactId));
75        builder.appendEncodedPath(AggregationSuggestions.CONTENT_DIRECTORY);
76
77        final String filter = getQueryString();
78        if (!TextUtils.isEmpty(filter)) {
79            builder.appendEncodedPath(Uri.encode(filter));
80        }
81
82        builder.appendQueryParameter("limit", String.valueOf(MAX_SUGGESTIONS));
83
84        loader.setSuggestionUri(builder.build());
85
86        // TODO simplify projection
87        loader.setProjection(getProjection(false));
88        final Uri allContactsUri;
89        if (!TextUtils.isEmpty(filter)) {
90            allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_FILTER_URI).buildUpon()
91                .appendEncodedPath(Uri.encode(filter))
92                .appendQueryParameter(
93                        ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
94                .build();
95        } else {
96            allContactsUri = buildSectionIndexerUri(Contacts.CONTENT_URI).buildUpon()
97                .appendQueryParameter(
98                        ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(Directory.DEFAULT))
99                .build();
100        }
101        loader.setUri(allContactsUri);
102        loader.setSelection(Contacts._ID + "!=?");
103        loader.setSelectionArgs(new String[]{ String.valueOf(mTargetContactId) });
104        if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
105            loader.setSortOrder(Contacts.SORT_KEY_PRIMARY);
106        } else {
107            loader.setSortOrder(Contacts.SORT_KEY_ALTERNATIVE);
108        }
109    }
110
111    @Override
112    public boolean isEmpty() {
113        return false;
114    }
115
116    public void setSuggestionsCursor(Cursor cursor) {
117        changeCursor(PARTITION_SUGGESTIONS, cursor);
118    }
119
120    @Override
121    public void changeCursor(Cursor cursor) {
122        changeCursor(PARTITION_ALL_CONTACTS, cursor);
123    }
124
125    @Override
126    public void configureDefaultPartition(boolean showIfEmpty, boolean hasHeader) {
127         // Don't change default partition parameters from these defaults
128        super.configureDefaultPartition(false, true);
129    }
130
131    @Override
132    public int getViewTypeCount() {
133        return super.getViewTypeCount();
134    }
135
136    @Override
137    public int getItemViewType(int partition, int position) {
138        return super.getItemViewType(partition, position);
139    }
140
141    @Override
142    protected View newHeaderView(Context context, int partition, Cursor cursor,
143            ViewGroup parent) {
144        switch (partition) {
145            case PARTITION_SUGGESTIONS: {
146                View view = inflate(R.layout.join_contact_picker_section_header, parent);
147                ((TextView) view.findViewById(R.id.text)).setText(
148                        R.string.separatorJoinAggregateSuggestions);
149                return view;
150            }
151            case PARTITION_ALL_CONTACTS: {
152                View view = inflate(R.layout.join_contact_picker_section_header, parent);
153                ((TextView) view.findViewById(R.id.text)).setText(
154                        R.string.separatorJoinAggregateAll);
155                return view;
156            }
157        }
158
159        return null;
160    }
161
162    @Override
163    protected void bindHeaderView(View view, int partitionIndex, Cursor cursor) {
164        // Header views are static - nothing needs to be bound
165    }
166
167    @Override
168    protected View newView(Context context, int partition, Cursor cursor, int position,
169            ViewGroup parent) {
170        switch (partition) {
171            case PARTITION_SUGGESTIONS:
172            case PARTITION_ALL_CONTACTS:
173                return super.newView(context, partition, cursor, position, parent);
174        }
175        return null;
176    }
177
178    private View inflate(int layoutId, ViewGroup parent) {
179        return LayoutInflater.from(getContext()).inflate(layoutId, parent, false);
180    }
181
182    @Override
183    protected void bindView(View itemView, int partition, Cursor cursor, int position) {
184        switch (partition) {
185            case PARTITION_SUGGESTIONS: {
186                final ContactListItemView view = (ContactListItemView) itemView;
187                view.setSectionHeader(null);
188                bindPhoto(view, partition, cursor);
189                bindName(view, cursor);
190                break;
191            }
192            case PARTITION_ALL_CONTACTS: {
193                final ContactListItemView view = (ContactListItemView) itemView;
194                bindSectionHeaderAndDivider(view, position, cursor);
195                bindPhoto(view, partition, cursor);
196                bindName(view, cursor);
197                break;
198            }
199        }
200    }
201
202    @Override
203    public Uri getContactUri(int partitionIndex, Cursor cursor) {
204        long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
205        String lookupKey = cursor.getString(ContactQuery.CONTACT_LOOKUP_KEY);
206        return Contacts.getLookupUri(contactId, lookupKey);
207    }
208}
209