14970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan/*
24970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * Copyright (C) 2010 The Android Open Source Project
34970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan *
44970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * Licensed under the Apache License, Version 2.0 (the "License");
54970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * you may not use this file except in compliance with the License.
64970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * You may obtain a copy of the License at
74970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan *
84970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan *      http://www.apache.org/licenses/LICENSE-2.0
94970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan *
104970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * Unless required by applicable law or agreed to in writing, software
114970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * distributed under the License is distributed on an "AS IS" BASIS,
124970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * See the License for the specific language governing permissions and
144970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan * limitations under the License.
154970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan */
164970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan
174970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chanpackage com.android.calendar;
184970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan
191d423f71b999f72b59e0accc483daa3b3c538ad7James Kungimport static android.provider.CalendarContract.EXTRA_EVENT_ALL_DAY;
20a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport static android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME;
21a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErikimport static android.provider.CalendarContract.EXTRA_EVENT_END_TIME;
226bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelsonimport static android.provider.CalendarContract.Attendees.ATTENDEE_STATUS;
239e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan
24ba1b94afd187279623a57417da1ef78efa1217e2Erikimport android.accounts.Account;
257dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFaddenimport android.accounts.AccountManager;
2683b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chanimport android.app.Activity;
276d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawaimport android.app.SearchManager;
286d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawaimport android.app.SearchableInfo;
296d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawaimport android.content.ComponentName;
30ba1b94afd187279623a57417da1ef78efa1217e2Erikimport android.content.ContentResolver;
319e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chanimport android.content.ContentUris;
32ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chanimport android.content.Context;
339e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chanimport android.content.Intent;
349e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chanimport android.net.Uri;
35ba1b94afd187279623a57417da1ef78efa1217e2Erikimport android.os.Bundle;
366bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelsonimport android.provider.CalendarContract.Attendees;
37a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Calendars;
38a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.Events;
394970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chanimport android.text.format.Time;
4083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chanimport android.util.Log;
413864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErikimport android.util.Pair;
4283b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
431d423f71b999f72b59e0accc483daa3b3c538ad7James Kungimport com.android.calendar.event.EditEventActivity;
441d423f71b999f72b59e0accc483daa3b3c538ad7James Kungimport com.android.calendar.selectcalendars.SelectVisibleCalendarsActivity;
451d423f71b999f72b59e0accc483daa3b3c538ad7James Kung
46a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowskiimport java.lang.ref.WeakReference;
473f348f3ea8a7927566a1283b6d6bb5e220662889Erikimport java.util.Iterator;
483f348f3ea8a7927566a1283b6d6bb5e220662889Erikimport java.util.LinkedHashMap;
49ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chanimport java.util.LinkedList;
503f348f3ea8a7927566a1283b6d6bb5e220662889Erikimport java.util.Map.Entry;
5183b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chanimport java.util.WeakHashMap;
5283b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
5325251192d80159d4cf0934f3ac5c84cb0b8b7365Erikpublic class CalendarController {
5448bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan    private static final boolean DEBUG = false;
5583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    private static final String TAG = "CalendarController";
5683b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
57a7694eead7cbb293990bc89c3906e17bad36194cErik    public static final String EVENT_EDIT_ON_LAUNCH = "editMode";
58a7694eead7cbb293990bc89c3906e17bad36194cErik
59981874e61ecf29a96a77601a3172b2503b6537eeErik    public static final int MIN_CALENDAR_YEAR = 1970;
60981874e61ecf29a96a77601a3172b2503b6537eeErik    public static final int MAX_CALENDAR_YEAR = 2036;
61981874e61ecf29a96a77601a3172b2503b6537eeErik    public static final int MIN_CALENDAR_WEEK = 0;
62981874e61ecf29a96a77601a3172b2503b6537eeErik    public static final int MAX_CALENDAR_WEEK = 3497; // weeks between 1/1/1970 and 1/1/2037
63981874e61ecf29a96a77601a3172b2503b6537eeErik
646bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    private final Context mContext;
65ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan
663f348f3ea8a7927566a1283b6d6bb5e220662889Erik    // This uses a LinkedHashMap so that we can replace fragments based on the
673f348f3ea8a7927566a1283b6d6bb5e220662889Erik    // view id they are being expanded into since we can't guarantee a reference
683f348f3ea8a7927566a1283b6d6bb5e220662889Erik    // to the handler will be findable
696bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    private final LinkedHashMap<Integer,EventHandler> eventHandlers =
703f348f3ea8a7927566a1283b6d6bb5e220662889Erik            new LinkedHashMap<Integer,EventHandler>(5);
716bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    private final LinkedList<Integer> mToBeRemovedEventHandlers = new LinkedList<Integer>();
726bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    private final LinkedHashMap<Integer, EventHandler> mToBeAddedEventHandlers = new LinkedHashMap<
73cb81189e4868769ea016253eca104e46df2f033aErik            Integer, EventHandler>();
743864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik    private Pair<Integer, EventHandler> mFirstEventHandler;
753864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik    private Pair<Integer, EventHandler> mToBeAddedFirstEventHandler;
76ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson    private volatile int mDispatchInProgressCounter = 0;
7783b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
78a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski    private static WeakHashMap<Context, WeakReference<CalendarController>> instances =
79a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski        new WeakHashMap<Context, WeakReference<CalendarController>>();
800558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan
816bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    private final WeakHashMap<Object, Long> filters = new WeakHashMap<Object, Long>(1);
824970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan
833458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan    private int mViewType = -1;
8485e550966b125220af5faa7407a0cfc0b54494aaMichael Chan    private int mDetailViewType = -1;
85ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan    private int mPreviousViewType = -1;
867b92da258a480284dcc15a518ea570072329a31dErik    private long mEventId = -1;
876bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    private final Time mTime = new Time();
88c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik    private long mDateFlags = 0;
893458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan
906bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    private final Runnable mUpdateTimezone = new Runnable() {
914679f6009e8d754e4d76c68a0c5a0a32b23f7f0cRoboErik        @Override
924679f6009e8d754e4d76c68a0c5a0a32b23f7f0cRoboErik        public void run() {
934679f6009e8d754e4d76c68a0c5a0a32b23f7f0cRoboErik            mTime.switchTimezone(Utils.getTimeZone(mContext, this));
944679f6009e8d754e4d76c68a0c5a0a32b23f7f0cRoboErik        }
954679f6009e8d754e4d76c68a0c5a0a32b23f7f0cRoboErik    };
964679f6009e8d754e4d76c68a0c5a0a32b23f7f0cRoboErik
974970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan    /**
9883b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * One of the event types that are sent to or from the controller
994970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan     */
10025251192d80159d4cf0934f3ac5c84cb0b8b7365Erik    public interface EventType {
1019e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        final long CREATE_EVENT = 1L;
102deced8999da73effe4133e2317c262fea7910090Michael Chan
103deced8999da73effe4133e2317c262fea7910090Michael Chan        // Simple view of an event
10483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        final long VIEW_EVENT = 1L << 1;
105deced8999da73effe4133e2317c262fea7910090Michael Chan
106deced8999da73effe4133e2317c262fea7910090Michael Chan        // Full detail view in read only mode
107deced8999da73effe4133e2317c262fea7910090Michael Chan        final long VIEW_EVENT_DETAILS = 1L << 2;
108deced8999da73effe4133e2317c262fea7910090Michael Chan
109a7694eead7cbb293990bc89c3906e17bad36194cErik        // full detail view in edit mode
110deced8999da73effe4133e2317c262fea7910090Michael Chan        final long EDIT_EVENT = 1L << 3;
111deced8999da73effe4133e2317c262fea7910090Michael Chan
112deced8999da73effe4133e2317c262fea7910090Michael Chan        final long DELETE_EVENT = 1L << 4;
11383b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
114deced8999da73effe4133e2317c262fea7910090Michael Chan        final long GO_TO = 1L << 5;
11583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
116deced8999da73effe4133e2317c262fea7910090Michael Chan        final long LAUNCH_SETTINGS = 1L << 6;
117954c871f4753d3182314d7027c0dd17c236d9ca7Erik
118deced8999da73effe4133e2317c262fea7910090Michael Chan        final long EVENTS_CHANGED = 1L << 7;
1194003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
120deced8999da73effe4133e2317c262fea7910090Michael Chan        final long SEARCH = 1L << 8;
1217b92da258a480284dcc15a518ea570072329a31dErik
1227b92da258a480284dcc15a518ea570072329a31dErik        // User has pressed the home key
123deced8999da73effe4133e2317c262fea7910090Michael Chan        final long USER_HOME = 1L << 9;
124eaafa2b48be7194a61754604ae37b3d62e9118d8Erik
125eaafa2b48be7194a61754604ae37b3d62e9118d8Erik        // date range has changed, update the title
126eaafa2b48be7194a61754604ae37b3d62e9118d8Erik        final long UPDATE_TITLE = 1L << 10;
1272aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan
1282aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan        // select which calendars to display
1292aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan        final long LAUNCH_SELECT_VISIBLE_CALENDARS = 1L << 11;
13083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
1314970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan
1324970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan    /**
13383b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * One of the Agenda/Day/Week/Month view types
1344970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan     */
13525251192d80159d4cf0934f3ac5c84cb0b8b7365Erik    public interface ViewType {
136d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan        final int DETAIL = -1;
1373458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        final int CURRENT = 0;
1383458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        final int AGENDA = 1;
1393458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        final int DAY = 2;
1403458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        final int WEEK = 3;
1413458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        final int MONTH = 4;
142dd95df57c8c5a58a85c4c0effad5652dec14f621Erik        final int EDIT = 5;
14321270b873715d23159bc26b0caadfa5cb4d916b4Isaac Katzenelson        final int MAX_VALUE = 5;
14483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
14583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
14625251192d80159d4cf0934f3ac5c84cb0b8b7365Erik    public static class EventInfo {
1476bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson
1486bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        private static final long ATTENTEE_STATUS_MASK = 0xFF;
1496bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        private static final long ALL_DAY_MASK = 0x100;
1506bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        private static final int ATTENDEE_STATUS_NONE_MASK = 0x01;
1516bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        private static final int ATTENDEE_STATUS_ACCEPTED_MASK = 0x02;
1526bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        private static final int ATTENDEE_STATUS_DECLINED_MASK = 0x04;
1536bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        private static final int ATTENDEE_STATUS_TENTATIVE_MASK = 0x08;
1546bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson
15500b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang        public long eventType; // one of the EventType
15600b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang        public int viewType; // one of the ViewType
15700b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang        public long id; // event id
15800b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang        public Time selectedTime; // the selected time in focus
1591d423f71b999f72b59e0accc483daa3b3c538ad7James Kung
1601d423f71b999f72b59e0accc483daa3b3c538ad7James Kung        // Event start and end times.  All-day events are represented in:
1611d423f71b999f72b59e0accc483daa3b3c538ad7James Kung        // - local time for GO_TO commands
1621d423f71b999f72b59e0accc483daa3b3c538ad7James Kung        // - UTC time for VIEW_EVENT and other event-related commands
1631d423f71b999f72b59e0accc483daa3b3c538ad7James Kung        public Time startTime;
1641d423f71b999f72b59e0accc483daa3b3c538ad7James Kung        public Time endTime;
1651d423f71b999f72b59e0accc483daa3b3c538ad7James Kung
16600b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang        public int x; // x coordinate in the activity space
16700b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang        public int y; // y coordinate in the activity space
16800b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tang        public String query; // query for a user search
1696d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        public ComponentName componentName;  // used in combination with query
17009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        public String eventTitle;
17109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        public long calendarId;
17246a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan
17346a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan        /**
17446a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan         * For EventType.VIEW_EVENT:
1756bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson         * It is the default attendee response and an all day event indicator.
1766bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson         * Set to Attendees.ATTENDEE_STATUS_NONE, Attendees.ATTENDEE_STATUS_ACCEPTED,
1776bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson         * Attendees.ATTENDEE_STATUS_DECLINED, or Attendees.ATTENDEE_STATUS_TENTATIVE.
1786bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson         * To signal the event is an all-day event, "or" ALL_DAY_MASK with the response.
1796bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson         * Alternatively, use buildViewExtraLong(), getResponse(), and isAllDay().
18046a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan         * <p>
181edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan         * For EventType.CREATE_EVENT:
182edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan         * Set to {@link #EXTRA_CREATE_ALL_DAY} for creating an all-day event.
183edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan         * <p>
18446a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan         * For EventType.GO_TO:
18546a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan         * Set to {@link #EXTRA_GOTO_TIME} to go to the specified date/time.
18646a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan         * Set to {@link #EXTRA_GOTO_DATE} to consider the date but ignore the time.
187fb0ec227f0d4b3108438c88a6b6d234f5e40fb5cMichael Chan         * Set to {@link #EXTRA_GOTO_BACK_TO_PREVIOUS} if back should bring back previous view.
1885b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik         * Set to {@link #EXTRA_GOTO_TODAY} if this is a user request to go to the current time.
189fb0ec227f0d4b3108438c88a6b6d234f5e40fb5cMichael Chan         * <p>
190fb0ec227f0d4b3108438c88a6b6d234f5e40fb5cMichael Chan         * For EventType.UPDATE_TITLE:
191fb0ec227f0d4b3108438c88a6b6d234f5e40fb5cMichael Chan         * Set formatting flags for Utils.formatDateRange
19246a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan         */
19346a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan        public long extraLong;
1946bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson
1956bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        public boolean isAllDay() {
1966bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            if (eventType != EventType.VIEW_EVENT) {
1976bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                Log.wtf(TAG, "illegal call to isAllDay , wrong event type " + eventType);
1986bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                return false;
1996bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            }
2006bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            return ((extraLong & ALL_DAY_MASK) != 0) ? true : false;
2016bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        }
2026bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson
2036bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        public  int getResponse() {
2046bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            if (eventType != EventType.VIEW_EVENT) {
2056bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                Log.wtf(TAG, "illegal call to getResponse , wrong event type " + eventType);
2066bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                return Attendees.ATTENDEE_STATUS_NONE;
2076bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            }
2086bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson
2096bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            int response = (int)(extraLong & ATTENTEE_STATUS_MASK);
2106bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            switch (response) {
2116bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                case ATTENDEE_STATUS_NONE_MASK:
2126bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    return Attendees.ATTENDEE_STATUS_NONE;
2136bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                case ATTENDEE_STATUS_ACCEPTED_MASK:
2146bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    return Attendees.ATTENDEE_STATUS_ACCEPTED;
2156bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                case ATTENDEE_STATUS_DECLINED_MASK:
2166bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    return Attendees.ATTENDEE_STATUS_DECLINED;
2176bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                case ATTENDEE_STATUS_TENTATIVE_MASK:
2186bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    return Attendees.ATTENDEE_STATUS_TENTATIVE;
2196bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                default:
2206bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    Log.wtf(TAG,"Unknown attendee response " + response);
2216bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            }
2226bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            return ATTENDEE_STATUS_NONE_MASK;
2236bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        }
2246bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson
2256bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        // Used to build the extra long for a VIEW event.
2266bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        public static long buildViewExtraLong(int response, boolean allDay) {
2276bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            long extra = allDay ? ALL_DAY_MASK : 0;
2286bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson
2296bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            switch (response) {
2306bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                case Attendees.ATTENDEE_STATUS_NONE:
2316bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    extra |= ATTENDEE_STATUS_NONE_MASK;
2326bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    break;
2336bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                case Attendees.ATTENDEE_STATUS_ACCEPTED:
2346bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    extra |= ATTENDEE_STATUS_ACCEPTED_MASK;
2356bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    break;
2366bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                case Attendees.ATTENDEE_STATUS_DECLINED:
2376bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    extra |= ATTENDEE_STATUS_DECLINED_MASK;
2386bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    break;
2396bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                case Attendees.ATTENDEE_STATUS_TENTATIVE:
2406bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    extra |= ATTENDEE_STATUS_TENTATIVE_MASK;
2416bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    break;
2426bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                default:
2436bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    Log.wtf(TAG,"Unknown attendee response " + response);
2446bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    extra |= ATTENDEE_STATUS_NONE_MASK;
2456bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                    break;
2466bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            }
2476bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson            return extra;
2486bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        }
24983b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
25083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
25146a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan    /**
252edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan     * Pass to the ExtraLong parameter for EventType.CREATE_EVENT to create
253edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan     * an all-day event
254edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan     */
255edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan    public static final long EXTRA_CREATE_ALL_DAY = 0x10;
256edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan
257edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan    /**
25846a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan     * Pass to the ExtraLong parameter for EventType.GO_TO to signal the time
25946a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan     * can be ignored
26046a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan     */
26146a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan    public static final long EXTRA_GOTO_DATE = 1;
262fb0ec227f0d4b3108438c88a6b6d234f5e40fb5cMichael Chan    public static final long EXTRA_GOTO_TIME = 2;
263fb0ec227f0d4b3108438c88a6b6d234f5e40fb5cMichael Chan    public static final long EXTRA_GOTO_BACK_TO_PREVIOUS = 4;
2645b872523e28fc778a3fc34e7e9096ca1197c6509RoboErik    public static final long EXTRA_GOTO_TODAY = 8;
26546a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan
26625251192d80159d4cf0934f3ac5c84cb0b8b7365Erik    public interface EventHandler {
26783b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        long getSupportedEventTypes();
26883b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        void handleEvent(EventInfo event);
26983b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
27083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        /**
271954c871f4753d3182314d7027c0dd17c236d9ca7Erik         * This notifies the handler that the database has changed and it should
272954c871f4753d3182314d7027c0dd17c236d9ca7Erik         * update its view.
27383b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan         */
27483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        void eventsChanged();
27583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
27683b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
2770558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan    /**
2780558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan     * Creates and/or returns an instance of CalendarController associated with
2790558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan     * the supplied context. It is best to pass in the current Activity.
2800558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan     *
2810558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan     * @param context The activity if at all possible.
2820558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan     */
2830558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan    public static CalendarController getInstance(Context context) {
2840558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan        synchronized (instances) {
285a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski            CalendarController controller = null;
286a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski            WeakReference<CalendarController> weakController = instances.get(context);
287a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski            if (weakController != null) {
288a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski                controller = weakController.get();
289a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski            }
290a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski
2910558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan            if (controller == null) {
2920558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan                controller = new CalendarController(context);
293a8ad418a0552a03f40b1976b874044a99a5cba1cPaul Sliwowski                instances.put(context, new WeakReference(controller));
2940558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan            }
2950558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan            return controller;
2960558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan        }
2970558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan    }
2980558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan
299ed61b48c048c5e8f6646f528561988fd25fe7416Erik    /**
300ed61b48c048c5e8f6646f528561988fd25fe7416Erik     * Removes an instance when it is no longer needed. This should be called in
301ed61b48c048c5e8f6646f528561988fd25fe7416Erik     * an activity's onDestroy method.
302ed61b48c048c5e8f6646f528561988fd25fe7416Erik     *
303ed61b48c048c5e8f6646f528561988fd25fe7416Erik     * @param context The activity used to create the controller
304ed61b48c048c5e8f6646f528561988fd25fe7416Erik     */
305ed61b48c048c5e8f6646f528561988fd25fe7416Erik    public static void removeInstance(Context context) {
306ed61b48c048c5e8f6646f528561988fd25fe7416Erik        instances.remove(context);
307ed61b48c048c5e8f6646f528561988fd25fe7416Erik    }
308ed61b48c048c5e8f6646f528561988fd25fe7416Erik
3090558defd2215696cee0768ce2bf2cb4da56efc42Michael Chan    private CalendarController(Context context) {
310ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        mContext = context;
3114679f6009e8d754e4d76c68a0c5a0a32b23f7f0cRoboErik        mUpdateTimezone.run();
3123458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        mTime.setToNow();
31385e550966b125220af5faa7407a0cfc0b54494aaMichael Chan        mDetailViewType = Utils.getSharedPreference(mContext,
3144b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa                GeneralPreferences.KEY_DETAILED_VIEW,
3154b441bd6544fe6d11be75f974a41afd8fa040a4fDaisuke Miyakawa                GeneralPreferences.DEFAULT_DETAILED_VIEW);
31683b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
3174970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan
318deced8999da73effe4133e2317c262fea7910090Michael Chan    public void sendEventRelatedEvent(Object sender, long eventType, long eventId, long startMillis,
31987f993ff96172f508d3f241f8a425f953c7eb739RoboErik            long endMillis, int x, int y, long selectedMillis) {
3206bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        // TODO: pass the real allDay status or at least a status that says we don't know the
3216bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        // status and have the receiver query the data.
3226bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        // The current use of this method for VIEW_EVENT is by the day view to show an EventInfo
3236bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        // so currently the missing allDay status has no effect.
324edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan        sendEventRelatedEventWithExtra(sender, eventType, eventId, startMillis, endMillis, x, y,
3256bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                EventInfo.buildViewExtraLong(Attendees.ATTENDEE_STATUS_NONE, false),
3266bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                selectedMillis);
327deced8999da73effe4133e2317c262fea7910090Michael Chan    }
328deced8999da73effe4133e2317c262fea7910090Michael Chan
3294970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan    /**
33083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * Helper for sending New/View/Edit/Delete events
33183b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     *
33283b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param sender object of the caller
33383b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param eventType one of {@link EventType}
33483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param eventId event id
3353458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan     * @param startMillis start time
3363458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan     * @param endMillis end time
33783b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param x x coordinate in the activity space
33883b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param y y coordinate in the activity space
3396bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson     * @param extraLong default response value for the "simple event view" and all day indication.
3406bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson     *        Use Attendees.ATTENDEE_STATUS_NONE for no response.
34187f993ff96172f508d3f241f8a425f953c7eb739RoboErik     * @param selectedMillis The time to specify as selected
3424970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan     */
343edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan    public void sendEventRelatedEventWithExtra(Object sender, long eventType, long eventId,
34487f993ff96172f508d3f241f8a425f953c7eb739RoboErik            long startMillis, long endMillis, int x, int y, long extraLong, long selectedMillis) {
34509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        sendEventRelatedEventWithExtraWithTitleWithCalendarId(sender, eventType, eventId,
34609fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            startMillis, endMillis, x, y, extraLong, selectedMillis, null, -1);
34709fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    }
34809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung
34909fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    /**
35009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * Helper for sending New/View/Edit/Delete events
35109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     *
35209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param sender object of the caller
35309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param eventType one of {@link EventType}
35409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param eventId event id
35509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param startMillis start time
35609fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param endMillis end time
35709fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param x x coordinate in the activity space
35809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param y y coordinate in the activity space
35909fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param extraLong default response value for the "simple event view" and all day indication.
36009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     *        Use Attendees.ATTENDEE_STATUS_NONE for no response.
36109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param selectedMillis The time to specify as selected
36209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param title The title of the event
36309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     * @param calendarId The id of the calendar which the event belongs to
36409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung     */
36509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    public void sendEventRelatedEventWithExtraWithTitleWithCalendarId(Object sender, long eventType,
36609fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung          long eventId, long startMillis, long endMillis, int x, int y, long extraLong,
36709fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung          long selectedMillis, String title, long calendarId) {
36883b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        EventInfo info = new EventInfo();
36983b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.eventType = eventType;
370a7694eead7cbb293990bc89c3906e17bad36194cErik        if (eventType == EventType.EDIT_EVENT || eventType == EventType.VIEW_EVENT_DETAILS) {
3715f62079ab9daefe95ede87631766e99e8b4a2220Erik            info.viewType = ViewType.CURRENT;
372dd95df57c8c5a58a85c4c0effad5652dec14f621Erik        }
37309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung
37483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.id = eventId;
375f068eabefac222bba99f3967bcbf7869be1065b1James Kung        info.startTime = new Time(Utils.getTimeZone(mContext, mUpdateTimezone));
3769e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        info.startTime.set(startMillis);
37787f993ff96172f508d3f241f8a425f953c7eb739RoboErik        if (selectedMillis != -1) {
3784679f6009e8d754e4d76c68a0c5a0a32b23f7f0cRoboErik            info.selectedTime = new Time(Utils.getTimeZone(mContext, mUpdateTimezone));
37987f993ff96172f508d3f241f8a425f953c7eb739RoboErik            info.selectedTime.set(selectedMillis);
38087f993ff96172f508d3f241f8a425f953c7eb739RoboErik        } else {
38187f993ff96172f508d3f241f8a425f953c7eb739RoboErik            info.selectedTime = info.startTime;
38287f993ff96172f508d3f241f8a425f953c7eb739RoboErik        }
383f068eabefac222bba99f3967bcbf7869be1065b1James Kung        info.endTime = new Time(Utils.getTimeZone(mContext, mUpdateTimezone));
3849e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        info.endTime.set(endMillis);
38583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.x = x;
38683b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.y = y;
387deced8999da73effe4133e2317c262fea7910090Michael Chan        info.extraLong = extraLong;
38809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        info.eventTitle = title;
38909fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        info.calendarId = calendarId;
39083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        this.sendEvent(sender, info);
39183b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
3924970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan    /**
39383b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * Helper for sending non-calendar-event events
39483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     *
39583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param sender object of the caller
39683b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param eventType one of {@link EventType}
39783b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param start start time
39883b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param end end time
399d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan     * @param eventId event id
40083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan     * @param viewType {@link ViewType}
4014970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan     */
40225251192d80159d4cf0934f3ac5c84cb0b8b7365Erik    public void sendEvent(Object sender, long eventType, Time start, Time end, long eventId,
4033458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan            int viewType) {
404f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        sendEvent(sender, eventType, start, end, start, eventId, viewType, EXTRA_GOTO_TIME, null,
405f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                null);
4066d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    }
4076d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa
4086d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    /**
40946a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan     * sendEvent() variant with extraLong, search query, and search component name.
4106d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa     */
4116d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    public void sendEvent(Object sender, long eventType, Time start, Time end, long eventId,
41246a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan            int viewType, long extraLong, String query, ComponentName componentName) {
413f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        sendEvent(sender, eventType, start, end, start, eventId, viewType, extraLong, query,
414f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                componentName);
415f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan    }
416f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan
417f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan    public void sendEvent(Object sender, long eventType, Time start, Time end, Time selected,
418f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan            long eventId, int viewType, long extraLong, String query, ComponentName componentName) {
41983b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        EventInfo info = new EventInfo();
42083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.eventType = eventType;
42183b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.startTime = start;
422f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        info.selectedTime = selected;
42383b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.endTime = end;
42483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.id = eventId;
42583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        info.viewType = viewType;
4266d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        info.query = query;
4276d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        info.componentName = componentName;
42846a8b1117b0510a8dfd50586d5d22aa86b8dc1b9Michael Chan        info.extraLong = extraLong;
42983b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        this.sendEvent(sender, info);
43083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
43183b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
43225251192d80159d4cf0934f3ac5c84cb0b8b7365Erik    public void sendEvent(Object sender, final EventInfo event) {
43383b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        // TODO Throw exception on invalid events
43483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
4353f348f3ea8a7927566a1283b6d6bb5e220662889Erik        if (DEBUG) {
436f068eabefac222bba99f3967bcbf7869be1065b1James Kung            Log.d(TAG, eventInfoToString(event));
4373f348f3ea8a7927566a1283b6d6bb5e220662889Erik        }
43883b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
43983b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        Long filteredTypes = filters.get(sender);
44083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        if (filteredTypes != null && (filteredTypes.longValue() & event.eventType) != 0) {
44183b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan            // Suppress event per filter
4423f348f3ea8a7927566a1283b6d6bb5e220662889Erik            if (DEBUG) {
4433f348f3ea8a7927566a1283b6d6bb5e220662889Erik                Log.d(TAG, "Event suppressed");
4443f348f3ea8a7927566a1283b6d6bb5e220662889Erik            }
44583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan            return;
44683b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        }
44783b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
448ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        mPreviousViewType = mViewType;
44983b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
4503458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        // Fix up view if not specified
451d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan        if (event.viewType == ViewType.DETAIL) {
45285e550966b125220af5faa7407a0cfc0b54494aaMichael Chan            event.viewType = mDetailViewType;
45385e550966b125220af5faa7407a0cfc0b54494aaMichael Chan            mViewType = mDetailViewType;
454d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan        } else if (event.viewType == ViewType.CURRENT) {
4553458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan            event.viewType = mViewType;
456f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        } else if (event.viewType != ViewType.EDIT) {
457ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan            mViewType = event.viewType;
45885e550966b125220af5faa7407a0cfc0b54494aaMichael Chan
45963cd053150e00fde045b019dbe0f48b8a9ed3559Erik            if (event.viewType == ViewType.AGENDA || event.viewType == ViewType.DAY
46063cd053150e00fde045b019dbe0f48b8a9ed3559Erik                    || (Utils.getAllowWeekForDetailView() && event.viewType == ViewType.WEEK)) {
46185e550966b125220af5faa7407a0cfc0b54494aaMichael Chan                mDetailViewType = mViewType;
46285e550966b125220af5faa7407a0cfc0b54494aaMichael Chan            }
4633458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        }
4643458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan
465f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        if (DEBUG) {
46648bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "vvvvvvvvvvvvvvv");
46748bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "Start  " + (event.startTime == null ? "null" : event.startTime.toString()));
46848bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "End    " + (event.endTime == null ? "null" : event.endTime.toString()));
46948bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "Select " + (event.selectedTime == null ? "null" : event.selectedTime.toString()));
47048bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "mTime  " + (mTime == null ? "null" : mTime.toString()));
471f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        }
472f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan
473f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        long startMillis = 0;
474f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        if (event.startTime != null) {
475f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan            startMillis = event.startTime.toMillis(false);
476f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        }
477f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan
478f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        // Set mTime if selectedTime is set
479f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        if (event.selectedTime != null && event.selectedTime.toMillis(false) != 0) {
480f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan            mTime.set(event.selectedTime);
481f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        } else {
482f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan            if (startMillis != 0) {
483f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                // selectedTime is not set so set mTime to startTime iff it is not
484f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                // within start and end times
485f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                long mtimeMillis = mTime.toMillis(false);
486f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                if (mtimeMillis < startMillis
487f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                        || (event.endTime != null && mtimeMillis > event.endTime.toMillis(false))) {
488f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                    mTime.set(event.startTime);
489f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan                }
490f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan            }
491f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan            event.selectedTime = mTime;
492f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        }
493c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik        // Store the formatting flags if this is an update to the title
494c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik        if (event.eventType == EventType.UPDATE_TITLE) {
495c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik            mDateFlags = event.extraLong;
496c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik        }
497f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan
4984003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        // Fix up start time if not specified
499f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        if (startMillis == 0) {
500f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan            event.startTime = mTime;
501f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        }
502f0868f61983ff1b04a49f1b6f2ef6d49311011e8Michael Chan        if (DEBUG) {
50348bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "Start  " + (event.startTime == null ? "null" : event.startTime.toString()));
50448bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "End    " + (event.endTime == null ? "null" : event.endTime.toString()));
50548bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "Select " + (event.selectedTime == null ? "null" : event.selectedTime.toString()));
50648bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "mTime  " + (mTime == null ? "null" : mTime.toString()));
50748bcc4cb015dbf802341698a3a04e28d2cfb2ddcMichael Chan            Log.d(TAG, "^^^^^^^^^^^^^^^");
5084003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        }
5094003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
5107b92da258a480284dcc15a518ea570072329a31dErik        // Store the eventId if we're entering edit event
511a7694eead7cbb293990bc89c3906e17bad36194cErik        if ((event.eventType
512a7694eead7cbb293990bc89c3906e17bad36194cErik                & (EventType.CREATE_EVENT | EventType.EDIT_EVENT | EventType.VIEW_EVENT_DETAILS))
513a7694eead7cbb293990bc89c3906e17bad36194cErik                != 0) {
5147b92da258a480284dcc15a518ea570072329a31dErik            if (event.id > 0) {
5157b92da258a480284dcc15a518ea570072329a31dErik                mEventId = event.id;
5167b92da258a480284dcc15a518ea570072329a31dErik            } else {
5177b92da258a480284dcc15a518ea570072329a31dErik                mEventId = -1;
5187b92da258a480284dcc15a518ea570072329a31dErik            }
5197b92da258a480284dcc15a518ea570072329a31dErik        }
5207b92da258a480284dcc15a518ea570072329a31dErik
5214003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        boolean handled = false;
522ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        synchronized (this) {
523ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            mDispatchInProgressCounter ++;
524ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan
5253f348f3ea8a7927566a1283b6d6bb5e220662889Erik            if (DEBUG) {
5263f348f3ea8a7927566a1283b6d6bb5e220662889Erik                Log.d(TAG, "sendEvent: Dispatching to " + eventHandlers.size() + " handlers");
5273f348f3ea8a7927566a1283b6d6bb5e220662889Erik            }
528ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan            // Dispatch to event handler(s)
5293864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik            if (mFirstEventHandler != null) {
5303864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                // Handle the 'first' one before handling the others
5313864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                EventHandler handler = mFirstEventHandler.second;
5323864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                if (handler != null && (handler.getSupportedEventTypes() & event.eventType) != 0
5333864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                        && !mToBeRemovedEventHandlers.contains(mFirstEventHandler.first)) {
5343864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                    handler.handleEvent(event);
5353864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                    handled = true;
5363864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                }
5373864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik            }
5383f348f3ea8a7927566a1283b6d6bb5e220662889Erik            for (Iterator<Entry<Integer, EventHandler>> handlers =
5393f348f3ea8a7927566a1283b6d6bb5e220662889Erik                    eventHandlers.entrySet().iterator(); handlers.hasNext();) {
5403f348f3ea8a7927566a1283b6d6bb5e220662889Erik                Entry<Integer, EventHandler> entry = handlers.next();
5413f348f3ea8a7927566a1283b6d6bb5e220662889Erik                int key = entry.getKey();
5423864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                if (mFirstEventHandler != null && key == mFirstEventHandler.first) {
5433864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                    // If this was the 'first' handler it was already handled
5443864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                    continue;
5453864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                }
5463f348f3ea8a7927566a1283b6d6bb5e220662889Erik                EventHandler eventHandler = entry.getValue();
547ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan                if (eventHandler != null
548ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan                        && (eventHandler.getSupportedEventTypes() & event.eventType) != 0) {
5493f348f3ea8a7927566a1283b6d6bb5e220662889Erik                    if (mToBeRemovedEventHandlers.contains(key)) {
550ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan                        continue;
551ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan                    }
552ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan                    eventHandler.handleEvent(event);
5534003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                    handled = true;
554ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan                }
555ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan            }
5563458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan
557ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            mDispatchInProgressCounter --;
558cb81189e4868769ea016253eca104e46df2f033aErik
559ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            if (mDispatchInProgressCounter == 0) {
560ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson
561ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                // Deregister removed handlers
562ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                if (mToBeRemovedEventHandlers.size() > 0) {
563ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                    for (Integer zombie : mToBeRemovedEventHandlers) {
564ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                        eventHandlers.remove(zombie);
5653864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                        if (mFirstEventHandler != null && zombie.equals(mFirstEventHandler.first)) {
5663864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                            mFirstEventHandler = null;
5673864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                        }
568ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                    }
569ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                    mToBeRemovedEventHandlers.clear();
57083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan                }
571ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                // Add new handlers
5723864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                if (mToBeAddedFirstEventHandler != null) {
5733864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                    mFirstEventHandler = mToBeAddedFirstEventHandler;
5743864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                    mToBeAddedFirstEventHandler = null;
5753864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                }
576ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                if (mToBeAddedEventHandlers.size() > 0) {
577ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                    for (Entry<Integer, EventHandler> food : mToBeAddedEventHandlers.entrySet()) {
578ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                        eventHandlers.put(food.getKey(), food.getValue());
579ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson                    }
580cb81189e4868769ea016253eca104e46df2f033aErik                }
581cb81189e4868769ea016253eca104e46df2f033aErik            }
58283b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        }
5834003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
5844003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        if (!handled) {
5856b858fc6f8afad95a075595016c5c22547924886Erik            // Launch Settings
5866b858fc6f8afad95a075595016c5c22547924886Erik            if (event.eventType == EventType.LAUNCH_SETTINGS) {
5874003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                launchSettings();
5884003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                return;
5894003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            }
5904003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang
5912aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan            // Launch Calendar Visible Selector
5922aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan            if (event.eventType == EventType.LAUNCH_SELECT_VISIBLE_CALENDARS) {
5932aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan                launchSelectVisibleCalendars();
5942aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan                return;
5952aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan            }
5962aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan
5974003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            // Create/View/Edit/Delete Event
5984003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            long endTime = (event.endTime == null) ? -1 : event.endTime.toMillis(false);
5994003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            if (event.eventType == EventType.CREATE_EVENT) {
600edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan                launchCreateEvent(event.startTime.toMillis(false), endTime,
60109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung                        event.extraLong == EXTRA_CREATE_ALL_DAY, event.eventTitle,
60209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung                        event.calendarId);
6034003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                return;
6044003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            } else if (event.eventType == EventType.VIEW_EVENT) {
6056bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                launchViewEvent(event.id, event.startTime.toMillis(false), endTime,
6066bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson                        event.getResponse());
6074003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                return;
6084003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            } else if (event.eventType == EventType.EDIT_EVENT) {
609a7694eead7cbb293990bc89c3906e17bad36194cErik                launchEditEvent(event.id, event.startTime.toMillis(false), endTime, true);
610a7694eead7cbb293990bc89c3906e17bad36194cErik                return;
611a7694eead7cbb293990bc89c3906e17bad36194cErik            } else if (event.eventType == EventType.VIEW_EVENT_DETAILS) {
612a7694eead7cbb293990bc89c3906e17bad36194cErik                launchEditEvent(event.id, event.startTime.toMillis(false), endTime, false);
6134003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                return;
6144003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            } else if (event.eventType == EventType.DELETE_EVENT) {
6154003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                launchDeleteEvent(event.id, event.startTime.toMillis(false), endTime);
6164003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang                return;
6176d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa            } else if (event.eventType == EventType.SEARCH) {
6186d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa                launchSearch(event.id, event.query, event.componentName);
6196d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa                return;
6204003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            }
6214003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        }
62283b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
62383b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
6243f348f3ea8a7927566a1283b6d6bb5e220662889Erik    /**
6253f348f3ea8a7927566a1283b6d6bb5e220662889Erik     * Adds or updates an event handler. This uses a LinkedHashMap so that we can
6263f348f3ea8a7927566a1283b6d6bb5e220662889Erik     * replace fragments based on the view id they are being expanded into.
6273f348f3ea8a7927566a1283b6d6bb5e220662889Erik     *
6283f348f3ea8a7927566a1283b6d6bb5e220662889Erik     * @param key The view id or placeholder for this handler
6293f348f3ea8a7927566a1283b6d6bb5e220662889Erik     * @param eventHandler Typically a fragment or activity in the calendar app
6303f348f3ea8a7927566a1283b6d6bb5e220662889Erik     */
6313f348f3ea8a7927566a1283b6d6bb5e220662889Erik    public void registerEventHandler(int key, EventHandler eventHandler) {
632ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        synchronized (this) {
633ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            if (mDispatchInProgressCounter > 0) {
634cb81189e4868769ea016253eca104e46df2f033aErik                mToBeAddedEventHandlers.put(key, eventHandler);
635cb81189e4868769ea016253eca104e46df2f033aErik            } else {
636cb81189e4868769ea016253eca104e46df2f033aErik                eventHandlers.put(key, eventHandler);
637cb81189e4868769ea016253eca104e46df2f033aErik            }
638ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        }
63983b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
64083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
6413864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik    public void registerFirstEventHandler(int key, EventHandler eventHandler) {
6423864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik        synchronized (this) {
6433864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik            registerEventHandler(key, eventHandler);
6443864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik            if (mDispatchInProgressCounter > 0) {
6453864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                mToBeAddedFirstEventHandler = new Pair<Integer, EventHandler>(key, eventHandler);
6463864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik            } else {
6473864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                mFirstEventHandler = new Pair<Integer, EventHandler>(key, eventHandler);
6483864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik            }
6493864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik        }
6503864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik    }
6513864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik
6523f348f3ea8a7927566a1283b6d6bb5e220662889Erik    public void deregisterEventHandler(Integer key) {
653ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        synchronized (this) {
654ccf565b6a00e1df8c0de824ac91e9f6746e246b5Isaac Katzenelson            if (mDispatchInProgressCounter > 0) {
655ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan                // To avoid ConcurrencyException, stash away the event handler for now.
6563f348f3ea8a7927566a1283b6d6bb5e220662889Erik                mToBeRemovedEventHandlers.add(key);
657ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan            } else {
6583f348f3ea8a7927566a1283b6d6bb5e220662889Erik                eventHandlers.remove(key);
6593864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                if (mFirstEventHandler != null && mFirstEventHandler.first == key) {
6603864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                    mFirstEventHandler = null;
6613864be025ed7fa5bcb33c7adaae9267d5b34f17fRoboErik                }
662ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan            }
663ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        }
66483b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
66583b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
66661310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook    public void deregisterAllEventHandlers() {
66761310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook        synchronized (this) {
66861310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook            if (mDispatchInProgressCounter > 0) {
66961310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook                // To avoid ConcurrencyException, stash away the event handler for now.
67061310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook                mToBeRemovedEventHandlers.addAll(eventHandlers.keySet());
67161310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook            } else {
67261310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook                eventHandlers.clear();
67361310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook                mFirstEventHandler = null;
67461310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook            }
67561310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook        }
67661310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook    }
67761310b7263c6d6477f252789f6288991d51ec8ccPaul Westbrook
6783458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan    // FRAG_TODO doesn't work yet
67925251192d80159d4cf0934f3ac5c84cb0b8b7365Erik    public void filterBroadcasts(Object sender, long eventTypes) {
68083b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan        filters.put(sender, eventTypes);
68183b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan    }
68283b0fe36b523192a504a1d2baf2f36676a80b9d5Michael Chan
6838e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang    /**
6848e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang     * @return the time that this controller is currently pointed at
6858e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang     */
6868e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang    public long getTime() {
6878e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang        return mTime.toMillis(false);
6888e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang    }
6898e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang
6907b92da258a480284dcc15a518ea570072329a31dErik    /**
691c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik     * @return the last set of date flags sent with
692c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik     *         {@link EventType#UPDATE_TITLE}
693c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik     */
694c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik    public long getDateFlags() {
695c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik        return mDateFlags;
696c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik    }
697c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik
698c8e0f21af5e2508d6e53a59e0f997dffd6a5321cRoboErik    /**
699144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik     * Set the time this controller is currently pointed at
700144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik     *
701144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik     * @param millisTime Time since epoch in millis
702144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik     */
703144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik    public void setTime(long millisTime) {
704144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik        mTime.set(millisTime);
705144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik    }
706144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik
707144edfa3f69dd13d2ae5f107a8f4d422f11dc620Erik    /**
7087b92da258a480284dcc15a518ea570072329a31dErik     * @return the last event ID the edit view was launched with
7097b92da258a480284dcc15a518ea570072329a31dErik     */
7107b92da258a480284dcc15a518ea570072329a31dErik    public long getEventId() {
7117b92da258a480284dcc15a518ea570072329a31dErik        return mEventId;
7127b92da258a480284dcc15a518ea570072329a31dErik    }
7137b92da258a480284dcc15a518ea570072329a31dErik
714ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan    public int getViewType() {
715ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        return mViewType;
716ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan    }
717ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan
718ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan    public int getPreviousViewType() {
719ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        return mPreviousViewType;
720ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan    }
7218e3d430a020744faa21bf4ca24f1a99c36ec5c4fMason Tang
7222aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan    private void launchSelectVisibleCalendars() {
7232aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan        Intent intent = new Intent(Intent.ACTION_VIEW);
72407d9fee87bc02849c0dd7b66326a320d53cf5479Michael Chan        intent.setClass(mContext, SelectVisibleCalendarsActivity.class);
7252aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan        intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
7262aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan        mContext.startActivity(intent);
7272aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan    }
7282aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan
7299e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    private void launchSettings() {
7309e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        Intent intent = new Intent(Intent.ACTION_VIEW);
73107d9fee87bc02849c0dd7b66326a320d53cf5479Michael Chan        intent.setClass(mContext, CalendarSettingsActivity.class);
7329e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
733ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        mContext.startActivity(intent);
7349e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    }
7359e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan
73609fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    private void launchCreateEvent(long startMillis, long endMillis, boolean allDayEvent,
73709fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            String title, long calendarId) {
73809fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        Intent intent = generateCreateEventIntent(startMillis, endMillis, allDayEvent, title,
73909fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung            calendarId);
74009fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        mEventId = -1;
74109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        mContext.startActivity(intent);
74209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    }
74309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung
74409fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung    public Intent generateCreateEventIntent(long startMillis, long endMillis,
74509fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        boolean allDayEvent, String title, long calendarId) {
7469e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        Intent intent = new Intent(Intent.ACTION_VIEW);
74707d9fee87bc02849c0dd7b66326a320d53cf5479Michael Chan        intent.setClass(mContext, EditEventActivity.class);
748a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
749a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
750edecd9a97e02ff14bd5abeec3414e1bf3cc631dfMichael Chan        intent.putExtra(EXTRA_EVENT_ALL_DAY, allDayEvent);
75109fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        intent.putExtra(Events.CALENDAR_ID, calendarId);
75209fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        intent.putExtra(Events.TITLE, title);
75309fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9James Kung        return intent;
7549e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    }
7559e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan
7566bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson    public void launchViewEvent(long eventId, long startMillis, long endMillis, int response) {
7579e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        Intent intent = new Intent(Intent.ACTION_VIEW);
7589e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
7599e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        intent.setData(eventUri);
76007d9fee87bc02849c0dd7b66326a320d53cf5479Michael Chan        intent.setClass(mContext, AllInOneActivity.class);
761a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
762a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
7636bcafcf4f28c2d1053547694bd60b3dd9c7fbaa1Isaac Katzenelson        intent.putExtra(ATTENDEE_STATUS, response);
7644024dee06fbe7c4bbd5b56e7d58917e86b66802eIsaac Katzenelson        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
765ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        mContext.startActivity(intent);
7669e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    }
7679e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan
768a7694eead7cbb293990bc89c3906e17bad36194cErik    private void launchEditEvent(long eventId, long startMillis, long endMillis, boolean edit) {
7699e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
7709e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        Intent intent = new Intent(Intent.ACTION_EDIT, uri);
771a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis);
772a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik        intent.putExtra(EXTRA_EVENT_END_TIME, endMillis);
773ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        intent.setClass(mContext, EditEventActivity.class);
774a7694eead7cbb293990bc89c3906e17bad36194cErik        intent.putExtra(EVENT_EDIT_ON_LAUNCH, edit);
7757b92da258a480284dcc15a518ea570072329a31dErik        mEventId = eventId;
776ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        mContext.startActivity(intent);
7779e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    }
7789e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan
7791881a896a82c425845e3ef2a1a716d329f0e45f1Michael Chan//    private void launchAlerts() {
7801881a896a82c425845e3ef2a1a716d329f0e45f1Michael Chan//        Intent intent = new Intent();
7811881a896a82c425845e3ef2a1a716d329f0e45f1Michael Chan//        intent.setClass(mContext, AlertActivity.class);
7821881a896a82c425845e3ef2a1a716d329f0e45f1Michael Chan//        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7831881a896a82c425845e3ef2a1a716d329f0e45f1Michael Chan//        mContext.startActivity(intent);
7841881a896a82c425845e3ef2a1a716d329f0e45f1Michael Chan//    }
7851881a896a82c425845e3ef2a1a716d329f0e45f1Michael Chan
7869e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    private void launchDeleteEvent(long eventId, long startMillis, long endMillis) {
7879e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        launchDeleteEventAndFinish(null, eventId, startMillis, endMillis, -1);
7889e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    }
7899e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan
7909e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    private void launchDeleteEventAndFinish(Activity parentActivity, long eventId, long startMillis,
7919e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan            long endMillis, int deleteWhich) {
792ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        DeleteEventHelper deleteEventHelper = new DeleteEventHelper(mContext, parentActivity,
7939e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan                parentActivity != null /* exit when done */);
7949e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan        deleteEventHelper.delete(startMillis, endMillis, eventId, deleteWhich);
7959e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan    }
7963458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan
7976d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    private void launchSearch(long eventId, String query, ComponentName componentName) {
7986d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        final SearchManager searchManager =
7996d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa                (SearchManager)mContext.getSystemService(Context.SEARCH_SERVICE);
8006d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        final SearchableInfo searchableInfo = searchManager.getSearchableInfo(componentName);
8016d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        final Intent intent = new Intent(Intent.ACTION_SEARCH);
8026d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        intent.putExtra(SearchManager.QUERY, query);
8036d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        intent.setComponent(searchableInfo.getSearchActivity());
8042bd5cc06a7a89a848688416456f1b8f915542d57RoboErik        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
8056d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa        mContext.startActivity(intent);
8066d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa    }
8076d2e6f78726cc167e561148a3efb27aa15524b82Daisuke Miyakawa
8087dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden    /**
8097dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden     * Performs a manual refresh of calendars in all known accounts.
8107dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden     */
811ba1b94afd187279623a57417da1ef78efa1217e2Erik    public void refreshCalendars() {
8127dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden        Account[] accounts = AccountManager.get(mContext).getAccounts();
8137dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden        Log.d(TAG, "Refreshing " + accounts.length + " accounts");
8147dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden
8157dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden        String authority = Calendars.CONTENT_URI.getAuthority();
8167dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden        for (int i = 0; i < accounts.length; i++) {
8177dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden            if (Log.isLoggable(TAG, Log.DEBUG)) {
8187dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden                Log.d(TAG, "Refreshing calendars for: " + accounts[i]);
8197dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden            }
8207dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden            Bundle extras = new Bundle();
8217dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden            extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
8227dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden            ContentResolver.requestSync(accounts[i], authority, extras);
8237dcd301cab15959d0d745f0a460f1dce2065d44eAndy McFadden        }
824ba1b94afd187279623a57417da1ef78efa1217e2Erik    }
825ba1b94afd187279623a57417da1ef78efa1217e2Erik
826dd95df57c8c5a58a85c4c0effad5652dec14f621Erik    // Forces the viewType. Should only be used for initialization.
827dd95df57c8c5a58a85c4c0effad5652dec14f621Erik    public void setViewType(int viewType) {
828dd95df57c8c5a58a85c4c0effad5652dec14f621Erik        mViewType = viewType;
829dd95df57c8c5a58a85c4c0effad5652dec14f621Erik    }
830dd95df57c8c5a58a85c4c0effad5652dec14f621Erik
8317b92da258a480284dcc15a518ea570072329a31dErik    // Sets the eventId. Should only be used for initialization.
8327b92da258a480284dcc15a518ea570072329a31dErik    public void setEventId(long eventId) {
8337b92da258a480284dcc15a518ea570072329a31dErik        mEventId = eventId;
8347b92da258a480284dcc15a518ea570072329a31dErik    }
8357b92da258a480284dcc15a518ea570072329a31dErik
836f068eabefac222bba99f3967bcbf7869be1065b1James Kung    private String eventInfoToString(EventInfo eventInfo) {
8373458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        String tmp = "Unknown";
838f068eabefac222bba99f3967bcbf7869be1065b1James Kung
839f068eabefac222bba99f3967bcbf7869be1065b1James Kung        StringBuilder builder = new StringBuilder();
840ab29d9ea9a4fe6b835c7f484a2273e92e8bc323dMichael Chan        if ((eventInfo.eventType & EventType.GO_TO) != 0) {
8413458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan            tmp = "Go to time/event";
8423458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        } else if ((eventInfo.eventType & EventType.CREATE_EVENT) != 0) {
8433458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan            tmp = "New event";
8443458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        } else if ((eventInfo.eventType & EventType.VIEW_EVENT) != 0) {
8453458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan            tmp = "View event";
8466d4ce6ed308da8b4d8f2e62660865e396713c025Michael Chan        } else if ((eventInfo.eventType & EventType.VIEW_EVENT_DETAILS) != 0) {
8476d4ce6ed308da8b4d8f2e62660865e396713c025Michael Chan            tmp = "View details";
8483458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        } else if ((eventInfo.eventType & EventType.EDIT_EVENT) != 0) {
8493458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan            tmp = "Edit event";
8503458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        } else if ((eventInfo.eventType & EventType.DELETE_EVENT) != 0) {
8513458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan            tmp = "Delete event";
8522aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan        } else if ((eventInfo.eventType & EventType.LAUNCH_SELECT_VISIBLE_CALENDARS) != 0) {
8532aeb8d988aa4b65d3402374832613ab977e009dcMichael Chan            tmp = "Launch select visible calendars";
8543458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        } else if ((eventInfo.eventType & EventType.LAUNCH_SETTINGS) != 0) {
8553458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan            tmp = "Launch settings";
8563f348f3ea8a7927566a1283b6d6bb5e220662889Erik        } else if ((eventInfo.eventType & EventType.EVENTS_CHANGED) != 0) {
8573f348f3ea8a7927566a1283b6d6bb5e220662889Erik            tmp = "Refresh events";
8584003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang        } else if ((eventInfo.eventType & EventType.SEARCH) != 0) {
8594003d1cd4d1ebe3863c9d3e92cd4232595183064Mason Tang            tmp = "Search";
8606d4ce6ed308da8b4d8f2e62660865e396713c025Michael Chan        } else if ((eventInfo.eventType & EventType.USER_HOME) != 0) {
8616d4ce6ed308da8b4d8f2e62660865e396713c025Michael Chan            tmp = "Gone home";
8626d4ce6ed308da8b4d8f2e62660865e396713c025Michael Chan        } else if ((eventInfo.eventType & EventType.UPDATE_TITLE) != 0) {
8636d4ce6ed308da8b4d8f2e62660865e396713c025Michael Chan            tmp = "Update title";
8643458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        }
865f068eabefac222bba99f3967bcbf7869be1065b1James Kung        builder.append(tmp);
8663458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(": id=");
8673458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(eventInfo.id);
868d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan        builder.append(", selected=");
869d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan        builder.append(eventInfo.selectedTime);
870d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan        builder.append(", start=");
8713458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(eventInfo.startTime);
872d6734dbbd704cdb1bc331d1bd74b7a3be58f69ffMichael Chan        builder.append(", end=");
8733458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(eventInfo.endTime);
8743458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(", viewType=");
8753458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(eventInfo.viewType);
8763458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(", x=");
8773458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(eventInfo.x);
8783458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(", y=");
8793458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        builder.append(eventInfo.y);
8803458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan        return builder.toString();
8813458a1775920dda53099b7f1913cd4ec4c8b4095Michael Chan    }
8824970159b2e6674fc5d61425aa0fcff8e5fc15bdbMichael Chan}
883