1/*
2 * Copyright (C) 2012 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 */
16package com.android.camera.ui;
17
18import android.content.Context;
19import android.content.res.Resources;
20import android.util.AttributeSet;
21import android.util.Log;
22import android.view.View;
23import android.widget.Button;
24import android.widget.CompoundButton;
25import android.widget.NumberPicker;
26import android.widget.Switch;
27import android.widget.TextView;
28
29import com.android.camera.IconListPreference;
30import com.android.camera.ListPreference;
31import com.android.camera2.R;
32
33import java.text.NumberFormat;
34import java.util.Locale;
35
36/**
37 * This is a popup window that allows users to turn on/off time lapse feature,
38 * and to select a time interval for taking a time lapse video.
39 */
40public class TimeIntervalPopup extends AbstractSettingPopup {
41    private static final String TAG = "TimeIntervalPopup";
42    private NumberPicker mNumberSpinner;
43    private NumberPicker mUnitSpinner;
44    private Switch mTimeLapseSwitch;
45    private final String[] mUnits;
46    private final String[] mDurations;
47    private IconListPreference mPreference;
48    private Listener mListener;
49    private Button mConfirmButton;
50    private TextView mHelpText;
51    private View mTimePicker;
52
53    static public interface Listener {
54        public void onListPrefChanged(ListPreference pref);
55    }
56
57    public void setSettingChangedListener(Listener listener) {
58        mListener = listener;
59    }
60
61    public TimeIntervalPopup(Context context, AttributeSet attrs) {
62        super(context, attrs);
63
64        Resources res = context.getResources();
65        mUnits = res.getStringArray(R.array.pref_video_time_lapse_frame_interval_units);
66        mDurations = localizeNumbers(res
67                .getStringArray(R.array.pref_video_time_lapse_frame_interval_duration_values));
68    }
69
70    /**
71     * Localizes an array of US formatted numbers.
72     */
73    private static String[] localizeNumbers(String[] mDurations) {
74        NumberFormat format = NumberFormat.getInstance(Locale.getDefault());
75        String[] result = new String[mDurations.length];
76        for (int i = 0; i < mDurations.length; ++i) {
77            double value = Double.valueOf(mDurations[i]);
78            result[i] = format.format(value);
79        }
80        return result;
81    }
82
83    public void initialize(IconListPreference preference) {
84        mPreference = preference;
85
86        // Set title.
87        mTitle.setText(mPreference.getTitle());
88
89        // Duration
90        int durationCount = mDurations.length;
91        mNumberSpinner = (NumberPicker) findViewById(R.id.duration);
92        mNumberSpinner.setMinValue(0);
93        mNumberSpinner.setMaxValue(durationCount - 1);
94        mNumberSpinner.setDisplayedValues(mDurations);
95        mNumberSpinner.setWrapSelectorWheel(false);
96
97        // Units for duration (i.e. seconds, minutes, etc)
98        mUnitSpinner = (NumberPicker) findViewById(R.id.duration_unit);
99        mUnitSpinner.setMinValue(0);
100        mUnitSpinner.setMaxValue(mUnits.length - 1);
101        mUnitSpinner.setDisplayedValues(mUnits);
102        mUnitSpinner.setWrapSelectorWheel(false);
103
104        mTimePicker = findViewById(R.id.time_interval_picker);
105        mTimeLapseSwitch = (Switch) findViewById(R.id.time_lapse_switch);
106        mHelpText = (TextView) findViewById(R.id.set_time_interval_help_text);
107        mConfirmButton = (Button) findViewById(R.id.time_lapse_interval_set_button);
108
109        // Disable focus on the spinners to prevent keyboard from coming up
110        mNumberSpinner.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
111        mUnitSpinner.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
112
113        mTimeLapseSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
114            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
115                setTimeSelectionEnabled(isChecked);
116            }
117        });
118        mConfirmButton.setOnClickListener(new View.OnClickListener() {
119            public void onClick(View v) {
120                updateInputState();
121            }
122        });
123    }
124
125    private void restoreSetting() {
126        int index = mPreference.findIndexOfValue(mPreference.getValue());
127        if (index == -1) {
128            Log.e(TAG, "Invalid preference value.");
129            mPreference.print();
130            throw new IllegalArgumentException();
131        } else if (index == 0) {
132            // default choice: time lapse off
133            mTimeLapseSwitch.setChecked(false);
134            setTimeSelectionEnabled(false);
135        } else {
136            mTimeLapseSwitch.setChecked(true);
137            setTimeSelectionEnabled(true);
138            int durationCount = mNumberSpinner.getMaxValue() + 1;
139            int unit = (index - 1) / durationCount;
140            int number = (index - 1) % durationCount;
141            mUnitSpinner.setValue(unit);
142            mNumberSpinner.setValue(number);
143        }
144    }
145
146    @Override
147    public void setVisibility(int visibility) {
148        if (visibility == View.VISIBLE) {
149            if (getVisibility() != View.VISIBLE) {
150                // Set the number pickers and on/off switch to be consistent
151                // with the preference
152                restoreSetting();
153            }
154        }
155        super.setVisibility(visibility);
156    }
157
158    protected void setTimeSelectionEnabled(boolean enabled) {
159        mHelpText.setVisibility(enabled ? GONE : VISIBLE);
160        mTimePicker.setVisibility(enabled ? VISIBLE : GONE);
161    }
162
163    @Override
164    public void reloadPreference() {
165    }
166
167    private void updateInputState() {
168        if (mTimeLapseSwitch.isChecked()) {
169            int newId = mUnitSpinner.getValue() * (mNumberSpinner.getMaxValue() + 1)
170                    + mNumberSpinner.getValue() + 1;
171            mPreference.setValueIndex(newId);
172        } else {
173            mPreference.setValueIndex(0);
174        }
175
176        if (mListener != null) {
177            mListener.onListPrefChanged(mPreference);
178        }
179    }
180}
181