/*
 * Copyright (C) 2014 Hippo Seven
 *
 * 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.hippo.ehviewer.effect;

import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.drawable.Drawable;

public class DrawableTransition {

    public static void transit(final Drawable drawable, boolean fromDark, long duration) {
        AlphaSatColorMatrixEvaluator evaluator = new AlphaSatColorMatrixEvaluator(fromDark);
        final AnimateColorMatrixColorFilter filter = new AnimateColorMatrixColorFilter(evaluator.getColorMatrix());
        drawable.setColorFilter(filter.getColorFilter());

        ObjectAnimator animator = ObjectAnimator.ofObject(filter, "colorMatrix", evaluator,
                evaluator.getColorMatrix());
        animator.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                drawable.setColorFilter (filter.getColorFilter());
            }
        });
        animator.setDuration(duration);
        animator.start();
    }

    // From rnr.tests.imageloadingpattern.MainActivity.AnimateColorMatrixColorFilter
    /// Thanks to @DavidCrawford \
    /// see http://stackoverflow.com/a/27301389/2573335
    private static class AnimateColorMatrixColorFilter {
        private ColorMatrixColorFilter mFilter;
        private ColorMatrix mMatrix;

        public AnimateColorMatrixColorFilter(ColorMatrix matrix) {
            setColorMatrix(matrix);
        }

        public ColorMatrixColorFilter getColorFilter() {
            return mFilter;
        }

        public void setColorMatrix(ColorMatrix matrix) {
            mMatrix = matrix;
            mFilter = new ColorMatrixColorFilter(matrix);
        }

        public ColorMatrix getColorMatrix() {
            return mMatrix;
        }
    }

    // From rnr.tests.imageloadingpattern.AlphaSatColorMatrixEvaluator
    // with modification
    private static class AlphaSatColorMatrixEvaluator implements TypeEvaluator {
        private final ColorMatrix colorMatrix;
        private final float[] elements = new float[20];
        private final boolean mFromDark;

        public AlphaSatColorMatrixEvaluator(boolean fromDark) {
            colorMatrix = new ColorMatrix ();
            mFromDark = fromDark;
        }

        public ColorMatrix getColorMatrix() {
            return colorMatrix;
        }

        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            // There are 4 phases so we multiply fraction by that amount
            float phase = fraction * 4;

            // Compute the alpha change over period [0, 2]
            float alpha = Math.min(phase, 2.0f) / 2.0f;
            elements [19] = Math.round(alpha * 255);

            // We substract to make the picture look darker, it will automatically clamp
            // This is spread over period [0, 3]
            final int MaxBlacker = 50;
            float blackening = Math.round((1 - Math.min(phase, 3.0f) / 3.0f) * MaxBlacker);
            elements [4] = elements [9] = elements [14] = mFromDark ? -blackening : blackening;

            // Finally we desaturate over [0, 4], taken from ColorMatrix.SetSaturation
            float invSat = 1 - Math.max(0.2f, fraction);
            float R = 0.213f * invSat;
            float G = 0.715f * invSat;
            float B = 0.072f * invSat;

            elements[0] = R + fraction; elements[1] = G;            elements[2] = B;
            elements[5] = R;            elements[6] = G + fraction; elements[7] = B;
            elements[10] = R;           elements[11] = G;           elements[12] = B + fraction;

            colorMatrix.set(elements);
            return colorMatrix;
        }
    }
}

@@ -634,89 +634,8 @@
 t;%0A%0A
-import android.animation.ObjectAnimator;%0Aimport android.animation.TypeEvaluator;%0A
 impo
@@ -933,16 +933,22 @@
         
+final 
 AlphaSat
@@ -1036,170 +1036,122 @@
     
-final AnimateColorMatrixColorFilter filter = new AnimateColorMatrixColorFilter(evaluator.getColorMatrix());%0A        drawable.setColorFilter(filter.getColorFilter(
+evaluator.setFraction(0.0f);%0A        drawable.setColorFilter(new ColorMatrixColorFilter(evaluator.getColorMatrix()
 ));%0A
@@ -1159,22 +1159,21 @@
         
-Object
+Value
 Animator
@@ -1184,22 +1184,21 @@
 mator = 
-Object
+Value
 Animator
@@ -1204,91 +1204,24 @@
 r.of
-Object(filter, %22colorMatrix%22, evaluator,%0A                evaluator.getColorMatrix()
+Float(0.0f, 1.0f
 );%0A 
@@ -1254,17 +1254,16 @@
 istener(
- 
 new Valu
@@ -1410,522 +1410,178 @@
     
-drawable.setColorFilter (filter.getColorFilter());%0A            %7D%0A        %7D);%0A        animator.setDuration(duration);%0A        animator.start();%0A
+float f = (Float) animation.getAnimatedValue();%0A        
     
-%7D%0A%0A
     
-// From rnr.tests.imageloadingpattern.MainActivity.AnimateColorMatrixColorFilter%0A    /// Thanks to @DavidCrawford %5C%0A    /// see http://stackoverflow.com/a/27301389/2573335%0A    private static class AnimateColorMatrixColorFilter %7B%0A        private ColorMatrixColorFilter mFilter;%0A        private ColorMatrix mMatrix;%0A%0A        public AnimateColorMatrixColorFilter(
+evaluator.setFraction(f);%0A                drawable.setColorFilter(new ColorMatrixColorFilter(evaluator.get
 Colo
@@ -1583,34 +1583,29 @@
 tColorMatrix
- matrix) %7B
+()));
 %0A           
@@ -1609,31 +1609,9 @@
     
-setColorMatrix(matrix);
+%7D
 %0A   
@@ -1608,33 +1608,34 @@
      %7D%0A        %7D
-%0A
+);
 %0A        public 
@@ -1631,335 +1631,65 @@
     
-public ColorMatrixColorFilter getColorFilter() %7B%0A            return mFilter;%0A        %7D%0A%0A        public void setColorMatrix(ColorMatrix matrix) %7B%0A            mMatrix = matrix;%0A            mFilter = new ColorMatrixColorFilter(matrix);%0A        %7D%0A%0A        public ColorMatrix getColorMatrix() %7B%0A            return mMatrix;%0A        %7D
+animator.setDuration(duration);%0A        animator.start();
 %0A   
@@ -1846,33 +1846,8 @@
 tor 
-implements TypeEvaluator 
 %7B%0A  
@@ -2245,99 +2245,46 @@
     
-@Override%0A        public Object evaluate(float fraction, Object startValue, Object endValue
+public void setFraction(float fraction
 ) %7B%0A
@@ -3505,40 +3505,8 @@
 s);%0A
-            return colorMatrix;%0A
     

优化 DrawableTransition