/*
 * 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 com.android.systemui.statusbar;

import android.app.Notification;
import android.graphics.PorterDuff;
import android.graphics.drawable.Icon;
import android.text.TextUtils;
import android.view.NotificationHeaderView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * A Util to manage {@link android.view.NotificationHeaderView} objects and their redundancies.
 */
public class NotificationHeaderUtil {

    private static final TextViewComparator sTextViewComparator = new TextViewComparator();
    private static final VisibilityApplicator sVisibilityApplicator = new VisibilityApplicator();
    private static  final DataExtractor sIconExtractor = new DataExtractor() {
        @Override
        public Object extractData(ExpandableNotificationRow row) {
            return row.getStatusBarNotification().getNotification();
        }
    };
    private static final IconComparator sIconVisibilityComparator = new IconComparator() {
        public boolean compare(View parent, View child, Object parentData,
                Object childData) {
            return hasSameIcon(parentData, childData)
                    && hasSameColor(parentData, childData);
        }
    };
    private static final IconComparator sGreyComparator = new IconComparator() {
        public boolean compare(View parent, View child, Object parentData,
                Object childData) {
            return !hasSameIcon(parentData, childData)
                    || hasSameColor(parentData, childData);
        }
    };
    private final static ResultApplicator mGreyApplicator = new ResultApplicator() {
        @Override
        public void apply(View view, boolean apply) {
            NotificationHeaderView header = (NotificationHeaderView) view;
            ImageView icon = (ImageView) view.findViewById(
                    com.android.internal.R.id.icon);
            ImageView expand = (ImageView) view.findViewById(
                    com.android.internal.R.id.expand_button);
            applyToChild(icon, apply, header.getOriginalIconColor());
            applyToChild(expand, apply, header.getOriginalNotificationColor());
        }

        private void applyToChild(View view, boolean shouldApply, int originalColor) {
            if (originalColor != NotificationHeaderView.NO_COLOR) {
                ImageView imageView = (ImageView) view;
                imageView.getDrawable().mutate();
                if (shouldApply) {
                    // lets gray it out
                    int grey = view.getContext().getColor(
                            com.android.internal.R.color.notification_icon_default_color);
                    imageView.getDrawable().setColorFilter(grey, PorterDuff.Mode.SRC_ATOP);
                } else {
                    // lets reset it
                    imageView.getDrawable().setColorFilter(originalColor,
                            PorterDuff.Mode.SRC_ATOP);
                }
            }
        }
    };

    private final ExpandableNotificationRow mRow;
    private final ArrayList<HeaderProcessor> mComparators = new ArrayList<>();
    private final HashSet<Integer> mDividers = new HashSet<>();

    public NotificationHeaderUtil(ExpandableNotificationRow row) {
        mRow = row;
        // To hide the icons if they are the same and the color is the same
        mComparators.add(new HeaderProcessor(mRow,
                com.android.internal.R.id.icon,
                sIconExtractor,
                sIconVisibilityComparator,
                sVisibilityApplicator));
        // To grey them out the icons and expand button when the icons are not the same
        mComparators.add(new HeaderProcessor(mRow,
                com.android.internal.R.id.notification_header,
                sIconExtractor,
                sGreyComparator,
                mGreyApplicator));
        mComparators.add(new HeaderProcessor(mRow,
                com.android.internal.R.id.profile_badge,
                null /* Extractor */,
                new ViewComparator() {
                    @Override
                    public boolean compare(View parent, View child, Object parentData,
                            Object childData) {
                        return parent.getVisibility() != View.GONE;
                    }

                    @Override
                    public boolean isEmpty(View view) {
                        if (view instanceof ImageView) {
                            return ((ImageView) view).getDrawable() == null;
                        }
                        return false;
                    }
                },
                sVisibilityApplicator));
        mComparators.add(HeaderProcessor.forTextView(mRow,
                com.android.internal.R.id.app_name_text));
        mComparators.add(HeaderProcessor.forTextView(mRow,
                com.android.internal.R.id.header_text));
        mDividers.add(com.android.internal.R.id.header_text_divider);
        mDividers.add(com.android.internal.R.id.time_divider);
    }

