RecurrencePickerDialog.java revision 56f42bfb36d710726051e8268a115697477add61
1b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan/*
2b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * Copyright (C) 2013 The Android Open Source Project
3b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan *
4b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * Licensed under the Apache License, Version 2.0 (the "License");
5b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * you may not use this file except in compliance with the License.
6b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * You may obtain a copy of the License at
7b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan *
8b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan *      http://www.apache.org/licenses/LICENSE-2.0
9b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan *
10b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * Unless required by applicable law or agreed to in writing, software
11b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * distributed under the License is distributed on an "AS IS" BASIS,
12b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * See the License for the specific language governing permissions and
14b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan * limitations under the License.
15b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan */
16b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
17b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanpackage com.android.calendar.recurrencepicker;
18b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
19b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.app.DialogFragment;
20b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.content.res.Resources;
21b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.os.Bundle;
22b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.os.Parcel;
23b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.os.Parcelable;
24b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.text.Editable;
25b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.text.TextUtils;
26b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.text.TextWatcher;
27b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.text.format.DateUtils;
28b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.text.format.Time;
29b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.util.Log;
30b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.util.TimeFormatException;
31b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.view.LayoutInflater;
32b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.view.View;
33b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.view.View.OnClickListener;
34b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.view.ViewGroup;
35b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.AdapterView;
36b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.AdapterView.OnItemSelectedListener;
37b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.ArrayAdapter;
38b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.Button;
39b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.CompoundButton;
40b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.CompoundButton.OnCheckedChangeListener;
41b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.EditText;
42b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chanimport android.widget.ImageButton;
43b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.LinearLayout;
44b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.RadioButton;
45b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.RadioGroup;
46b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.Spinner;
47b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.TextView;
48b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.Toast;
49b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport android.widget.ToggleButton;
50b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
51b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport com.android.calendar.R;
52b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport com.android.calendar.Utils;
53b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport com.android.calendarcommon2.EventRecurrence;
5456f42bfb36d710726051e8268a115697477add61James Kungimport com.android.datetimepicker.date.DatePickerDialog;
55b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
56b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport java.text.DateFormatSymbols;
57b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport java.util.ArrayList;
58b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport java.util.Arrays;
59b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanimport java.util.Calendar;
60b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
61b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chanpublic class RecurrencePickerDialog extends DialogFragment implements OnItemSelectedListener,
62b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        OnCheckedChangeListener, OnClickListener,
63b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        android.widget.RadioGroup.OnCheckedChangeListener, DatePickerDialog.OnDateSetListener {
64b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
65b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final String TAG = "RecurrencePickerDialog";
66b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
67b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // in dp's
68b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    private static final int MIN_SCREEN_WIDTH_FOR_SINGLE_ROW_WEEK = 450;
69b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
70b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Update android:maxLength in EditText as needed
71b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final int INTERVAL_MAX = 99;
72b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final int INTERVAL_DEFAULT = 1;
73b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Update android:maxLength in EditText as needed
74b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final int COUNT_MAX = 730;
75b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final int COUNT_DEFAULT = 5;
76b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
77b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    private static final int DAY_OF_WEEK_CHECKED_TEXT_COLOR = 0xFFFFFFFF;
78b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    private static final int DAY_OF_WEEK_UNCHECKED_TEXT_COLOR = 0xFF000000;
79b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
8056f42bfb36d710726051e8268a115697477add61James Kung    private DatePickerDialog mDatePickerDialog;
8156f42bfb36d710726051e8268a115697477add61James Kung
82b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private class Model implements Parcelable {
83b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
84b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Not repeating
85b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int FREQ_NONE = -1;
86b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
87b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Should match EventRecurrence.DAILY, etc
88b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int FREQ_DAILY = 0;
89b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int FREQ_WEEKLY = 1;
90b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int FREQ_MONTHLY = 2;
91b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int FREQ_YEARLY = 3;
92b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
93b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int END_NEVER = 0;
94b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int END_BY_DATE = 1;
95b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int END_BY_COUNT = 2;
96b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
97b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int MONTHLY_BY_DATE = 0;
98b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        static final int MONTHLY_BY_NTH_DAY_OF_WEEK = 1;
99b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
100b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
101b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * FREQ: Repeat pattern
102b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         *
103b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see FREQ_DAILY
104b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see FREQ_WEEKLY
105b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see FREQ_MONTHLY
106b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see FREQ_YEARLY
107b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
108b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int freq = FREQ_NONE;
109b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
110b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
111b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * INTERVAL: Every n days/weeks/months/years. n >= 1
112b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
113b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int interval = INTERVAL_DEFAULT;
114b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
115b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
116b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * UNTIL and COUNT: How does the the event end?
117b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         *
118b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see END_NEVER
119b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see END_BY_DATE
120b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see END_BY_COUNT
121b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see untilDate
122b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see untilCount
123b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
124b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int end;
125b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
126b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
127b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * UNTIL: Date of the last recurrence. Used when until == END_BY_DATE
128b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
129b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        Time endDate;
130b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
131b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
132b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * COUNT: Times to repeat. Use when until == END_BY_COUNT
133b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
134b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int endCount = COUNT_DEFAULT;
135b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
136b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
137b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * BYDAY: Days of the week to be repeated. Sun = 0, Mon = 1, etc
138b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
139b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        boolean[] weeklyByDayOfWeek = new boolean[7];
140b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
141b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
142b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * BYDAY AND BYMONTHDAY: How to repeat monthly events? Same date of the
143b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * month or Same nth day of week.
144b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         *
145b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see MONTHLY_BY_DATE
146b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * @see MONTHLY_BY_NTH_DAY_OF_WEEK
147b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
148b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int monthlyRepeat;
149b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
150b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
151b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * Day of the month to repeat. Used when monthlyRepeat ==
152b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * MONTHLY_BY_DATE
153b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
154b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int monthlyByMonthDay;
155b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
156b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
157b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * Day of the week to repeat. Used when monthlyRepeat ==
158b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * MONTHLY_BY_NTH_DAY_OF_WEEK
159b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
160b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int monthlyByDayOfWeek;
161b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
162b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /**
163b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * Nth day of the week to repeat. Used when monthlyRepeat ==
164b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * MONTHLY_BY_NTH_DAY_OF_WEEK 0=undefined, 1=1st, 2=2nd, etc
165b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
166b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int monthlyByNthDayOfWeek;
167b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
168b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /*
169b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * (generated method)
170b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
171b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        @Override
172b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        public String toString() {
173b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            return "Model [freq=" + freq + ", interval=" + interval + ", end=" + end + ", endDate="
174b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    + endDate + ", endCount=" + endCount + ", weeklyByDayOfWeek="
175b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    + Arrays.toString(weeklyByDayOfWeek) + ", monthlyRepeat=" + monthlyRepeat
176b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    + ", monthlyByMonthDay=" + monthlyByMonthDay + ", monthlyByDayOfWeek="
177b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    + monthlyByDayOfWeek + ", monthlyByNthDayOfWeek=" + monthlyByNthDayOfWeek + "]";
178b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
179b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
180b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        @Override
181b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        public int describeContents() {
182b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            return 0;
183b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
184b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
185b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        public Model() {
186b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
187b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
188b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // protected Model(Parcel in) {
189b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // freq = in.readInt();
190b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // interval = in.readInt();
191b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // end = in.readInt();
192b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // endDate = new Time(); // TODO timezone?
193b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // endDate.hour = endDate.minute = endDate.second = 0;
194b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // endDate.year = in.readInt();
195b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // endDate.month = in.readInt();
196b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // endDate.monthDay = in.readInt();
197b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // endCount = in.readInt();
198b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // in.readBooleanArray(weeklyByDayOfWeek);
199b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // monthlyRepeat = in.readInt();
200b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // monthlyByMonthDay = in.readInt();
201b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // monthlyByDayOfWeek = in.readInt();
202b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // monthlyByNthDayOfWeek = in.readInt();
203b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // }
204b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        //
205b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // public static final Parcelable.Creator<Model> CREATOR = new
206b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Parcelable.Creator<Model>() {
207b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // @Override
208b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // public Model createFromParcel(Parcel in) {
209b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // return new Model(in);
210b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // }
211b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        //
212b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // @Override
213b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // public Model[] newArray(int size) {
214b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // return new Model[size];
215b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // }
216b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // };
217b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
218b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        @Override
219b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        public void writeToParcel(Parcel dest, int flags) {
220b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(freq);
221b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(interval);
222b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(end);
223b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(endDate.year);
224b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(endDate.month);
225b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(endDate.monthDay);
226b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(endCount);
227b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeBooleanArray(weeklyByDayOfWeek);
228b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(monthlyRepeat);
229b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(monthlyByMonthDay);
230b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(monthlyByDayOfWeek);
231b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dest.writeInt(monthlyByNthDayOfWeek);
232b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
233b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
234b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
235b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    class minMaxTextWatcher implements TextWatcher {
236b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        private int mMin;
237b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        private int mMax;
238b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        private int mDefault;
239b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
240b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        public minMaxTextWatcher(int min, int defaultInt, int max) {
241b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mMin = min;
242b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mMax = max;
243b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mDefault = defaultInt;
244b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
245b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
246b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        @Override
247b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        public void afterTextChanged(Editable s) {
248b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
249b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            boolean updated = false;
250b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            int value;
251b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            try {
252b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                value = Integer.parseInt(s.toString());
253b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            } catch (NumberFormatException e) {
254b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                value = mDefault;
255b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
256b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
257b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (value < mMin) {
258b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                value = mMin;
259b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                updated = true;
260b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            } else if (value > mMax) {
261b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                updated = true;
262b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                value = mMax;
263b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
264b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
265b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            // Update UI
266b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (updated) {
267b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                s.clear();
268b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                s.append(Integer.toString(value));
269b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
270b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
271b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            onChange(value);
272b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
273b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
274b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /** Override to be called after each key stroke */
275b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        void onChange(int value) {
276b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
277b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
278b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        @Override
279b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
280b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
281b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
282b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        @Override
283b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        public void onTextChanged(CharSequence s, int start, int before, int count) {
284b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
285b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
286b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
287b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private Resources mResources;
288b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private EventRecurrence mRecurrence = new EventRecurrence();
289b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private Time mTime = new Time(); // TODO timezone?
290b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private Model mModel = new Model();
291b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private Toast mToast;
292b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
293b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private final int[] TIME_DAY_TO_CALENDAR_DAY = new int[] {
294b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Calendar.SUNDAY,
295b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Calendar.MONDAY,
296b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Calendar.TUESDAY,
297b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Calendar.WEDNESDAY,
298b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Calendar.THURSDAY,
299b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Calendar.FRIDAY,
300b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Calendar.SATURDAY,
301b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    };
302b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
303b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Call mStringBuilder.setLength(0) before formatting any string or else the
304b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // formatted text will accumulate.
305b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // private final StringBuilder mStringBuilder = new StringBuilder();
306b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // private Formatter mFormatter = new Formatter(mStringBuilder);
307b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
308b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private View mView;
309b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
310b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private Spinner mFreqSpinner;
311b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final int[] mFreqModelToEventRecurrence = {
312b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            EventRecurrence.DAILY,
313b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            EventRecurrence.WEEKLY,
314b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            EventRecurrence.MONTHLY,
315b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            EventRecurrence.YEARLY
316b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    };
317b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
318b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public static final String BUNDLE_START_TIME_MILLIS = "bundle_event_start_time";
319b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public static final String BUNDLE_TIME_ZONE = "bundle_event_time_zone";
320b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public static final String BUNDLE_RRULE = "bundle_event_rrule";
321b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
322b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final String BUNDLE_MODEL = "bundle_model";
323b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final String BUNDLE_END_YEAR = "bundle_end_year";
324b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final String BUNDLE_END_MONTH = "bundle_end_month";
325b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final String BUNDLE_END_DAY = "bundle_end_day";
326b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    private static final String BUNDLE_END_COUNT_HAS_FOCUS = "bundle_end_count_has_focus";
327b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
328b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private static final String FRAG_TAG_DATE_PICKER = "tag_date_picker_frag";
329b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
330b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private LinearLayout mIntervalGroup;
331b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private EditText mInterval;
332b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private TextView mIntervalPreText;
333b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private TextView mIntervalPostText;
334b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
335b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private LinearLayout mEndGroup;
336b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private Spinner mEndSpinner;
337b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    private ImageButton mEndDateTextView;
338b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private EditText mEndCount;
339b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
340b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private ArrayList<CharSequence> mEndSpinnerArray = new ArrayList<CharSequence>(3);
341b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private ArrayAdapter<CharSequence> mEndSpinnerAdapter;
342b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private String mEndNeverStr;
343b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    private String mEndDateLabel;
344b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
345b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    /** Hold toggle buttons in the order per user's first day of week preference */
346b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private LinearLayout mWeekGroup;
347b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    private LinearLayout mWeekGroup2;
348b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Sun = 0
349b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private ToggleButton[] mWeekByDayButtons = new ToggleButton[7];
350b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private String[] mDayOfWeekString;
351b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private String[] mOrdinalArray;
352b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
353b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private LinearLayout mMonthGroup;
354b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private RadioGroup mMonthRepeatByRadioGroup;
355b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private RadioButton mMonthRepeatByNthDayOfWeek;
356b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private String mMonthRepeatByDayOfWeekStr;
357b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
358b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private Button mDone;
359b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
360b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private OnRecurrenceSetListener mRecurrenceSetListener;
361b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
362b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public RecurrencePickerDialog() {
363b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
364b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
365b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    static public boolean canHandleRecurrenceRule(EventRecurrence er) {
366b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        switch (er.freq) {
367b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case EventRecurrence.DAILY:
368b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case EventRecurrence.MONTHLY:
369b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case EventRecurrence.YEARLY:
370b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case EventRecurrence.WEEKLY:
371b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
372b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            default:
373b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                return false;
374b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
375b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
376b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (er.count > 0 && !TextUtils.isEmpty(er.until)) {
377b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            return false;
378b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
379b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
380b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Weekly: For "repeat by day of week", the day of week to repeat is in
381b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // er.byday[]
382b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
383b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        /*
384b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * Monthly: For "repeat by nth day of week" the day of week to repeat is
385b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * in er.byday[] and the "nth" is stored in er.bydayNum[]. Currently we
386b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         * can handle only one and only in monthly
387b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan         */
388b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int numOfByDayNum = 0;
389b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        for (int i = 0; i < er.bydayCount; i++) {
390b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (er.bydayNum[i] > 0) {
391b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                ++numOfByDayNum;
392b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
393b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
394b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
395b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (numOfByDayNum > 1) {
396b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            return false;
397b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
398b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
399b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (numOfByDayNum > 0 && er.freq != EventRecurrence.MONTHLY) {
400b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            return false;
401b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
402b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
403b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // The UI only handle repeat by one day of month i.e. not 9th and 10th
404b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // of every month
405b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (er.bymonthdayCount > 1) {
406b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            return false;
407b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
408b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
409b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (er.freq == EventRecurrence.MONTHLY) {
410b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (er.bydayCount > 1) {
411b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                return false;
412b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
413b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (er.bydayCount > 0 && er.bymonthdayCount > 0) {
414b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                return false;
415b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
416b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
417b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
418b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        return true;
419b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
420b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
421b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // TODO compare
422b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // private boolean isCustomRecurrence() {
423b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    //
424b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // if (mEventRecurrence.until != null
425b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // || (mEventRecurrence.interval != 0 && mEventRecurrence.interval != 1)
426b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // || mEventRecurrence.count != 0) {
427b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return true;
428b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // }
429b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    //
430b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // if (mEventRecurrence.freq == 0) {
431b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return false;
432b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // }
433b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    //
434b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // switch (mEventRecurrence.freq) {
435b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // case EventRecurrence.DAILY:
436b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return false;
437b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // case EventRecurrence.WEEKLY:
438b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // if (mEventRecurrence.repeatsOnEveryWeekDay() && isWeekdayEvent()) {
439b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return false;
440b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // } else if (mEventRecurrence.bydayCount == 1) {
441b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return false;
442b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // }
443b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // break;
444b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // case EventRecurrence.MONTHLY:
445b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // if (mEventRecurrence.repeatsMonthlyOnDayCount()) {
446b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // /* this is a "3rd Tuesday of every month" sort of rule */
447b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return false;
448b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // } else if (mEventRecurrence.bydayCount == 0
449b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // && mEventRecurrence.bymonthdayCount == 1
450b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // && mEventRecurrence.bymonthday[0] > 0) {
451b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // /* this is a "22nd day of every month" sort of rule */
452b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return false;
453b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // }
454b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // break;
455b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // case EventRecurrence.YEARLY:
456b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return false;
457b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // }
458b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    //
459b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // return true;
460b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    // }
461b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
462b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // TODO don't lose data when getting data that our UI can't handle
463b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    static private void copyEventRecurrenceToModel(final EventRecurrence er, Model model) {
464b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Freq:
465b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        switch (er.freq) {
466b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case EventRecurrence.DAILY:
467b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.freq = Model.FREQ_DAILY;
468b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
469b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case EventRecurrence.MONTHLY:
470b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.freq = Model.FREQ_MONTHLY;
471b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
472b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case EventRecurrence.YEARLY:
473b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.freq = Model.FREQ_YEARLY;
474b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
475b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case EventRecurrence.WEEKLY:
476b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.freq = Model.FREQ_WEEKLY;
477b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
478b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            default:
479b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                throw new IllegalStateException("freq=" + er.freq);
480b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
481b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
482b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Interval:
483b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (er.interval > 0) {
484b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            model.interval = er.interval;
485b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
486b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
487b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // End:
488b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // End by count:
489b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        model.endCount = er.count;
490b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (model.endCount > 0) {
491b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            model.end = Model.END_BY_COUNT;
492b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
493b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
494b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // End by date:
495b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (!TextUtils.isEmpty(er.until)) {
496b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (model.endDate == null) {
497b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.endDate = new Time();
498b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
499b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
500b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            try {
501b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.endDate.parse(er.until);
502b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            } catch (TimeFormatException e) {
503b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.endDate = null;
504b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
505b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
506b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            // LIMITATION: The UI can only handle END_BY_DATE or END_BY_COUNT
507b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (model.end == Model.END_BY_COUNT && model.endDate != null) {
508b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                throw new IllegalStateException("freq=" + er.freq);
509b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
510b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
511b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            model.end = Model.END_BY_DATE;
512b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
513b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
514b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Weekly: repeat by day of week or Monthly: repeat by nth day of week
515b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // in the month
516b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        Arrays.fill(model.weeklyByDayOfWeek, false);
517b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (er.bydayCount > 0) {
518b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            int count = 0;
519b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            for (int i = 0; i < er.bydayCount; i++) {
520b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                int dayOfWeek = EventRecurrence.day2TimeDay(er.byday[i]);
521b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.weeklyByDayOfWeek[dayOfWeek] = true;
522b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
523b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (model.freq == Model.FREQ_MONTHLY && er.bydayNum[i] > 0) {
524b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    // LIMITATION: Can handle only (one) weekDayNum and only
525b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    // when
526b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    // monthly
527b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    model.monthlyByDayOfWeek = dayOfWeek;
528b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    model.monthlyByNthDayOfWeek = er.bydayNum[i];
529b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    model.monthlyRepeat = Model.MONTHLY_BY_NTH_DAY_OF_WEEK;
530b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    count++;
531b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
532b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
533b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
534b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (model.freq == Model.FREQ_MONTHLY) {
535b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (er.bydayCount != 1) {
536b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    // Can't handle 1st Monday and 2nd Wed
537b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    throw new IllegalStateException("Can handle only 1 byDayOfWeek in monthly");
538b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
539b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (count != 1) {
540b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    throw new IllegalStateException(
541b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                            "Didn't specify which nth day of week to repeat for a monthly");
542b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
543b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
544b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
545b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
546b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Monthly by day of month
547b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (model.freq == Model.FREQ_MONTHLY) {
548b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (er.bymonthdayCount == 1) {
549b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (model.monthlyRepeat == Model.MONTHLY_BY_NTH_DAY_OF_WEEK) {
550b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    throw new IllegalStateException(
551b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                            "Can handle only by monthday or by nth day of week, not both");
552b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
553b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.monthlyByMonthDay = er.bymonthday[0];
554b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                model.monthlyRepeat = Model.MONTHLY_BY_DATE;
555b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            } else if (er.bymonthCount > 1) {
556b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                // LIMITATION: Can handle only one month day
557b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                throw new IllegalStateException("Can handle only one bymonthday");
558b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
559b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
560b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
561b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
562b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    static private void copyModelToEventRecurrence(final Model model, EventRecurrence er) {
563b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (model.freq == Model.FREQ_NONE) {
564b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            throw new IllegalStateException("There's no recurrence");
565b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
566b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
567b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Freq
568b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        er.freq = mFreqModelToEventRecurrence[model.freq];
569b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
570b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Interval
571b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (model.interval <= 1) {
572b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            er.interval = 0;
573b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        } else {
574b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            er.interval = model.interval;
575b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
576b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
577b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // End
578b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        switch (model.end) {
579b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case Model.END_BY_DATE:
580b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (model.endDate != null) {
581b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    model.endDate.switchTimezone(Time.TIMEZONE_UTC);
582b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    model.endDate.normalize(false);
583b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    er.until = model.endDate.format2445();
584b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    er.count = 0;
585b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                } else {
586b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    throw new IllegalStateException("end = END_BY_DATE but endDate is null");
587b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
588b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
589b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case Model.END_BY_COUNT:
590b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                er.count = model.endCount;
591b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                er.until = null;
592b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (er.count <= 0) {
593b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    throw new IllegalStateException("count is " + er.count);
594b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
595b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
596b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            default:
597b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                er.count = 0;
598b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                er.until = null;
599b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
600b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
601b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
602b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Weekly && monthly repeat patterns
603b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        er.bydayCount = 0;
604b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        er.bymonthdayCount = 0;
605b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
606b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        switch (model.freq) {
607b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case Model.FREQ_MONTHLY:
608b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (model.monthlyRepeat == Model.MONTHLY_BY_DATE) {
609b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (model.monthlyByMonthDay > 0) {
610b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        if (er.bymonthday == null || er.bymonthdayCount < 1) {
611b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                            er.bymonthday = new int[1];
612b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        }
613b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        er.bymonthday[0] = model.monthlyByMonthDay;
614b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        er.bymonthdayCount = 1;
615b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
616b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                } else if (model.monthlyRepeat == Model.MONTHLY_BY_NTH_DAY_OF_WEEK) {
617b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (model.monthlyByNthDayOfWeek <= 0) {
618b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        throw new IllegalStateException("month repeat by nth week but n is "
619b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                                + model.monthlyByNthDayOfWeek);
620b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
621b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    int count = 1;
622b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (er.bydayCount < count || er.byday == null || er.bydayNum == null) {
623b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        er.byday = new int[count];
624b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        er.bydayNum = new int[count];
625b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
626b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    er.bydayCount = count;
627b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    er.byday[0] = EventRecurrence.timeDay2Day(model.monthlyByDayOfWeek);
628b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    er.bydayNum[0] = model.monthlyByNthDayOfWeek;
629b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
630b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
631b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            case Model.FREQ_WEEKLY:
632b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                int count = 0;
633b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                for (int i = 0; i < 7; i++) {
634b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (model.weeklyByDayOfWeek[i]) {
635b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        count++;
636b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
637b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
638b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
639b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (er.bydayCount < count || er.byday == null || er.bydayNum == null) {
640b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    er.byday = new int[count];
641b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    er.bydayNum = new int[count];
642b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
643b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                er.bydayCount = count;
644b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
645b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                for (int i = 6; i >= 0; i--) {
646b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (model.weeklyByDayOfWeek[i]) {
647b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        er.bydayNum[--count] = 0;
648b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        er.byday[count] = EventRecurrence.timeDay2Day(i);
649b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
650b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
651b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                break;
652b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
653b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
654b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (!canHandleRecurrenceRule(er)) {
655b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            throw new IllegalStateException("UI generated recurrence that it can't handle. ER:"
656b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    + er.toString() + " Model: " + model.toString());
657b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
658b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
659b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
660b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
661b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public View onCreateView(LayoutInflater inflater, ViewGroup container,
662b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Bundle savedInstanceState) {
663b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mRecurrence.wkst = EventRecurrence.timeDay2Day(Utils.getFirstDayOfWeek(getActivity()));
664b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
665b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        boolean endCountHasFocus = false;
666b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (savedInstanceState != null) {
667b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Model m = (Model) savedInstanceState.get(BUNDLE_MODEL);
668b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (m != null) {
669b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mModel = m;
670b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
671b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            endCountHasFocus = savedInstanceState.getBoolean(BUNDLE_END_COUNT_HAS_FOCUS);
672b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        } else {
673b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            Bundle b = getArguments();
674b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (b != null) {
675b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mTime.set(b.getLong(BUNDLE_START_TIME_MILLIS));
676b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
677b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                String tz = b.getString(BUNDLE_TIME_ZONE);
678b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (!TextUtils.isEmpty(tz)) {
679b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mTime.timezone = tz;
680b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
681b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mTime.normalize(false);
682b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
683b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                // Time days of week: Sun=0, Mon=1, etc
684b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mModel.weeklyByDayOfWeek[mTime.weekDay] = true;
685b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
686b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                String rrule = b.getString(BUNDLE_RRULE);
687b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (!TextUtils.isEmpty(rrule)) {
688b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mRecurrence.parse(rrule);
689b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    copyEventRecurrenceToModel(mRecurrence, mModel);
690b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
691b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            } else {
692b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mTime.setToNow();
693b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
694b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
695b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
696b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mResources = getResources();
697b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mView = inflater.inflate(R.layout.recurrencepicker, container);
698b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
699b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mFreqSpinner = (Spinner) mView.findViewById(R.id.freqSpinner);
700b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mFreqSpinner.setOnItemSelectedListener(this);
701b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        ArrayAdapter<CharSequence> freqAdapter = ArrayAdapter.createFromResource(getActivity(),
702b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                R.array.recurrence_freq, R.layout.recurrencepicker_freq_item);
703b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        freqAdapter.setDropDownViewResource(R.layout.recurrencepicker_freq_item);
704b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mFreqSpinner.setAdapter(freqAdapter);
705b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
706b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mIntervalGroup = (LinearLayout) mView.findViewById(R.id.intervalGroup);
707b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mInterval = (EditText) mView.findViewById(R.id.interval);
708b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mInterval.addTextChangedListener(new minMaxTextWatcher(1, INTERVAL_DEFAULT, INTERVAL_MAX) {
709b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            @Override
710b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            void onChange(int v) {
711b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mModel.interval = v;
712b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
713b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        });
714b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mIntervalPreText = (TextView) mView.findViewById(R.id.intervalPreText);
715b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mIntervalPostText = (TextView) mView.findViewById(R.id.intervalPostText);
716b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
717b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndGroup = (LinearLayout) mView.findViewById(R.id.endGroup);
718b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndNeverStr = mResources.getString(R.string.recurrence_end_continously);
719b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        mEndDateLabel = mResources.getString(R.string.recurrence_end_date_label);
720b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // mEndByDateFormatStr =
721b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // mResources.getString(R.string.recurrence_end_date);
722b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // mEndByCountFormatStr =
723b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // mResources.getString(R.string.recurrence_end_count);
724b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndSpinnerArray.add(mEndNeverStr);
725b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        mEndSpinnerArray.add(mEndDateLabel);
726b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndSpinnerArray.add(mResources.getString(R.string.recurrence_end_count_label));
727b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndSpinner = (Spinner) mView.findViewById(R.id.endSpinner);
728b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndSpinner.setOnItemSelectedListener(this);
729b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndSpinnerAdapter = new ArrayAdapter<CharSequence>(getActivity(),
730b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                R.layout.recurrencepicker_freq_item, mEndSpinnerArray);
731b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndSpinnerAdapter.setDropDownViewResource(R.layout.recurrencepicker_freq_item);
732b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndSpinner.setAdapter(mEndSpinnerAdapter);
733b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
734b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndCount = (EditText) mView.findViewById(R.id.endCount);
735b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndCount.addTextChangedListener(new minMaxTextWatcher(1, COUNT_DEFAULT, COUNT_MAX) {
736b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            @Override
737b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            void onChange(int v) {
738b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mModel.endCount = v;
739b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
740b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        });
741b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        mEndDateTextView = (ImageButton) mView.findViewById(R.id.endDate);
742b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mEndDateTextView.setOnClickListener(this);
743b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (mModel.endDate == null) {
744b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.endDate = new Time(mTime);
745b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            switch (mModel.freq) {
746b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_NONE:
747b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_DAILY:
748b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_WEEKLY:
749b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mModel.endDate.month += 1;
750b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
751b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_MONTHLY:
752b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mModel.endDate.month += 3;
753b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
754b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_YEARLY:
755b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mModel.endDate.year += 3;
756b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
757b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
758b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.endDate.normalize(false);
759b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
760b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
761b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mWeekGroup = (LinearLayout) mView.findViewById(R.id.weekGroup);
762b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        mWeekGroup2 = (LinearLayout) mView.findViewById(R.id.weekGroup2);
763b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
764b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mOrdinalArray = mResources.getStringArray(R.array.ordinal_labels);
765b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
766b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // In Calendar.java day of week order e.g Sun = 1 ... Sat = 7
767b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        String[] dayOfWeekString = new DateFormatSymbols().getWeekdays();
768b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mDayOfWeekString = new String[7];
769b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        for (int i = 0; i < 7; i++) {
770b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mDayOfWeekString[i] = dayOfWeekString[TIME_DAY_TO_CALENDAR_DAY[i]];
771b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
772b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
773b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // In Time.java day of week order e.g. Sun = 0
774b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int idx = Utils.getFirstDayOfWeek(getActivity());
775b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
776b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // In Calendar.java day of week order e.g Sun = 1 ... Sat = 7
777b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        dayOfWeekString = new DateFormatSymbols().getShortWeekdays();
778b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
779b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        int numOfButtonsInRow1;
780b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        int numOfButtonsInRow2;
781b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
782b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        if (mResources.getConfiguration().screenWidthDp > MIN_SCREEN_WIDTH_FOR_SINGLE_ROW_WEEK) {
783b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            numOfButtonsInRow1 = 7;
784b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            numOfButtonsInRow2 = 0;
785b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mWeekGroup2.setVisibility(View.GONE);
786b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mWeekGroup2.getChildAt(3).setVisibility(View.GONE);
787b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        } else {
788b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            numOfButtonsInRow1 = 4;
789b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            numOfButtonsInRow2 = 3;
790b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
791b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mWeekGroup2.setVisibility(View.VISIBLE);
792b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            // Set rightmost button on the second row invisible so it takes up
793b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            // space and everything centers properly
794b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mWeekGroup2.getChildAt(3).setVisibility(View.INVISIBLE);
795b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        }
796b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
797b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        /* First row */
798b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        for (int i = 0; i < 7; i++) {
799b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            if (i >= numOfButtonsInRow1) {
800b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                mWeekGroup.getChildAt(i).setVisibility(View.GONE);
801b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                continue;
802b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            }
803b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
804b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mWeekByDayButtons[idx] = (ToggleButton) mWeekGroup.getChildAt(i);
805b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mWeekByDayButtons[idx].setTextOff(dayOfWeekString[TIME_DAY_TO_CALENDAR_DAY[idx]]);
806b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mWeekByDayButtons[idx].setTextOn(dayOfWeekString[TIME_DAY_TO_CALENDAR_DAY[idx]]);
807b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mWeekByDayButtons[idx].setOnCheckedChangeListener(this);
808b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
809b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (++idx >= 7) {
810b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                idx = 0;
811b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
812b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
813b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
814b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        /* 2nd Row */
815b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        for (int i = 0; i < 3; i++) {
816b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            if (i >= numOfButtonsInRow2) {
817b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                mWeekGroup2.getChildAt(i).setVisibility(View.GONE);
818b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                continue;
819b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            }
820b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mWeekByDayButtons[idx] = (ToggleButton) mWeekGroup2.getChildAt(i);
821b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mWeekByDayButtons[idx].setTextOff(dayOfWeekString[TIME_DAY_TO_CALENDAR_DAY[idx]]);
822b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mWeekByDayButtons[idx].setTextOn(dayOfWeekString[TIME_DAY_TO_CALENDAR_DAY[idx]]);
823b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mWeekByDayButtons[idx].setOnCheckedChangeListener(this);
824b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
825b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            if (++idx >= 7) {
826b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                idx = 0;
827b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            }
828b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        }
829b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
830b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mMonthGroup = (LinearLayout) mView.findViewById(R.id.monthGroup);
831b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mMonthRepeatByRadioGroup = (RadioGroup) mView.findViewById(R.id.monthGroup);
832b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mMonthRepeatByRadioGroup.setOnCheckedChangeListener(this);
833b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mMonthRepeatByNthDayOfWeek = (RadioButton) mView
834b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                .findViewById(R.id.repeatMonthlyByNthDayOfTheWeek);
835b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
836b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mDone = (Button) mView.findViewById(R.id.done);
837b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mDone.setOnClickListener(this);
838b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
839b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        updateDialog();
840b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        if (endCountHasFocus) {
841b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mEndCount.requestFocus();
842b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        }
843b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        return mView;
844b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
845b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
846b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
847b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void onSaveInstanceState(Bundle outState) {
848b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        super.onSaveInstanceState(outState);
849b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        outState.putParcelable(BUNDLE_MODEL, mModel);
850b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        if (mEndCount.hasFocus()) {
851b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            outState.putBoolean(BUNDLE_END_COUNT_HAS_FOCUS, true);
852b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        }
853b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
854b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
855b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void updateDialog() {
856b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Interval
857b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Checking before setting because this causes infinite recursion
858b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // in afterTextWatcher
859b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        final String intervalStr = Integer.toString(mModel.interval);
860b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (!intervalStr.equals(mInterval.getText().toString())) {
861b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mInterval.setText(intervalStr);
862b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
863b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
864b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mFreqSpinner.setSelection(mModel.freq + 1); // FREQ_* starts at -1
865b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mWeekGroup.setVisibility(mModel.freq == Model.FREQ_WEEKLY ? View.VISIBLE : View.GONE);
866b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        mWeekGroup2.setVisibility(mModel.freq == Model.FREQ_WEEKLY ? View.VISIBLE : View.GONE);
867b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mMonthGroup.setVisibility(mModel.freq == Model.FREQ_MONTHLY ? View.VISIBLE : View.GONE);
868b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
869b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (mModel.freq == Model.FREQ_NONE) {
870b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mIntervalGroup.setVisibility(View.INVISIBLE);
871b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mEndGroup.setVisibility(View.INVISIBLE);
872b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        } else {
873b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mIntervalGroup.setVisibility(View.VISIBLE);
874b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mEndGroup.setVisibility(View.VISIBLE);
875b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
876b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            switch (mModel.freq) {
877b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_DAILY:
878b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    updateIntervalText(R.string.recurrence_interval_daily);
879b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
880b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
881b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_WEEKLY:
882b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    updateIntervalText(R.string.recurrence_interval_weekly);
883b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
884b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    int count = 0;
885b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    for (int i = 0; i < 7; i++) {
886b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mWeekByDayButtons[i].setChecked(mModel.weeklyByDayOfWeek[i]);
887b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        if (mModel.weeklyByDayOfWeek[i]) {
888b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                            count++;
889b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                            mWeekByDayButtons[i].setTextColor(DAY_OF_WEEK_CHECKED_TEXT_COLOR);
890b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                        } else {
891b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                            mWeekByDayButtons[i].setTextColor(DAY_OF_WEEK_UNCHECKED_TEXT_COLOR);
892b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        }
893b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
894b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (count == 0) {
895b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mModel.weeklyByDayOfWeek[mTime.weekDay] = true;
896b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mWeekByDayButtons[mTime.weekDay].setChecked(true);
897b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                        mWeekByDayButtons[mTime.weekDay]
898b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                                .setTextColor(DAY_OF_WEEK_CHECKED_TEXT_COLOR);
899b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
900b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
901b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
902b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_MONTHLY:
903b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    updateIntervalText(R.string.recurrence_interval_monthly);
904b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
905b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (mModel.monthlyRepeat == Model.MONTHLY_BY_DATE) {
906b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mMonthRepeatByRadioGroup.check(R.id.repeatMonthlyByNthDayOfMonth);
907b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    } else if (mModel.monthlyRepeat == Model.MONTHLY_BY_NTH_DAY_OF_WEEK) {
908b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mMonthRepeatByRadioGroup.check(R.id.repeatMonthlyByNthDayOfTheWeek);
909b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
910b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
911b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (mMonthRepeatByDayOfWeekStr == null) {
912b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        if (mModel.monthlyByNthDayOfWeek == 0) {
913b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                            mModel.monthlyByNthDayOfWeek = (mTime.monthDay + 6) / 7;
914b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                            mModel.monthlyByDayOfWeek = mTime.weekDay;
915b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        }
916b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
917b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mMonthRepeatByDayOfWeekStr = mResources.getString(
918b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                                R.string.recurrence_month_pattern_by_day_of_week,
919b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                                mOrdinalArray[mModel.monthlyByNthDayOfWeek - 1],
920b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                                mDayOfWeekString[mModel.monthlyByDayOfWeek]);
921b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mMonthRepeatByNthDayOfWeek.setText(mMonthRepeatByDayOfWeekStr);
922b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
923b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
924b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
925b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.FREQ_YEARLY:
926b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    updateIntervalText(R.string.recurrence_interval_yearly);
927b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
928b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
929b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
930b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mEndSpinner.setSelection(mModel.end);
931b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (mModel.end == Model.END_BY_DATE) {
932b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                final String dateStr = DateUtils.formatDateTime(getActivity(),
933b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mModel.endDate.toMillis(false), DateUtils.FORMAT_NUMERIC_DATE);
934b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                final String endDateString = mResources.getString(R.string.recurrence_end_date,
935b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                        dateStr);
936b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                setEndSpinnerEndDateStr(endDateString);
937b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            } else {
938b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                setEndSpinnerEndDateStr(mEndDateLabel);
939b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                if (mModel.end == Model.END_BY_COUNT) {
940b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                    // Checking before setting because this causes infinite
941b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                    // recursion
942b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                    // in afterTextWatcher
943b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                    final String countStr = Integer.toString(mModel.endCount);
944b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                    if (!countStr.equals(mEndCount.getText().toString())) {
945b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                        mEndCount.setText(countStr);
946b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                    }
947b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
948b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
949b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
950b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
951b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // TODO Update title with pretty rrule
952b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (getDialog() != null) {
953b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            getDialog().setTitle(R.string.recurrence_dialog_title);
954b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
955b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
956b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
957b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    /**
958b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan     * @param endDateString
959b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan     */
960b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    private void setEndSpinnerEndDateStr(final String endDateString) {
961b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        mEndSpinnerArray.set(1, endDateString);
962b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        mEndSpinnerAdapter.notifyDataSetChanged();
963b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan    }
964b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
965b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private void doToast() {
966b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        Log.e(TAG, "Model = " + mModel.toString());
967b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        String rrule;
968b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (mModel.freq == Model.FREQ_NONE) {
969b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            rrule = "Not repeating";
970b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        } else {
971b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            copyModelToEventRecurrence(mModel, mRecurrence);
972b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            rrule = mRecurrence.toString();
973b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
974b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
975b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (mToast != null) {
976b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mToast.cancel();
977b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
978b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mToast = Toast.makeText(getActivity(), rrule,
979b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                Toast.LENGTH_LONG);
980b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mToast.show();
981b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
982b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
983b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // TODO Test and update for Right-to-Left
984b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    private void updateIntervalText(int intervalStringId) {
985b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        final String INTERVAL_COUNT_MARKER = "%d";
986b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        String intervalString = mResources.getString(intervalStringId);
987b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int markerStart = intervalString.indexOf(INTERVAL_COUNT_MARKER);
988b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
989b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (markerStart != -1) {
990b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (markerStart == 0) {
991b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mIntervalPreText.setText("");
992b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            } else {
993b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                int postTextStart = markerStart + INTERVAL_COUNT_MARKER.length();
994b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (intervalString.charAt(postTextStart) == ' ') {
995b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    postTextStart++;
996b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
997b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mIntervalPostText.setText(intervalString.subSequence(postTextStart,
998b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        intervalString.length()));
999b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1000b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                if (intervalString.charAt(markerStart - 1) == ' ') {
1001b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    markerStart--;
1002b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                }
1003b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mIntervalPreText.setText(intervalString.subSequence(0, markerStart));
1004b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
1005b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1006b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1007b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1008b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Implements OnItemSelectedListener interface
1009b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Freq spinner
1010b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // End spinner
1011b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
1012b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
1013b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (parent == mFreqSpinner) {
1014b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            // FREQ_* starts at -1.
1015b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            // Spinner starts at 0.
1016b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan            mModel.freq = position - 1;
1017b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        } else if (parent == mEndSpinner) {
1018b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            switch (position) {
1019b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.END_NEVER:
1020b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mModel.end = Model.END_NEVER;
1021b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
1022b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.END_BY_DATE:
1023b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mModel.end = Model.END_BY_DATE;
1024b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
1025b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                case Model.END_BY_COUNT:
1026b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    mModel.end = Model.END_BY_COUNT;
1027b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1028b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    if (mModel.endCount <= 1) {
1029b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mModel.endCount = 1;
1030b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    } else if (mModel.endCount > COUNT_MAX) {
1031b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                        mModel.endCount = COUNT_MAX;
1032b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    }
1033b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    break;
1034b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
1035b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mEndCount.setVisibility(mModel.end == Model.END_BY_COUNT ? View.VISIBLE
1036b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    : View.GONE);
1037b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mEndDateTextView.setVisibility(mModel.end == Model.END_BY_DATE ? View.VISIBLE
1038b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                    : View.GONE);
1039b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1040b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        updateDialog();
1041b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1042b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1043b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Implements OnItemSelectedListener interface
1044b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
1045b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void onNothingSelected(AdapterView<?> arg0) {
1046b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1047b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1048b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
104956f42bfb36d710726051e8268a115697477add61James Kung    public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {
1050b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (mModel.endDate == null) {
1051b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.endDate = new Time(mTime.timezone);
1052b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.endDate.hour = mModel.endDate.minute = mModel.endDate.second = 0;
1053b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1054b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mModel.endDate.year = year;
1055b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mModel.endDate.month = monthOfYear;
1056b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mModel.endDate.monthDay = dayOfMonth;
1057b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mModel.endDate.normalize(false);
1058b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        updateDialog();
1059b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1060b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1061b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Implements OnCheckedChangeListener interface
1062b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Week repeat by day of week
1063b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
1064b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
1065b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int itemIdx = -1;
1066b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        int checkedItems = 0;
1067b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        for (int i = 0; i < 7; i++) {
1068b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (itemIdx == -1 && buttonView == mWeekByDayButtons[i]) {
1069b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                itemIdx = i;
1070b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                mModel.weeklyByDayOfWeek[i] = isChecked;
1071b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
1072b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1073b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (mModel.weeklyByDayOfWeek[i]) {
1074b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                checkedItems++;
1075b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
1076b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1077b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1078b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        // Re-enable item if nothing was enabled.
1079b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (checkedItems == 0 && itemIdx != -1) {
1080b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            buttonView.setChecked(true);
1081b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.weeklyByDayOfWeek[itemIdx] = true;
1082b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1083b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1084b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan        buttonView.setTextColor(isChecked ? DAY_OF_WEEK_CHECKED_TEXT_COLOR
1085b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan                : DAY_OF_WEEK_UNCHECKED_TEXT_COLOR);
1086b39a2e929a98ab329ce0f4e40b7b0fc617dc6575Michael Chan
1087b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        updateDialog();
1088b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1089b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1090b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Implements android.widget.RadioGroup.OnCheckedChangeListener interface
1091b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Month repeat by radio buttons
1092b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
1093b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void onCheckedChanged(RadioGroup group, int checkedId) {
1094b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (checkedId == R.id.repeatMonthlyByNthDayOfMonth) {
1095b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.monthlyRepeat = Model.MONTHLY_BY_DATE;
1096b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        } else if (checkedId == R.id.repeatMonthlyByNthDayOfTheWeek) {
1097b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mModel.monthlyRepeat = Model.MONTHLY_BY_NTH_DAY_OF_WEEK;
1098b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1099b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        updateDialog();
1100b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1101b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1102b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Implements OnClickListener interface
1103b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // EndDate button
1104b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    // Done button
1105b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
1106b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void onClick(View v) {
1107b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        if (mEndDateTextView == v) {
110856f42bfb36d710726051e8268a115697477add61James Kung            if (mDatePickerDialog != null) {
110956f42bfb36d710726051e8268a115697477add61James Kung                mDatePickerDialog.dismiss();
1110b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
111156f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog = DatePickerDialog.newInstance(this, mModel.endDate.year,
111256f42bfb36d710726051e8268a115697477add61James Kung                    mModel.endDate.month, mModel.endDate.monthDay);
111356f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog.setFirstDayOfWeek(Utils.getFirstDayOfWeekAsCalendar(getActivity()));
111456f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog.setYearRange(Utils.YEAR_MIN, Utils.YEAR_MAX);
111556f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog.show(getFragmentManager(), FRAG_TAG_DATE_PICKER);
1116b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        } else if (mDone == v) {
1117b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            String rrule;
1118b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            if (mModel.freq == Model.FREQ_NONE) {
1119b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                rrule = null;
1120b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            } else {
1121b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                copyModelToEventRecurrence(mModel, mRecurrence);
1122b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                rrule = mRecurrence.toString();
1123b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            }
1124b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1125b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            mRecurrenceSetListener.onRecurrenceSet(rrule);
1126b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan            dismiss();
1127b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1128b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1129b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1130b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    @Override
1131b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void onActivityCreated(Bundle savedInstanceState) {
1132b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        super.onActivityCreated(savedInstanceState);
113356f42bfb36d710726051e8268a115697477add61James Kung        mDatePickerDialog = (DatePickerDialog) getFragmentManager()
1134b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan                .findFragmentByTag(FRAG_TAG_DATE_PICKER);
113556f42bfb36d710726051e8268a115697477add61James Kung        if (mDatePickerDialog != null) {
113656f42bfb36d710726051e8268a115697477add61James Kung            mDatePickerDialog.setOnDateSetListener(this);
1137b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        }
1138b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1139b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1140b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public interface OnRecurrenceSetListener {
1141b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        void onRecurrenceSet(String rrule);
1142b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1143b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan
1144b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    public void setOnRecurrenceSetListener(OnRecurrenceSetListener l) {
1145b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan        mRecurrenceSetListener = l;
1146b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan    }
1147b21c638ca11d9be3a3d9e7d28223bb4a3dab5f15Michael Chan}
1148