/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.ui;
import java.text.ParseException;
import java.util.Date;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Configuration;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import com.google.ical.values.Frequency;
import com.google.ical.values.RRule;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.activity.AstridActivity;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.repeats.RepeatTaskCompleteListener;
import com.todoroo.astrid.ui.DateAndTimeDialog.DateAndTimeDialogListener;
import com.todoroo.astrid.utility.Flags;
/**
* Helper class that creates a dialog to confirm the results of a quick add markup
* @author Sam
*
*/
public class DateChangedAlerts {
/** Preference key for how many of these helper dialogs we've shown */
public static final String PREF_NUM_HELPERS_SHOWN = "pref_num_date_helpers"; //$NON-NLS-1$
/** Preference key for whether or not we should show such dialogs */
public static final int PREF_SHOW_HELPERS = R.string.p_showSmartConfirmation_key;
/** Start showing the option to hide future notifs after this many confirmation dialogs */
public static final int HIDE_CHECKBOX_AFTER_SHOWS = 3;
public static void showQuickAddMarkupDialog(final AstridActivity activity, Task task, String originalText) {
if (!Preferences.getBoolean(PREF_SHOW_HELPERS, true))
return;
final Dialog d = new Dialog(activity, R.style.ReminderDialog);
final long taskId = task.getId();
final boolean editable = task.isEditable();
d.setContentView(R.layout.astrid_reminder_view);
Button okButton = (Button) d.findViewById(R.id.reminder_complete);
okButton.setText(R.string.DLG_ok);
d.findViewById(R.id.reminder_snooze).setVisibility(View.GONE);
((TextView) d.findViewById(R.id.reminder_title)).setText(activity.getString(R.string.TLA_quickadd_confirm_title, originalText));
Spanned speechBubbleText = constructSpeechBubbleTextForQuickAdd(activity, task);
((TextView) d.findViewById(R.id.reminder_message)).setText(speechBubbleText, TextView.BufferType.SPANNABLE);
setupOkAndDismissButtons(d);
setupHideCheckbox(d);
d.findViewById(R.id.reminder_edit).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
activity.onTaskListItemClicked(taskId, editable);
}
});
setupDialogLayoutParams(activity, d);
d.setOwnerActivity(activity);
d.show();
}
public static void showRepeatChangedDialog(final AstridActivity activity, Task task) {
if (!Preferences.getBoolean(PREF_SHOW_HELPERS, true))
return;
final Dialog d = new Dialog(activity, R.style.ReminderDialog);
d.setContentView(R.layout.astrid_reminder_view);
Button okButton = (Button) d.findViewById(R.id.reminder_complete);
okButton.setText(R.string.DLG_ok);
d.findViewById(R.id.reminder_snooze).setVisibility(View.GONE);
d.findViewById(R.id.reminder_edit).setVisibility(View.GONE);
((TextView) d.findViewById(R.id.reminder_title)).setText(activity.getString(R.string.TLA_repeat_scheduled_title, task.getValue(Task.TITLE)));
String speechBubbleText = constructSpeechBubbleTextForRepeat(activity, task);
((TextView) d.findViewById(R.id.reminder_message)).setText(speechBubbleText);
setupOkAndDismissButtons(d);
setupHideCheckbox(d);
setupDialogLayoutParams(activity, d);
d.setOwnerActivity(activity);
d.show();
}
public static final Property<?>[] REPEAT_RESCHEDULED_PROPERTIES =
new Property<?>[] {
Task.ID,
Task.TITLE,
Task.DUE_DATE,
Task.HIDE_UNTIL,
Task.REPEAT_UNTIL
};
public static void showRepeatTaskRescheduledDialog(final AstridActivity activity, final Task task,
final long oldDueDate, final long newDueDate, final boolean lastTime) {
if (!Preferences.getBoolean(PREF_SHOW_HELPERS, true))
return;
final Dialog d = new Dialog(activity, R.style.ReminderDialog);
d.setContentView(R.layout.astrid_reminder_view);
Button okButton = (Button) d.findViewById(R.id.reminder_complete);
Button undoButton = (Button) d.findViewById(R.id.reminder_edit);
Button keepGoing = (Button) d.findViewById(R.id.reminder_snooze);
if (!lastTime) {
keepGoing.setVisibility(View.GONE);
} else {
keepGoing.setText(R.string.repeat_keep_going);
keepGoing.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
long startDate = 0;
DateAndTimeDialog picker = new DateAndTimeDialog(activity, startDate, R.layout.repeat_until_dialog, R.string.repeat_until_title);
picker.setDateAndTimeDialogListener(new DateAndTimeDialogListener() {
@Override
public void onDateAndTimeSelected(long date) {
d.dismiss();
task.setValue(Task.REPEAT_UNTIL, date);
RepeatTaskCompleteListener.rescheduleTask(task, newDueDate);
Flags.set(Flags.REFRESH);
}
@Override
public void onDateAndTimeCancelled() {
//
}
});
picker.show();
}
});
}
okButton.setText(R.string.DLG_ok);
undoButton.setText(R.string.DLG_undo);
int titleResource = lastTime ? R.string.repeat_rescheduling_dialog_title_last_time : R.string.repeat_rescheduling_dialog_title;
((TextView) d.findViewById(R.id.reminder_title)).setText(
activity.getString(titleResource, task.getValue(Task.TITLE)));
String oldDueDateString = getRelativeDateAndTimeString(activity, oldDueDate);
String newDueDateString = getRelativeDateAndTimeString(activity, newDueDate);
String repeatUntilDateString = getRelativeDateAndTimeString(activity, task.getValue(Task.REPEAT_UNTIL));
int encouragementResource = lastTime ? R.array.repeat_encouragement_last_time : R.array.repeat_encouragement;
String[] encouragements = activity.getResources().getStringArray(encouragementResource);
String encouragement = encouragements[(int) (Math.random()*encouragements.length)];
String speechBubbleText;
if (lastTime)
speechBubbleText = activity.getString(R.string.repeat_rescheduling_dialog_bubble_last_time, repeatUntilDateString, encouragement);
else if (!TextUtils.isEmpty(oldDueDateString))
speechBubbleText = activity.getString(R.string.repeat_rescheduling_dialog_bubble, encouragement, oldDueDateString, newDueDateString);
else
speechBubbleText = activity.getString(R.string.repeat_rescheduling_dialog_bubble_no_date, encouragement, newDueDateString);
((TextView) d.findViewById(R.id.reminder_message)).setText(speechBubbleText);
setupOkAndDismissButtons(d);
setupHideCheckbox(d);
undoButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
task.setValue(Task.DUE_DATE, oldDueDate);
task.setValue(Task.COMPLETION_DATE, 0L);
long hideUntil = task.getValue(Task.HIDE_UNTIL);
if (hideUntil > 0)
task.setValue(Task.HIDE_UNTIL, hideUntil - (newDueDate - oldDueDate));
PluginServices.getTaskService().save(task);
Flags.set(Flags.REFRESH);
}
});
setupDialogLayoutParams(activity, d);
d.setOwnerActivity(activity);
d.show();
}
private static void setupOkAndDismissButtons(final Dialog d) {
d.findViewById(R.id.reminder_complete).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
}
});
d.findViewById(R.id.dismiss).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
d.dismiss();
}
});
}
private static void setupHideCheckbox(final Dialog d) {
int numShows = Preferences.getInt(PREF_NUM_HELPERS_SHOWN, 0);
numShows++;
if (numShows >= HIDE_CHECKBOX_AFTER_SHOWS) {
CheckBox checkbox = (CheckBox) d.findViewById(R.id.reminders_should_show);
checkbox.setVisibility(View.VISIBLE);
checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Preferences.setBoolean(PREF_SHOW_HELPERS, !isChecked);
}
});
}
Preferences.setInt(PREF_NUM_HELPERS_SHOWN, numShows);
}
private static void setupDialogLayoutParams(Context context, Dialog d) {
LayoutParams params = d.getWindow().getAttributes();
params.width = LayoutParams.FILL_PARENT;
params.height = LayoutParams.WRAP_CONTENT;
Configuration config = context.getResources().getConfiguration();
int size = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
if (AndroidUtilities.getSdkVersion() >= 9 && size == Configuration.SCREENLAYOUT_SIZE_XLARGE || size == Configuration.SCREENLAYOUT_SIZE_LARGE) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
params.width = metrics.widthPixels / 2;
}
d.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
}
@SuppressWarnings("nls")
private static Spanned constructSpeechBubbleTextForQuickAdd(Context context, Task task) {
String[] priorityStrings = context.getResources().getStringArray(R.array.TLA_priority_strings);
int[] colorsArray = new int[] { R.color.importance_1, R.color.importance_2, R.color.importance_3, R.color.importance_4 };
String title = task.getValue(Task.TITLE);
long date = task.getValue(Task.DUE_DATE);
String dueString = "";
if (!TextUtils.isEmpty(task.getValue(Task.RECURRENCE))) {
dueString = getRecurrenceString(context, task);
}
if (TextUtils.isEmpty(dueString)) {
dueString = getRelativeDateAndTimeString(context, date);
}
if (!TextUtils.isEmpty(dueString))
dueString = context.getString(R.string.TLA_quickadd_confirm_speech_bubble_date, dueString);
int priority = task.getValue(Task.IMPORTANCE);
if (priority >= priorityStrings.length)
priority = priorityStrings.length - 1;
String priorityString = priorityStrings[priority];
int color = context.getResources().getColor(colorsArray[priority]) - 0xff000000;
priorityString = String.format("<font color=\"#%s\">%s</font>", Integer.toHexString(color), priorityString);
String fullString = context.getString(R.string.TLA_quickadd_confirm_speech_bubble, title, dueString, priorityString);
return Html.fromHtml(fullString);
}
private static String constructSpeechBubbleTextForRepeat(Context context, Task task) {
String recurrence = getRecurrenceString(context, task);
return context.getString(R.string.TLA_repeat_scheduled_speech_bubble, recurrence);
}
@SuppressWarnings("nls")
private static String getRelativeDateAndTimeString(Context context, long date) {
String dueString = date > 0 ? DateUtilities.getRelativeDay(context, date, false) : "";
if(Task.hasDueTime(date))
dueString = String.format("%s at %s", dueString, //$NON-NLS-1$
DateUtilities.getTimeString(context, new Date(date)));
return dueString;
}
@SuppressWarnings("nls")
private static String getRecurrenceString(Context context, Task task) {
try {
RRule rrule = new RRule(task.sanitizedRecurrence());
String[] dateAbbrev = context.getResources().getStringArray(
R.array.repeat_interval);
String frequency = "";
Frequency freq = rrule.getFreq();
switch(freq) {
case DAILY:
frequency = dateAbbrev[0].toLowerCase();
break;
case WEEKLY:
frequency = dateAbbrev[1].toLowerCase();
break;
case MONTHLY:
frequency = dateAbbrev[2].toLowerCase();
break;
case HOURLY:
frequency = dateAbbrev[3].toLowerCase();
break;
case MINUTELY:
frequency = dateAbbrev[4].toLowerCase();
break;
case YEARLY:
frequency = dateAbbrev[5].toLowerCase();
}
if (!TextUtils.isEmpty(frequency)) {
String date = String.format("%s %s", rrule.getInterval(), frequency); //$NON-NLS-1$
return String.format(context.getString(R.string.repeat_detail_duedate),
date).toLowerCase(); // Every freq int
}
} catch (ParseException e) {
// Eh
}
return "";
}
}