package com.hypodiabetic.happ.integration.Objects; import android.app.Dialog; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Color; import android.support.design.widget.Snackbar; import android.support.v7.app.NotificationCompat; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.Button; import android.widget.ImageView; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import com.hypodiabetic.happ.Constants; import com.hypodiabetic.happ.MainActivity; import com.hypodiabetic.happ.MainApp; import com.hypodiabetic.happ.Notifications; import com.hypodiabetic.happ.Objects.Bolus; import com.hypodiabetic.happ.Objects.Integration; import com.hypodiabetic.happ.Objects.Profile; import com.hypodiabetic.happ.Objects.Pump; import com.hypodiabetic.happ.Objects.TempBasal; import com.hypodiabetic.happ.R; import com.hypodiabetic.happ.tools; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import io.realm.Realm; /** * Created by Tim on 14/02/2016. * This class collects and reviews updates from Insulin Integration App, as multiple updates may hit HAPP at once, this class combines them */ public class InsulinIntegrationNotify { ArrayList<HashMap<String, String>> detailList; //Details of Integrations ArrayList<HashMap<String, String>> detailListErrorsOnly; //Details of Integrations with errors List<Integration> recentlyUpdated; //All Integrations recently updated List<Integration> withErrors; //All Integrations with errors that have not been Acknowledged String snackbarMsg; //Summary String for Snackbar String errorMsg; //Summary String of error items public Boolean foundError; //Where errors found? public Boolean haveUpdates; //Updates found? private Realm realm; private Pump pump; private static String TAG = "InsulinIntegratNotify"; public InsulinIntegrationNotify(Realm realm){ Log.d(TAG, "InsulinIntegrationNotify: START"); this.realm = realm; detailList = new ArrayList<>(); detailListErrorsOnly = new ArrayList<>(); recentlyUpdated = Integration.getUpdatedInLastMins(1, Constants.treatmentService.INSULIN_INTEGRATION_APP, realm); withErrors = Integration.getIntegrationsWithErrors(Constants.treatmentService.INSULIN_INTEGRATION_APP, realm); snackbarMsg = ""; errorMsg = ""; foundError = false; haveUpdates = false; pump = new Pump(new Profile(new Date()), realm); SimpleDateFormat sdfDateTime = new SimpleDateFormat("dd MMM HH:mm", MainApp.instance().getResources().getConfiguration().locale); SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm", MainApp.instance().getResources().getConfiguration().locale); if (recentlyUpdated.size() > 0) haveUpdates = true; for (Integration integration : recentlyUpdated) { if (!integration.getState().equals("error") && !integration.getState().equals("error_ack")) { //Deal with errors later HashMap<String, String> detailListItem = new HashMap<String, String>(); if (!integration.getState().equals("delete_me")) { switch (integration.getLocal_object()) { case "bolus_delivery": Bolus bolus = Bolus.getBolus(integration.getLocal_object_id(), realm); detailListItem.put("value", tools.formatDisplayInsulin(bolus.getValue(), 2)); detailListItem.put("summary", bolus.getType()); snackbarMsg += integration.getState().toUpperCase() + ": " + tools.formatDisplayInsulin(bolus.getValue(), 2) + " " + integration.getType() + " " + sdfTime.format(integration.getDate_updated()) + "\n"; break; case "temp_basal": TempBasal tempBasal = TempBasal.getTempBasalByID(integration.getLocal_object_id(), realm); pump.setNewTempBasal(null, tempBasal); detailListItem.put("value", tools.formatDisplayBasal(tempBasal.getRate(), true)); detailListItem.put("summary", "(" + pump.getTempBasalPercent() + "%) " + tempBasal.getDuration() + "mins"); snackbarMsg += integration.getState().toUpperCase() + ": " + tools.formatDisplayBasal(tempBasal.getRate(), false) + " (" + pump.getTempBasalPercent() + "%) " + tempBasal.getDuration() + "mins " + sdfTime.format(integration.getDate_updated()) + "\n"; break; } detailListItem.put("happObjectType", integration.getLocal_object()); detailListItem.put("state", integration.getState().toUpperCase()); detailListItem.put("details", integration.getDetails()); detailListItem.put("action", "action:" + integration.getAction()); detailListItem.put("date", sdfDateTime.format(integration.getDate_updated())); detailListItem.put("intID", "INT ID:" + integration.getId()); detailList.add(detailListItem); } } } if (withErrors.size() > 0) foundError = true; for (Integration integrationWithError : withErrors) { HashMap<String, String> detailListItem = new HashMap<String, String>(); if (!integrationWithError.getState().equals("deleted")) { switch (integrationWithError.getLocal_object()) { case "bolus_delivery": Bolus bolus = Bolus.getBolus(integrationWithError.getLocal_object_id(), realm); detailListItem.put("value", tools.formatDisplayInsulin(bolus.getValue(), 2)); detailListItem.put("summary", bolus.getType()); errorMsg += integrationWithError.getState().toUpperCase() + ": " + tools.formatDisplayInsulin(bolus.getValue(), 2) + " " + bolus.getType() + "\n"; break; case "temp_basal": TempBasal tempBasal = TempBasal.getTempBasalByID(integrationWithError.getLocal_object_id(), realm); pump.setNewTempBasal(null, tempBasal); detailListItem.put("value", tools.formatDisplayBasal(tempBasal.getRate(), true)); detailListItem.put("summary", "(" + pump.getTempBasalPercent() + "%) " + tempBasal.getDuration() + "mins"); errorMsg += integrationWithError.getState().toUpperCase() + ": " + tools.formatDisplayBasal(tempBasal.getRate(), false) + " (" + pump.getTempBasalPercent() + "%) " + tempBasal.getDuration() + "mins\n"; break; } detailListItem.put("happObjectType", integrationWithError.getLocal_object()); detailListItem.put("state", integrationWithError.getState().toUpperCase()); detailListItem.put("details", integrationWithError.getDetails()); detailListItem.put("action", "action:" + integrationWithError.getAction()); detailListItem.put("date", sdfDateTime.format(integrationWithError.getDate_updated())); detailListItem.put("intID", "INT ID:" + integrationWithError.getId()); detailListErrorsOnly.add(detailListItem); } } Log.d(TAG, "InsulinIntegrationNotify: FINISH"); } public Snackbar getSnackbar(View v){ if (recentlyUpdated.size() > 0) { int snackbarLength = Snackbar.LENGTH_LONG; Snackbar snackbar = Snackbar.make(v, snackbarMsg, snackbarLength); View snackbarView = snackbar.getView(); TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text); //textView.setTextSize(TypedValue.COMPLEX_UNIT_SP,10F); textView.setMaxLines(recentlyUpdated.size()); snackbar.setAction("DETAILS", new View.OnClickListener() { @Override public void onClick(View view) { Dialog dialog = new Dialog(view.getContext()); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.integration_dialog); dialog.setCancelable(true); dialog.setCanceledOnTouchOutside(true); ListView list = (ListView) dialog.findViewById(R.id.integrationList); mySimpleAdapter adapter = new mySimpleAdapter(MainActivity.getInstance(), detailList, R.layout.integration_list_layout_insulin_summary, new String[]{"value", "summary", "state", "details", "happObjectType", "action", "date"}, new int[]{R.id.insulinSummaryAmount, R.id.insulinSummarySummary, R.id.insulinSummaryState, R.id.insulinSummaryDetails, R.id.insulinSummaryHappObjectType, R.id.insulinSummaryAction, R.id.insulinSummaryDate}); list.setAdapter(adapter); dialog.show(); } }); return snackbar; } else { return null; } } public Dialog showErrorDetailsDialog(View view){ final Dialog dialog = new Dialog(view.getContext()); dialog.setTitle("Error: Insulin Actions"); dialog.setContentView(R.layout.integration_dialog); dialog.setCancelable(true); dialog.setCanceledOnTouchOutside(true); TextView msg = (TextView) dialog.findViewById(R.id.integrationMsg); msg.setText(R.string.InsulinIntegrationNotify_actions_failed); msg.setVisibility(View.VISIBLE); Button buttonOK = (Button) dialog.findViewById(R.id.integrationOK); buttonOK.setText(R.string.InsulinIntegrationNotify_acknowledge); buttonOK.setVisibility(View.VISIBLE); buttonOK.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { for (Integration integrationWithError : withErrors) { realm.beginTransaction(); integrationWithError.setState ("error_ack"); //User has Acknowledged the errors realm.commitTransaction(); } Notifications.clear("INSULIN_UPDATE"); dialog.dismiss(); } }); ListView list = (ListView) dialog.findViewById(R.id.integrationList); mySimpleAdapter adapter = new mySimpleAdapter(MainActivity.getInstance(), detailListErrorsOnly, R.layout.integration_list_layout_insulin_summary, new String[]{"value", "summary", "state", "details", "happObjectType", "action", "date", "intID"}, new int[]{R.id.insulinSummaryAmount, R.id.insulinSummarySummary, R.id.insulinSummaryState, R.id.insulinSummaryDetails, R.id.insulinSummaryHappObjectType, R.id.insulinSummaryAction, R.id.insulinSummaryDate, R.id.insulinSummaryINTID}); list.setAdapter(adapter); return dialog; } public NotificationCompat.Builder getErrorNotification(){ if (foundError) { Context c = MainApp.instance(); String title = "Error: Insulin Actions"; String msg = errorMsg; Bitmap bitmap = Bitmap.createBitmap(320,320, Bitmap.Config.ARGB_8888); bitmap.eraseColor(Color.RED); Intent intent_open_activity = new Intent(c, MainActivity.class); PendingIntent pending_intent_open_activity = PendingIntent.getActivity(c, 2, intent_open_activity, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(c); notificationBuilder.setSmallIcon(R.drawable.alert_circle); notificationBuilder.setContentTitle(title); notificationBuilder.setContentText(msg); notificationBuilder.setContentIntent(pending_intent_open_activity); notificationBuilder.setPriority(Notification.PRIORITY_MAX); notificationBuilder.setCategory(Notification.CATEGORY_ALARM); notificationBuilder.setVisibility(Notification.VISIBILITY_PUBLIC); notificationBuilder.setVibrate(new long[]{500, 1000, 500, 500, 500, 1000, 500}); return notificationBuilder; } else { return null; } } public class mySimpleAdapter extends SimpleAdapter { private Context mContext; public mySimpleAdapter(Context context, List<HashMap<String, String>> items, int resource, String[] from, int[] to) { super(context, items, resource, from, to); this.mContext = context; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); ImageView imageView = (ImageView) view.findViewById(R.id.insulinSummaryStateImage); TextView textView = (TextView) view.findViewById(R.id.insulinSummaryState); imageView.setBackgroundResource(tools.getIntegrationStatusImg(textView.getText().toString())); TextView happObject = (TextView) view.findViewById(R.id.insulinSummaryHappObjectType); TextView value = (TextView) view.findViewById(R.id.insulinSummaryAmount); switch (happObject.getText().toString()){ case "bolus_delivery": value.setBackgroundResource(R.drawable.insulin_treatment_round); value.setMaxLines(1); break; case "temp_basal": value.setBackgroundResource(R.drawable.insulin_basal_square); value.setMaxLines(2); break; } return view; } } }