/* * The MIT License (MIT) * * Copyright (c) 2015 Curt Binder * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package info.curtbinder.reefangel.phone; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.widget.SeekBar; import android.widget.SimpleAdapter; import android.widget.Spinner; import android.widget.TextView; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import info.curtbinder.reefangel.controller.Controller; import info.curtbinder.reefangel.service.MessageCommands; import info.curtbinder.reefangel.service.RequestCommands; import info.curtbinder.reefangel.service.UpdateService; public class DialogDCPump extends DialogFragment implements SeekBar.OnSeekBarChangeListener { public static final int DCPUMP_UPPER_MODES_OFFSET = 4; private static final String TAG = DialogDCPump.class.getSimpleName(); private static final String TYPE_KEY = "type_key"; private static final String VALUE_KEY = "value_key"; private static final int MAX_SPEED_VALUE = 100; private static final int MAX_DURATION_VALUE = 255; private int popupType; private int currentValue; private int[] locations; private Spinner spinner; private SeekBar seek; private TextView tvValue; public DialogDCPump() { currentValue = 0; popupType = Controller.DCPUMP_MODE; // memory locations for the types: MODE, SPEED, DURATION, THRESHOLD locations = new int[]{337, 338, 339, 364}; } public static DialogDCPump newInstance(int type, int value) { DialogDCPump d = new DialogDCPump(); Bundle args = new Bundle(); args.putInt(TYPE_KEY, type); args.putInt(VALUE_KEY, value); d.setArguments(args); return d; } @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // TODO improve getting current theme final int themeId = R.style.AlertDialogStyle; final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(getActivity(), themeId); LayoutInflater inflater = getActivity().getLayoutInflater().cloneInContext(themeWrapper); AlertDialog.Builder builder = new AlertDialog.Builder(themeWrapper, themeId); Bundle args = getArguments(); if (args != null) { popupType = args.getInt(TYPE_KEY); currentValue = args.getInt(VALUE_KEY); } validateArguments(); int layoutId = R.layout.dlg_mds_seekbar; if (popupType == Controller.DCPUMP_MODE) { layoutId = R.layout.dlg_mds_spinner; } View root = inflater.inflate(layoutId, null); updateDialogType(root); builder.setTitle(R.string.titleDCPump) .setView(root) .setPositiveButton(R.string.buttonUpdate, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { updateDCPumpSettings(); } }) .setNegativeButton(R.string.buttonCancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dismiss(); } }); return builder.create(); } private void validateArguments() { // validate the input arguments if ((popupType > Controller.DCPUMP_THRESHOLD) || (popupType < Controller.DCPUMP_MODE)) { popupType = Controller.DCPUMP_MODE; } if (popupType == Controller.DCPUMP_MODE) { // make sure the value is within the range if ((currentValue < 0) || ((currentValue > 6) && (currentValue < 11)) || (currentValue > 14)) { currentValue = 0; } // the value being passed in will be the exact value that is stored // in the parameters database from the controller. we need to adjust the offset // here before displaying the dialog box. the offset will be adjusted again // before se send the value out to the controller. see getModeValue() if ((currentValue > 10) && (currentValue < 15)) { currentValue = currentValue - DCPUMP_UPPER_MODES_OFFSET; } } if ((popupType == Controller.DCPUMP_SPEED) || (popupType == Controller.DCPUMP_THRESHOLD)) { if ((currentValue > MAX_SPEED_VALUE) || (currentValue < 0)) { currentValue = 0; } } if (popupType == Controller.DCPUMP_DURATION) { if ((currentValue > MAX_DURATION_VALUE) || (currentValue < 0)) { currentValue = 0; } } } private void updateDialogType(View v) { // updates the type of the dialog // updates the description and configures the spinner int descriptionId; boolean fSpeed = false; switch (popupType) { default: // in case of an invalid type, default to the MODE config popupType = Controller.DCPUMP_MODE; case Controller.DCPUMP_MODE: descriptionId = R.string.descriptionMode; break; case Controller.DCPUMP_SPEED: descriptionId = R.string.descriptionSpeed; fSpeed = true; break; case Controller.DCPUMP_DURATION: descriptionId = R.string.descriptionDuration; break; case Controller.DCPUMP_THRESHOLD: descriptionId = R.string.descriptionThreshold; fSpeed = true; break; } ((TextView) v.findViewById(R.id.textDescription)).setText(descriptionId); if (popupType == Controller.DCPUMP_MODE) { spinner = (Spinner) v.findViewById(R.id.vtSpinner); setupSpinner(); } else { seek = (SeekBar) v.findViewById(R.id.vtSeek); tvValue = (TextView) v.findViewById(R.id.vtSeekValue); setupSeekBar(fSpeed); } } private void setupSpinner() { List<Map<String, String>> data = new ArrayList<Map<String, String>>(); String[] from = new String[]{"data"}; int[] to = new int[]{android.R.id.text1}; String[] labels = getResources().getStringArray(R.array.dcPumpModeLabels); for (String label : labels) { data.add(addData(label)); } SimpleAdapter simpleAdapter = new SimpleAdapter(getActivity(), data, android.R.layout.simple_spinner_item, from, to); simpleAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(simpleAdapter); spinner.setSelection(currentValue); } private Map<String, String> addData(String value) { Map<String, String> mapList = new HashMap<String, String>(); mapList.put("data", value); return mapList; } private void setupSeekBar(boolean fSpeed) { int max; if (fSpeed) { max = MAX_SPEED_VALUE; //100; } else { max = MAX_DURATION_VALUE; //255; } seek.setMax(max); seek.setProgress(currentValue); seek.setOnSeekBarChangeListener(this); updateProgressText(); } private void updateProgressText() { String fmt; if (popupType == Controller.DCPUMP_SPEED) { fmt = "%d%%"; } else { fmt = "%d"; } tvValue.setText(String.format(Locale.getDefault(), fmt, currentValue)); } private int getModeValue() { /* modes 0-6 return the exact position value. modes 7-10 return the value + 4 */ int v = spinner.getSelectedItemPosition(); if ( v > 6 ) { v += DCPUMP_UPPER_MODES_OFFSET; } return v; } private void updateDCPumpSettings() { // get the starting memory locations Intent i = new Intent(getActivity(), UpdateService.class); i.setAction(MessageCommands.MEMORY_SEND_INTENT); // grab the current value from the dialog // use the spinner for the MODES and use the seek bar for the SPEED & DURATION // could use the currentValue variable because it is updated each time int value; if (popupType == Controller.DCPUMP_MODE) { value = getModeValue(); } else { value = seek.getProgress(); } i.putExtra(MessageCommands.MEMORY_SEND_TYPE_STRING, RequestCommands.MemoryByte); i.putExtra(MessageCommands.MEMORY_SEND_LOCATION_INT, locations[popupType]); i.putExtra(MessageCommands.MEMORY_SEND_VALUE_INT, value); Log.d(TAG, "Update DC Pump: " + RequestCommands.MemoryByte + locations[popupType] + "," + value); // send the memory command getActivity().startService(i); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { currentValue = progress; updateProgressText(); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }