/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/* $Id$ */

package org.apache.xmlgraphics.image.loader;

import java.awt.Dimension;
import java.awt.geom.Dimension2D;

import org.apache.xmlgraphics.util.UnitConv;

/**
 * Encapsulates the size of an image.
 */
public class ImageSize {

    private int widthPx;
    private int heightPx;
    
    private int widthMpt;
    private int heightMpt;
    private int baselinePositionFromBottomMpt;
    
    private double dpiHorizontal;
    private double dpiVertical;
    
    
    /**
     * Constructor.
     * @param widthPx the width of the image in pixels
     * @param heightPx the height of the image in pixels
     * @param dpiHorizontal the horizontal resolution in dots per inch
     * @param dpiVertical the vertical resolution in dots per inch
     */
    public ImageSize(int widthPx, int heightPx, double dpiHorizontal, double dpiVertical) {
        setSizeInPixels(widthPx, heightPx);
        setResolution(dpiHorizontal, dpiVertical);
    }
    
    /**
     * Constructor.
     * @param widthPx the width of the image in pixels
     * @param heightPx the height of the image in pixels
     * @param dpi the resolution in dots per inch
     */
    public ImageSize(int widthPx, int heightPx, double dpi) {
        this(widthPx, heightPx, dpi, dpi);
    }
    
    /**
     * Default Constructor.
     */
    public ImageSize() {
        //nop
    }
    
    /**
     * Sets the image's size in pixels.
     * @param width the width in pixels 
     * @param height the height in pixels
     */
    public void setSizeInPixels(int width, int height) {
        this.widthPx = width;
        this.heightPx = height;
    }
    
    /**
     * Sets the image's size in millipoints.
     * @param width the width in millipoints 
     * @param height the height in millipoints
     */
    public void setSizeInMillipoints(int width, int height) {
        this.widthMpt = width;
        this.heightMpt = height;
    }
    
    /**
     * Sets the image's resolution for interpreting the pixel size.
     * @param horizontal the horizontal resolution in dpi
     * @param vertical the vertical resolution in dpi
     */
    public void setResolution(double horizontal, double vertical) {
        this.dpiHorizontal = horizontal;
        this.dpiVertical = vertical;
    }
    
    /**
     * Sets the image's resolution for interpreting the pixel size.
     * @param resolution the resolution in dpi
     */
    public void setResolution(double resolution) {
        setResolution(resolution, resolution);
    }
    
    /**
     * Sets the vertical position of the baseline of the image relative to the bottom of the image.
     * The default is 0mpt (i.e. the image is bottom-aligned). This is used for MathML images, for
     * example, which have a baseline. Using the value the images can be properly aligned with
     * other text. Most other image don't have an implicit baseline.
     * @param distance the distance from the bottom of the image in millipoints 
     */
    public void setBaselinePositionFromBottom(int distance) {
        this.baselinePositionFromBottomMpt = distance;
    }
    
    /**
     * Returns the vertical position of the baseline of the image relative to the bottom of the
     * image. The default is 0mpt (i.e. the image is bottom-aligned). This is used for MathML
     * images, for example, which have a baseline. Using the value the images can be properly
     * aligned with other text. Most other image don't have an implicit baseline.
     * @return the distance from the bottom of the image in millipoints
     */
    public int getBaselinePositionFromBottom() {
        return this.baselinePositionFromBottomMpt;
    }
    
    /**
     * Returns the image's width in pixels.
     * @return the width in pixels
     */
    public int getWidthPx() {
        return widthPx;
    }

    /**
     * Returns the image's height in pixels.
     * @return the height in pixels
     */
    public int getHeightPx() {
        return heightPx;
    }

    /**
     * Returns the image's width in millipoints.
     * @return the width in millipoints
     */
    public int getWidthMpt() {
        return widthMpt;
    }

    /**
     * Returns the image's height in millipoints.
     * @return the height in millipoints
     */
    public int getHeightMpt() {
        return heightMpt;
    }

    /**
     * Returns the image's horizontal resolution in dpi (dots per inch).
     * @return the horizontal resolution in dpi
     */
    public double getDpiHorizontal() {
        return dpiHorizontal;
    }

    /**
     * Returns the image's vertical resolution in dpi (dots per inch).
     * @return the vertical resolution in dpi
     */
    public double getDpiVertical() {
        return dpiVertical;
    }

    /**
     * Returns the size in millipoints as a Dimension object.
     * @return the size in millipoints
     */
    public Dimension getDimensionMpt() {
        return new Dimension(getWidthMpt(), getHeightMpt());
    }
    
    /**
     * Returns the size in points as a Dimension2D object.
     * @return the size in points
     */
    public Dimension2D getDimensionPt() {
        return new DoubleDimension2D(getWidthMpt() / 1000.0, getHeightMpt() / 1000.0);
    }
    
    private static final class DoubleDimension2D extends Dimension2D {
        private double width;
        private double height;

        private DoubleDimension2D(double width, double height) {
            this.width = width;
            this.height = height;
        }

        public double getWidth() {
            return width;
        }

        public double getHeight() {
            return height;
        }

        public void setSize(double w, double h) {
            this.width = w;
            this.height = h;
        }
    }

    /**
     * Returns the size in pixels as a Dimension object.
     * @return the size in pixels
     */
    public Dimension getDimensionPx() {
        return new Dimension(getWidthPx(), getHeightPx());
    }
    
    /**
     * Calculates the size in millipoints based on the size in pixels and the resolution.
     */
    public void calcSizeFromPixels() {
        if (this.dpiHorizontal == 0 || this.dpiVertical == 0) {
            throw new IllegalStateException("The resolution mus be set");
        }
        this.widthMpt = (int)Math.round(UnitConv.in2mpt(this.widthPx / this.dpiHorizontal));
        this.heightMpt = (int)Math.round(UnitConv.in2mpt(this.heightPx / this.dpiVertical));
    }

    /**
     * Calculates the size in pixels based on the size in millipoints and the resolution.
     */
    public void calcPixelsFromSize() {
        if (this.dpiHorizontal == 0 || this.dpiVertical == 0) {
            throw new IllegalStateException("The resolution mus be set");
        }
        this.widthPx = (int)Math.round(UnitConv.mpt2in(this.widthMpt * this.dpiHorizontal));
        this.heightPx = (int)Math.round(UnitConv.mpt2in(this.heightMpt * this.dpiVertical));
    }

    /** {@inheritDoc} */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("Size: ");
        sb.append(getWidthMpt()).append('x').append(getHeightMpt()).append(" mpt");
        sb.append(" (");
        sb.append(getWidthPx()).append('x').append(getHeightPx()).append(" px");
        sb.append(" at ").append(getDpiHorizontal()).append('x').append(getDpiVertical());
        sb.append(" dpi");
        sb.append(")");
        return sb.toString();
    }

}
