/*
* Copyright (C) 2013 jonas.oreland@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 3 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, see <http://www.gnu.org/licenses/>.
*/
package org.runnerup.view;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import org.runnerup.R;
import org.runnerup.common.util.Constants.DB;
import org.runnerup.db.DBHelper;
import org.runnerup.util.Formatter;
import org.runnerup.util.HRZones;
import org.runnerup.widget.TitleSpinner;
import org.runnerup.widget.TitleSpinner.OnSetValueListener;
import org.runnerup.widget.WidgetUtil;
import org.runnerup.workout.Feedback;
import org.runnerup.workout.Workout;
import org.runnerup.workout.WorkoutBuilder;
import org.runnerup.workout.feedback.RUTextToSpeech;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
@TargetApi(Build.VERSION_CODES.FROYO)
public class AudioCueSettingsActivity extends PreferenceActivity {
boolean started = false;
boolean delete = false;
String settingsName = null;
AudioSchemeListAdapter adapter = null;
SQLiteDatabase mDB = null;
MenuItem newSettings;
private String DEFAULT = "Default";
public static final String SUFFIX = "_audio_cues";
static final String PREFS_DIR = "shared_prefs";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WidgetUtil.addLegacyOverflowButton(getWindow());
mDB = DBHelper.getWritableDatabase(this);
DEFAULT = getString(R.string.Default);
Intent intent = getIntent();
settingsName = intent.getStringExtra("name");
if (settingsName != null) {
PreferenceManager prefMgr = getPreferenceManager();
prefMgr.setSharedPreferencesName(settingsName + SUFFIX);
prefMgr.setSharedPreferencesMode(MODE_PRIVATE);
}
addPreferencesFromResource(R.xml.audio_cue_settings);
setContentView(R.layout.settings_wrapper);
{
Preference btn = findPreference("test_cueinfo");
btn.setOnPreferenceClickListener(onTestCueinfoClick);
}
{
Preference btn = findPreference("cue_silence");
if (btn != null) {
btn.setOnPreferenceClickListener(this.onSilenceClick);
}
}
HRZones hrZones = new HRZones(this);
boolean hasHR = SettingsActivity.hasHR(this);
boolean hasHRZones = hrZones.isConfigured();
if (!hasHR || !hasHRZones) {
final int remove[] = {
R.string.cueinfo_total_hrz,
R.string.cueinfo_step_hrz,
R.string.cueinfo_lap_hrz,
R.string.cueinfo_current_hrz
};
removePrefs(remove);
}
if (!hasHR) {
final int remove[] = {
R.string.cueinfo_total_hr,
R.string.cueinfo_step_hr,
R.string.cueinfo_lap_hr,
R.string.cueinfo_current_hr
};
removePrefs(remove);
}
{
Preference btn = findPreference("tts_settings");
btn.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent();
intent.setAction("com.android.settings.TTS_SETTINGS");
startActivity(intent);
return false;
}
});
}
final boolean createNewItem = true;
adapter = new AudioSchemeListAdapter(mDB,
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE),
createNewItem);
adapter.reload();
{
TitleSpinner spinner = (TitleSpinner) findViewById(R.id.settings_spinner);
spinner.setVisibility(View.VISIBLE);
spinner.setAdapter(adapter);
if (settingsName == null) {
spinner.setValue(0);
} else {
int idx = adapter.find(settingsName);
spinner.setValue(idx);
}
spinner.setOnSetValueListener(onSetValueListener);
}
}
private void removePrefs(int[] remove) {
Resources res = getResources();
PreferenceGroup group = (PreferenceGroup) findPreference("cueinfo");
if (group == null)
return;
for (int aRemove : remove) {
String s = res.getString(aRemove);
Preference pref = findPreference(s);
group.removePreference(pref);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (delete) {
deleteAudioSchemeImpl(settingsName);
}
DBHelper.closeDB(mDB);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
newSettings = menu.add("New settings");
MenuItem deleteMenuItem = menu.add("Delete settings");
if (settingsName == null)
deleteMenuItem.setEnabled(false);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item == newSettings) {
createNewAudioSchemeDialog();
return true;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.Are_you_sure));
builder.setPositiveButton(getString(R.string.Yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
deleteAudioScheme();
}
});
builder.setNegativeButton(getString(R.string.No),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Do nothing but close the dialog
dialog.dismiss();
}
});
builder.show();
return true;
}
void createNewAudioScheme(String scheme) {
ContentValues tmp = new ContentValues();
tmp.put(DB.AUDIO_SCHEMES.NAME, scheme);
tmp.put(DB.AUDIO_SCHEMES.SORT_ORDER, 0);
mDB.insert(DB.AUDIO_SCHEMES.TABLE, null, tmp);
}
private void deleteAudioScheme() {
delete = true;
getPreferenceManager().getSharedPreferences().edit().clear().commit();
/**
* Can only delete file in "next" activity...cause on destory on this,
* will save file...
*/
switchTo(null);
}
private void deleteAudioSchemeImpl(String name) {
/**
* Start by deleting file...then delete from table...so we don't get
* stray files
*/
File a = new File(getFilesDir().getAbsoluteFile() + "/../" + PREFS_DIR + "/" + name
+ SUFFIX + ".xml");
//noinspection ResultOfMethodCallIgnored
a.delete();
String args[] = {
name
};
mDB.delete(DB.AUDIO_SCHEMES.TABLE, DB.AUDIO_SCHEMES.NAME + "= ?", args);
}
void updateSortOrder(String name) {
mDB.execSQL("UPDATE " + DB.AUDIO_SCHEMES.TABLE + " set " + DB.AUDIO_SCHEMES.SORT_ORDER +
" = (SELECT MAX(" + DB.AUDIO_SCHEMES.SORT_ORDER + ") + 1 FROM "
+ DB.AUDIO_SCHEMES.TABLE + ") " +
" WHERE " + DB.AUDIO_SCHEMES.NAME + " = '" + name + "'");
}
final OnSetValueListener onSetValueListener = new OnSetValueListener() {
@Override
public String preSetValue(String newValue)
throws IllegalArgumentException {
return newValue;
}
@Override
public int preSetValue(int newValueId) throws IllegalArgumentException {
String newValue = (String) adapter.getItem(newValueId);
PreferenceManager prefMgr = getPreferenceManager();
if (newValue.contentEquals(DEFAULT)) {
prefMgr.getSharedPreferences().edit().commit();
switchTo(null);
} else if (newValue.contentEquals(getString(R.string.New_audio_scheme))) {
createNewAudioSchemeDialog();
} else {
prefMgr.getSharedPreferences().edit().commit();
updateSortOrder(newValue);
switchTo(newValue);
}
throw new IllegalArgumentException();
}
};
private void switchTo(String name) {
if (started == false) {
// TODO investigate "spurious" onItemSelected during start
started = true;
return;
}
if (name == null && settingsName == null) {
return;
}
if (name != null && settingsName != null && name.contentEquals(settingsName)) {
return;
}
Intent i = new Intent(this, AudioCueSettingsActivity.class);
if (name != null) {
i.putExtra("name", name);
}
startActivity(i);
finish();
}
private void createNewAudioSchemeDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.Create_new_audio_cue_scheme));
// Get the layout inflater
final EditText editText = new EditText(this);
builder.setView(editText);
builder.setPositiveButton(getString(R.string.Create), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String scheme = editText.getText().toString();
if (!scheme.contentEquals("")) {
createNewAudioScheme(scheme);
updateSortOrder(scheme);
switchTo(scheme);
}
}
});
builder.setNegativeButton(getString(R.string.Cancel), new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
final OnPreferenceClickListener onSilenceClick = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Resources res = getResources();
int clearList[] = {
R.string.cueinfo_total_distance,
R.string.cueinfo_total_time,
R.string.cueinfo_total_speed,
R.string.cueinfo_total_pace,
R.string.cueinfo_lap_distance,
R.string.cueinfo_lap_time,
R.string.cueinfo_lap_speed,
R.string.cueinfo_lap_pace,
R.string.cueinfo_target_coaching
};
int setList[] = {
R.string.cueinfo_skip_startstop
};
for (int s : clearList) {
Preference a = getPreferenceManager().findPreference(res.getString(s));
if (a != null) {
a.getEditor().putBoolean(res.getString(s), false);
a.getEditor().commit();
}
}
for (int s : setList) {
Preference a = getPreferenceManager().findPreference(res.getString(s));
if (a != null) {
a.getEditor().putBoolean(res.getString(s), true);
a.getEditor().commit();
}
}
return false;
}
};
final OnPreferenceClickListener onTestCueinfoClick = new OnPreferenceClickListener() {
TextToSpeech tts = null;
final ArrayList<Feedback> feedback = new ArrayList<Feedback>();
private final OnInitListener mTTSOnInitListener = new OnInitListener() {
@Override
public void onInit(int arg0) {
SharedPreferences prefs = null;
if (settingsName == null || settingsName.contentEquals(DEFAULT))
prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
else
prefs = getApplicationContext().getSharedPreferences(settingsName + SUFFIX,
Context.MODE_PRIVATE);
final boolean mute = prefs.getBoolean(getResources().getString(R.string.pref_mute_bool),
false);
Workout w = Workout.fakeWorkoutForTestingAudioCue();
RUTextToSpeech rutts = new RUTextToSpeech(tts, mute, getApplicationContext());
HashMap<String, Object> bindValues = new HashMap<String, Object>();
bindValues.put(Workout.KEY_TTS, rutts);
bindValues.put(Workout.KEY_FORMATTER, new Formatter(AudioCueSettingsActivity.this));
bindValues.put(Workout.KEY_HRZONES, new HRZones(AudioCueSettingsActivity.this));
w.onBind(w, bindValues);
for (Feedback f : feedback) {
f.onInit(w);
f.onBind(w, bindValues);
f.emit(w, AudioCueSettingsActivity.this.getApplicationContext());
rutts.emit();
}
}
};
@Override
public boolean onPreferenceClick(Preference arg0) {
Context ctx = getApplicationContext();
Resources res = getResources();
feedback.clear();
SharedPreferences prefs = null;
if (settingsName == null || settingsName.contentEquals(DEFAULT))
prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
else
prefs = ctx.getSharedPreferences(settingsName + SUFFIX, Context.MODE_PRIVATE);
WorkoutBuilder.addFeedbackFromPreferences(prefs, res, feedback);
tts = new TextToSpeech(ctx, mTTSOnInitListener);
return false;
}
};
}