/* ====================================================================
   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.
==================================================================== */
package org.apache.poi.ss.util;

import static org.apache.poi.util.Units.EMU_PER_PIXEL;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * @author Yegor Kozlov
 */
public class ImageUtils {
    private static final POILogger logger = POILogFactory.getLogger(ImageUtils.class);

    public static final int PIXEL_DPI = 96;

    /**
     * Return the dimension of this image
     *
     * @param is the stream containing the image data
     * @param type type of the picture: {@link org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_JPEG},
     * {@link org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_PNG} or {@link org.apache.poi.ss.usermodel.Workbook#PICTURE_TYPE_DIB}
     *
     * @return image dimension in pixels
     */
    public static Dimension getImageDimension(InputStream is, int type){
        Dimension size = new Dimension();

        switch (type){
            //we can calculate the preferred size only for JPEG, PNG and BMP
            //other formats like WMF, EMF and PICT are not supported in Java
            case Workbook.PICTURE_TYPE_JPEG:
            case Workbook.PICTURE_TYPE_PNG:
            case Workbook.PICTURE_TYPE_DIB:
                try {
                    //read the image using javax.imageio.*
                    ImageInputStream iis = ImageIO.createImageInputStream( is );
                    try {
                        Iterator<ImageReader> i = ImageIO.getImageReaders( iis );
                        ImageReader r = i.next();
                        try {
                            r.setInput( iis );
                            BufferedImage img = r.read(0);
        
                            int[] dpi = getResolution(r);
        
                            //if DPI is zero then assume standard 96 DPI
                            //since cannot divide by zero
                            if (dpi[0] == 0) dpi[0] = PIXEL_DPI;
                            if (dpi[1] == 0) dpi[1] = PIXEL_DPI;
        
                            size.width = img.getWidth()*PIXEL_DPI/dpi[0];
                            size.height = img.getHeight()*PIXEL_DPI/dpi[1];
                        } finally {
                            r.dispose();
                        }
                    } finally {
                        iis.close();
                    }

                } catch (IOException e) {
                    //silently return if ImageIO failed to read the image
                    logger.log(POILogger.WARN, e);
                }

                break;
            default:
                logger.log(POILogger.WARN, "Only JPEG, PNG and DIB pictures can be automatically sized");
        }
        return size;
    }

    /**
     * The metadata of PNG and JPEG can contain the width of a pixel in millimeters.
     * Return the the "effective" dpi calculated as <code>25.4/HorizontalPixelSize</code>
     * and <code>25.4/VerticalPixelSize</code>.  Where 25.4 is the number of mm in inch.
     *
     * @return array of two elements: <code>{horisontalPdi, verticalDpi}</code>.
     * {96, 96} is the default.
     */
    public static int[] getResolution(ImageReader r) throws IOException {
        int hdpi=96, vdpi=96;
        double mm2inch = 25.4;

        NodeList lst;
        Element node = (Element)r.getImageMetadata(0).getAsTree("javax_imageio_1.0");
        lst = node.getElementsByTagName("HorizontalPixelSize");
        if(lst != null && lst.getLength() == 1) hdpi = (int)(mm2inch/Float.parseFloat(((Element)lst.item(0)).getAttribute("value")));

        lst = node.getElementsByTagName("VerticalPixelSize");
        if(lst != null && lst.getLength() == 1) vdpi = (int)(mm2inch/Float.parseFloat(((Element)lst.item(0)).getAttribute("value")));

        return new int[]{hdpi, vdpi};
    }

