/**
 * Copyright (C) 2015 ogaclejapan
 * Copyright (C) 2013 The Android Open Source Project
 * <p/>
 * 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
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * 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.zxhl.cms.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;

import com.zxhl.cms.R;


/**
 * <p/>
 * Forked from Google Samples &gt; SlidingTabsBasic &gt;
 * <a href="https://developer.android.com/samples/SlidingTabsBasic/src/com.example.android.common/view/SlidingTabLayout.html">SlidingTabStrip</a>
 */
public class TabLayout extends LinearLayout {

    private static final int AUTO_WIDTH = -1;

    private final RectF indicatorRectF = new RectF();
    private final boolean indicatorWithoutPadding;
    private final boolean indicatorAlwaysInCenter;
    private final int indicatorThickness;
    private final int indicatorWidth;
    private final float indicatorCornerRadius;
    private final Paint indicatorPaint;
    private final Paint dividerPaint;
    private final SimpleTabColorizer defaultTabColorizer;
    private final int indicatorMarginTop;
    private final int indicatorIndent;

    private int lastPosition;
    private int selectedPosition;
    private float selectionOffset;
    private TabIndicationInterpolator indicationInterpolator;
    private TabPagerIndicator.TabColorizer customTabColorizer;

    public TabLayout(Context context, AttributeSet attrs) {
        super(context);
        setWillNotDraw(false);

        final float density = getResources().getDisplayMetrics().density;

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabPagerIndicator);
        int indicatorColorsId = a.getResourceId(
                R.styleable.TabPagerIndicator_indicatorColors, NO_ID);
        // muti-colors
        final int[] indicatorColors = (indicatorColorsId == NO_ID)
                ? new int[]{a.getColor(
                R.styleable.TabPagerIndicator_indicatorColor, 0xFF33B5E5)}
                : getResources().getIntArray(indicatorColorsId);
        this.defaultTabColorizer = new SimpleTabColorizer();
        this.defaultTabColorizer.setIndicatorColors(indicatorColors);
        this.defaultTabColorizer.setDividerColors(0x20);
        this.indicatorAlwaysInCenter = a.getBoolean(
                R.styleable.TabPagerIndicator_indicatorAlwaysInCenter, false);
        this.indicatorWithoutPadding = a.getBoolean(
                R.styleable.TabPagerIndicator_indicatorWithoutPadding, false);
        this.indicatorThickness = a.getDimensionPixelSize(
                R.styleable.TabPagerIndicator_indicatorThickness, (int) (2 * density));
        this.indicatorMarginTop = a.getDimensionPixelSize(
                R.styleable.TabPagerIndicator_indicatorMarginTop, (int) (1.5 * density));
        this.indicatorWidth = a.getLayoutDimension(
                R.styleable.TabPagerIndicator_indicatorWidth, -1);
        this.indicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        this.indicatorCornerRadius = a.getDimension(
                R.styleable.TabPagerIndicator_indicatorCornerRadius, 0);
        this.indicatorIndent = a.getDimensionPixelOffset(R.styleable.TabPagerIndicator_indicatorIndent, 0);
        this.dividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        this.dividerPaint.setStrokeWidth((int) (1 * density));
        this.indicationInterpolator = TabIndicationInterpolator.of(a.getInt(
                R.styleable.TabPagerIndicator_indicatorInterpolation, TabIndicationInterpolator.ID_SMART));
        a.recycle();
    }


    /**
     * Blend {@code color1} and {@code color2} using the given ratio.
     *
     * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
     *              0.0 will return {@code color2}.
     */
    private static int blendColors(int color1, int color2, float ratio) {
        final float inverseRation = 1f - ratio;
        float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
        float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
        float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
        return Color.rgb((int) r, (int) g, (int) b);
    }

    void setSelectedIndicatorColors(int... colors) {
        // Make sure that the custom colorizer is removed
        customTabColorizer = null;
        defaultTabColorizer.setIndicatorColors(colors);
        invalidate();
    }

    void onViewPagerPageChanged(int position, float positionOffset) {
        selectedPosition = position;
        selectionOffset = positionOffset;
        if (positionOffset == 0f && lastPosition != selectedPosition) {
            lastPosition = selectedPosition;
        }
        invalidate();
    }

    boolean isIndicatorAlwaysInCenter() {
        return indicatorAlwaysInCenter;
    }

    TabPagerIndicator.TabColorizer getTabColorizer() {
        return (customTabColorizer != null) ? customTabColorizer : defaultTabColorizer;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawDecoration(canvas);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        drawDecoration(canvas);
    }

    private void drawDecoration(Canvas canvas) {
        // Thick colored underline below the current selection
        if (getChildCount() > 1) {
            TabPagerIndicator.TabColorizer tabColorizer = getTabColorizer();
            View selectedTab = getChildAt(selectedPosition);
            int left = TabPagerIndicator.Utils.getStart(selectedTab, indicatorWithoutPadding);
            int right = TabPagerIndicator.Utils.getEnd(selectedTab, indicatorWithoutPadding);

            int color = tabColorizer.getIndicatorColor(selectedPosition);
            float thickness = indicatorThickness;

            if (selectionOffset > 0f && selectedPosition < (getChildCount() - 1)) {
                int nextColor = tabColorizer.getIndicatorColor(selectedPosition + 1);
                if (color != nextColor) {
                    color = blendColors(nextColor, color, selectionOffset);
                }

                // Draw the selection partway between the tabs
                float startOffset = indicationInterpolator.getLeftEdge(selectionOffset);
                float endOffset = indicationInterpolator.getRightEdge(selectionOffset);

                View nextTab = getChildAt(selectedPosition + 1);
                int nextStart = TabPagerIndicator.Utils.getStart(nextTab, indicatorWithoutPadding);
                int nextEnd = TabPagerIndicator.Utils.getEnd(nextTab, indicatorWithoutPadding);
                left = (int) (startOffset * nextStart + (1.0f - startOffset) * left);
                right = (int) (endOffset * nextEnd + (1.0f - endOffset) * right);
            }

            drawIndicator(canvas, left, right, (int) (indicatorMarginTop +  thickness / 2), thickness, color);
        }
    }


    private void drawIndicator(Canvas canvas, int left, int right, int start, float thickness,
                               int color) {
        if (indicatorThickness <= 0 || indicatorWidth == 0) {
            return;
        }

        float center = start - (thickness / 2f);
        float top = center - (thickness / 2f);
        float bottom = center + (thickness / 2f);

        indicatorPaint.setColor(color);
        if (indicatorWidth == AUTO_WIDTH) {
            indicatorRectF.set(left + indicatorIndent, top, right - indicatorIndent, bottom);
        } else {
            float padding = (Math.abs(left - right) - indicatorWidth) / 2f;
            indicatorRectF.set(left + padding + indicatorIndent, top, right - padding - indicatorIndent, bottom);
        }

        if (indicatorCornerRadius > 0f) {
            canvas.drawRoundRect(
                    indicatorRectF, indicatorCornerRadius,
                    indicatorCornerRadius, indicatorPaint);
        } else {
            canvas.drawRect(indicatorRectF, indicatorPaint);
        }
    }

    private static class SimpleTabColorizer implements TabPagerIndicator.TabColorizer {

        private int[] indicatorColors;
        private int[] dividerColors;

        @Override
        public final int getIndicatorColor(int position) {
            return indicatorColors[position % indicatorColors.length];
        }

        @Override
        public final int getDividerColor(int position) {
            return dividerColors[position % dividerColors.length];
        }

        void setIndicatorColors(int... colors) {
            indicatorColors = colors;
        }

        void setDividerColors(int... colors) {
            dividerColors = colors;
        }
    }

    public void setIndicatorColor(int color) {
        if (defaultTabColorizer != null) {
            defaultTabColorizer.setIndicatorColors(color);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        int childTop;
//        int childBottom;
//        int childHeight;
//
//        childHeight = getChildAt(0).getMeasuredHeight();
//        childTop = t + ((b - t) - childHeight) / 2;
//        childBottom = b - ((b - t) - childHeight) / 2;
//
//        if (getChildCount() == 3) {
//            int[] childWidth = new int[]{getChildAt(0).getMeasuredWidth(), getChildAt(1).getMeasuredWidth(), getChildAt(2).getMeasuredWidth()};
//            int dimen = Utils.getDimenPx(getResources(), R.dimen.x170);
//            int childMargin = (getMeasuredWidth() - dimen * 2 - childWidth[0] - childWidth[1] - childWidth[2]) / 2;
//
//            getChildAt(0).layout(dimen, childTop, dimen + childWidth[0], childBottom);
//            getChildAt(1).layout(dimen + childWidth[0] + childMargin, childTop, dimen + childWidth[0] + childMargin + childWidth[1], childBottom);
//            getChildAt(2).layout(dimen + childWidth[0] + childMargin + childWidth[1] + childMargin, childTop, dimen + childWidth[0] + childMargin +
//                childWidth[1] + childMargin + childWidth[2], childBottom);
//        } else if (getChildCount() == 2) {
//            int dimen = Utils.getDimenPx(getResources(), R.dimen.x260);
//            View child1 = getChildAt(0);
//            View child2 = getChildAt(1);
//
//            int childLift = getMeasuredWidth() - child2.getMeasuredWidth() - dimen;
//            child1.layout(dimen, childTop, dimen + child1.getMeasuredWidth(), childBottom);
//            child2.layout(childLift, childTop, childLift + child2.getMeasuredWidth(), childBottom);
//        } else {
            super.onLayout(changed, l, t, r, b);
//        }
    }

    public abstract static class TabIndicationInterpolator {

        public static final TabIndicationInterpolator SMART = new SmartIndicationInterpolator();
        public static final TabIndicationInterpolator LINEAR = new LinearIndicationInterpolator();

        static final int ID_SMART = 0;
        static final int ID_LINEAR = 1;

        public static TabIndicationInterpolator of(int id) {
            switch (id) {
                case ID_SMART:
                    return SMART;
                case ID_LINEAR:
                    return LINEAR;
                default:
                    throw new IllegalArgumentException("Unknown id: " + id);
            }
        }

        public abstract float getLeftEdge(float offset);

        public abstract float getRightEdge(float offset);

        public static class SmartIndicationInterpolator extends TabIndicationInterpolator {

            private static final float DEFAULT_INDICATOR_INTERPOLATION_FACTOR = 3.0f;

            private final Interpolator leftEdgeInterpolator;
            private final Interpolator rightEdgeInterpolator;

            public SmartIndicationInterpolator() {
                this(DEFAULT_INDICATOR_INTERPOLATION_FACTOR);
            }

            public SmartIndicationInterpolator(float factor) {
                leftEdgeInterpolator = new AccelerateInterpolator(factor);
                rightEdgeInterpolator = new DecelerateInterpolator(factor);
            }

            @Override
            public float getLeftEdge(float offset) {
                return leftEdgeInterpolator.getInterpolation(offset);
            }

            @Override
            public float getRightEdge(float offset) {
                return rightEdgeInterpolator.getInterpolation(offset);
            }
        }

        public static class LinearIndicationInterpolator extends TabIndicationInterpolator {

            @Override
            public float getLeftEdge(float offset) {
                return offset;
            }

            @Override
            public float getRightEdge(float offset) {
                return offset;
            }
        }
    }
}
