1/*
2 * Copyright (C) 2013 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.datetimepicker;
18
19import android.animation.Keyframe;
20import android.animation.ObjectAnimator;
21import android.animation.PropertyValuesHolder;
22import android.annotation.SuppressLint;
23import android.os.Build;
24import android.text.format.Time;
25import android.view.View;
26
27import java.util.Calendar;
28
29/**
30 * Utility helper functions for time and date pickers.
31 */
32public class Utils {
33
34    public static final int MONDAY_BEFORE_JULIAN_EPOCH = Time.EPOCH_JULIAN_DAY - 3;
35    public static final int PULSE_ANIMATOR_DURATION = 544;
36
37    // Alpha level for time picker selection.
38    public static final int SELECTED_ALPHA = 51;
39    public static final int SELECTED_ALPHA_THEME_DARK = 102;
40    // Alpha level for fully opaque.
41    public static final int FULL_ALPHA = 255;
42
43
44    static final String SHARED_PREFS_NAME = "com.android.calendar_preferences";
45
46    public static boolean isJellybeanOrLater() {
47      return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
48    }
49
50    /**
51     * Try to speak the specified text, for accessibility. Only available on JB or later.
52     * @param text Text to announce.
53     */
54    @SuppressLint("NewApi")
55    public static void tryAccessibilityAnnounce(View view, CharSequence text) {
56        if (isJellybeanOrLater() && view != null && text != null) {
57            view.announceForAccessibility(text);
58        }
59    }
60
61    public static int getDaysInMonth(int month, int year) {
62        switch (month) {
63            case Calendar.JANUARY:
64            case Calendar.MARCH:
65            case Calendar.MAY:
66            case Calendar.JULY:
67            case Calendar.AUGUST:
68            case Calendar.OCTOBER:
69            case Calendar.DECEMBER:
70                return 31;
71            case Calendar.APRIL:
72            case Calendar.JUNE:
73            case Calendar.SEPTEMBER:
74            case Calendar.NOVEMBER:
75                return 30;
76            case Calendar.FEBRUARY:
77                return (year % 4 == 0) ? 29 : 28;
78            default:
79                throw new IllegalArgumentException("Invalid Month");
80        }
81    }
82
83    /**
84     * Takes a number of weeks since the epoch and calculates the Julian day of
85     * the Monday for that week.
86     *
87     * This assumes that the week containing the {@link Time#EPOCH_JULIAN_DAY}
88     * is considered week 0. It returns the Julian day for the Monday
89     * {@code week} weeks after the Monday of the week containing the epoch.
90     *
91     * @param week Number of weeks since the epoch
92     * @return The julian day for the Monday of the given week since the epoch
93     */
94    public static int getJulianMondayFromWeeksSinceEpoch(int week) {
95        return MONDAY_BEFORE_JULIAN_EPOCH + week * 7;
96    }
97
98    /**
99     * Returns the week since {@link Time#EPOCH_JULIAN_DAY} (Jan 1, 1970)
100     * adjusted for first day of week.
101     *
102     * This takes a julian day and the week start day and calculates which
103     * week since {@link Time#EPOCH_JULIAN_DAY} that day occurs in, starting
104     * at 0. *Do not* use this to compute the ISO week number for the year.
105     *
106     * @param julianDay The julian day to calculate the week number for
107     * @param firstDayOfWeek Which week day is the first day of the week,
108     *          see {@link Time#SUNDAY}
109     * @return Weeks since the epoch
110     */
111    public static int getWeeksSinceEpochFromJulianDay(int julianDay, int firstDayOfWeek) {
112        int diff = Time.THURSDAY - firstDayOfWeek;
113        if (diff < 0) {
114            diff += 7;
115        }
116        int refDay = Time.EPOCH_JULIAN_DAY - diff;
117        return (julianDay - refDay) / 7;
118    }
119
120    /**
121     * Render an animator to pulsate a view in place.
122     * @param labelToAnimate the view to pulsate.
123     * @return The animator object. Use .start() to begin.
124     */
125    public static ObjectAnimator getPulseAnimator(View labelToAnimate, float decreaseRatio,
126            float increaseRatio) {
127        Keyframe k0 = Keyframe.ofFloat(0f, 1f);
128        Keyframe k1 = Keyframe.ofFloat(0.275f, decreaseRatio);
129        Keyframe k2 = Keyframe.ofFloat(0.69f, increaseRatio);
130        Keyframe k3 = Keyframe.ofFloat(1f, 1f);
131
132        PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe("scaleX", k0, k1, k2, k3);
133        PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe("scaleY", k0, k1, k2, k3);
134        ObjectAnimator pulseAnimator =
135                ObjectAnimator.ofPropertyValuesHolder(labelToAnimate, scaleX, scaleY);
136        pulseAnimator.setDuration(PULSE_ANIMATOR_DURATION);
137
138        return pulseAnimator;
139    }
140}
141