EventInfoFragment.java revision 71b221ae5d0f514352584a955630f5494f686c51
12bebde787f9490408ceaf14166de4b016a10daf1Mason Tang/*
22bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Copyright (C) 2010 The Android Open Source Project
32bebde787f9490408ceaf14166de4b016a10daf1Mason Tang *
42bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Licensed under the Apache License, Version 2.0 (the "License");
52bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * you may not use this file except in compliance with the License.
62bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * You may obtain a copy of the License at
72bebde787f9490408ceaf14166de4b016a10daf1Mason Tang *
82bebde787f9490408ceaf14166de4b016a10daf1Mason Tang *      http://www.apache.org/licenses/LICENSE-2.0
92bebde787f9490408ceaf14166de4b016a10daf1Mason Tang *
102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * Unless required by applicable law or agreed to in writing, software
112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * distributed under the License is distributed on an "AS IS" BASIS,
122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * See the License for the specific language governing permissions and
142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang * limitations under the License.
152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang */
162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
172bebde787f9490408ceaf14166de4b016a10daf1Mason Tangpackage com.android.calendar;
182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
19cb81189e4868769ea016253eca104e46df2f033aErikimport com.android.calendar.CalendarController.EventInfo;
202bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport com.android.calendar.CalendarController.EventType;
21fbce65e53c7a111955f638db5bf8bee35381e5b7Erikimport com.android.calendar.event.EditEventHelper;
222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
232bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.app.Activity;
2471d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.app.Dialog;
2571d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.app.DialogFragment;
262bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ActivityNotFoundException;
272bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentResolver;
282bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentUris;
292bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.ContentValues;
302bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.Context;
312bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.Intent;
322bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.content.res.Resources;
332bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.database.Cursor;
342bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.graphics.Rect;
3571b221ae5d0f514352584a955630f5494f686c51Michael Chanimport android.graphics.Typeface;
362bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.net.Uri;
372bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.os.Bundle;
382bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.pim.EventRecurrence;
392bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.Calendar.Attendees;
402bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.Calendar.Calendars;
412bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.Calendar.Events;
42cb81189e4868769ea016253eca104e46df2f033aErikimport android.provider.ContactsContract;
432bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.CommonDataKinds;
442bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.Intents;
452bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.provider.ContactsContract.QuickContact;
468ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.Spannable;
478ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.SpannableStringBuilder;
482bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.TextUtils;
492bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.DateFormat;
502bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.DateUtils;
512bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.format.Time;
528ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.style.ForegroundColorSpan;
538ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.text.style.StrikethroughSpan;
5471b221ae5d0f514352584a955630f5494f686c51Michael Chanimport android.text.style.StyleSpan;
552bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.util.Linkify;
562bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.text.util.Rfc822Token;
572bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.util.Log;
5871d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.Gravity;
592bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.LayoutInflater;
602bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.MotionEvent;
612bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.View;
62cb81189e4868769ea016253eca104e46df2f033aErikimport android.view.View.OnClickListener;
63cb81189e4868769ea016253eca104e46df2f033aErikimport android.view.View.OnTouchListener;
642bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.view.ViewGroup;
6571d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.Window;
6671d08836af4cf5fc45d340b1883044a9f8290232Michael Chanimport android.view.WindowManager;
672bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.AdapterView;
682bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.ArrayAdapter;
698ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chanimport android.widget.Button;
702bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.Spinner;
712bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.TextView;
722bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport android.widget.Toast;
732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
742bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport java.util.ArrayList;
752bebde787f9490408ceaf14166de4b016a10daf1Mason Tangimport java.util.regex.Pattern;
762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7771b221ae5d0f514352584a955630f5494f686c51Michael Chanpublic class EventInfoFragment extends DialogFragment implements
78cb81189e4868769ea016253eca104e46df2f033aErik        AdapterView.OnItemSelectedListener, CalendarController.EventHandler {
79d845fbe558d5229102b58cce70a1b29fe6cb6967Erik    public static final boolean DEBUG = false;
802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public static final String TAG = "EventInfoActivity";
822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
834003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private static final String BUNDLE_KEY_EVENT_ID = "key_event_id";
844003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
854003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private static final String BUNDLE_KEY_START_MILLIS = "key_start_millis";
864003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
874003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    private static final String BUNDLE_KEY_END_MILLIS = "key_end_millis";
884003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
8971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private static final String BUNDLE_KEY_IS_DIALOG = "key_fragment_is_dialog";
9071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    /**
922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * These are the corresponding indices into the array of strings
932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * "R.array.change_response_labels" in the resource file.
942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     */
952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int UPDATE_SINGLE = 0;
962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int UPDATE_ALL = 1;
972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    // Query tokens for QueryHandler
992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int TOKEN_QUERY_EVENT = 0;
1002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int TOKEN_QUERY_CALENDARS = 1;
1012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int TOKEN_QUERY_ATTENDEES = 2;
10271b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int TOKEN_QUERY_DUPLICATE_CALENDARS = 3;
1032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final String[] EVENT_PROJECTION = new String[] {
1052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events._ID,                  // 0  do not remove; used in DeleteEventHelper
1062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.TITLE,                // 1  do not remove; used in DeleteEventHelper
1072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.RRULE,                // 2  do not remove; used in DeleteEventHelper
1082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.ALL_DAY,              // 3  do not remove; used in DeleteEventHelper
1092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.CALENDAR_ID,          // 4  do not remove; used in DeleteEventHelper
1102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.DTSTART,              // 5  do not remove; used in DeleteEventHelper
1112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events._SYNC_ID,             // 6  do not remove; used in DeleteEventHelper
1122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.EVENT_TIMEZONE,       // 7  do not remove; used in DeleteEventHelper
1132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.DESCRIPTION,          // 8
1142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Events.EVENT_LOCATION,       // 9
11571b221ae5d0f514352584a955630f5494f686c51Michael Chan        Calendars.ACCESS_LEVEL,      // 10
11671b221ae5d0f514352584a955630f5494f686c51Michael Chan        Calendars.COLOR,             // 11
11771b221ae5d0f514352584a955630f5494f686c51Michael Chan        Events.HAS_ATTENDEE_DATA,    // 12
11871b221ae5d0f514352584a955630f5494f686c51Michael Chan        Events.ORGANIZER,            // 13
11971b221ae5d0f514352584a955630f5494f686c51Michael Chan        Events.ORIGINAL_EVENT        // 14 do not remove; used in DeleteEventHelper
1202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    };
1212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_ID = 0;
1222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_TITLE = 1;
1232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_RRULE = 2;
1242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_ALL_DAY = 3;
1252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_CALENDAR_ID = 4;
1262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_SYNC_ID = 6;
1272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_EVENT_TIMEZONE = 7;
1282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_DESCRIPTION = 8;
1292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int EVENT_INDEX_EVENT_LOCATION = 9;
13071b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int EVENT_INDEX_ACCESS_LEVEL = 10;
13171b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int EVENT_INDEX_COLOR = 11;
13271b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int EVENT_INDEX_HAS_ATTENDEE_DATA = 12;
13371b221ae5d0f514352584a955630f5494f686c51Michael Chan    private static final int EVENT_INDEX_ORGANIZER = 13;
1342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final String[] ATTENDEES_PROJECTION = new String[] {
1362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees._ID,                      // 0
1372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees.ATTENDEE_NAME,            // 1
1382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees.ATTENDEE_EMAIL,           // 2
1392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees.ATTENDEE_RELATIONSHIP,    // 3
1402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendees.ATTENDEE_STATUS,          // 4
1412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    };
1422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_ID = 0;
1432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_NAME = 1;
1442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_EMAIL = 2;
1452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_RELATIONSHIP = 3;
1462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final int ATTENDEES_INDEX_STATUS = 4;
1472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final String ATTENDEES_WHERE = Attendees.EVENT_ID + "=?";
1492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static final String ATTENDEES_SORT_ORDER = Attendees.ATTENDEE_NAME + " ASC, "
1512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            + Attendees.ATTENDEE_EMAIL + " ASC";
1522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final String[] CALENDARS_PROJECTION = new String[] {
1542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Calendars._ID,           // 0
1552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Calendars.DISPLAY_NAME,  // 1
1562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Calendars.OWNER_ACCOUNT, // 2
1572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Calendars.ORGANIZER_CAN_RESPOND // 3
1582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    };
1592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int CALENDARS_INDEX_DISPLAY_NAME = 1;
1602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int CALENDARS_INDEX_OWNER_ACCOUNT = 2;
1612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final int CALENDARS_INDEX_OWNER_CAN_RESPOND = 3;
1622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final String CALENDARS_WHERE = Calendars._ID + "=?";
1642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    static final String CALENDARS_DUPLICATE_NAME_WHERE = Calendars.DISPLAY_NAME + "=?";
1652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private View mView;
1672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Uri mUri;
1692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private long mEventId;
1702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Cursor mEventCursor;
1712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Cursor mAttendeesCursor;
1722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Cursor mCalendarsCursor;
1732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private long mStartMillis;
1752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private long mEndMillis;
1762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mHasAttendeeData;
1782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mIsOrganizer;
179d845fbe558d5229102b58cce70a1b29fe6cb6967Erik    private long mCalendarOwnerAttendeeId = EditEventHelper.ATTENDEE_ID_NONE;
180352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan    private boolean mOwnerCanRespond;
1812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private String mCalendarOwnerAccount;
1822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mCanModifyCalendar;
1832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mIsBusyFreeCalendar;
1842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private int mNumOfAttendees;
1852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private EditResponseHelper mEditResponseHelper;
1872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private int mResponseOffset;
1892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private int mOriginalAttendeeResponse;
190d845fbe558d5229102b58cce70a1b29fe6cb6967Erik    private int mAttendeeResponseFromIntent = EditEventHelper.ATTENDEE_NO_RESPONSE;
1912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean mIsRepeating;
1922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private Pattern mWildcardPattern = Pattern.compile("^.*$");
1942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
1952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    ArrayList<Attendee> mAcceptedAttendees = new ArrayList<Attendee>();
1962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    ArrayList<Attendee> mDeclinedAttendees = new ArrayList<Attendee>();
1972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    ArrayList<Attendee> mTentativeAttendees = new ArrayList<Attendee>();
1982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    ArrayList<Attendee> mNoResponseAttendees = new ArrayList<Attendee>();
1992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private int mColor;
2002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private QueryHandler mHandler;
2022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
203cb81189e4868769ea016253eca104e46df2f033aErik    private Runnable mTZUpdater = new Runnable() {
204cb81189e4868769ea016253eca104e46df2f033aErik        @Override
205cb81189e4868769ea016253eca104e46df2f033aErik        public void run() {
206cb81189e4868769ea016253eca104e46df2f033aErik            updateEvent(mView);
207cb81189e4868769ea016253eca104e46df2f033aErik        }
208cb81189e4868769ea016253eca104e46df2f033aErik    };
209cb81189e4868769ea016253eca104e46df2f033aErik
21071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private static final int DIALOG_WIDTH = 500; // FRAG_TODO scale
211352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan    private static final int DIALOG_HEIGHT = 600;
21271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private boolean mIsDialog = false;
21371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private int mX = -1;
21471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private int mY = -1;
21571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
2162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private class QueryHandler extends AsyncQueryService {
2172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        public QueryHandler(Context context) {
2182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            super(context);
2192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
2202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        @Override
2222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
2234003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            // if the activity is finishing, then close the cursor and return
2244003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            final Activity activity = getActivity();
2254003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            if (activity == null || activity.isFinishing()) {
2264003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                cursor.close();
2274003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                return;
2284003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            }
2294003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
2302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            switch (token) {
2312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case TOKEN_QUERY_EVENT:
2322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mEventCursor = Utils.matrixCursorFromCursor(cursor);
2332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                if (initEventCursor()) {
2342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    // The cursor is empty. This can happen if the event was
2352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    // deleted.
2362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    // FRAG_TODO we should no longer rely on Activity.finish()
2371df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang                    activity.finish();
2382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    return;
2392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                }
2402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateEvent(mView);
2412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                // start calendar query
2432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                Uri uri = Calendars.CONTENT_URI;
2442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                String[] args = new String[] {
2452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        Long.toString(mEventCursor.getLong(EVENT_INDEX_CALENDAR_ID))};
2462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                startQuery(TOKEN_QUERY_CALENDARS, null, uri, CALENDARS_PROJECTION,
2472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        CALENDARS_WHERE, args, null);
2482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
2492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case TOKEN_QUERY_CALENDARS:
2502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mCalendarsCursor = Utils.matrixCursorFromCursor(cursor);
2512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateCalendar(mView);
2524003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                // FRAG_TODO fragments shouldn't set the title anymore
2532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateTitle();
2541df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang                // update the action bar since our option set might have changed
2551df2ca65a852fda463b1d787cd4f81680103b6a2Mason Tang                activity.invalidateOptionsMenu();
2562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
257352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                if (!mIsBusyFreeCalendar) {
258352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    args = new String[] { Long.toString(mEventId) };
259352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan
260352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    // start attendees query
261352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    uri = Attendees.CONTENT_URI;
262352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    startQuery(TOKEN_QUERY_ATTENDEES, null, uri, ATTENDEES_PROJECTION,
263352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                            ATTENDEES_WHERE, args, ATTENDEES_SORT_ORDER);
2642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                }
2652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
2662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case TOKEN_QUERY_ATTENDEES:
2672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mAttendeesCursor = Utils.matrixCursorFromCursor(cursor);
2682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                initAttendeesCursor(mView);
2692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateResponse(mView);
2702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
2712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case TOKEN_QUERY_DUPLICATE_CALENDARS:
27271b221ae5d0f514352584a955630f5494f686c51Michael Chan                Resources res = activity.getResources();
27371b221ae5d0f514352584a955630f5494f686c51Michael Chan                SpannableStringBuilder sb = new SpannableStringBuilder();
27471b221ae5d0f514352584a955630f5494f686c51Michael Chan
27571b221ae5d0f514352584a955630f5494f686c51Michael Chan                // Label
27671b221ae5d0f514352584a955630f5494f686c51Michael Chan                String label = res.getString(R.string.view_event_calendar_label);
27771b221ae5d0f514352584a955630f5494f686c51Michael Chan                sb.append(label).append(" ");
27871b221ae5d0f514352584a955630f5494f686c51Michael Chan                sb.setSpan(new StyleSpan(Typeface.BOLD), 0, label.length(),
27971b221ae5d0f514352584a955630f5494f686c51Michael Chan                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
28071b221ae5d0f514352584a955630f5494f686c51Michael Chan
28171b221ae5d0f514352584a955630f5494f686c51Michael Chan                // Calendar display name
2822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                String calendarName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME);
28371b221ae5d0f514352584a955630f5494f686c51Michael Chan                sb.append(calendarName);
28471b221ae5d0f514352584a955630f5494f686c51Michael Chan
28571b221ae5d0f514352584a955630f5494f686c51Michael Chan                // Show email account if display name is not unique and
28671b221ae5d0f514352584a955630f5494f686c51Michael Chan                // display name != email
28771b221ae5d0f514352584a955630f5494f686c51Michael Chan                String email = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT);
28871b221ae5d0f514352584a955630f5494f686c51Michael Chan                if (cursor.getCount() > 1 && !calendarName.equalsIgnoreCase(email)) {
28971b221ae5d0f514352584a955630f5494f686c51Michael Chan                    sb.append(" (").append(email).append(")");
29071b221ae5d0f514352584a955630f5494f686c51Michael Chan                }
29171b221ae5d0f514352584a955630f5494f686c51Michael Chan
29271b221ae5d0f514352584a955630f5494f686c51Michael Chan                TextView calendarTv = (TextView) mView.findViewById(R.id.calendar);
29371b221ae5d0f514352584a955630f5494f686c51Michael Chan                calendarTv.setText(sb);
2942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
2952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
2962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            cursor.close();
2972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
2982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
2992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
3002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3014003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public EventInfoFragment() {
3024003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mUri = null;
3034003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
3044003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
3052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public EventInfoFragment(Uri uri, long startMillis, long endMillis, int attendeeResponse) {
30671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        setStyle(DialogFragment.STYLE_NO_TITLE, 0);
3072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mUri = uri;
3082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mStartMillis = startMillis;
3092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEndMillis = endMillis;
3102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mAttendeeResponseFromIntent = attendeeResponse;
3112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
3122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3134003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public EventInfoFragment(long eventId, long startMillis, long endMillis) {
3144003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        this(ContentUris.withAppendedId(Events.CONTENT_URI, eventId),
3154003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                startMillis, endMillis, EventInfoActivity.ATTENDEE_NO_RESPONSE);
3164003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        mEventId = eventId;
3174003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
3184003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
31971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    @Override
32071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    public void onActivityCreated(Bundle savedInstanceState) {
32171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        super.onActivityCreated(savedInstanceState);
32271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
32371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        if (savedInstanceState != null) {
32471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan            mIsDialog = savedInstanceState.getBoolean(BUNDLE_KEY_IS_DIALOG, false);
32571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        }
32671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
32771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        if (mIsDialog) {
32871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan            applyDialogParams();
32971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        }
33071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    }
33171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
33271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    private void applyDialogParams() {
33371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        Dialog dialog = getDialog();
33471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        dialog.setCanceledOnTouchOutside(true);
33571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
33671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        Window window = dialog.getWindow();
33771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
33871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
33971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        WindowManager.LayoutParams a = window.getAttributes();
34071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        a.dimAmount = .4f;
34171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
34271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        a.width = DIALOG_WIDTH;
343352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        a.height = DIALOG_HEIGHT;
34471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
34571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        if (mX != -1 || mY != -1) {
3468ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            a.x = mX - a.width - 64; // FRAG_TODO event sender should return the left edge or a rect
3478ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            a.y = mY - 64; // FRAG_TODO should set height after layout is done
34871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan            a.gravity = Gravity.LEFT | Gravity.TOP;
34971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        }
35071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
35171d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        window.setAttributes(a);
35271d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    }
35371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
35471d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    public void setDialogParams(int x, int y) {
35571d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        mIsDialog = true;
35671d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        mX = x;
35771d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        mY = y;
35871d08836af4cf5fc45d340b1883044a9f8290232Michael Chan    }
35971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
3602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
3612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If they selected the "No response" option, then don't display the
3622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // dialog asking which events to change.
3632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (id == 0 && mResponseOffset == 0) {
3642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
3652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
3662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If this is not a repeating event, then don't display the dialog
3682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // asking which events to change.
3692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (!mIsRepeating) {
3702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
3712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
3722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If the selection is the same as the original, then don't display the
3742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // dialog asking which events to change.
3752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        int index = findResponseIndexFor(mOriginalAttendeeResponse);
3762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (position == index + mResponseOffset) {
3772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
3782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
3792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // This is a repeating event. We need to ask the user if they mean to
3812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // change just this one instance or all instances.
3822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEditResponseHelper.showDialog(mEditResponseHelper.getWhichEvents());
3832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
3842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void onNothingSelected(AdapterView<?> parent) {
3862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
3872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @Override
3892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void onAttach(Activity activity) {
3902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        super.onAttach(activity);
3912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEditResponseHelper = new EditResponseHelper(activity);
3922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mHandler = new QueryHandler(activity);
3932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
3942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
3952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @Override
3962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public View onCreateView(LayoutInflater inflater, ViewGroup container,
3972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            Bundle savedInstanceState) {
3982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mView = inflater.inflate(R.layout.event_info_activity, null);
3992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4004003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        if (mUri == null) {
4014003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            // restore event ID from bundle
4024003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mEventId = savedInstanceState.getLong(BUNDLE_KEY_EVENT_ID);
4034003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mUri = ContentUris.withAppendedId(Events.CONTENT_URI, mEventId);
4044003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mStartMillis = savedInstanceState.getLong(BUNDLE_KEY_START_MILLIS);
4054003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            mEndMillis = savedInstanceState.getLong(BUNDLE_KEY_END_MILLIS);
4064003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        }
4074003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
4082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // start loading the data
4092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION,
4102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                null, null, null);
4112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4128ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        Button b = (Button) mView.findViewById(R.id.done);
4138ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        b.setOnClickListener(new OnClickListener() {
4148ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            @Override
4158ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            public void onClick(View v) {
4168ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                EventInfoFragment.this.dismiss();
4178ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            }});
4188ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
4192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return mView;
4202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
4212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateTitle() {
4232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Resources res = getActivity().getResources();
4242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mCanModifyCalendar && !mIsOrganizer) {
4252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            getActivity().setTitle(res.getString(R.string.event_info_title_invite));
4262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
4272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            getActivity().setTitle(res.getString(R.string.event_info_title));
4282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
4292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
4302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    /**
4322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * Initializes the event cursor, which is expected to point to the first
4332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * (and only) result from a query.
4342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * @return true if the cursor is empty.
4352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     */
4362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean initEventCursor() {
4372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if ((mEventCursor == null) || (mEventCursor.getCount() == 0)) {
4382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return true;
4392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
4402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEventCursor.moveToFirst();
4412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mEventId = mEventCursor.getInt(EVENT_INDEX_ID);
4422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String rRule = mEventCursor.getString(EVENT_INDEX_RRULE);
4432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mIsRepeating = (rRule != null);
4442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return false;
4452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
4462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private static class Attendee {
4482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String mName;
4492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String mEmail;
4502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Attendee(String name, String email) {
4522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mName = name;
4532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mEmail = email;
4542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
4558ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
4568ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        String getDisplayName() {
4578ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            if (TextUtils.isEmpty(mName)) {
4588ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                return mEmail;
4598ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            } else {
4608ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                return mName;
4618ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            }
4628ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        }
4632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
4642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @SuppressWarnings("fallthrough")
4662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void initAttendeesCursor(View view) {
467d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        mOriginalAttendeeResponse = EditEventHelper.ATTENDEE_NO_RESPONSE;
468d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        mCalendarOwnerAttendeeId = EditEventHelper.ATTENDEE_ID_NONE;
4692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mNumOfAttendees = 0;
4702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mAttendeesCursor != null) {
4712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mNumOfAttendees = mAttendeesCursor.getCount();
4722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            if (mAttendeesCursor.moveToFirst()) {
4732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mAcceptedAttendees.clear();
4742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mDeclinedAttendees.clear();
4752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mTentativeAttendees.clear();
4762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mNoResponseAttendees.clear();
4772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
4782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                do {
4792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    int status = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS);
4802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    String name = mAttendeesCursor.getString(ATTENDEES_INDEX_NAME);
4812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    String email = mAttendeesCursor.getString(ATTENDEES_INDEX_EMAIL);
4822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
483d845fbe558d5229102b58cce70a1b29fe6cb6967Erik                    if (mCalendarOwnerAttendeeId == EditEventHelper.ATTENDEE_ID_NONE &&
4842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            mCalendarOwnerAccount.equalsIgnoreCase(email)) {
4852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        mCalendarOwnerAttendeeId = mAttendeesCursor.getInt(ATTENDEES_INDEX_ID);
4862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        mOriginalAttendeeResponse = mAttendeesCursor.getInt(ATTENDEES_INDEX_STATUS);
4872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    } else {
4882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        // Don't show your own status in the list because:
4892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        //  1) it doesn't make sense for event without other guests.
4902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        //  2) there's a spinner for that for events with guests.
4912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        switch(status) {
4922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            case Attendees.ATTENDEE_STATUS_ACCEPTED:
4932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                mAcceptedAttendees.add(new Attendee(name, email));
4942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                break;
4952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            case Attendees.ATTENDEE_STATUS_DECLINED:
4962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                mDeclinedAttendees.add(new Attendee(name, email));
4972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                break;
4988ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                            case Attendees.ATTENDEE_STATUS_TENTATIVE:
4992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                mTentativeAttendees.add(new Attendee(name, email));
5008ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                                break;
5018ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                            default:
5028ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                                mNoResponseAttendees.add(new Attendee(name, email));
5032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        }
5042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    }
5052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                } while (mAttendeesCursor.moveToNext());
5062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                mAttendeesCursor.moveToFirst();
5072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateAttendees(view);
5092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
5102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
5122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @Override
5144003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public void onSaveInstanceState(Bundle outState) {
5154003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        super.onSaveInstanceState(outState);
5164003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        outState.putLong(BUNDLE_KEY_EVENT_ID, mEventId);
5174003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        outState.putLong(BUNDLE_KEY_START_MILLIS, mStartMillis);
5184003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        outState.putLong(BUNDLE_KEY_END_MILLIS, mEndMillis);
51971d08836af4cf5fc45d340b1883044a9f8290232Michael Chan
52071d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        outState.putBoolean(BUNDLE_KEY_IS_DIALOG, mIsDialog);
5214003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    }
5224003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
5234003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
5244003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    @Override
5254003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang    public void onDestroyView() {
52671b221ae5d0f514352584a955630f5494f686c51Michael Chan        if (saveResponse()) {
5272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            Toast.makeText(getActivity(), R.string.saving_event, Toast.LENGTH_SHORT).show();
5282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5294003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        super.onDestroyView();
5302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
5312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    @Override
5332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void onDestroy() {
5342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mEventCursor != null) {
5352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mEventCursor.close();
5362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mCalendarsCursor != null) {
5382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mCalendarsCursor.close();
5392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mAttendeesCursor != null) {
5412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mAttendeesCursor.close();
5422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
54371d08836af4cf5fc45d340b1883044a9f8290232Michael Chan        super.onDestroy();
5442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
5452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    /**
5472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * Asynchronously saves the response to an invitation if the user changed
5482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * the response. Returns true if the database will be updated.
5492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     *
5502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * @param cr the ContentResolver
5512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * @return true if the database will be changed
5522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     */
5532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private boolean saveResponse() {
5542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mAttendeesCursor == null || mEventCursor == null) {
5552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return false;
5562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Spinner spinner = (Spinner) getView().findViewById(R.id.response_value);
5582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        int position = spinner.getSelectedItemPosition() - mResponseOffset;
5592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (position <= 0) {
5602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return false;
5612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
563d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        int status = EditEventHelper.ATTENDEE_VALUES[position];
5642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If the status has not changed, then don't update the database
5662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (status == mOriginalAttendeeResponse) {
5672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return false;
5682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // If we never got an owner attendee id we can't set the status
571d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        if (mCalendarOwnerAttendeeId == EditEventHelper.ATTENDEE_ID_NONE) {
5722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return false;
5732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (!mIsRepeating) {
5762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // This is a non-repeating event
5772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            updateResponse(mEventId, mCalendarOwnerAttendeeId, status);
5782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return true;
5792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // This is a repeating event
5822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        int whichEvents = mEditResponseHelper.getWhichEvents();
5832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        switch (whichEvents) {
5842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case -1:
5852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                return false;
5862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case UPDATE_SINGLE:
5872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                createExceptionResponse(mEventId, mCalendarOwnerAttendeeId, status);
5882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                return true;
5892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            case UPDATE_ALL:
5902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                updateResponse(mEventId, mCalendarOwnerAttendeeId, status);
5912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                return true;
5922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            default:
5932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                Log.e(TAG, "Unexpected choice for updating invitation response");
5942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                break;
5952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
5962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return false;
5972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
5982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
5992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateResponse(long eventId, long attendeeId, int status) {
6002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // Update the attendee status in the attendees table.  the provider
6012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // takes care of updating the self attendance status.
6022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        ContentValues values = new ContentValues();
6032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (!TextUtils.isEmpty(mCalendarOwnerAccount)) {
6052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            values.put(Attendees.ATTENDEE_EMAIL, mCalendarOwnerAccount);
6062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
6072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Attendees.ATTENDEE_STATUS, status);
6082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Attendees.EVENT_ID, eventId);
6092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Uri uri = ContentUris.withAppendedId(Attendees.CONTENT_URI, attendeeId);
6112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mHandler.startUpdate(mHandler.getNextToken(), null, uri, values,
6132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                null, null, Utils.UNDO_DELAY);
6142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
6152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void createExceptionResponse(long eventId, long attendeeId,
6172bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            int status) {
6182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mEventCursor == null || !mEventCursor.moveToFirst()) {
6192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
6202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
6212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        ContentValues values = new ContentValues();
6232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String title = mEventCursor.getString(EVENT_INDEX_TITLE);
6252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String timezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE);
6262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        int calendarId = mEventCursor.getInt(EVENT_INDEX_CALENDAR_ID);
6272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        boolean allDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
6282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String syncId = mEventCursor.getString(EVENT_INDEX_SYNC_ID);
6292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.TITLE, title);
6312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.EVENT_TIMEZONE, timezone);
6322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.ALL_DAY, allDay ? 1 : 0);
6332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.CALENDAR_ID, calendarId);
6342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.DTSTART, mStartMillis);
6352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.DTEND, mEndMillis);
6362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.ORIGINAL_EVENT, syncId);
6372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.ORIGINAL_INSTANCE_TIME, mStartMillis);
6382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.ORIGINAL_ALL_DAY, allDay ? 1 : 0);
6392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.STATUS, Events.STATUS_CONFIRMED);
6402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        values.put(Events.SELF_ATTENDEE_STATUS, status);
6412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // Create a recurrence exception
6432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mHandler.startInsert(mHandler.getNextToken(), null,
6442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                Events.CONTENT_URI, values, Utils.UNDO_DELAY);
6452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
6462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private int findResponseIndexFor(int response) {
648d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        int size = EditEventHelper.ATTENDEE_VALUES.length;
6492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        for (int index = 0; index < size; index++) {
650d845fbe558d5229102b58cce70a1b29fe6cb6967Erik            if (EditEventHelper.ATTENDEE_VALUES[index] == response) {
6512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                return index;
6522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
6532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
6542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return 0;
6552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
6562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void doEdit() {
6582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        CalendarController.getInstance(getActivity()).sendEventRelatedEvent(
6592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                this, EventType.EDIT_EVENT, mEventId, mStartMillis, mEndMillis, 0, 0);
6602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
6612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateEvent(View view) {
6632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mEventCursor == null) {
6642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
6652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
6662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String eventName = mEventCursor.getString(EVENT_INDEX_TITLE);
6682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (eventName == null || eventName.length() == 0) {
6692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            eventName = getActivity().getString(R.string.no_title_label);
6702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
6712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        boolean allDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) != 0;
6732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String location = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION);
6742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String description = mEventCursor.getString(EVENT_INDEX_DESCRIPTION);
6752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String rRule = mEventCursor.getString(EVENT_INDEX_RRULE);
6762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String eventTimezone = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE);
6772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mColor = mEventCursor.getInt(EVENT_INDEX_COLOR) & 0xbbffffff;
6782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6798ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        view.findViewById(R.id.color).setBackgroundColor(mColor);
6802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        TextView title = (TextView) view.findViewById(R.id.title);
6822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        title.setTextColor(mColor);
6832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6848ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        View divider = view.findViewById(R.id.divider);
6858ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        divider.getBackground().setColorFilter(mColor, PorterDuff.Mode.SRC_IN);
6862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // What
6882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (eventName != null) {
6892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setTextCommon(view, R.id.title, eventName);
6902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
6912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
6922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // When
6932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        String when;
69471b221ae5d0f514352584a955630f5494f686c51Michael Chan        int flags = DateUtils.FORMAT_SHOW_DATE;
6952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (allDay) {
69671b221ae5d0f514352584a955630f5494f686c51Michael Chan            flags |= DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_WEEKDAY;
6972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
69871b221ae5d0f514352584a955630f5494f686c51Michael Chan            flags |= DateUtils.FORMAT_SHOW_TIME;
6992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            if (DateFormat.is24HourFormat(getActivity())) {
7002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                flags |= DateUtils.FORMAT_24HOUR;
7012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
7022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
703cb81189e4868769ea016253eca104e46df2f033aErik        when = Utils.formatDateRange(getActivity(), mStartMillis, mEndMillis, flags);
7042bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        setTextCommon(view, R.id.when, when);
7052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7068ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//CLEANUP        // Show the event timezone if it is different from the local timezone
7078ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        Time time = new Time();
7088ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        String localTimezone = time.timezone;
7098ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        if (allDay) {
7108ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            localTimezone = Time.TIMEZONE_UTC;
7118ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        }
7128ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        if (eventTimezone != null && !localTimezone.equals(eventTimezone) && !allDay) {
7138ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            String displayName;
7148ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            TimeZone tz = TimeZone.getTimeZone(localTimezone);
7158ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            if (tz == null || tz.getID().equals("GMT")) {
7168ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//                displayName = localTimezone;
7178ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            } else {
7188ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//                displayName = tz.getDisplayName();
7198ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            }
7208ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//
7218ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            setTextCommon(view, R.id.timezone, displayName);
7228ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            setVisibilityCommon(view, R.id.timezone_container, View.VISIBLE);
7238ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        } else {
7248ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//            setVisibilityCommon(view, R.id.timezone_container, View.GONE);
7258ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan//        }
7262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // Repeat
7282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (rRule != null) {
7292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            EventRecurrence eventRecurrence = new EventRecurrence();
7302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            eventRecurrence.parse(rRule);
731cb81189e4868769ea016253eca104e46df2f033aErik            Time date = new Time(Utils.getTimeZone(getActivity(), mTZUpdater));
7322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            if (allDay) {
7332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                date.timezone = Time.TIMEZONE_UTC;
7342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
7352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            date.set(mStartMillis);
7362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            eventRecurrence.setStartDate(date);
7372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            String repeatString = EventRecurrenceFormatter.getRepeatString(
7382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    getActivity().getResources(), eventRecurrence);
7392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setTextCommon(view, R.id.repeat, repeatString);
7409c1989989b8f633210ef1761b0e4e7ecd5b43581Mason Tang            setVisibilityCommon(view, R.id.repeat_container, View.VISIBLE);
7412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
7422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setVisibilityCommon(view, R.id.repeat_container, View.GONE);
7432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
7442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // Where
7462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (location == null || location.length() == 0) {
7472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setVisibilityCommon(view, R.id.where, View.GONE);
7482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
7492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            final TextView textView = (TextView) view.findViewById(R.id.where);
7502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            if (textView != null) {
7512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    textView.setAutoLinkMask(0);
7522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    textView.setText(location);
7532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q=");
7542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    textView.setOnTouchListener(new OnTouchListener() {
7552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        public boolean onTouch(View v, MotionEvent event) {
7562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            try {
7572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                return v.onTouchEvent(event);
7582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            } catch (ActivityNotFoundException e) {
7592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                // ignore
7602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                                return true;
7612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                            }
7622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        }
7632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    });
7642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
7652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
7662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // Description
768352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        if (description != null && description.length() != 0) {
7692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setTextCommon(view, R.id.description, description);
7702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
7712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
7722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateCalendar(View view) {
7742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mCalendarOwnerAccount = "";
7752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (mCalendarsCursor != null && mEventCursor != null) {
7762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mCalendarsCursor.moveToFirst();
7772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            String tempAccount = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT);
7782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mCalendarOwnerAccount = (tempAccount == null) ? "" : tempAccount;
779352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            mOwnerCanRespond = mCalendarsCursor.getInt(CALENDARS_INDEX_OWNER_CAN_RESPOND) != 0;
7802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            String displayName = mCalendarsCursor.getString(CALENDARS_INDEX_DISPLAY_NAME);
7822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // start duplicate calendars query
7842bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mHandler.startQuery(TOKEN_QUERY_DUPLICATE_CALENDARS, null, Calendars.CONTENT_URI,
7852bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    CALENDARS_PROJECTION, CALENDARS_DUPLICATE_NAME_WHERE,
7862bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    new String[] {displayName}, null);
7872bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
7882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            String eventOrganizer = mEventCursor.getString(EVENT_INDEX_ORGANIZER);
7892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mIsOrganizer = mCalendarOwnerAccount.equalsIgnoreCase(eventOrganizer);
7902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mHasAttendeeData = mEventCursor.getInt(EVENT_INDEX_HAS_ATTENDEE_DATA) != 0;
7912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mCanModifyCalendar =
7922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL) >= Calendars.CONTRIBUTOR_ACCESS;
7932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mIsBusyFreeCalendar =
7942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL) == Calendars.FREEBUSY_ACCESS;
795352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan
796352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan            if (!mIsBusyFreeCalendar) {
7978ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                Button b = (Button) mView.findViewById(R.id.edit);
798352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                b.setEnabled(true);
7998ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                b.setOnClickListener(new OnClickListener() {
8008ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                    @Override
8018ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                    public void onClick(View v) {
8028ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                        doEdit();
8038ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                        EventInfoFragment.this.dismiss();
804352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                    }
805352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                });
8068ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            }
8072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
80871b221ae5d0f514352584a955630f5494f686c51Michael Chan            setVisibilityCommon(view, R.id.calendar, View.GONE);
8092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
8102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
8112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
8122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void updateAttendees(View view) {
8138ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        TextView tv = (TextView) view.findViewById(R.id.attendee_list);
8148ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        SpannableStringBuilder sb = new SpannableStringBuilder();
8158ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        formatAttendees(mAcceptedAttendees, sb, Attendees.ATTENDEE_STATUS_ACCEPTED);
8168ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        formatAttendees(mDeclinedAttendees, sb, Attendees.ATTENDEE_STATUS_DECLINED);
8178ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        formatAttendees(mTentativeAttendees, sb, Attendees.ATTENDEE_STATUS_TENTATIVE);
8188ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        formatAttendees(mNoResponseAttendees, sb, Attendees.ATTENDEE_STATUS_NONE);
81971b221ae5d0f514352584a955630f5494f686c51Michael Chan
82071b221ae5d0f514352584a955630f5494f686c51Michael Chan        if (sb.length() > 0) {
82171b221ae5d0f514352584a955630f5494f686c51Michael Chan            // Add the label after the attendees are formatted because
82271b221ae5d0f514352584a955630f5494f686c51Michael Chan            // formatAttendees would prepend ", " if sb.length != 0
82371b221ae5d0f514352584a955630f5494f686c51Michael Chan            String label = getActivity().getResources().getString(R.string.attendees_label);
82471b221ae5d0f514352584a955630f5494f686c51Michael Chan            sb.insert(0, label);
82571b221ae5d0f514352584a955630f5494f686c51Michael Chan            sb.insert(label.length(), " ");
82671b221ae5d0f514352584a955630f5494f686c51Michael Chan            sb.setSpan(new StyleSpan(Typeface.BOLD), 0, label.length(),
82771b221ae5d0f514352584a955630f5494f686c51Michael Chan                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
82871b221ae5d0f514352584a955630f5494f686c51Michael Chan
82971b221ae5d0f514352584a955630f5494f686c51Michael Chan            tv.setText(sb);
83071b221ae5d0f514352584a955630f5494f686c51Michael Chan        }
8318ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan    }
8328ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
8338ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan    private void formatAttendees(ArrayList<Attendee> attendees, SpannableStringBuilder sb, int type) {
8348ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        if (attendees.size() <= 0) {
8358ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            return;
8368ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        }
8378ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
8388ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        int begin = sb.length();
8398ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        boolean firstTime = sb.length() == 0;
8408ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
8418ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        if (firstTime == false) {
8428ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            begin += 2; // skip over the ", " for formatting.
8438ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        }
8448ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
8458ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        for (Attendee attendee : attendees) {
8468ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            if (firstTime) {
8478ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                firstTime = false;
8488ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            } else {
8498ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                sb.append(", ");
8508ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            }
8518ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
8528ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            String name = attendee.getDisplayName();
8538ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            sb.append(name);
8548ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        }
8558ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan
8568ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan        switch (type) {
8578ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            case Attendees.ATTENDEE_STATUS_ACCEPTED:
8588ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                break;
8598ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            case Attendees.ATTENDEE_STATUS_DECLINED:
8608ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                sb.setSpan(new StrikethroughSpan(), begin, sb.length(),
8618ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
8628ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                // fall through
8638ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan            default:
8648ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                // The last INCLUSIVE causes the foreground color to be applied
8658ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                // to the rest of the span. If not, the comma at the end of the
8668ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                // declined or tentative may be black.
8678ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                sb.setSpan(new ForegroundColorSpan(0xFF888888), begin, sb.length(),
8688ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                        Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
8698ce3b7db4d7644ecc8c358fd16a06c4d9af48904Michael Chan                break;
8702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
8712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
8722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
8732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    void updateResponse(View view) {
8742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // we only let the user accept/reject/etc. a meeting if:
8752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // a) you can edit the event's containing calendar AND
8762bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // b) you're not the organizer and only attendee AND
8772bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // c) organizerCanRespond is enabled for the calendar
8782bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // (if the attendee data has been hidden, the visible number of attendees
8792bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // will be 1 -- the calendar owner's).
8802bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // (there are more cases involved to be 100% accurate, such as
8812bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // paying attention to whether or not an attendee status was
8822bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // included in the feed, but we're currently omitting those corner cases
8832bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // for simplicity).
884352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan
885352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan        // TODO Switch to EditEventHelper.canRespond when this class uses CalendarEventModel.
886d785cd533f6a3c23813c15315aed74efa9a116f5Michael Chan        if (!mCanModifyCalendar || (mHasAttendeeData && mIsOrganizer && mNumOfAttendees <= 1) ||
887352e1a2f834460bd54e03ce94cadd36a46debacbMichael Chan                (mIsOrganizer && !mOwnerCanRespond)) {
8882bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            setVisibilityCommon(view, R.id.response_container, View.GONE);
8892bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
8902bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
8912bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
8922bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        setVisibilityCommon(view, R.id.response_container, View.VISIBLE);
8932bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
8942bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        Spinner spinner = (Spinner) view.findViewById(R.id.response_value);
8952bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
8962bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        mResponseOffset = 0;
8972bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
8982bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        /* If the user has previously responded to this event
8992bebde787f9490408ceaf14166de4b016a10daf1Mason Tang         * we should not allow them to select no response again.
9002bebde787f9490408ceaf14166de4b016a10daf1Mason Tang         * Switch the entries to a set of entries without the
9012bebde787f9490408ceaf14166de4b016a10daf1Mason Tang         * no response option.
9022bebde787f9490408ceaf14166de4b016a10daf1Mason Tang         */
9032bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if ((mOriginalAttendeeResponse != Attendees.ATTENDEE_STATUS_INVITED)
904d845fbe558d5229102b58cce70a1b29fe6cb6967Erik                && (mOriginalAttendeeResponse != EditEventHelper.ATTENDEE_NO_RESPONSE)
9052bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                && (mOriginalAttendeeResponse != Attendees.ATTENDEE_STATUS_NONE)) {
9062bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            CharSequence[] entries;
9072bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            entries = getActivity().getResources().getTextArray(R.array.response_labels2);
9082bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            mResponseOffset = -1;
9092bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            ArrayAdapter<CharSequence> adapter =
9102bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                new ArrayAdapter<CharSequence>(getActivity(),
9112bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                        android.R.layout.simple_spinner_item, entries);
9122bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
9132bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            spinner.setAdapter(adapter);
9142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9152bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9162bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        int index;
917d845fbe558d5229102b58cce70a1b29fe6cb6967Erik        if (mAttendeeResponseFromIntent != EditEventHelper.ATTENDEE_NO_RESPONSE) {
9182bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            index = findResponseIndexFor(mAttendeeResponseFromIntent);
9192bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
9202bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            index = findResponseIndexFor(mOriginalAttendeeResponse);
9212bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9222bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        spinner.setSelection(index + mResponseOffset);
9232bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        spinner.setOnItemSelectedListener(this);
9242bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
9252bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9262bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void setTextCommon(View view, int id, CharSequence text) {
9272bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        TextView textView = (TextView) view.findViewById(id);
9282bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (textView == null)
9292bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            return;
9302bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        textView.setText(text);
9312bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
9322bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9332bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    private void setVisibilityCommon(View view, int id, int visibility) {
9342bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        View v = view.findViewById(id);
9352bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (v != null) {
9362bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            v.setVisibility(visibility);
9372bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9382bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        return;
9392bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
9402bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9412bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    /**
9422bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * Taken from com.google.android.gm.HtmlConversationActivity
9432bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     *
9442bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     * Send the intent that shows the Contact info corresponding to the email address.
9452bebde787f9490408ceaf14166de4b016a10daf1Mason Tang     */
9462bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    public void showContactInfo(Attendee attendee, Rect rect) {
9472bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        // First perform lookup query to find existing contact
9482bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        final ContentResolver resolver = getActivity().getContentResolver();
9492bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        final String address = attendee.mEmail;
9502bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        final Uri dataUri = Uri.withAppendedPath(CommonDataKinds.Email.CONTENT_FILTER_URI,
9512bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                Uri.encode(address));
9522bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        final Uri lookupUri = ContactsContract.Data.getContactLookupUri(resolver, dataUri);
9532bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9542bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        if (lookupUri != null) {
9552bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // Found matching contact, trigger QuickContact
9562bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            QuickContact.showQuickContact(getActivity(), rect, lookupUri,
9572bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                    QuickContact.MODE_MEDIUM, null);
9582bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        } else {
9592bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // No matching contact, ask user to create one
9602bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            final Uri mailUri = Uri.fromParts("mailto", address, null);
9612bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, mailUri);
9622bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9632bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // Pass along full E-mail string for possible create dialog
9642bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            Rfc822Token sender = new Rfc822Token(attendee.mName, attendee.mEmail, null);
9652bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            intent.putExtra(Intents.EXTRA_CREATE_DESCRIPTION, sender.toString());
9662bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9672bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            // Only provide personal name hint if we have one
9682bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            final String senderPersonal = attendee.mName;
9692bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            if (!TextUtils.isEmpty(senderPersonal)) {
9702bebde787f9490408ceaf14166de4b016a10daf1Mason Tang                intent.putExtra(Intents.Insert.NAME, senderPersonal);
9712bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            }
9722bebde787f9490408ceaf14166de4b016a10daf1Mason Tang
9732bebde787f9490408ceaf14166de4b016a10daf1Mason Tang            startActivity(intent);
9742bebde787f9490408ceaf14166de4b016a10daf1Mason Tang        }
9752bebde787f9490408ceaf14166de4b016a10daf1Mason Tang    }
976cb81189e4868769ea016253eca104e46df2f033aErik
977cb81189e4868769ea016253eca104e46df2f033aErik    @Override
978cb81189e4868769ea016253eca104e46df2f033aErik    public void eventsChanged() {
979cb81189e4868769ea016253eca104e46df2f033aErik    }
980cb81189e4868769ea016253eca104e46df2f033aErik
981cb81189e4868769ea016253eca104e46df2f033aErik    @Override
982cb81189e4868769ea016253eca104e46df2f033aErik    public boolean getAllDay() {
983cb81189e4868769ea016253eca104e46df2f033aErik        return false;
984cb81189e4868769ea016253eca104e46df2f033aErik    }
985cb81189e4868769ea016253eca104e46df2f033aErik
986cb81189e4868769ea016253eca104e46df2f033aErik    @Override
987cb81189e4868769ea016253eca104e46df2f033aErik    public long getSelectedTime() {
988cb81189e4868769ea016253eca104e46df2f033aErik        return mStartMillis;
989cb81189e4868769ea016253eca104e46df2f033aErik    }
990cb81189e4868769ea016253eca104e46df2f033aErik
991cb81189e4868769ea016253eca104e46df2f033aErik    @Override
992cb81189e4868769ea016253eca104e46df2f033aErik    public long getSupportedEventTypes() {
993cb81189e4868769ea016253eca104e46df2f033aErik        return EventType.EVENTS_CHANGED;
994cb81189e4868769ea016253eca104e46df2f033aErik    }
995cb81189e4868769ea016253eca104e46df2f033aErik
996cb81189e4868769ea016253eca104e46df2f033aErik    @Override
997cb81189e4868769ea016253eca104e46df2f033aErik    public void goTo(Time time, boolean animate) {
998cb81189e4868769ea016253eca104e46df2f033aErik    }
999cb81189e4868769ea016253eca104e46df2f033aErik
1000cb81189e4868769ea016253eca104e46df2f033aErik    @Override
1001cb81189e4868769ea016253eca104e46df2f033aErik    public void goToToday() {
1002cb81189e4868769ea016253eca104e46df2f033aErik
1003cb81189e4868769ea016253eca104e46df2f033aErik    }
1004cb81189e4868769ea016253eca104e46df2f033aErik
1005cb81189e4868769ea016253eca104e46df2f033aErik    @Override
1006cb81189e4868769ea016253eca104e46df2f033aErik    public void handleEvent(EventInfo event) {
1007cb81189e4868769ea016253eca104e46df2f033aErik        if (event.eventType == EventType.EVENTS_CHANGED) {
1008cb81189e4868769ea016253eca104e46df2f033aErik            // reload the data
1009cb81189e4868769ea016253eca104e46df2f033aErik            mHandler.startQuery(TOKEN_QUERY_EVENT, null, mUri, EVENT_PROJECTION,
1010cb81189e4868769ea016253eca104e46df2f033aErik                    null, null, null);
1011cb81189e4868769ea016253eca104e46df2f033aErik        }
1012cb81189e4868769ea016253eca104e46df2f033aErik
1013cb81189e4868769ea016253eca104e46df2f033aErik    }
10142bebde787f9490408ceaf14166de4b016a10daf1Mason Tang}
1015