package de.fau.cs.mad.fablab.android.widget;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.util.Log;
import android.widget.RemoteViews;
import net.spaceapi.HackerSpace;
import net.spaceapi.State;
import java.util.Calendar;
import de.fau.cs.mad.fablab.android.R;
import de.fau.cs.mad.fablab.android.model.util.RestClient;
import de.fau.cs.mad.fablab.android.util.Formatter;
import de.fau.cs.mad.fablab.android.view.activities.MainActivity;
import de.fau.cs.mad.fablab.rest.myapi.SpaceApi;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public abstract class WidgetProviderBase extends AppWidgetProvider
{
protected RestClient restClient;
protected SpaceApi mSpaceApi;
protected static String DOOR_STATE_WIDGET_UPDATE = "de.fau.cs.mad.fablab.android.widget.DOOR_STATE_WIDGET_UPDATE";
protected String mSpaceName;
protected static SharedPreferences.Editor editor;
protected Handler mSpaceApiHandler = new Handler();
protected Runnable mSpaceApiRunner = new SpaceApiRunner();
protected static final String LOG_TAG = "widget";
protected Callback<HackerSpace> mSpaceApiCallback = new Callback<HackerSpace>()
{
@Override
public void success(HackerSpace hackerSpace, Response response)
{
State state = hackerSpace.getState();
updateState(state.getOpen(), state.getLastchange());
}
@Override
public void failure(RetrofitError error)
{
}
};
private PendingIntent createDoorStateIntent(Context context)
{
SharedPreferences prefs = context.getSharedPreferences("widget", Context.MODE_PRIVATE);
editor = prefs.edit();
Intent intent = new Intent(DOOR_STATE_WIDGET_UPDATE);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
Log.d(LOG_TAG, "Received intent " + intent);
SharedPreferences prefs = context.getSharedPreferences("widget", Context.MODE_PRIVATE);
editor = prefs.edit();
restClient = new RestClient(context, false);
mSpaceApi = restClient.getSpaceApi();
mSpaceName = context.getString(R.string.space_name);
double time = Double.longBitsToDouble(prefs.getLong("widget_time", 0L));
boolean isOpen = prefs.getBoolean("widget_isOpen", false);
mSpaceApiHandler.removeCallbacks(mSpaceApiRunner);
mSpaceApi.getSpace(mSpaceName, mSpaceApiCallback);
if (DOOR_STATE_WIDGET_UPDATE.equals(intent.getAction()))
{
Log.d(LOG_TAG, "Door state update");
// Get the widget manager and ids for this widget provider, then call the shared
// door state update method
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
for (int appWidgetID : ids)
{
updateAppWidget(context, appWidgetManager, appWidgetID, time, isOpen);
}
}
}
@Override
public void onEnabled(Context context)
{
super.onEnabled(context);
Log.d(LOG_TAG, "widget Provider enabled. Starting timer to update widget every second");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
SharedPreferences prefs = context.getSharedPreferences("widget", Context.MODE_PRIVATE);
editor = prefs.edit();
editor.putLong("widget_time", Double.doubleToLongBits(0.0));
editor.putBoolean("widget_isOpen", false);
Calendar calender = Calendar.getInstance();
calender.setTimeInMillis(System.currentTimeMillis());
calender.add(Calendar.SECOND, 1);
// update alarmManager each minute because the text view can display each minute
// creats an intent which calls onReceive each time interval
alarmManager.setRepeating(AlarmManager.RTC, calender.getTimeInMillis(), 10000, createDoorStateIntent(context));
}
@Override
public void onDisabled(Context context)
{
super.onDisabled(context);
Log.d(LOG_TAG, "Widget Provider disabled. Turning off timer");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(createDoorStateIntent(context));
SharedPreferences prefs = context.getSharedPreferences("widget", Context.MODE_PRIVATE);
editor = prefs.edit();
editor.remove("widget_time");
editor.remove("widget_isOpen");
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
super.onUpdate(context, appWidgetManager, appWidgetIds);
SharedPreferences prefs = context.getSharedPreferences("widget", Context.MODE_PRIVATE);
editor = prefs.edit();
double time = Double.longBitsToDouble(prefs.getLong("widget_time", 0L));
boolean isOpen = prefs.getBoolean("widget_isOpen", false);
for (int appWidgetID : appWidgetIds)
{
updateAppWidget(context, appWidgetManager, appWidgetID, time, isOpen);
}
}
protected void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, double lastChange, boolean isOpen)
{
long currentTimeSeconds = System.currentTimeMillis() / 1000L;
double minutesSinceLastChange = (currentTimeSeconds - lastChange) / 60;
long timeSinceLastChange = Double.valueOf(minutesSinceLastChange).longValue();
String timeSinceLastChangeAsString;
if(lastChange == 0.0) {
timeSinceLastChangeAsString = "0m";
} else {
timeSinceLastChangeAsString = Formatter.formatTime(timeSinceLastChange);
}
RemoteViews updateViews = new RemoteViews(context.getPackageName(), setRemoteViews());
updateViews.setTextViewText(R.id.widget_tv, timeSinceLastChangeAsString);
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntentClick = PendingIntent.getActivity(context, 0, intent, 0);
updateViews.setOnClickPendingIntent(R.id.widget, pendingIntentClick);
if(isOpen)
{
updateViews.setTextColor(R.id.widget_tv, context.getResources().getColor(R.color.appbar_color_opened));
updateViews.setImageViewResource(R.id.widget_iv, R.drawable.opened);
}
else
{
updateViews.setTextColor(R.id.widget_tv, context.getResources().getColor(R.color.appbar_color_closed));
updateViews.setImageViewResource(R.id.widget_iv, R.drawable.closed);
}
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
}
protected void updateState(boolean isOpen, double time)
{
if(editor != null) {
editor.putLong("widget_time", Double.doubleToLongBits(time));
editor.putBoolean("widget_isOpen", isOpen);
editor.apply();
}
}
abstract int setRemoteViews();
private class SpaceApiRunner implements Runnable {
@Override
public void run() {
mSpaceApi.getSpace(mSpaceName, mSpaceApiCallback);
}
}
}