/*
* Copyright (C) 2014 AChep@xda <artemchep@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.achep.acdisplay.ui.preferences;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
import com.achep.acdisplay.Config;
import com.achep.acdisplay.R;
import com.achep.base.content.ConfigBase;
import com.achep.base.ui.preferences.MaterialDialogPreference;
import com.afollestad.materialdialogs.MaterialDialog;
import java.lang.ref.SoftReference;
/**
* Preference to configure timeouts.
* Creates the dialog in settings to change the TimeOut settings.
*
* @author Artem Chepurnoy
*/
public class TimeoutPreference extends MaterialDialogPreference implements
SeekBar.OnSeekBarChangeListener {
private static final String TAG = "TimeoutPreference";
private static final int MULTIPLIER = 500;
private final String mValueLabel;
private SoftReference<String>[] mSoftStoredLabels;
private Group[] mGroups;
private int[] mProgresses = new int[3];
private int mMin;
public TimeoutPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mValueLabel = context.getResources().getString(R.string.preference_timeout_sec);
}
@NonNull
@Override
public MaterialDialog onBuildDialog(@NonNull MaterialDialog.Builder builder) {
Resources res = getContext().getResources();
MaterialDialog md = builder
.customView(R.layout.preference_dialog_timeout, false)
.build();
Config config = Config.getInstance();
View root = md.getCustomView();
assert root != null;
mProgresses = new int[2];
mGroups = new Group[mProgresses.length];
mGroups[0] = new Group(
(SeekBar) root.findViewById(R.id.normal_timeout_seekbar),
(TextView) root.findViewById(R.id.normal_timeout_value),
config.getOption(Config.KEY_TIMEOUT_NORMAL));
mGroups[1] = new Group(
(SeekBar) root.findViewById(R.id.short_timeout_seekbar),
(TextView) root.findViewById(R.id.short_timeout_value),
config.getOption(Config.KEY_TIMEOUT_SHORT));
final int max = res.getInteger(R.integer.config_timeout_maxDurationMillis) / MULTIPLIER;
mMin = res.getInteger(R.integer.config_timeout_minDurationMillis) / MULTIPLIER;
mSoftStoredLabels = new SoftReference[max + 1];
for (Group group : mGroups) {
int progress = (int) group.option.read(config);
group.seekBar.setOnSeekBarChangeListener(this);
group.seekBar.setMax(max);
group.seekBar.setProgress(progress / MULTIPLIER);
}
return md;
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (!positiveResult) {
return;
}
// Save changes to config.
Config config = Config.getInstance();
for (Group group : mGroups) {
int value = group.seekBar.getProgress() * MULTIPLIER;
group.option.write(config, getContext(), value, null);
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean byUser) {
int i = 0;
Group group = null;
for (; i < mGroups.length; i++)
if (mGroups[i].seekBar == seekBar) {
group = mGroups[i];
break;
}
assert group != null;
// Store labels to soft references array
// to prevent lots of new strings.
String label;
SoftReference<String> cached = mSoftStoredLabels[progress];
if (cached == null || cached.get() == null) {
label = String.format(mValueLabel, Float.toString(progress * MULTIPLIER / 1000f));
mSoftStoredLabels[progress] = new SoftReference<>(label);
} else {
label = cached.get();
}
group.textView.setText(label);
if (!byUser) {
return;
}
if (progress < mMin) {
seekBar.setProgress(mMin);
return;
}
for (int j = i - 1; j >= 0; j--) {
int old = mGroups[j].seekBar.getProgress();
int current = Math.max(mProgresses[j], progress);
if (old != current) {
mGroups[j].seekBar.setProgress(current);
}
}
for (++i; i < mGroups.length; i++) {
int old = mGroups[i].seekBar.getProgress();
int current = Math.min(mProgresses[i], progress);
if (old != current) {
mGroups[i].seekBar.setProgress(current);
}
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
for (int i = 0; i < mProgresses.length; i++) {
mProgresses[i] = mGroups[i].seekBar.getProgress();
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) { /* unused */ }
/**
* An object to store the seekbars and variables in that are used in the dialog
*/
private static class Group {
SeekBar seekBar;
TextView textView;
ConfigBase.Option option;
public Group(SeekBar seekBar, TextView textView, ConfigBase.Option option) {
this.seekBar = seekBar;
this.textView = textView;
this.option = option;
}
}
}