/*
 * Copyright (C) 2015 The Android Open Source 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 android.support.v7.app;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.SystemClock;
import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
import android.support.v4.app.NotificationCompatBase;
import android.support.v7.appcompat.R;
import android.util.TypedValue;
import android.view.View;
import android.widget.RemoteViews;

import java.text.NumberFormat;
import java.util.List;

/**
 * Helper class to generate MediaStyle notifications for pre-Lollipop platforms. Overrides
 * contentView and bigContentView of the notification.
 */
class NotificationCompatImplBase {

    static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
    static final int MAX_MEDIA_BUTTONS = 5;

    public static <T extends NotificationCompatBase.Action> void overrideContentView(
            NotificationBuilderWithBuilderAccessor builder,
            Context context, CharSequence contentTitle, CharSequence contentText,
            CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
            boolean useChronometer, long when, List<T> actions, int[] actionsToShowInCompact,
            boolean showCancelButton, PendingIntent cancelButtonIntent) {
        RemoteViews views = generateContentView(context, contentTitle, contentText, contentInfo,
                number, largeIcon, subText, useChronometer, when, actions, actionsToShowInCompact,
                showCancelButton, cancelButtonIntent);
        builder.getBuilder().setContent(views);
        if (showCancelButton) {
            builder.getBuilder().setOngoing(true);
        }
    }