    /**
     * Calculate and set the preferred size (anchor) for this picture.
     *
     * @param scaleX the amount by which image width is multiplied relative to the original width.
     * @param scaleY the amount by which image height is multiplied relative to the original height.
     * @return the new Dimensions of the scaled picture in EMUs
     */
    public static Dimension setPreferredSize(Picture picture, double scaleX, double scaleY){
        ClientAnchor anchor = picture.getClientAnchor();
        boolean isHSSF = (anchor instanceof HSSFClientAnchor);
        PictureData data = picture.getPictureData();
        Sheet sheet = picture.getSheet();
        
        // in pixel
        Dimension imgSize = getImageDimension(new ByteArrayInputStream(data.getData()), data.getPictureType());
        // in emus
        Dimension anchorSize = ImageUtils.getDimensionFromAnchor(picture);
        final double scaledWidth = (scaleX == Double.MAX_VALUE)
            ? imgSize.getWidth() : anchorSize.getWidth()/EMU_PER_PIXEL * scaleX;
        final double scaledHeight = (scaleY == Double.MAX_VALUE)
            ? imgSize.getHeight() : anchorSize.getHeight()/EMU_PER_PIXEL * scaleY;

        double w = 0;
        int col2 = anchor.getCol1();
        int dx2 = 0;

        //space in the leftmost cell
        w = sheet.getColumnWidthInPixels(col2++);
        if (isHSSF) {
            w *= 1 - anchor.getDx1()/1024d;
        } else {
            w -= anchor.getDx1()/EMU_PER_PIXEL;
        }
        
        while(w < scaledWidth){
            w += sheet.getColumnWidthInPixels(col2++);
        }
        
        if(w > scaledWidth) {
            //calculate dx2, offset in the rightmost cell
            double cw = sheet.getColumnWidthInPixels(--col2);
            double delta = w - scaledWidth;
            if (isHSSF) {
                dx2 = (int)((cw-delta)/cw*1024);
            } else {
                dx2 = (int)((cw-delta)*EMU_PER_PIXEL);
            }
            if (dx2 < 0) dx2 = 0;
        }
        anchor.setCol2(col2);
        anchor.setDx2(dx2);

        double h = 0;
        int row2 = anchor.getRow1();
        int dy2 = 0;
        
        h = getRowHeightInPixels(sheet,row2++);
        if (isHSSF) {
            h *= 1 - anchor.getDy1()/256d;
        } else {
            h -= anchor.getDy1()/EMU_PER_PIXEL;
        }

        while(h < scaledHeight){
            h += getRowHeightInPixels(sheet,row2++);
        }
        
        if(h > scaledHeight) {
            double ch = getRowHeightInPixels(sheet,--row2);
            double delta = h - scaledHeight;
            if (isHSSF) {
                dy2 = (int)((ch-delta)/ch*256);
            } else {
                dy2 = (int)((ch-delta)*EMU_PER_PIXEL);
            }
            if (dy2 < 0) dy2 = 0;
        }

        anchor.setRow2(row2);
        anchor.setDy2(dy2);

        Dimension dim = new Dimension(
            (int)Math.round(scaledWidth*EMU_PER_PIXEL),
            (int)Math.round(scaledHeight*EMU_PER_PIXEL)
        );
        
        return dim;
    }

    /**
     * Calculates the dimensions in EMUs for the anchor of the given picture
     *
     * @param picture the picture containing the anchor
     * @return the dimensions in EMUs
     */
    public static Dimension getDimensionFromAnchor(Picture picture) {
        ClientAnchor anchor = picture.getClientAnchor();
        boolean isHSSF = (anchor instanceof HSSFClientAnchor);
        Sheet sheet = picture.getSheet();

        double w = 0;
        int col2 = anchor.getCol1();

        //space in the leftmost cell
        w = sheet.getColumnWidthInPixels(col2++);
        if (isHSSF) {
            w *= 1 - anchor.getDx1()/1024d;
        } else {
            w -= anchor.getDx1()/EMU_PER_PIXEL;
        }
        
        while(col2 < anchor.getCol2()){
            w += sheet.getColumnWidthInPixels(col2++);
        }
        
        if (isHSSF) {
            w += sheet.getColumnWidthInPixels(col2) * anchor.getDx2()/1024d;
        } else {
            w += anchor.getDx2()/EMU_PER_PIXEL;
        }

        double h = 0;
        int row2 = anchor.getRow1();
        
        h = getRowHeightInPixels(sheet,row2++);
        if (isHSSF) {
            h *= 1 - anchor.getDy1()/256d;
        } else {
            h -= anchor.getDy1()/EMU_PER_PIXEL;
        }

        while(row2 < anchor.getRow2()){
            h += getRowHeightInPixels(sheet,row2++);
        }
        
        if (isHSSF) {
            h += getRowHeightInPixels(sheet,row2) * anchor.getDy2()/256;
        } else {
            h += anchor.getDy2()/EMU_PER_PIXEL;
        }

        return new Dimension((int)w*EMU_PER_PIXEL, (int)h*EMU_PER_PIXEL);
    }
    
    
    private static double getRowHeightInPixels(Sheet sheet, int rowNum) {
        Row r = sheet.getRow(rowNum);
        double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints();
        return Units.toEMU(points)/EMU_PER_PIXEL;
    }
}
