1/*
2 * Copyright (C) 2010 Google Inc.
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.loaderapp.fragments;
18
19import com.android.loaderapp.CursorFactoryListAdapter;
20import com.android.loaderapp.R;
21import com.android.loaderapp.CursorFactoryListAdapter.ResourceViewFactory;
22import com.android.loaderapp.model.ContactsListLoader;
23
24import android.app.LoaderManagingFragment;
25import android.content.Loader;
26import android.content.res.Configuration;
27import android.database.Cursor;
28import android.net.Uri;
29import android.os.Bundle;
30import android.provider.ContactsContract.Contacts;
31import android.view.LayoutInflater;
32import android.view.View;
33import android.view.ViewGroup;
34import android.widget.AdapterView;
35import android.widget.ListView;
36import android.widget.AdapterView.OnItemClickListener;
37
38public class ContactsListFragment extends LoaderManagingFragment<Cursor>
39        implements OnItemClickListener {
40    private static final int LOADER_LIST = 1;
41
42    public static final int MODE_NULL = 0;
43    public static final int MODE_VISIBLE = 1;
44    public static final int MODE_STREQUENT = 2;
45    public static final int MODE_GROUP = 3;
46
47    private static final int DEFAULT_MODE = MODE_VISIBLE;
48
49    public interface Controller {
50        public void onContactSelected(Uri contact);
51    }
52
53    Controller mController;
54    ListView mList;
55    CursorFactoryListAdapter mAdapter;
56    int mMode;
57    String mGroupName;
58
59    public ContactsListFragment() {
60        super();
61        mMode = DEFAULT_MODE;
62    }
63
64    public ContactsListFragment(int mode) {
65        super();
66        mMode = mode;
67    }
68
69    @Override
70    public void onInitializeLoaders() {
71        if (mMode != MODE_NULL) {
72            startLoading(LOADER_LIST, null);
73        }
74    }
75
76    @Override
77    protected Loader onCreateLoader(int id, Bundle args) {
78        switch (mMode) {
79            case MODE_GROUP:
80                return ContactsListLoader.newContactGroupLoader(getActivity(), mGroupName);
81            case MODE_STREQUENT:
82                return ContactsListLoader.newStrequentContactsLoader(getActivity());
83            default:
84                return ContactsListLoader.newVisibleContactsLoader(getActivity());
85        }
86    }
87
88    @Override
89    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
90        mAdapter.changeCursor(data);
91    }
92
93    @Override
94    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
95        ListView list = (ListView) inflater.inflate(R.layout.contacts_list, container, false);
96        list.setOnItemClickListener(this);
97        mAdapter = new CursorFactoryListAdapter(getActivity(),
98                new ResourceViewFactory(getListItemResId()));
99        list.setAdapter(mAdapter);
100        mList = list;
101        return list;
102    }
103
104    public void setMode(int mode) {
105        boolean reload = mode != mMode;
106        mMode = mode;
107        if (reload) {
108            startLoading(LOADER_LIST, null);
109        }
110    }
111
112    public void setGroupMode(String groupName) {
113        boolean reload = (MODE_GROUP != mMode) || !groupName.equals(mGroupName);
114        mMode = MODE_GROUP;
115        mGroupName = groupName;
116        if (reload) {
117            startLoading(LOADER_LIST, null);
118        }
119    }
120
121    public void setController(Controller controller) {
122        mController = controller;
123    }
124
125    public int getMode() {
126        return mMode;
127    }
128
129    /**
130     * Build the {@link Contacts#CONTENT_LOOKUP_URI} for the given
131     * {@link ListView} position.
132     */
133    public Uri getContactUri(int position) {
134        if (position == ListView.INVALID_POSITION) {
135            throw new IllegalArgumentException("Position not in list bounds");
136        }
137
138        final Cursor cursor = (Cursor) mAdapter.getItem(position);
139        if (cursor == null) {
140            return null;
141        }
142
143        // Build and return soft, lookup reference
144        final long contactId = cursor.getLong(ContactsListLoader.COLUMN_ID);
145        final String lookupKey = cursor.getString(ContactsListLoader.COLUMN_LOOKUP_KEY);
146        return Contacts.getLookupUri(contactId, lookupKey);
147    }
148
149    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
150        // The user clicked on an item in the left side pane, start loading the data for it
151        if (mController != null) {
152            mController.onContactSelected(getContactUri(position));
153        }
154    }
155
156    private int getListItemResId() {
157        // This should be done using the resource system, but for now we want to override
158        // the configuration for running xlarge UIs on normal screens and vice versa
159        Configuration config = getActivity().getResources().getConfiguration();
160        int screenLayoutSize = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
161        if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
162            return R.layout.xlarge_list_item;
163        } else {
164            return R.layout.normal_list_item;
165        }
166    }
167}
168