    public void updateChildrenHeaderAppearance() {
        List<ExpandableNotificationRow> notificationChildren = mRow.getNotificationChildren();
        if (notificationChildren == null) {
            return;
        }
        // Initialize the comparators
        for (int compI = 0; compI < mComparators.size(); compI++) {
            mComparators.get(compI).init();
        }

        // Compare all notification headers
        for (int i = 0; i < notificationChildren.size(); i++) {
            ExpandableNotificationRow row = notificationChildren.get(i);
            for (int compI = 0; compI < mComparators.size(); compI++) {
                mComparators.get(compI).compareToHeader(row);
            }
        }

        // Apply the comparison to the row
        for (int i = 0; i < notificationChildren.size(); i++) {
            ExpandableNotificationRow row = notificationChildren.get(i);
            for (int compI = 0; compI < mComparators.size(); compI++) {
                mComparators.get(compI).apply(row);
            }
            // We need to sanitize the dividers since they might be off-balance now
            sanitizeHeaderViews(row);
        }
    }

    private void sanitizeHeaderViews(ExpandableNotificationRow row) {
        if (row.isSummaryWithChildren()) {
            sanitizeHeader(row.getNotificationHeader());
            return;
        }
        final NotificationContentView layout = row.getPrivateLayout();
        sanitizeChild(layout.getContractedChild());
        sanitizeChild(layout.getHeadsUpChild());
        sanitizeChild(layout.getExpandedChild());
    }

    private void sanitizeChild(View child) {
        if (child != null) {
            NotificationHeaderView header = (NotificationHeaderView) child.findViewById(
                    com.android.internal.R.id.notification_header);
            sanitizeHeader(header);
        }
    }

    private void sanitizeHeader(NotificationHeaderView rowHeader) {
        if (rowHeader == null) {
            return;
        }
        final int childCount = rowHeader.getChildCount();
        View time = rowHeader.findViewById(com.android.internal.R.id.time);
        boolean hasVisibleText = false;
        for (int i = 1; i < childCount - 1 ; i++) {
            View child = rowHeader.getChildAt(i);
            if (child instanceof TextView
                    && child.getVisibility() != View.GONE
                    && !mDividers.contains(Integer.valueOf(child.getId()))
                    && child != time) {
                hasVisibleText = true;
                break;
            }
        }
        // in case no view is visible we make sure the time is visible
        int timeVisibility = !hasVisibleText
                || mRow.getStatusBarNotification().getNotification().showsTime()
                ? View.VISIBLE : View.GONE;
        time.setVisibility(timeVisibility);
        View left = null;
        View right;
        for (int i = 1; i < childCount - 1 ; i++) {
            View child = rowHeader.getChildAt(i);
            if (mDividers.contains(Integer.valueOf(child.getId()))) {
                boolean visible = false;
                // Lets find the item to the right
                for (i++; i < childCount - 1; i++) {
                    right = rowHeader.getChildAt(i);
                    if (mDividers.contains(Integer.valueOf(right.getId()))) {
                        // A divider was found, this needs to be hidden
                        i--;
                        break;
                    } else if (right.getVisibility() != View.GONE && right instanceof TextView) {
                        visible = left != null;
                        left = right;
                        break;
                    }
                }
                child.setVisibility(visible ? View.VISIBLE : View.GONE);
            } else if (child.getVisibility() != View.GONE && child instanceof TextView) {
                left = child;
            }
        }
    }

    public void restoreNotificationHeader(ExpandableNotificationRow row) {
        for (int compI = 0; compI < mComparators.size(); compI++) {
            mComparators.get(compI).apply(row, true /* reset */);
        }
        sanitizeHeaderViews(row);
    }

