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 */
16
17package com.android.calendar.selectcalendars;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.database.Cursor;
22import android.graphics.drawable.shapes.RectShape;
23import android.provider.CalendarContract.Calendars;
24import android.text.TextUtils;
25import android.view.LayoutInflater;
26import android.view.View;
27import android.view.ViewGroup;
28import android.widget.AdapterView;
29import android.widget.BaseAdapter;
30import android.widget.CheckBox;
31import android.widget.ListAdapter;
32import android.widget.TextView;
33
34import com.android.calendar.R;
35import com.android.calendar.Utils;
36
37import java.util.HashMap;
38
39public class SelectCalendarsSyncAdapter extends BaseAdapter
40        implements ListAdapter, AdapterView.OnItemClickListener {
41    private static final String TAG = "SelCalsAdapter";
42    private static int COLOR_CHIP_SIZE = 30;
43    private RectShape r = new RectShape();
44
45    private LayoutInflater mInflater;
46    private static final int LAYOUT = R.layout.calendar_sync_item;
47    private CalendarRow[] mData;
48    private HashMap<Long, CalendarRow> mChanges = new HashMap<Long, CalendarRow>();
49    private int mRowCount = 0;
50
51    private int mIdColumn;
52    private int mNameColumn;
53    private int mColorColumn;
54    private int mSyncedColumn;
55
56    private final String mSyncedString;
57    private final String mNotSyncedString;
58
59    public class CalendarRow {
60        long id;
61        String displayName;
62        int color;
63        boolean synced;
64        boolean originalSynced;
65    }
66
67    public SelectCalendarsSyncAdapter(Context context, Cursor c) {
68        super();
69        initData(c);
70        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
71        COLOR_CHIP_SIZE *= context.getResources().getDisplayMetrics().density;
72        r.resize(COLOR_CHIP_SIZE, COLOR_CHIP_SIZE);
73        Resources res = context.getResources();
74        mSyncedString = res.getString(R.string.synced);
75        mNotSyncedString = res.getString(R.string.not_synced);
76    }
77
78    private void initData(Cursor c) {
79        if (c == null) {
80            mRowCount = 0;
81            mData = null;
82            return;
83        }
84
85        mIdColumn = c.getColumnIndexOrThrow(Calendars._ID);
86        mNameColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME);
87        mColorColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR);
88        mSyncedColumn = c.getColumnIndexOrThrow(Calendars.SYNC_EVENTS);
89
90        mRowCount = c.getCount();
91        mData = new CalendarRow[mRowCount];
92        c.moveToPosition(-1);
93        int p = 0;
94        while (c.moveToNext()) {
95            long id = c.getLong(mIdColumn);
96            mData[p] = new CalendarRow();
97            mData[p].id = id;
98            mData[p].displayName = c.getString(mNameColumn);
99            mData[p].color = c.getInt(mColorColumn);
100            mData[p].originalSynced = c.getInt(mSyncedColumn) != 0;
101            if (mChanges.containsKey(id)) {
102                mData[p].synced = mChanges.get(id).synced;
103            } else {
104                mData[p].synced = mData[p].originalSynced;
105            }
106            p++;
107        }
108    }
109
110    public void changeCursor(Cursor c) {
111        initData(c);
112        notifyDataSetChanged();
113    }
114
115    @Override
116    public View getView(int position, View convertView, ViewGroup parent) {
117        if (position >= mRowCount) {
118            return null;
119        }
120        String name = mData[position].displayName;
121        boolean selected = mData[position].synced;
122        int color = Utils.getDisplayColorFromColor(mData[position].color);
123        View view;
124        if (convertView == null) {
125            view = mInflater.inflate(LAYOUT, parent, false);
126        } else {
127            view = convertView;
128        }
129
130        view.setTag(mData[position]);
131
132        CheckBox cb = (CheckBox) view.findViewById(R.id.sync);
133        cb.setChecked(selected);
134
135        if (selected) {
136            setText(view, R.id.status, mSyncedString);
137        } else {
138            setText(view, R.id.status, mNotSyncedString);
139        }
140
141        View colorView = view.findViewById(R.id.color);
142
143        colorView.setBackgroundColor(color);
144
145        setText(view, R.id.calendar, name);
146        return view;
147    }
148
149    private static void setText(View view, int id, String text) {
150        if (TextUtils.isEmpty(text)) {
151            return;
152        }
153        TextView textView = (TextView) view.findViewById(id);
154        textView.setText(text);
155    }
156
157    @Override
158    public int getCount() {
159        return mRowCount;
160    }
161
162    @Override
163    public Object getItem(int position) {
164        if (position >= mRowCount) {
165            return null;
166        }
167        CalendarRow item = mData[position];
168        return item;
169    }
170
171    @Override
172    public long getItemId(int position) {
173        if (position >= mRowCount) {
174            return 0;
175        }
176        return mData[position].id;
177    }
178
179    @Override
180    public boolean hasStableIds() {
181        return true;
182    }
183
184    public int getSynced(int position) {
185        return mData[position].synced ? 1 : 0;
186    }
187
188    @Override
189    public void onItemClick(AdapterView<?> parent, View view, int position, long id)  {
190        CalendarRow row = (CalendarRow) view.getTag();
191        row.synced = !row.synced;
192
193        String status;
194        if (row.synced) {
195            status = mSyncedString;
196        } else {
197            status = mNotSyncedString;
198        }
199        setText(view, R.id.status, status);
200
201        CheckBox cb = (CheckBox) view.findViewById(R.id.sync);
202        cb.setChecked(row.synced);
203
204        // There is some data loss in long -> int, but we should never see it in
205        // practice regarding calendar ids.
206        mChanges.put(row.id, row);
207    }
208
209    public HashMap<Long, CalendarRow> getChanges() {
210        return mChanges;
211    }
212}
213