/* UtilLib - Copyright (c) 2010-2011 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.awt;


/**
 *
 * @author Vincent Calame
 */
public final class ResizeInfo {

    public final static short WIDTH_RESIZING = 1;
    public final static short HEIGHT_RESIZING = 2;
    public final static short BOTH_RESIZING = 3;
    private final short type;
    private int width = 0;
    private int height = 0;
    private boolean max = false;

    private ResizeInfo(short type) {
        this.type = type;
    }

    public short getType() {
        return type;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public boolean isOnlyMax() {
        return max;
    }

    public Check checkDim(int dimWidth, int dimHeight) {
        int resultWidth = dimWidth;
        int resultHeight = dimHeight;
        float ratio = 1.0f;
        if (type == ResizeInfo.WIDTH_RESIZING) {
            if ((dimWidth != width) && ((!max) || (dimWidth > width))) {
                resultWidth = width;
                ratio = ((float) width) / dimWidth;
                resultHeight = (int) (ratio * dimHeight);
            }
        } else if (type == ResizeInfo.HEIGHT_RESIZING) {
            if ((dimHeight != height) && ((!max) || (dimHeight > height))) {
                resultHeight = height;
                ratio = ((float) height) / dimHeight;
                resultWidth = (int) (ratio * dimWidth);
            }
        } else if (type == ResizeInfo.BOTH_RESIZING) {
            resultWidth = width;
            resultHeight = height;
            if (max) {
                float widthRatio = ((float) width) / dimWidth;
                float heightRatio = ((float) height) / dimHeight;
                if (widthRatio < heightRatio) {
                    ratio = widthRatio;
                    resultHeight = (int) (ratio * height);
                } else {
                    ratio = heightRatio;
                    resultWidth = (int) (ratio * width);
                }
            } else {
                ratio = Math.max(((float) width) / dimWidth, ((float) height) / dimHeight);
            }
        }
        return new Check(resultWidth, resultHeight, ratio);
    }

    @Override
    public int hashCode() {
        return type + height + width;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null) {
            return false;
        }
        if (other == this) {
            return true;
        }
        if (other.getClass() != this.getClass()) {
            return false;
        }
        ResizeInfo otherResizeInfo = (ResizeInfo) other;
        if (otherResizeInfo.type != this.type) {
            return false;
        }
        if (otherResizeInfo.width != this.width) {
            return false;
        }
        if (otherResizeInfo.height != this.height) {
            return false;
        }
        if (otherResizeInfo.max != this.max) {
            return false;
        }
        return true;
    }

    public static ResizeInfo newFixedWidthInstance(int width) {
        if (width < 1) {
            throw new IllegalArgumentException("width < 1");
        }
        ResizeInfo obj = new ResizeInfo(WIDTH_RESIZING);
        obj.width = width;
        obj.max = false;
        return obj;
    }

    public static ResizeInfo newFixedHeightInstance(int height) {
        if (height < 1) {
            throw new IllegalArgumentException("width < 1");
        }
        ResizeInfo obj = new ResizeInfo(HEIGHT_RESIZING);
        obj.height = height;
        obj.max = false;
        return obj;
    }

    public static ResizeInfo newFixedDimInstance(int width, int height) {
        if (width < 1) {
            throw new IllegalArgumentException("width < 1");
        }
        if (height < 1) {
            throw new IllegalArgumentException("height < 1");
        }
        ResizeInfo obj = new ResizeInfo(BOTH_RESIZING);
        obj.width = width;
        obj.height = height;
        obj.max = false;
        return obj;
    }

    public static ResizeInfo newMaxWidthInstance(int width) {
        if (width < 1) {
            throw new IllegalArgumentException("width < 1");
        }
        ResizeInfo obj = new ResizeInfo(WIDTH_RESIZING);
        obj.width = width;
        obj.max = true;
        return obj;
    }

    public static ResizeInfo newMaxHeightInstance(int height) {
        if (height < 1) {
            throw new IllegalArgumentException("height < 1");
        }
        ResizeInfo obj = new ResizeInfo(HEIGHT_RESIZING);
        obj.height = height;
        obj.max = true;
        return obj;
    }

    public static ResizeInfo newMaxDimInstance(int width, int height) {
        if (width < 1) {
            throw new IllegalArgumentException("width < 1");
        }
        if (height < 1) {
            throw new IllegalArgumentException("height < 1");
        }
        ResizeInfo obj = new ResizeInfo(BOTH_RESIZING);
        obj.width = width;
        obj.height = height;
        obj.max = true;
        return obj;
    }


    public static class Check {

        private final int width;
        private final int height;
        private final float ratio;

        private Check(int width, int height, float ratio) {
            this.width = width;
            this.height = height;
            this.ratio = ratio;
        }

        public int getWidth() {
            return width;
        }

        public int getHeight() {
            return height;
        }

        public float getRatio() {
            return ratio;
        }

    }

}
