package info.nightscout.androidaps.plugins.ConfigBuilder;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import java.util.ArrayList;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventConfigBuilderChange;
import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.FragmentBase;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.NSProfile.NSProfilePlugin;
import info.nightscout.androidaps.plugins.VirtualPump.VirtualPumpPlugin;
import info.nightscout.utils.PasswordProtection;
public class ConfigBuilderFragment extends Fragment implements FragmentBase {
static ConfigBuilderPlugin configBuilderPlugin = new ConfigBuilderPlugin();
static public ConfigBuilderPlugin getPlugin() {
return configBuilderPlugin;
}
ListView bgsourceListView;
ListView pumpListView;
TextView pumpLabel;
ListView loopListView;
TextView loopLabel;
ListView treatmentsListView;
ListView tempsListView;
TextView tempsLabel;
ListView profileListView;
ListView apsListView;
TextView apsLabel;
ListView constraintsListView;
TextView constraintsLabel;
ListView generalListView;
TextView nsclientVerView;
TextView nightscoutVerView;
PluginCustomAdapter bgsourceDataAdapter = null;
PluginCustomAdapter pumpDataAdapter = null;
PluginCustomAdapter loopDataAdapter = null;
PluginCustomAdapter treatmentsDataAdapter = null;
PluginCustomAdapter tempsDataAdapter = null;
PluginCustomAdapter profileDataAdapter = null;
PluginCustomAdapter apsDataAdapter = null;
PluginCustomAdapter constraintsDataAdapter = null;
PluginCustomAdapter generalDataAdapter = null;
LinearLayout mainLayout;
Button unlock;
// TODO: sorting
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
bgsourceListView = (ListView) view.findViewById(R.id.configbuilder_bgsourcelistview);
pumpListView = (ListView) view.findViewById(R.id.configbuilder_pumplistview);
pumpLabel = (TextView) view.findViewById(R.id.configbuilder_pumplabel);
loopListView = (ListView) view.findViewById(R.id.configbuilder_looplistview);
loopLabel = (TextView) view.findViewById(R.id.configbuilder_looplabel);
treatmentsListView = (ListView) view.findViewById(R.id.configbuilder_treatmentslistview);
tempsListView = (ListView) view.findViewById(R.id.configbuilder_tempslistview);
tempsLabel = (TextView) view.findViewById(R.id.configbuilder_tempslabel);
profileListView = (ListView) view.findViewById(R.id.configbuilder_profilelistview);
apsListView = (ListView) view.findViewById(R.id.configbuilder_apslistview);
apsLabel = (TextView) view.findViewById(R.id.configbuilder_apslabel);
constraintsListView = (ListView) view.findViewById(R.id.configbuilder_constraintslistview);
constraintsLabel = (TextView) view.findViewById(R.id.configbuilder_constraintslabel);
generalListView = (ListView) view.findViewById(R.id.configbuilder_generallistview);
nsclientVerView = (TextView) view.findViewById(R.id.configbuilder_nsclientversion);
nightscoutVerView = (TextView) view.findViewById(R.id.configbuilder_nightscoutversion);
nsclientVerView.setText(ConfigBuilderPlugin.nsClientVersionName);
nightscoutVerView.setText(ConfigBuilderPlugin.nightscoutVersionName);
if (ConfigBuilderPlugin.nsClientVersionCode < 117) nsclientVerView.setTextColor(Color.RED);
if (ConfigBuilderPlugin.nightscoutVersionCode < 900)
nightscoutVerView.setTextColor(Color.RED);
setViews();
unlock = (Button) view.findViewById(R.id.configbuilder_unlock);
mainLayout = (LinearLayout) view.findViewById(R.id.configbuilder_mainlayout);
if (PasswordProtection.isLocked("settings_password")) {
mainLayout.setVisibility(View.GONE);
unlock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
@Override
public void run() {
mainLayout.setVisibility(View.VISIBLE);
unlock.setVisibility(View.GONE);
}
}, null);
}
});
} else {
unlock.setVisibility(View.GONE);
}
return view;
}
void setViews() {
bgsourceDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsListByInterface(BgSourceInterface.class), PluginBase.BGSOURCE);
bgsourceListView.setAdapter(bgsourceDataAdapter);
setListViewHeightBasedOnChildren(bgsourceListView);
pumpDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsList(PluginBase.PUMP), PluginBase.PUMP);
pumpListView.setAdapter(pumpDataAdapter);
if (MainApp.getSpecificPluginsList(PluginBase.PUMP).size() == 0)
pumpLabel.setVisibility(View.GONE);
setListViewHeightBasedOnChildren(pumpListView);
loopDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsList(PluginBase.LOOP), PluginBase.LOOP);
loopListView.setAdapter(loopDataAdapter);
setListViewHeightBasedOnChildren(loopListView);
if (MainApp.getSpecificPluginsList(PluginBase.LOOP).size() == 0)
loopLabel.setVisibility(View.GONE);
treatmentsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsList(PluginBase.TREATMENT), PluginBase.TREATMENT);
treatmentsListView.setAdapter(treatmentsDataAdapter);
setListViewHeightBasedOnChildren(treatmentsListView);
tempsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsList(PluginBase.TEMPBASAL), PluginBase.TEMPBASAL);
tempsListView.setAdapter(tempsDataAdapter);
setListViewHeightBasedOnChildren(tempsListView);
if (MainApp.getSpecificPluginsList(PluginBase.TEMPBASAL).size() == 0)
tempsLabel.setVisibility(View.GONE);
profileDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsListByInterface(ProfileInterface.class), PluginBase.PROFILE);
profileListView.setAdapter(profileDataAdapter);
setListViewHeightBasedOnChildren(profileListView);
apsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsList(PluginBase.APS), PluginBase.APS);
apsListView.setAdapter(apsDataAdapter);
setListViewHeightBasedOnChildren(apsListView);
if (MainApp.getSpecificPluginsList(PluginBase.APS).size() == 0)
apsLabel.setVisibility(View.GONE);
constraintsDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class), PluginBase.CONSTRAINTS);
constraintsListView.setAdapter(constraintsDataAdapter);
setListViewHeightBasedOnChildren(constraintsListView);
if (MainApp.getSpecificPluginsList(PluginBase.CONSTRAINTS).size() == 0)
constraintsLabel.setVisibility(View.GONE);
generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsList(PluginBase.GENERAL), PluginBase.GENERAL);
generalListView.setAdapter(generalDataAdapter);
setListViewHeightBasedOnChildren(generalListView);
}
/*
* ConfigBuilderFragment code
*/
private class PluginCustomAdapter extends ArrayAdapter<PluginBase> {
private ArrayList<PluginBase> pluginList;
final private int type;
public PluginCustomAdapter(Context context, int textViewResourceId,
ArrayList<PluginBase> pluginList, int type) {
super(context, textViewResourceId, pluginList);
this.pluginList = new ArrayList<PluginBase>();
this.pluginList.addAll(pluginList);
this.type = type;
}
private class PluginViewHolder {
TextView name;
CheckBox checkboxEnabled;
CheckBox checkboxVisible;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
PluginViewHolder holder = null;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.configbuilder_simpleitem, null);
holder = new PluginViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.configbuilder_simpleitem_name);
holder.checkboxEnabled = (CheckBox) convertView.findViewById(R.id.configbuilder_simpleitem_checkboxenabled);
holder.checkboxVisible = (CheckBox) convertView.findViewById(R.id.configbuilder_simpleitem_checkboxvisible);
convertView.setTag(holder);
holder.checkboxEnabled.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
PluginBase plugin = (PluginBase) cb.getTag();
plugin.setFragmentEnabled(type, cb.isChecked());
plugin.setFragmentVisible(type, cb.isChecked());
onEnabledCategoryChanged(plugin, type);
configBuilderPlugin.storeSettings();
MainApp.bus().post(new EventRefreshGui(true));
MainApp.bus().post(new EventConfigBuilderChange());
getPlugin().logPluginStatus();
Answers.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
}
});
holder.checkboxVisible.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
PluginBase plugin = (PluginBase) cb.getTag();
plugin.setFragmentVisible(type, cb.isChecked());
configBuilderPlugin.storeSettings();
MainApp.bus().post(new EventRefreshGui(true));
getPlugin().logPluginStatus();
}
});
} else {
holder = (PluginViewHolder) convertView.getTag();
}
PluginBase plugin = pluginList.get(position);
holder.name.setText(plugin.getName());
holder.checkboxEnabled.setChecked(plugin.isEnabled(type));
holder.checkboxVisible.setChecked(plugin.isVisibleInTabs(type));
holder.name.setTag(plugin);
holder.checkboxEnabled.setTag(plugin);
holder.checkboxVisible.setTag(plugin);
if (!plugin.canBeHidden(type)) {
holder.checkboxEnabled.setEnabled(false);
holder.checkboxVisible.setEnabled(false);
}
if (!plugin.isEnabled(type)) {
holder.checkboxVisible.setEnabled(false);
}
// Hide enabled control and force enabled plugin if there is only one plugin available
if (type == PluginBase.PUMP || type == PluginBase.TREATMENT || type == PluginBase.TEMPBASAL || type == PluginBase.PROFILE)
if (pluginList.size() < 2) {
holder.checkboxEnabled.setEnabled(false);
plugin.setFragmentEnabled(type, true);
getPlugin().storeSettings();
}
// Constraints cannot be disabled
if (type == PluginBase.CONSTRAINTS)
holder.checkboxEnabled.setEnabled(false);
// Hide disabled profiles by default
if (type == PluginBase.PROFILE) {
if (!plugin.isEnabled(type)) {
holder.checkboxVisible.setEnabled(false);
holder.checkboxVisible.setChecked(false);
} else {
holder.checkboxVisible.setEnabled(true);
}
}
// Disable profile control for pump profiles if pump is not enabled
if (type == PluginBase.PROFILE) {
if (PumpInterface.class.isAssignableFrom(plugin.getClass())) {
if (!plugin.isEnabled(PluginBase.PUMP)) {
holder.checkboxEnabled.setEnabled(false);
holder.checkboxEnabled.setChecked(false);
}
}
}
return convertView;
}
}
void onEnabledCategoryChanged(PluginBase changedPlugin, int type) {
ArrayList<PluginBase> pluginsInCategory = null;
switch (type) {
// Multiple selection allowed
case PluginBase.GENERAL:
case PluginBase.CONSTRAINTS:
case PluginBase.LOOP:
break;
// Single selection allowed
case PluginBase.APS:
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(APSInterface.class);
break;
case PluginBase.PROFILE:
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(ProfileInterface.class);
break;
case PluginBase.BGSOURCE:
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(BgSourceInterface.class);
break;
case PluginBase.TEMPBASAL:
case PluginBase.TREATMENT:
case PluginBase.PUMP:
pluginsInCategory = MainApp.getSpecificPluginsListByInterface(PumpInterface.class);
break;
}
if (pluginsInCategory != null) {
boolean newSelection = changedPlugin.isEnabled(type);
if (newSelection) { // new plugin selected -> disable others
for (PluginBase p : pluginsInCategory) {
if (p.getName().equals(changedPlugin.getName())) {
// this is new selected
} else {
p.setFragmentEnabled(type, false);
p.setFragmentVisible(type, false);
}
}
} else { // enable first plugin in list
if (type == PluginBase.PUMP)
MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setFragmentEnabled(type, true);
else if (type == PluginBase.PROFILE)
MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentEnabled(type, true);
else
pluginsInCategory.get(0).setFragmentEnabled(type, true);
}
setViews();
}
}
/****
* Method for Setting the Height of the ListView dynamically.
* *** Hack to fix the issue of not showing all the items of the ListView
* *** when placed inside a ScrollView
****/
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
}