/*
 * Copyright (C) 2016 Jorge Ruesga
 *
 * 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.ruesga.rview.widget;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.databinding.DataBindingUtil;
import android.graphics.drawable.Drawable;
import android.support.annotation.Keep;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;

import com.google.android.flexbox.FlexboxLayout;
import com.ruesga.rview.R;
import com.ruesga.rview.databinding.ScoreItemBinding;
import com.ruesga.rview.gerrit.model.LabelInfo;
import com.ruesga.rview.misc.AndroidHelper;
import com.ruesga.rview.misc.BitmapUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ScoreLabelsView extends FlexboxLayout {
    @Keep
    public static class Model {
        public boolean visible = false;
        public String label;
        public String score;
        public ColorStateList color;
    }

    private static final Pattern sShortLabelPattern = Pattern.compile("[A-Z]+");
    private static final Map<String, String> sShortLabelCache = new HashMap<>();

    private final Map<String, Model> mScores = new TreeMap<>();
    private final List<ScoreItemBinding> mBindings = new ArrayList<>();
    private final LayoutInflater mInflater;
    private boolean mIsShortLabels;

    private final ColorStateList mApprovedColor, mRejectedColor, mNoScoreColor;

    public ScoreLabelsView(Context context) {
        this(context, null);
    }

    public ScoreLabelsView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ScoreLabelsView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mInflater = LayoutInflater.from(context);

        mApprovedColor = ContextCompat.getColorStateList(getContext(), R.color.approved);
        mRejectedColor = ContextCompat.getColorStateList(getContext(), R.color.rejected);
        mNoScoreColor = ContextCompat.getColorStateList(getContext(), R.color.noscore);

        Resources.Theme theme = context.getTheme();
        TypedArray a = theme.obtainStyledAttributes(
                attrs, R.styleable.ScoreLabelsView, defStyleAttr, 0);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.ScoreLabelsView_shortLabels:
                    mIsShortLabels = a.getBoolean(attr, false);
                    break;
            }
        }
        a.recycle();
    }

    public void setScores(Map<String, LabelInfo> scores) {
        if (scores.size() == 0) {
            mScores.clear();
            setVisibility(View.GONE);
            return;
        } else {
            setVisibility(View.VISIBLE);
        }

        sortScores(scores);
        int i = 0;
        for (String label : mScores.keySet()) {
            if (i >= getChildCount()) {
                ScoreItemBinding binding = DataBindingUtil.inflate(
                        mInflater, R.layout.score_item, this, false);
                addView(binding.getRoot());
                mBindings.add(binding);
            }

            Model model = mScores.get(label);
            model.visible = true;
            ScoreItemBinding binding = mBindings.get(i);

            if (!AndroidHelper.isLollipopOrGreater()) {
                Drawable dw = ContextCompat.getDrawable(getContext(), R.drawable.bg_tag);
                binding.scoreLayout.setBackground(BitmapUtils.tintDrawable(
                        getResources(), dw, model.color.getDefaultColor()));
            } else {
                ViewCompat.setBackgroundTintList(binding.scoreLayout, model.color);
            }
            binding.setModel(model);
            i++;
        }
        while (i < getChildCount()) {
            ScoreItemBinding binding = mBindings.get(i);
            Model model = new Model();
            binding.setModel(model);
            i++;
        }
    }

    private void sortScores(Map<String, LabelInfo> scores) {
        mScores.clear();
        if (scores != null) {
            for (String label : scores.keySet()) {
                final LabelInfo info = scores.get(label);
                final Model model = new Model();
                model.label = (mIsShortLabels ? toShortLabel(label) : label) + ": ";
                if (info.blocking || info.rejected != null) {
                    model.score = "\u2717";
                    model.color = mRejectedColor;
                } else if (info.disliked != null) {
                    model.score = "-1";
                    model.color = mRejectedColor;
                } else if (info.recommended != null) {
                    model.score = "+1";
                    model.color = mApprovedColor;
                } else if (info.approved != null) {
                    model.score = "\u2713";
                    model.color = mApprovedColor;
                } else {
                    model.score = " ";
                    model.color = mNoScoreColor;
                }
                model.visible = true;
                mScores.put(model.label, model);
            }
        }
    }

    private static String toShortLabel(String label) {
        if (!sShortLabelCache.containsKey(label)) {
            Matcher matcher = sShortLabelPattern.matcher(label);
            StringBuilder sb = new StringBuilder();
            while (matcher.find()) {
                sb.append(matcher.group(0));
            }
            sShortLabelCache.put(label, sb.toString());
        }
        return sShortLabelCache.get(label);
    }
}

@@ -5358,32 +5358,178 @@
 mRejectedColor;%0A
+                %7D else if (info.approved != null) %7B%0A                    model.score = %22%5Cu2713%22;%0A                    model.color = mApprovedColor;%0A
                 
@@ -5803,154 +5803,8 @@
 or;%0A
-                %7D else if (info.approved != null) %7B%0A                    model.score = %22%5Cu2713%22;%0A                    model.color = mApprovedColor;%0A
     

Increase approved's order preference