/*
* Copyright 2013-2015 The GDG Frisbee Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gdg.frisbee.android.appwidget;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.widget.RemoteViews;
import org.gdg.frisbee.android.Const;
import org.gdg.frisbee.android.R;
import org.gdg.frisbee.android.api.Callback;
import org.gdg.frisbee.android.api.model.Chapter;
import org.gdg.frisbee.android.api.model.Directory;
import org.gdg.frisbee.android.api.model.Event;
import org.gdg.frisbee.android.api.model.PagedList;
import org.gdg.frisbee.android.app.App;
import org.gdg.frisbee.android.cache.ModelCache;
import org.gdg.frisbee.android.chapter.MainActivity;
import org.gdg.frisbee.android.event.EventActivity;
import org.gdg.frisbee.android.utils.PrefUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import timber.log.Timber;
public class UpcomingEventWidgetProvider extends AppWidgetProvider {
private static final int REQUEST_CODE_LAUNCH_FRISBEE = 1000;
@Override
public void onUpdate(Context context, final AppWidgetManager appWidgetManager, int[] appWidgetIds) {
context.startService(new Intent(context, UpdateService.class));
}
public static class UpdateService extends Service {
private ArrayList<Chapter> mChapters;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
ComponentName thisWidget = new ComponentName(this, UpcomingEventWidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
// Build the widget update for today
buildUpdate(this, manager, thisWidget);
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Nullable
private Chapter findChapter(@Nullable String chapterId) {
if (chapterId != null) {
for (Chapter chapter : mChapters) {
if (chapter.getGplusId().equals(chapterId)) {
return chapter;
}
}
}
return null;
}
public void buildUpdate(final Context context, final AppWidgetManager manager, final ComponentName thisWidget) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_upcoming_event);
Intent mainIntent = new Intent(context, MainActivity.class);
final PendingIntent pi = PendingIntent.getActivity(context, REQUEST_CODE_LAUNCH_FRISBEE,
mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.container, pi);
App.from(this).getModelCache().getAsync(ModelCache.KEY_CHAPTER_LIST_HUB, false,
new ModelCache.CacheListener() {
@Override
public void onGet(Object item) {
mChapters = ((Directory) item).getGroups();
final Chapter homeGdg = findChapter(PrefUtils.getHomeChapterId(UpdateService.this));
if (homeGdg == null) {
Timber.d("Got no Home GDG");
showErrorChild(views, R.string.loading_data_failed, context);
} else {
Timber.d("Fetching events");
String groupName = homeGdg.getShortName();
views.setTextViewText(R.id.groupName, groupName);
views.setTextViewText(R.id.groupName2, groupName);
fetchEvents(homeGdg, views, manager, thisWidget);
}
}
@Override
public void onNotFound(String key) {
//To change body of implemented methods use File | Settings | File Templates.
}
});
}
@Nullable
private static Event getNextEvent(List<Event> listEvents) {
Event nextEvent = null;
for (Event e : listEvents) {
if (e.getStart().isBeforeNow()) {
continue;
}
if (nextEvent == null || e.getStart().isBefore(nextEvent.getStart())) {
nextEvent = e;
}
}
return nextEvent;
}
private void fetchEvents(Chapter homeGdg,
final RemoteViews views,
final AppWidgetManager manager,
final ComponentName thisWidget) {
App.from(this).getGdgXHub()
.getChapterEventList(homeGdg.getGplusId(),
new DateTime(),
new DateTime().plusMonths(1))
.enqueue(new Callback<PagedList<Event>>() {
@Override
public void onSuccess(PagedList<Event> eventsPagedList) {
Event nextEvent = getNextEvent(eventsPagedList.getItems());
if (nextEvent != null) {
views.setTextViewText(R.id.title, nextEvent.getTitle());
views.setTextViewText(R.id.location, nextEvent.getLocation());
views.setTextViewText(R.id.startDate,
nextEvent.getStart().toLocalDateTime()
.toString(DateTimeFormat.patternForStyle("MS",
Locale.getDefault())));
showChild(views, 1);
Intent i = new Intent(UpdateService.this, EventActivity.class);
i.putExtra(Const.EXTRA_EVENT_ID, nextEvent.getId());
views.setOnClickPendingIntent(R.id.container,
PendingIntent.getActivity(UpdateService.this, 0, i, 0));
} else {
showErrorChild(views, R.string.no_scheduled_events, UpdateService.this);
}
manager.updateAppWidget(thisWidget, views);
}
@Override
public void onError() {
showErrorChild(views, R.string.loading_data_failed, UpdateService.this);
manager.updateAppWidget(thisWidget, views);
}
@Override
public void onNetworkFailure(Throwable error) {
showErrorChild(views, R.string.offline_alert, UpdateService.this);
manager.updateAppWidget(thisWidget, views);
}
});
}
private void showErrorChild(RemoteViews views, int errorStringResource, Context context) {
views.setTextViewText(R.id.textView_no_events, getString(errorStringResource));
showChild(views, 0);
Intent i = new Intent(context, MainActivity.class);
views.setOnClickPendingIntent(R.id.container, PendingIntent.getActivity(context, 0, i, 0));
}
private static void showChild(RemoteViews views, int i) {
views.setDisplayedChild(R.id.viewFlipper, i);
}
}
}