    private static <T extends NotificationCompatBase.Action> RemoteViews generateContentView(
            Context context, CharSequence contentTitle, CharSequence contentText,
            CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
            boolean useChronometer, long when, List<T> actions, int[] actionsToShowInCompact,
            boolean showCancelButton, PendingIntent cancelButtonIntent) {
        RemoteViews view = applyStandardTemplate(context, contentTitle, contentText, contentInfo,
                number, largeIcon, subText, useChronometer, when,
                R.layout.notification_template_media, true /* fitIn1U */);

        final int numActions = actions.size();
        final int N = actionsToShowInCompact == null
                ? 0
                : Math.min(actionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
        view.removeAllViews(R.id.media_actions);
        if (N > 0) {
            for (int i = 0; i < N; i++) {
                if (i >= numActions) {
                    throw new IllegalArgumentException(String.format(
                            "setShowActionsInCompactView: action %d out of bounds (max %d)",
                            i, numActions - 1));
                }

                final NotificationCompatBase.Action action = actions.get(actionsToShowInCompact[i]);
                final RemoteViews button = generateMediaActionButton(context, action);
                view.addView(R.id.media_actions, button);
            }
        }
        if (showCancelButton) {
            view.setViewVisibility(R.id.end_padder, View.GONE);
            view.setViewVisibility(R.id.cancel_action, View.VISIBLE);
            view.setOnClickPendingIntent(R.id.cancel_action, cancelButtonIntent);
            view.setInt(R.id.cancel_action, "setAlpha",
                    context.getResources().getInteger(R.integer.cancel_button_image_alpha));
        } else {
            view.setViewVisibility(R.id.end_padder, View.VISIBLE);
            view.setViewVisibility(R.id.cancel_action, View.GONE);
        }
        return view;
    }

    public static <T extends NotificationCompatBase.Action> void overrideBigContentView(
            Notification n, Context context, CharSequence contentTitle, CharSequence contentText,
            CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
            boolean useChronometer, long when, List<T> actions, boolean showCancelButton,
            PendingIntent cancelButtonIntent) {
        n.bigContentView = generateBigContentView(context, contentTitle, contentText, contentInfo,
                number, largeIcon, subText, useChronometer, when, actions, showCancelButton,
                cancelButtonIntent);
        if (showCancelButton) {
            n.flags |= Notification.FLAG_ONGOING_EVENT;
        }
    }

    private static <T extends NotificationCompatBase.Action> RemoteViews generateBigContentView(
            Context context, CharSequence contentTitle, CharSequence contentText,
            CharSequence contentInfo, int number, Bitmap largeIcon, CharSequence subText,
            boolean useChronometer, long when, List<T> actions, boolean showCancelButton,
            PendingIntent cancelButtonIntent) {
        final int actionCount = Math.min(actions.size(), MAX_MEDIA_BUTTONS);
        RemoteViews big = applyStandardTemplate(context, contentTitle, contentText, contentInfo,
                number, largeIcon, subText, useChronometer, when,
                getBigLayoutResource(actionCount), false /* fitIn1U */);

        big.removeAllViews(R.id.media_actions);
        if (actionCount > 0) {
            for (int i = 0; i < actionCount; i++) {
                final RemoteViews button = generateMediaActionButton(context, actions.get(i));
                big.addView(R.id.media_actions, button);
            }
        }
        if (showCancelButton) {
            big.setViewVisibility(R.id.cancel_action, View.VISIBLE);
            big.setInt(R.id.cancel_action, "setAlpha",
                    context.getResources().getInteger(R.integer.cancel_button_image_alpha));
            big.setOnClickPendingIntent(R.id.cancel_action, cancelButtonIntent);
        } else {
            big.setViewVisibility(R.id.cancel_action, View.GONE);
        }
        return big;
    }

    private static RemoteViews generateMediaActionButton(Context context,
            NotificationCompatBase.Action action) {
        final boolean tombstone = (action.getActionIntent() == null);
        RemoteViews button = new RemoteViews(context.getPackageName(),
                R.layout.notification_media_action);
        button.setImageViewResource(R.id.action0, action.getIcon());
        if (!tombstone) {
            button.setOnClickPendingIntent(R.id.action0, action.getActionIntent());
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
            button.setContentDescription(R.id.action0, action.getTitle());
        }
        return button;
    }

    private static int getBigLayoutResource(int actionCount) {
        if (actionCount <= 3) {
            return R.layout.notification_template_big_media_narrow;
        } else {
            return R.layout.notification_template_big_media;
        }
    }

    private static RemoteViews applyStandardTemplate(Context context,
            CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
            int number, Bitmap largeIcon, CharSequence subText, boolean useChronometer, long when,
            int resId, boolean fitIn1U) {
        RemoteViews contentView = new RemoteViews(context.getPackageName(), resId);
        boolean showLine3 = false;
        boolean showLine2 = false;

        // On versions before Jellybean, the large icon was shown by SystemUI, so we need to hide
        // it here.
        if (largeIcon != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            contentView.setViewVisibility(R.id.icon, View.VISIBLE);
            contentView.setImageViewBitmap(R.id.icon, largeIcon);
        } else {
            contentView.setViewVisibility(R.id.icon, View.GONE);
        }
        if (contentTitle != null) {
            contentView.setTextViewText(R.id.title, contentTitle);
        }
        if (contentText != null) {
            contentView.setTextViewText(R.id.text, contentText);
            showLine3 = true;
        }
        if (contentInfo != null) {
            contentView.setTextViewText(R.id.info, contentInfo);
            contentView.setViewVisibility(R.id.info, View.VISIBLE);
            showLine3 = true;
        } else if (number > 0) {
            final int tooBig = context.getResources().getInteger(
                    R.integer.status_bar_notification_info_maxnum);
            if (number > tooBig) {
                contentView.setTextViewText(R.id.info, context.getResources().getString(
                        R.string.status_bar_notification_info_overflow));
            } else {
                NumberFormat f = NumberFormat.getIntegerInstance();
                contentView.setTextViewText(R.id.info, f.format(number));
            }
            contentView.setViewVisibility(R.id.info, View.VISIBLE);
            showLine3 = true;
        } else {
            contentView.setViewVisibility(R.id.info, View.GONE);
        }

        // Need to show three lines? Only allow on Jellybean+
        if (subText != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            contentView.setTextViewText(R.id.text, subText);
            if (contentText != null) {
                contentView.setTextViewText(R.id.text2, contentText);
                contentView.setViewVisibility(R.id.text2, View.VISIBLE);
                showLine2 = true;
            } else {
                contentView.setViewVisibility(R.id.text2, View.GONE);
            }
        }

        // RemoteViews.setViewPadding and RemoteViews.setTextViewTextSize is not available on ICS-
        if (showLine2 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            if (fitIn1U) {
                // need to shrink all the type to make sure everything fits
                final Resources res = context.getResources();
                final float subTextSize = res.getDimensionPixelSize(
                        R.dimen.notification_subtext_size);
                contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
            }
            // vertical centering
            contentView.setViewPadding(R.id.line1, 0, 0, 0, 0);
        }

        if (when != 0) {
            if (useChronometer) {
                contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
                contentView.setLong(R.id.chronometer, "setBase",
                        when + (SystemClock.elapsedRealtime() - System.currentTimeMillis()));
                contentView.setBoolean(R.id.chronometer, "setStarted", true);
            } else {
                contentView.setViewVisibility(R.id.time, View.VISIBLE);
                contentView.setLong(R.id.time, "setTime", when);
            }
        }
        contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
        return contentView;
    }
}