    private static class HeaderProcessor {
        private final int mId;
        private final DataExtractor mExtractor;
        private final ResultApplicator mApplicator;
        private final ExpandableNotificationRow mParentRow;
        private boolean mApply;
        private View mParentView;
        private ViewComparator mComparator;
        private Object mParentData;

        public static HeaderProcessor forTextView(ExpandableNotificationRow row, int id) {
            return new HeaderProcessor(row, id, null, sTextViewComparator, sVisibilityApplicator);
        }

        HeaderProcessor(ExpandableNotificationRow row, int id, DataExtractor extractor,
                ViewComparator comparator,
                ResultApplicator applicator) {
            mId = id;
            mExtractor = extractor;
            mApplicator = applicator;
            mComparator = comparator;
            mParentRow = row;
        }

        public void init() {
            mParentView = mParentRow.getNotificationHeader().findViewById(mId);
            mParentData = mExtractor == null ? null : mExtractor.extractData(mParentRow);
            mApply = !mComparator.isEmpty(mParentView);
        }
        public void compareToHeader(ExpandableNotificationRow row) {
            if (!mApply) {
                return;
            }
            NotificationHeaderView header = row.getNotificationHeader();
            if (header == null) {
                mApply = false;
                return;
            }
            Object childData = mExtractor == null ? null : mExtractor.extractData(row);
            mApply = mComparator.compare(mParentView, header.findViewById(mId),
                    mParentData, childData);
        }

        public void apply(ExpandableNotificationRow row) {
            apply(row, false /* reset */);
        }

        public void apply(ExpandableNotificationRow row, boolean reset) {
            boolean apply = mApply && !reset;
            if (row.isSummaryWithChildren()) {
                applyToView(apply, row.getNotificationHeader());
                return;
            }
            applyToView(apply, row.getPrivateLayout().getContractedChild());
            applyToView(apply, row.getPrivateLayout().getHeadsUpChild());
            applyToView(apply, row.getPrivateLayout().getExpandedChild());
        }

        private void applyToView(boolean apply, View parent) {
            if (parent != null) {
                View view = parent.findViewById(mId);
                if (view != null && !mComparator.isEmpty(view)) {
                    mApplicator.apply(view, apply);
                }
            }
        }
    }

    private interface ViewComparator {
        /**
         * @param parent the parent view
         * @param child the child view
         * @param parentData optional data for the parent
         * @param childData optional data for the child
         * @return whether to views are the same
         */
        boolean compare(View parent, View child, Object parentData, Object childData);
        boolean isEmpty(View view);
    }

    private interface DataExtractor {
        Object extractData(ExpandableNotificationRow row);
    }

    private static class TextViewComparator implements ViewComparator {
        @Override
        public boolean compare(View parent, View child, Object parentData, Object childData) {
            TextView parentView = (TextView) parent;
            TextView childView = (TextView) child;
            return parentView.getText().equals(childView.getText());
        }

        @Override
        public boolean isEmpty(View view) {
            return TextUtils.isEmpty(((TextView) view).getText());
        }
    }

    private static abstract class IconComparator implements ViewComparator {
        @Override
        public boolean compare(View parent, View child, Object parentData, Object childData) {
            return false;
        }

        protected boolean hasSameIcon(Object parentData, Object childData) {
            Icon parentIcon = ((Notification) parentData).getSmallIcon();
            Icon childIcon = ((Notification) childData).getSmallIcon();
            return parentIcon.sameAs(childIcon);
        }

        /**
         * @return whether two ImageViews have the same colorFilterSet or none at all
         */
        protected boolean hasSameColor(Object parentData, Object childData) {
            int parentColor = ((Notification) parentData).color;
            int childColor = ((Notification) childData).color;
            return parentColor == childColor;
        }

        @Override
        public boolean isEmpty(View view) {
            return false;
        }
    }

    private interface ResultApplicator {
        void apply(View view, boolean apply);
    }

    private static class VisibilityApplicator implements ResultApplicator {

        @Override
        public void apply(View view, boolean apply) {
            view.setVisibility(apply ? View.GONE : View.VISIBLE);
        }
    }
}
