1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.deskclock.alarms;
18
19import android.app.Activity;
20import android.app.Dialog;
21import android.app.DialogFragment;
22import android.app.Fragment;
23import android.app.FragmentManager;
24import android.app.FragmentTransaction;
25import android.os.Bundle;
26import android.text.format.DateFormat;
27import android.widget.TimePicker;
28
29import com.android.datetimepicker.time.RadialPickerLayout;
30import com.android.datetimepicker.time.TimePickerDialog;
31import com.android.deskclock.R;
32import com.android.deskclock.Utils;
33import com.android.deskclock.provider.Alarm;
34
35import java.util.Calendar;
36
37/**
38 * Displays and handles callback for time picker UI.
39 */
40public final class TimePickerCompat {
41
42    /**
43     * Callback when a valid time is selected from UI.
44     */
45    public interface OnTimeSetListener {
46        void processTimeSet(int hourOfDay, int minute);
47    }
48
49    // Tag for timer picker fragment in FragmentManager.
50    private static final String FRAG_TAG_TIME_PICKER = "time_dialog";
51
52    // Do not instantiate.
53    private TimePickerCompat() {}
54
55    /**
56     * Pre-L implementation of timer picker UI.
57     */
58    public static class TimerPickerPreL extends TimePickerDialog {
59
60        public static TimerPickerPreL newInstance(final Fragment targetFragment, final int hour,
61                final int minutes, final boolean use24hourFormat) {
62            final TimerPickerPreL dialog = new TimerPickerPreL();
63            dialog.initialize(new OnTimeSetListener() {
64                @Override
65                public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) {
66                    ((TimePickerCompat.OnTimeSetListener) targetFragment)
67                            .processTimeSet(hourOfDay, minute);
68                }
69            }, hour, minutes, use24hourFormat);
70            dialog.setTargetFragment(targetFragment, 0);
71            dialog.setThemeDark(true);
72            return dialog;
73        }
74
75        @Override
76        public void onAttach(Activity activity) {
77            super.onAttach(activity);
78            if (getTargetFragment() instanceof TimePickerCompat.OnTimeSetListener) {
79                setOnTimeSetListener(new OnTimeSetListener() {
80                    @Override
81                    public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) {
82                        ((TimePickerCompat.OnTimeSetListener) getTargetFragment())
83                                .processTimeSet(hourOfDay, minute);
84                    }
85                });
86            }
87        }
88    }
89
90    /**
91     * Post-L implmenetation of timer picker UI.
92     */
93    public static class TimePickerPostL extends DialogFragment {
94
95        private Alarm mAlarm;
96        private android.app.TimePickerDialog.OnTimeSetListener mListener;
97
98        @Override
99        public Dialog onCreateDialog(Bundle savedInstanceState) {
100            final int hour, minute;
101            if (mAlarm == null) {
102                final Calendar c = Calendar.getInstance();
103                hour = c.get(Calendar.HOUR_OF_DAY);
104                minute = c.get(Calendar.MINUTE);
105            } else {
106                hour = mAlarm.hour;
107                minute = mAlarm.minutes;
108            }
109
110            return new android.app.TimePickerDialog(getActivity(), R.style.TimePickerTheme,
111                    mListener, hour, minute, DateFormat.is24HourFormat(getActivity()));
112        }
113
114        @Override
115        public void onAttach(Activity activity) {
116            super.onAttach(activity);
117            if (getTargetFragment() instanceof OnTimeSetListener) {
118                setOnTimeSetListener((OnTimeSetListener) getTargetFragment());
119            }
120        }
121
122        public void setOnTimeSetListener(final OnTimeSetListener listener) {
123            mListener = new android.app.TimePickerDialog.OnTimeSetListener() {
124                @Override
125                public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
126                    listener.processTimeSet(hourOfDay, minute);
127                }
128            };
129        }
130
131        public void setAlarm(Alarm alarm) {
132            mAlarm = alarm;
133        }
134    }
135
136    /**
137     * Show the time picker dialog for post-L devices.
138     * This is called from AlarmClockFragment to set alarm.
139     *
140     * @param targetFragment  The calling fragment (which is also a {@link OnTimeSetListener}),
141     *                        we use it as the target fragment of the time picker fragment, so later
142     *                        the latter can retrieve it and set it as its onTimeSetListener when
143     *                        the fragment is recreated.
144     * @param alarm           The clicked alarm, it can be null if user was clicking the fab.
145     * @param use24hourFormat Whether or not the time picker should use 24-hour format if supported.
146     */
147    public static void showTimeEditDialog(Fragment targetFragment, Alarm alarm,
148            boolean use24hourFormat) {
149        // Make sure the dialog isn't already added.
150        final FragmentManager manager = targetFragment.getFragmentManager();
151        final FragmentTransaction ft = manager.beginTransaction();
152        final Fragment prev = manager.findFragmentByTag(FRAG_TAG_TIME_PICKER);
153        if (prev != null) {
154            ft.remove(prev);
155        }
156        ft.commit();
157
158        if (Utils.isLOrLater()) {
159            final TimePickerPostL picker = new TimePickerPostL();
160            picker.setTargetFragment(targetFragment, 0);
161            picker.setOnTimeSetListener((OnTimeSetListener) targetFragment);
162            picker.setAlarm(alarm);
163            picker.show(manager, FRAG_TAG_TIME_PICKER);
164        } else {
165            final int hour, minutes;
166            if (alarm == null) {
167                hour = 0;
168                minutes = 0;
169            } else {
170                hour = alarm.hour;
171                minutes = alarm.minutes;
172            }
173            TimerPickerPreL picker = TimerPickerPreL.newInstance(targetFragment, hour,
174                    minutes, use24hourFormat);
175            if (!picker.isAdded()) {
176                picker.show(manager, FRAG_TAG_TIME_PICKER);
177            }
178        }
179    }
180}
181