/*
* 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.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import org.runnerup.R;
import org.runnerup.common.util.Constants.DB.DIMENSION;
import org.runnerup.util.Formatter;
import org.runnerup.util.SafeParse;
import org.runnerup.widget.NumberPicker;
import org.runnerup.widget.TitleSpinner;
import org.runnerup.workout.Dimension;
import org.runnerup.workout.Intensity;
import org.runnerup.workout.Range;
import org.runnerup.workout.Step;
@TargetApi(Build.VERSION_CODES.FROYO)
public class StepButton extends TableLayout {
private final Context mContext;
private final TableLayout mLayout;
private final TextView mIntensity;
private final TextView mDurationType;
private final TextView mDurationValue;
private final TextView mGoalType;
private final TextView mGoalValue;
private final TableRow mGoalRow;
private final Formatter formatter;
public Step getStep() {
return step;
}
private Step step;
private Runnable mOnChangedListener = null;
static final boolean editRepeatCount = true;
static final boolean editStepButton = true;
public StepButton(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.step_button, this);
formatter = new Formatter(context);
mLayout = (TableLayout) findViewById(R.id.step_button);
mIntensity = (TextView) findViewById(R.id.step_intensity);
mDurationType = (TextView) findViewById(R.id.step_duration_type);
mDurationValue = (TextView) findViewById(R.id.step_duration_value);
mGoalType = (TextView) findViewById(R.id.step_goal_type);
mGoalValue = (TextView) findViewById(R.id.step_goal_value);
mGoalRow = (TableRow) findViewById(R.id.step_row1);
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
mLayout.setEnabled(enabled);
for (int i = 0, j = mLayout.getChildCount(); i < j; i++) {
mLayout.getChildAt(i).setEnabled(enabled);
}
}
public void setOnChangedListener(Runnable runnable) {
mOnChangedListener = runnable;
}
public void setStep(Step step) {
this.step = step;
Resources res = getResources();
mIntensity.setText(res.getText(step.getIntensity().getTextId()));
if (step.getIntensity() == Intensity.REPEAT) {
mDurationType.setText("");
mDurationValue.setText("" + step.getRepeatCount());
mGoalRow.setVisibility(View.GONE);
if (editRepeatCount)
mLayout.setOnClickListener(onRepeatClickListener);
return;
}
Dimension durationType = step.getDurationType();
if (durationType == null) {
mDurationType.setText("");
mDurationValue.setText(res.getString(R.string.Until_press));
} else {
mDurationType.setText(res.getString(durationType.getTextId()));
mDurationValue.setText(formatter.format(Formatter.Format.TXT_LONG, durationType,
step.getDurationValue()));
}
Dimension goalType = step.getTargetType();
if (goalType == null) {
mGoalRow.setVisibility(View.GONE);
} else {
mGoalRow.setVisibility(View.VISIBLE);
mGoalType.setText(res.getString(goalType.getTextId()));
mGoalValue.setText(formatter.format(Formatter.Format.TXT_SHORT, goalType,
step.getTargetValue().minValue)
+ "-" +
formatter.format(Formatter.Format.TXT_LONG, goalType, step.getTargetValue().maxValue));
}
if (editStepButton) {
mLayout.setOnClickListener(onStepClickListener);
}
}
final OnClickListener onRepeatClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
final NumberPicker numberPicker = new NumberPicker(mContext, null);
numberPicker.setOrientation(VERTICAL);
numberPicker.setValue(step.getRepeatCount());
AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
alert.setTitle(getResources().getString(R.string.repeat));
final LinearLayout layout = new LinearLayout(mContext);
layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
layout.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
layout.addView(numberPicker);
alert.setView(layout);
alert.setPositiveButton(getResources().getString(R.string.OK), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
step.setRepeatCount(numberPicker.getValue());
dialog.dismiss();
setStep(step); // redraw
if (mOnChangedListener != null) {
mOnChangedListener.run();
}
}
});
alert.setNegativeButton(getResources().getString(R.string.Cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
AlertDialog dialog = alert.create();
dialog.show();
}
};
final OnClickListener onStepClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
alert.setTitle(getResources().getString(R.string.Edit_step));
final LayoutInflater inflater = LayoutInflater.from(mContext);
final View layout = inflater.inflate(
R.layout.step_dialog, null);
final Runnable save = setupEditStep(inflater, layout);
alert.setView(layout);
alert.setPositiveButton(getResources().getString(R.string.OK), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
save.run();
dialog.dismiss();
setStep(step); // redraw
if (mOnChangedListener != null) {
mOnChangedListener.run();
}
}
});
alert.setNegativeButton(getResources().getString(R.string.Cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
AlertDialog dialog = alert.create();
dialog.show();
}
};
Runnable setupEditStep(LayoutInflater inflator, View layout) {
final TitleSpinner stepType = (TitleSpinner) layout.findViewById(R.id.step_intensity);
stepType.setValue(step.getIntensity().getValue());
final HRZonesListAdapter hrZonesAdapter = new HRZonesListAdapter(mContext, inflator);
final TitleSpinner durationType = (TitleSpinner) layout.findViewById(R.id.step_duration_type);
final TitleSpinner durationTime = (TitleSpinner) layout.findViewById(R.id.step_duration_time);
final TitleSpinner durationDistance = (TitleSpinner) layout.findViewById(R.id.step_duration_distance);
durationType.setOnSetValueListener(new TitleSpinner.OnSetValueListener() {
@Override
public String preSetValue(String newValue) throws IllegalArgumentException {
return null;
}
@Override
public int preSetValue(int newValue) throws IllegalArgumentException {
switch (newValue) {
case DIMENSION.TIME:
durationTime.setEnabled(true);
durationTime.setVisibility(View.VISIBLE);
durationTime.setValue(formatter.formatElapsedTime(Formatter.Format.TXT,
(long) step.getDurationValue()));
durationDistance.setVisibility(View.GONE);
break;
case DIMENSION.DISTANCE:
durationTime.setVisibility(View.GONE);
durationDistance.setEnabled(true);
durationDistance.setVisibility(View.VISIBLE);
durationDistance.setValue(Long.toString((long) step.getDurationValue()));
break;
default:
durationTime.setEnabled(false);
durationDistance.setEnabled(false);
break;
}
return newValue;
}
});
if (step.getDurationType() == null) {
durationType.setValue(-1);
} else {
durationType.setValue(step.getDurationType().getValue());
}
final TitleSpinner targetType = (TitleSpinner) layout.findViewById(R.id.step_target_type);
final TitleSpinner targetPaceLo = (TitleSpinner) layout.findViewById(R.id.step_target_pace_lo);
final TitleSpinner targetPaceHi = (TitleSpinner) layout.findViewById(R.id.step_target_pace_hi);
final TitleSpinner targetHrz = (TitleSpinner) layout.findViewById(R.id.step_target_hrz);
if (!hrZonesAdapter.hrZones.isConfigured()) {
targetType.addDisabledValue(DIMENSION.HRZ);
} else {
targetHrz.setAdapter(hrZonesAdapter);
}
targetType.setOnSetValueListener(new TitleSpinner.OnSetValueListener() {
@Override
public String preSetValue(String newValue) throws IllegalArgumentException {
return null;
}
@Override
public int preSetValue(int newValue) throws IllegalArgumentException {
Range target = step.getTargetValue();
switch (newValue) {
case DIMENSION.PACE:
targetPaceLo.setEnabled(true);
targetPaceHi.setEnabled(true);
targetPaceLo.setVisibility(View.VISIBLE);
targetPaceHi.setVisibility(View.VISIBLE);
if (target != null) {
targetPaceLo.setValue(formatter.formatPace(Formatter.Format.TXT_SHORT,
target.minValue));
targetPaceHi.setValue(formatter.formatPace(Formatter.Format.TXT_SHORT,
target.maxValue));
}
targetHrz.setVisibility(View.GONE);
break;
case DIMENSION.HR:
case DIMENSION.HRZ:
targetPaceLo.setVisibility(View.GONE);
targetPaceHi.setVisibility(View.GONE);
targetHrz.setEnabled(true);
targetHrz.setVisibility(View.VISIBLE);
if (target != null) {
targetHrz.setValue(hrZonesAdapter.hrZones.match(target.minValue,
target.maxValue));
} else {
targetHrz.setValue(0);
}
break;
default:
targetPaceLo.setEnabled(false);
targetPaceHi
.setEnabled(false);
targetHrz.setEnabled(false);
break;
}
return newValue;
}
});
if (step.getTargetType() == null) {
targetType.setValue(-1);
} else if (step.getTargetType().getValue() == DIMENSION.HR) {
targetType.setValue(DIMENSION.HRZ);
} else {
targetType.setValue(step.getTargetType().getValue());
}
return new Runnable() {
@Override
public void run() {
step.setIntensity(Intensity.valueOf(stepType.getValueInt()));
step.setDurationType(Dimension.valueOf(durationType.getValueInt()));
switch (durationType.getValueInt()) {
case DIMENSION.DISTANCE:
step.setDurationValue(SafeParse.parseDouble(
durationDistance.getValue().toString(), 1000));
break;
case DIMENSION.TIME:
step.setDurationValue(SafeParse.parseSeconds(
durationTime.getValue().toString(), 60));
break;
}
step.setTargetType(Dimension.valueOf(targetType.getValueInt()));
switch (targetType.getValueInt()) {
case DIMENSION.PACE: {
double unitMeters = Formatter.getUnitMeters(mContext);
double paceLo = (double) SafeParse.parseSeconds(
targetPaceLo.getValue().toString(), 5 * 60);
double paceHi = (double) SafeParse.parseSeconds(
targetPaceHi.getValue().toString(), 5 * 60);
step.setTargetValue(paceLo / unitMeters, paceHi / unitMeters);
break;
}
case DIMENSION.HRZ:
step.setTargetType(Dimension.HR);
Pair<Integer, Integer> range = hrZonesAdapter.hrZones.getHRValues(
targetHrz.getValueInt() + 1);
step.setTargetValue(range.first, range.second);
}
}
};
}
}