package moontime.droid;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import moontime.MoonEvent;
import moontime.MoonEvent.EventAllocation;
import moontime.MoonEventType;
import moontime.droid.service.MoontimeApplication;
import moontime.droid.service.MoontimeService;
import moontime.droid.store.WidgetPreferences;
import moontime.droid.util.SpannableBuilder;
import moontime.droid.util.Util;
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.graphics.Typeface;
import android.net.Uri;
import android.text.Spannable;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.widget.RemoteViews;
import com.google.inject.Inject;
public class WidgetProvider extends AppWidgetProvider {
private static final Class<?> ON_CLICK_ACTIVITY = TabActivity.class;
@Inject
protected MoontimeService _moontimeService;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
updateService();
for (int widgetId : appWidgetIds) {
updateView(_moontimeService, context, appWidgetManager, widgetId);
}
}
private void updateService() {
if (_moontimeService == null) {
_moontimeService = MoontimeApplication._moontimeServiceInstance;
// don't know how to bind here
}
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
updateService();
if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) {
Uri data = intent.getData();
int ordinal = Integer.parseInt(data.getSchemeSpecificPart());
Action control = Action.values()[ordinal];
control.execute(_moontimeService, this, context);
}
}
static void updateView(MoontimeService moontimeService, Context context, AppWidgetManager appWidgetManager,
int widgetId) {
long now = System.currentTimeMillis();
WidgetPreferences preferences = WidgetPreferences.initFromPreferences(context, widgetId);
DateFormat datePattern = new SimpleDateFormat(preferences.getDatePattern());
List<MoonEvent> moonEvents = moontimeService.getNextMoonEvents(3);
SpannableBuilder builder = new SpannableBuilder();
MoonEvent nextMoonEvent = null;
for (int i = 0; i < moonEvents.size(); i++) {
if (i > 0) {
builder.append("\n");
}
MoonEvent moonEvent = moonEvents.get(i);
EventAllocation eventAllocation = EventAllocation.getEventAllocation(now, moonEvent.getDate().getTime(),
Util.hoursToMillis(12), Util.hoursToMillis(24));
if (eventAllocation != EventAllocation.IN_PAST && nextMoonEvent == null) {
nextMoonEvent = moonEvent;
}
String moonEventString = toString(moonEvent, datePattern, eventAllocation);
builder.startSpan().append(moonEventString);
if (eventAllocation == EventAllocation.IN_PRESENT) {
builder.setSpan(new StyleSpan(Typeface.BOLD), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
builder.closeSpan(getSpan(eventAllocation, moonEvent == nextMoonEvent), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setTextViewText(R.id.nextMoons, builder);
views.setTextColor(R.id.nextMoons, context.getResources().getColor(preferences.getTheme().getTextColor()));
Intent intent = new Intent(context, ON_CLICK_ACTIVITY);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
views.setOnClickPendingIntent(R.id.moonPic,
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
int moonPicId;
if (nextMoonEvent.getType() == MoonEventType.FULL_MOON) {
moonPicId = preferences.getTheme().getFullMoonPicId();
} else {
moonPicId = preferences.getTheme().getNewMoonPicId();
}
views.setImageViewResource(R.id.moonPic, moonPicId);
for (Action c : Action.values()) {
views.setOnClickPendingIntent(c.getId(), c.createIntent(context));
}
appWidgetManager.updateAppWidget(widgetId, views);
}
private static Object getSpan(EventAllocation eventAllocation, boolean isNextMoonEvent) {
switch (eventAllocation) {
case IN_FUTURE:
if (!isNextMoonEvent) {
// return new StyleSpan(Typeface.ITALIC);
return null;
}
return new StyleSpan(Typeface.BOLD);
case IN_PRESENT:
return new UnderlineSpan();
case IN_PAST:
return new StrikethroughSpan();
default:
throw new UnsupportedOperationException(eventAllocation.toString());
}
}
private static String toString(MoonEvent moonEvent, DateFormat datePattern, EventAllocation eventAllocation) {
String string = datePattern.format(moonEvent.getDate());
return string;
}
private static ComponentName[] WIDGET_PROVIDERS = { new ComponentName(WidgetProvider.class.getPackage().getName(),
WidgetProvider.class.getName()) };
enum Action {
DEBUG_ADD_TIME(R.id.debug_AddTimeButton) {
@Override
public void execute(MoontimeService moontimeService, WidgetProvider moontimeWidget, Context context) {
moontimeService.setDebugAdditionalTime(moontimeService.getDebugAdditionalTime() + Util.hoursToMillis(12));
updateViews(moontimeService, context);
}
},
DEBUG_REMOVE_TIME(R.id.debug_RemoveTimeButton) {
@Override
public void execute(MoontimeService moontimeService, WidgetProvider moontimeWidget, Context context) {
moontimeService.setDebugAdditionalTime(moontimeService.getDebugAdditionalTime() - Util.hoursToMillis(12));
updateViews(moontimeService, context);
}
},
RESET_ADD_TIME(R.id.debug_ResetTimeButton) {
@Override
public void execute(MoontimeService moontimeService, WidgetProvider moontimeWidget, Context context) {
moontimeService.setDebugAdditionalTime(0);
updateViews(moontimeService, context);
}
};
private int _id;
Action(int id) {
_id = id;
}
public abstract void execute(MoontimeService moontimeService, WidgetProvider moontimeWidget, Context context);
public int getId() {
return _id;
}
PendingIntent createIntent(Context context) {
Intent i = new Intent(context, WidgetProvider.class);
i.addCategory(Intent.CATEGORY_ALTERNATIVE);
i.setData(Uri.parse("custom:" + ordinal()));
return PendingIntent.getBroadcast(context, 0, i, 0);
}
private static void updateViews(MoontimeService moontimeService, Context context) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
for (ComponentName provider : WIDGET_PROVIDERS) {
int[] ids = appWidgetManager.getAppWidgetIds(provider);
for (int widgetId : ids) {
updateView(moontimeService, context, appWidgetManager, widgetId);
}
}
}
}
}