/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gcal;
import java.util.ArrayList;
import java.util.Collections;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gcal.Calendars.CalendarResult;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.ui.PopupControlSet;
/**
* Control Set for managing repeats
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class GCalControlSet extends PopupControlSet {
// --- instance variables
@Autowired
private ExceptionService exceptionService;
private Uri calendarUri = null;
private final CalendarResult calendars;
private boolean hasEvent = false;
private Spinner calendarSelector;
private final int title;
private final ImageView image;
public GCalControlSet(final Activity activity, int viewLayout, int displayViewLayout, int title) {
super(activity, viewLayout, displayViewLayout, title);
DependencyInjectionService.getInstance().inject(this);
this.title = title;
calendars = Calendars.getCalendars();
getView(); // Hack to force initialized
image = (ImageView) getDisplayView().findViewById(R.id.display_row_icon);
}
@Override
protected void afterInflate() {
((LinearLayout) getDisplayView()).addView(getView()); //hack for spinner
this.calendarSelector = (Spinner) getView().findViewById(R.id.calendars);
ArrayList<String> items = new ArrayList<String>();
Collections.addAll(items, calendars.calendars);
items.add(0, activity.getString(R.string.gcal_TEA_nocal));
ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity,
android.R.layout.simple_spinner_item, items.toArray(new String[items.size()]));
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
calendarSelector.setPromptId(title);
calendarSelector.setAdapter(adapter);
resetCalendarSelector();
calendarSelector.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
refreshDisplayView();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
//nothing
}
});
}
@Override
protected void readFromTaskOnInitialize() {
String uri = GCalHelper.getTaskEventUri(model);
if(!TextUtils.isEmpty(uri)) {
try {
calendarUri = Uri.parse(uri);
// try to load calendar
ContentResolver cr = activity.getContentResolver();
Cursor cursor = cr.query(calendarUri, new String[] { "dtstart" }, null, null, null); //$NON-NLS-1$
try {
boolean deleted = cursor.getCount() == 0;
if(deleted) {
calendarUri = null;
return;
}
} finally {
cursor.close();
}
hasEvent = true;
} catch (Exception e) {
exceptionService.reportError("unable-to-parse-calendar: " + //$NON-NLS-1$
model.getValue(Task.CALENDAR_URI), e);
}
} else {
hasEvent = false;
calendarUri = null;
}
refreshDisplayView();
}
public void resetCalendarSelector() {
if (calendarSelector != null)
calendarSelector.setSelection(calendars.defaultIndex + 1); // plus 1 for the no selection item
}
@SuppressWarnings("nls")
@Override
protected String writeToModelAfterInitialized(Task task) {
if (!task.hasDueDate())
return null;
boolean gcalCreateEventEnabled = Preferences.getStringValue(R.string.gcal_p_default) != null &&
!Preferences.getStringValue(R.string.gcal_p_default).equals("-1");
if ((gcalCreateEventEnabled || calendarSelector.getSelectedItemPosition() != 0) &&
calendarUri == null) {
StatisticsService.reportEvent(StatisticsConstants.CREATE_CALENDAR_EVENT);
try{
ContentResolver cr = activity.getContentResolver();
ContentValues values = new ContentValues();
String calendarId = calendars.calendarIds[calendarSelector.getSelectedItemPosition() - 1];
values.put("calendar_id", calendarId);
calendarUri = GCalHelper.createTaskEvent(task, cr, values);
if(calendarUri != null) {
task.setValue(Task.CALENDAR_URI, calendarUri.toString());
if (calendarSelector.getSelectedItemPosition() != 0 && !hasEvent) {
// pop up the new event
Intent intent = new Intent(Intent.ACTION_EDIT, calendarUri);
intent.putExtra("beginTime", values.getAsLong("dtstart"));
intent.putExtra("endTime", values.getAsLong("dtend"));
activity.startActivity(intent);
}
}
} catch (Exception e) {
exceptionService.displayAndReportError(activity,
activity.getString(R.string.gcal_TEA_error), e);
}
} else if(calendarUri != null) {
try {
ContentValues updateValues = new ContentValues();
// check if we need to update the item
ContentValues setValues = task.getSetValues();
if(setValues.containsKey(Task.TITLE.name))
updateValues.put("title", task.getValue(Task.TITLE));
if(setValues.containsKey(Task.NOTES.name))
updateValues.put("description", task.getValue(Task.NOTES));
if(setValues.containsKey(Task.DUE_DATE.name) || setValues.containsKey(Task.ESTIMATED_SECONDS.name))
GCalHelper.createStartAndEndDate(task, updateValues);
ContentResolver cr = activity.getContentResolver();
if(cr.update(calendarUri, updateValues, null, null) > 0)
return activity.getString(R.string.gcal_TEA_calendar_updated);
} catch (Exception e) {
exceptionService.reportError("unable-to-update-calendar: " + //$NON-NLS-1$
task.getValue(Task.CALENDAR_URI), e);
}
}
return null;
}
@SuppressWarnings("nls")
private void viewCalendarEvent() {
if(calendarUri == null)
return;
ContentResolver cr = activity.getContentResolver();
Intent intent = new Intent(Intent.ACTION_EDIT, calendarUri);
Cursor cursor = cr.query(calendarUri, new String[] { "dtstart", "dtend" },
null, null, null);
try {
if(cursor.getCount() == 0) {
// event no longer exists, recreate it
calendarUri = null;
writeToModel(model);
return;
}
cursor.moveToFirst();
intent.putExtra("beginTime", cursor.getLong(0));
intent.putExtra("endTime", cursor.getLong(1));
} catch (Exception e) {
Log.e("gcal-error", "Error opening calendar", e); //$NON-NLS-1$ //$NON-NLS-2$
Toast.makeText(activity, R.string.gcal_TEA_error, Toast.LENGTH_LONG).show();
} finally {
cursor.close();
}
activity.startActivity(intent);
}
@Override
protected void refreshDisplayView() {
TextView calendar = (TextView) getDisplayView().findViewById(R.id.calendar_display_which);
calendar.setTextColor(themeColor);
image.setImageResource(ThemeService.getTaskEditDrawable(R.drawable.tea_icn_addcal, R.drawable.tea_icn_addcal_lightblue));
if (initialized) {
if (hasEvent) {
calendar.setText(R.string.gcal_TEA_has_event);
} else if (calendarSelector.getSelectedItemPosition() != 0) {
calendar.setText((String)calendarSelector.getSelectedItem());
} else {
calendar.setTextColor(unsetColor);
image.setImageResource(R.drawable.tea_icn_addcal_gray);
calendar.setText(R.string.gcal_TEA_none_selected);
}
} else {
int index = calendars.defaultIndex;
if (!TextUtils.isEmpty(model.getValue(Task.CALENDAR_URI))) {
calendar.setText(R.string.gcal_TEA_has_event);
} else if (index >= 0 && index < calendars.calendars.length) {
calendar.setText(calendars.calendars[index]);
} else {
calendar.setTextColor(unsetColor);
image.setImageResource(R.drawable.tea_icn_addcal_gray);
calendar.setText(R.string.gcal_TEA_none_selected);
}
}
}
@Override
protected OnClickListener getDisplayClickListener() {
return new OnClickListener() {
@Override
public void onClick(View v) {
if (calendarSelector == null)
getView(); // Force load
if (!hasEvent) {
calendarSelector.performClick();
} else {
viewCalendarEvent();
}
}
};
}
}