/*
 * Copyright 2013 Nicolas Picon <nicopico.dev@gmail.com>
 *
 * 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 fr.nicopico.dashclock.birthday;

import fr.nicopico.dashclock.birthday.data.Birthday;
import fr.nicopico.dashclock.birthday.data.BirthdayRetriever;
import org.joda.time.DateTime;
import org.joda.time.DateTimeFieldType;
import org.joda.time.Days;

import java.util.List;

import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import com.google.android.apps.dashclock.api.DashClockExtension;
import com.google.android.apps.dashclock.api.ExtensionData;

/**
 * User: Nicolas PICON
 * Date: 24/08/13 - 17:22
 */
public class BirthdayService extends DashClockExtension {

    public static final String PREF_DAYS_LIMIT_KEY = "pref_days_limit";
    public static final String PREF_SHOW_QUICK_CONTACT = "pref_show_quickcontact";

    private BirthdayRetriever birthdayRetriever;
    private int daysLimit;
    private boolean showQuickContact;

    @Override
    protected void onInitialize(boolean isReconnect) {
        super.onInitialize(isReconnect);
        birthdayRetriever = new BirthdayRetriever();
        updatePreferences();

        // Listen for contact update
        //noinspection ConstantConditions
        addWatchContentUris(new String[] {
                ContactsContract.Contacts.CONTENT_URI.toString()
        });
    }

    @SuppressWarnings("ConstantConditions")
    private void updatePreferences() {
        final SharedPreferences sharedPreferences =
                PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        daysLimit = Integer.valueOf(sharedPreferences.getString(PREF_DAYS_LIMIT_KEY, "7"));
        showQuickContact = sharedPreferences.getBoolean(PREF_SHOW_QUICK_CONTACT, true);
    }

    @Override
    protected void onUpdateData(int reason) {
        final List<Birthday> birthdays = birthdayRetriever.getContactWithBirthdays(getApplicationContext());
        final Resources res = getResources();

        if (reason == UPDATE_REASON_SETTINGS_CHANGED) {
            updatePreferences();
        }

        DateTime today = new DateTime();

        int upcomingBirthdays = 0;
        String collapsedTitle = null;
        String expandedTitle = null;
        StringBuilder body = new StringBuilder();

        for (Birthday birthday : birthdays) {
            DateTime birthdayEvent = birthday.birthdayDate.toDateTime(today);

            // How many days before the birthday ?
            int days;
            if (birthdayEvent.isAfter(today) || birthdayEvent.isEqual(today)) {
                days = Days.daysBetween(today, birthdayEvent).getDays();
            }
            else {
                // Next birthday event is next year
                days = Days.daysBetween(today, birthdayEvent.plusYears(1)).getDays();
            }

            // Should the birthday be displayed ?
            if (days <= daysLimit) {
                upcomingBirthdays++;

                if (upcomingBirthdays == 1) {
                    // A single birthday will be displayed
                    collapsedTitle = birthday.displayName;
                    expandedTitle = res.getString(R.string.single_birthday_title_format, birthday.displayName);
                }
                else {
                    // More than one birthday will be displayed
                    collapsedTitle = res.getString(R.string.multiple_birthdays_collapsed_title, upcomingBirthdays);
                    expandedTitle = res.getString(R.string.multiple_birthdays_title_format, upcomingBirthdays);

                    if (upcomingBirthdays == 2) {
                        // Modify previous line to include the contact name
                        body.insert(0, ", ");
                        body.insert(0, birthdays.get(0).displayName);
                    }
                }

                // More than 1 upcoming birthday: display contact name
                if (upcomingBirthdays > 1) {
                    body.append("\n").append(birthday.displayName).append(", ");
                }

                // Age
                if (!birthday.unknownYear) {
                    int age = today.get(DateTimeFieldType.year()) - birthday.year;
                    body.append(res.getString(R.string.age_format, age));
                    body.append(' ');
                }

                // When
                int daysFormatResId;
                switch (days) {
                case 0:
                    daysFormatResId = R.string.when_today_format;
                    break;
                case 1:
                    daysFormatResId = R.string.when_tomorrow_format;
                    break;
                default:
                    daysFormatResId = R.string.when_days_format;
                }

                body.append(res.getString(daysFormatResId, days));
            }
            else {
                // All visible birthdays have been processed
                break;
            }
        }

        if (upcomingBirthdays > 0) {
            Intent clickIntent = buildClickIntent(birthdays.subList(0, upcomingBirthdays));

            // Display message
            publishUpdate(
                    new ExtensionData()
                            .visible(true)
                            .icon(R.drawable.ic_extension_white)
                            .status(collapsedTitle)
                            .expandedTitle(expandedTitle)
                            .expandedBody(body.toString())
                            .clickIntent(clickIntent)
            );
        }
        else {
            // Nothing to show
            publishUpdate(new ExtensionData().visible(false));
        }
    }

    private Intent buildClickIntent(List<Birthday> birthdays) {
        Intent clickIntent;
        if (showQuickContact) {
            // Open QuickContact dialog on click
            clickIntent = QuickContactProxy.buildIntent(getApplicationContext(), birthdays.get(0).lookupKey);
        }
        else {
            clickIntent = new Intent(Intent.ACTION_VIEW);
            //noinspection ConstantConditions
            clickIntent.setData(
                    Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(birthdays.get(0).contactId))
            );
        }

        return clickIntent;
    }
}

@@ -661,246 +661,8 @@
 y;%0A%0A
-import fr.nicopico.dashclock.birthday.data.Birthday;%0Aimport fr.nicopico.dashclock.birthday.data.BirthdayRetriever;%0Aimport org.joda.time.DateTime;%0Aimport org.joda.time.DateTimeFieldType;%0Aimport org.joda.time.Days;%0A%0Aimport java.util.List;%0A%0A
 impo
@@ -688,16 +688,16 @@
 Intent;%0A
+
 import a
@@ -879,16 +879,17 @@
 ntract;%0A
+%0A
 import c
@@ -945,16 +945,16 @@
 ension;%0A
-
 import c
@@ -1006,16 +1006,255 @@
 nData;%0A%0A
+import org.joda.time.DateTime;%0Aimport org.joda.time.DateTimeFieldType;%0Aimport org.joda.time.Days;%0A%0Aimport java.util.List;%0A%0Aimport fr.nicopico.dashclock.birthday.data.Birthday;%0Aimport fr.nicopico.dashclock.birthday.data.BirthdayRetriever;%0A%0A
 /**%0A * U
@@ -3920,606 +3920,8 @@
    %7D
-%0A                else %7B%0A                    // More than one birthday will be displayed%0A                    collapsedTitle = res.getString(R.string.multiple_birthdays_collapsed_title, upcomingBirthdays);%0A                    expandedTitle = res.getString(R.string.multiple_birthdays_title_format, upcomingBirthdays);%0A%0A                    if (upcomingBirthdays == 2) %7B%0A                        // Modify previous line to include the contact name%0A                        body.insert(0, %22, %22);%0A                        body.insert(0, birthdays.get(0).displayName);%0A                    %7D%0A                %7D
 %0A%0A  
@@ -5190,24 +5190,147 @@
 rthdays));%0A%0A
+            if (upcomingBirthdays %3E 1) %7B%0A                collapsedTitle += %22 + %22 + (upcomingBirthdays - 1);%0A            %7D%0A%0A
             

Change in multiple birthdays handling