/*
 * Copyright (C) 2013 Peng fei Pan <sky@xiaopan.me>
 *
 * 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 me.xiaopan.android.spear.util;

import android.view.ViewGroup;
import android.widget.ImageView;

import java.lang.reflect.Field;

/**
 * 图片尺寸计算器
 */
public class DefaultImageSizeCalculator implements ImageSizeCalculator{
    @Override
    public ImageSize calculateImageMaxsize(ImageView imageView) {
        int width = getWidth(imageView, true, true);
        int height = getHeight(imageView, true, true);
        if (width > 0 && height > 0){
            return new ImageSize(width, height);
        }
        return null;
    }

    @Override
    public ImageSize calculateImageResize(ImageView imageView) {
        int width = getWidth(imageView, true, false);
        int height = getHeight(imageView, true, false);
        if (width > 0 && height > 0){
            return new ImageSize(width, height);
        }
        return null;
    }

    @Override
    public int compareMaxsize(ImageSize maxsize1, ImageSize maxsize2) {
        if(maxsize1 == null || maxsize2 == null){
            return 0;
        }
        return (maxsize1.getWidth() * maxsize1.getHeight()) - (maxsize2.getWidth() - maxsize2.getHeight());
    }

    @Override
    public int compareResize(ImageSize resize1, ImageSize resize2) {
        if(resize1 == null || resize2 == null){
            return 0;
        }
        return (resize1.getWidth() * resize1.getHeight()) - (resize2.getWidth() - resize2.getHeight());
    }

    @Override
    public int calculateInSampleSize(int outWidth, int outHeight, int targetWidth, int targetHeight) {
        if(targetWidth <= 0 && targetHeight <= 0){
            return 1;
        }

        if(targetWidth >= outWidth && targetHeight >= outHeight){
            return 1;
        }

        int inSampleSize = 1;
        do{
            inSampleSize *= 2;
        }while ((outWidth/inSampleSize) > targetWidth && (outHeight/inSampleSize) > targetHeight);
        return inSampleSize;
    }

    public static int getWidth(ImageView imageView, boolean checkRealViewSize, boolean checkMaxViewSize) {
        if(imageView == null){
            return 0;
        }

        int width = 0;
        final ViewGroup.LayoutParams params = imageView.getLayoutParams();
        if (checkRealViewSize && params != null && params.width != ViewGroup.LayoutParams.WRAP_CONTENT) {
            width = imageView.getWidth();
        }
        if (width <= 0 && params != null){
            width = params.width;
        }
        if(width <= 0 && checkMaxViewSize){
            width = getImageViewFieldValue(imageView, "mMaxWidth");
        }
        return width;
    }

    public static int getHeight(ImageView imageView, boolean checkRealViewSize, boolean checkMaxViewSize) {
        if(imageView == null){
            return 0;
        }

        int height = 0;
        final ViewGroup.LayoutParams params = imageView.getLayoutParams();
        if (checkRealViewSize && params != null && params.height != ViewGroup.LayoutParams.WRAP_CONTENT) {
            height = imageView.getHeight();
        }
        if (height <= 0 && params != null){
            height = params.height;
        }
        if(height <= 0 && checkMaxViewSize){
            height = getImageViewFieldValue(imageView, "mMaxHeight");
        }
        return height;
    }

    private static int getImageViewFieldValue(Object object, String fieldName) {
        int value = 0;
        try {
            Field field = ImageView.class.getDeclaredField(fieldName);
            field.setAccessible(true);
            int fieldValue = (Integer) field.get(object);
            if (fieldValue > 0 && fieldValue < Integer.MAX_VALUE) {
                value = fieldValue;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }
}

@@ -955,32 +955,38 @@
 imageView, true,
+ true,
  true);%0A        
@@ -1020,24 +1020,30 @@
 eView, true,
+ true,
  true);%0A    
@@ -1048,33 +1048,34 @@
       if (width 
-%3E
+%3C=
  0 && height %3E 0
@@ -1063,38 +1063,79 @@
  %3C= 0 && height 
-%3E
+%3C=
  0)%7B%0A
+            return null;%0A        %7Delse%7B%0A
             retu
@@ -1177,37 +1177,16 @@
       %7D%0A
-        return null;%0A
     %7D%0A%0A 
@@ -1300,32 +1300,39 @@
 imageView, true,
+ false,
  false);%0A       
@@ -1367,24 +1367,31 @@
 eView, true,
+ false,
  false);%0A   
@@ -2672,32 +2672,59 @@
 checkMaxViewSize
+, boolean acceptWrapContent
 ) %7B%0A        if(i
@@ -3232,32 +3232,184 @@
 th%22);%0A        %7D%0A
+        if(width %3C= 0 && acceptWrapContent && params != null && params.width == ViewGroup.LayoutParams.WRAP_CONTENT)%7B%0A            width = -1;%0A        %7D%0A
         return w
@@ -3525,16 +3525,43 @@
 ViewSize
+, boolean acceptWrapContent
 ) %7B%0A    
@@ -4087,32 +4087,187 @@
 ht%22);%0A        %7D%0A
+        if(height %3C= 0 && acceptWrapContent && params != null && params.height == ViewGroup.LayoutParams.WRAP_CONTENT)%7B%0A            height = -1;%0A        %7D%0A
         return h

支持仅根据宽或高限制图片大小，例如maxsize为500x-1