/* ====================================================================
   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.hssf.usermodel;

import java.awt.Dimension;

import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream;
import org.apache.poi.ddf.DefaultEscherRecordFactory;
import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.ddf.EscherBlipRecord;
import org.apache.poi.ddf.EscherClientDataRecord;
import org.apache.poi.ddf.EscherComplexProperty;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherPropertyTypes;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hssf.model.InternalWorkbook;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.hssf.record.ObjRecord;
import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.util.ImageUtils;
import org.apache.poi.util.StringUtil;

/**
 * Represents a escher picture.  Eg. A GIF, JPEG etc...
 */
public class HSSFPicture extends HSSFSimpleShape implements Picture {

    public HSSFPicture(EscherContainerRecord spContainer, ObjRecord objRecord) {
        super(spContainer, objRecord);
    }

    /**
     * Constructs a picture object.
     */
    public HSSFPicture( HSSFShape parent, HSSFAnchor anchor )
    {
        super( parent, anchor );
        super.setShapeType(OBJECT_TYPE_PICTURE);
        CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
        cod.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE);
    }

    public int getPictureIndex()
    {
        EscherSimpleProperty property = getOptRecord().lookup(EscherPropertyTypes.BLIP__BLIPTODISPLAY);
        if (null == property){
            return -1;
        }
        return property.getPropertyValue();
    }

    public void setPictureIndex( int pictureIndex )
    {
        setPropertyValue(new EscherSimpleProperty( EscherPropertyTypes.BLIP__BLIPTODISPLAY, false, true, pictureIndex));
    }

    @Override
    protected EscherContainerRecord createSpContainer() {
        EscherContainerRecord spContainer = super.createSpContainer();
        EscherOptRecord opt = spContainer.getChildById(EscherOptRecord.RECORD_ID);
        assert(opt != null);
        opt.removeEscherProperty(EscherPropertyTypes.LINESTYLE__LINEDASHING);
        opt.removeEscherProperty(EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH);
        spContainer.removeChildRecord(spContainer.getChildById(EscherTextboxRecord.RECORD_ID));
        return spContainer;
    }

    /**
     * Reset the image to the dimension of the embedded image
     *
     * <p>
     * Please note, that this method works correctly only for workbooks
     * with default font size (Arial 10pt for .xls).
     * If the default font is changed the resized image can be streched vertically or horizontally.
     * </p>
     */
    @Override
    public void resize(){
        resize(Double.MAX_VALUE);
    }

    /**
     * Resize the image proportionally.
     *
     * @see #resize(double, double)
     */
    @Override
    public void resize(double scale) {
        resize(scale,scale);
    }

    /**
     * Resize the image
     * <p>
     * Please note, that this method works correctly only for workbooks
     * with default font size (Arial 10pt for .xls).
     * If the default font is changed the resized image can be streched vertically or horizontally.
     * </p>
     * <p>
     * <code>resize(1.0,1.0)</code> keeps the original size,<br>
     * <code>resize(0.5,0.5)</code> resize to 50% of the original,<br>
     * <code>resize(2.0,2.0)</code> resizes to 200% of the original.<br>
     * <code>resize({@link Double#MAX_VALUE},{@link Double#MAX_VALUE})</code> resizes to the dimension of the embedded image.
     * </p>
     *
     * @param scaleX the amount by which the image width is multiplied relative to the original width.
     * @param scaleY the amount by which the image height is multiplied relative to the original height.
     */
    @Override
    public void resize(double scaleX, double scaleY) {
        HSSFClientAnchor anchor = getClientAnchor();
        anchor.setAnchorType(AnchorType.MOVE_DONT_RESIZE);

        HSSFClientAnchor pref = getPreferredSize(scaleX,scaleY);

        int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1());
        int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1());

        anchor.setCol2((short)col2);
        // anchor.setDx1(0);
        anchor.setDx2(pref.getDx2());

        anchor.setRow2(row2);
        // anchor.setDy1(0);
        anchor.setDy2(pref.getDy2());
    }

    /**
     * Calculate the preferred size for this picture.
     *
     * @return HSSFClientAnchor with the preferred size for this image
     * @since POI 3.0.2
     */
    @Override
    public HSSFClientAnchor getPreferredSize(){
        return getPreferredSize(1.0);
    }

    /**
     * Calculate the preferred size for this picture.
     *
     * @param scale the amount by which image dimensions are multiplied relative to the original size.
     * @return HSSFClientAnchor with the preferred size for this image
     * @since POI 3.0.2
     */
    public HSSFClientAnchor getPreferredSize(double scale){
        return getPreferredSize(scale, scale);
    }

    /**
     * Calculate the preferred size 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 HSSFClientAnchor with the preferred size for this image
     * @since POI 3.11
     */
    @Override
    public HSSFClientAnchor getPreferredSize(double scaleX, double scaleY){
        ImageUtils.setPreferredSize(this, scaleX, scaleY);
        return getClientAnchor();
    }

    /**
     * Return the dimension of the embedded image in pixel
     *
     * @return image dimension in pixels
     */
    @Override
    public Dimension getImageDimension(){
        InternalWorkbook iwb = getPatriarch().getSheet().getWorkbook().getWorkbook();
        EscherBSERecord bse = iwb.getBSERecord(getPictureIndex());
        byte[] data = bse.getBlipRecord().getPicturedata();
        int type = bse.getBlipTypeWin32();
        return ImageUtils.getImageDimension(new UnsynchronizedByteArrayInputStream(data), type);
    }

    /**
     * Return picture data for this shape
     *
     * @return picture data for this shape or {@code null} if picture wasn't embedded, i.e. external linked
     */
    @Override
    public HSSFPictureData getPictureData(){
        int picIdx = getPictureIndex();
        if (picIdx == -1) {
            return null;
        }

        HSSFPatriarch patriarch = getPatriarch();
        HSSFShape parent = getParent();
        while(patriarch == null && parent != null) {
            patriarch = parent.getPatriarch();
            parent = parent.getParent();
        }
        if(patriarch == null) {
            throw new IllegalStateException("Could not find a patriarch for a HSSPicture");
        }

        InternalWorkbook iwb = patriarch.getSheet().getWorkbook().getWorkbook();
        EscherBSERecord bse = iwb.getBSERecord(picIdx);
        EscherBlipRecord blipRecord = bse.getBlipRecord();
        return new HSSFPictureData(blipRecord);
    }

    @Override
    void afterInsert(HSSFPatriarch patriarch) {
        EscherAggregate agg = patriarch.getBoundAggregate();
        agg.associateShapeToObjRecord(getEscherContainer().getChildById(EscherClientDataRecord.RECORD_ID), getObjRecord());
        if(getPictureIndex() != -1) {
            EscherBSERecord bse =
                    patriarch.getSheet().getWorkbook().getWorkbook().getBSERecord(getPictureIndex());
            bse.setRef(bse.getRef() + 1);
        }
    }

    /**
     * The filename of the embedded image
     */
    public String getFileName() {
        EscherComplexProperty propFile = getOptRecord().lookup(EscherPropertyTypes.BLIP__BLIPFILENAME);
        return (null == propFile)
            ? ""
            : StringUtil.getFromUnicodeLE(propFile.getComplexData()).trim();
    }

    public void setFileName(String data){
        // TODO: add trailing \u0000?
        byte[] bytes = StringUtil.getToUnicodeLE(data);
        EscherComplexProperty prop = new EscherComplexProperty(EscherPropertyTypes.BLIP__BLIPFILENAME, true, bytes.length);
        prop.setComplexData(bytes);
        setPropertyValue(prop);
    }

    @Override
    public void setShapeType(int shapeType) {
        throw new IllegalStateException("Shape type can not be changed in "+this.getClass().getSimpleName());
    }

    @Override
    protected HSSFShape cloneShape() {
        EscherContainerRecord spContainer = new EscherContainerRecord();
        byte [] inSp = getEscherContainer().serialize();
        spContainer.fillFields(inSp, 0, new DefaultEscherRecordFactory());
        ObjRecord obj = (ObjRecord) getObjRecord().cloneViaReserialise();
        return new HSSFPicture(spContainer, obj);
    }

    /**
     * @return the anchor that is used by this picture.
     */
    @Override
    public HSSFClientAnchor getClientAnchor() {
        HSSFAnchor a = getAnchor();
        return (a instanceof HSSFClientAnchor) ? (HSSFClientAnchor)a : null;
    }


    /**
     * @return the sheet which contains the picture shape
     */
    @Override
    public HSSFSheet getSheet() {
        return getPatriarch().getSheet();
    }
}
