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

import static org.apache.poi.openxml4j.opc.PackageRelationshipTypes.CORE_PROPERTIES_ECMA376_NS;

import java.awt.geom.Rectangle2D;
import java.io.IOException;

import javax.xml.namespace.QName;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.util.POIXMLUnits;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.GraphicalFrame;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Units;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;

@Beta
public class XSLFGraphicFrame extends XSLFShape implements GraphicalFrame<XSLFShape, XSLFTextParagraph> {
    private static final String DRAWINGML_CHART_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
    private static final Logger LOG = LogManager.getLogger(XSLFGraphicFrame.class);

    /*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){
        super(shape,sheet);
    }

    public ShapeType getShapeType(){
        throw new UnsupportedOperationException();
    }

    @Override
    public Rectangle2D getAnchor(){
        CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm();
        CTPoint2D off = xfrm.getOff();
        double x = Units.toPoints(POIXMLUnits.parseLength(off.xgetX()));
        double y = Units.toPoints(POIXMLUnits.parseLength(off.xgetY()));
        CTPositiveSize2D ext = xfrm.getExt();
        double cx = Units.toPoints(ext.getCx());
        double cy = Units.toPoints(ext.getCy());
        return new Rectangle2D.Double(x, y, cx, cy);
    }

    @Override
    public void setAnchor(Rectangle2D anchor){
        CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm();
        CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
        long x = Units.toEMU(anchor.getX());
        long y = Units.toEMU(anchor.getY());
        off.setX(x);
        off.setY(y);
        CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm
                .addNewExt();
        long cx = Units.toEMU(anchor.getWidth());
        long cy = Units.toEMU(anchor.getHeight());
        ext.setCx(cx);
        ext.setCy(cy);
    }


    static XSLFGraphicFrame create(CTGraphicalObjectFrame shape, XSLFSheet sheet){
        final String uri = getUri(shape);
        switch (uri == null ? "" : uri) {
        case XSLFTable.TABLE_URI:
            return new XSLFTable(shape, sheet);
        case XSLFObjectShape.OLE_URI:
            return new XSLFObjectShape(shape, sheet);
        default:
            return new XSLFGraphicFrame(shape, sheet);
        }
    }

    private static String getUri(CTGraphicalObjectFrame shape) {
        final CTGraphicalObject g = shape.getGraphic();
        if (g == null) {
            return null;
        }
        CTGraphicalObjectData gd = g.getGraphicData();
        return (gd == null) ? null : gd.getUri();
    }

    /**
     * Rotate this shape.
     * <p>
     * Positive angles are clockwise (i.e., towards the positive y axis);
     * negative angles are counter-clockwise (i.e., towards the negative y axis).
     * </p>
     *
     * @param theta the rotation angle in degrees.
     */
    @Override
    public void setRotation(double theta){
    	throw new IllegalArgumentException("Operation not supported");
    }

    /**
     * Rotation angle in degrees
     * <p>
     * Positive angles are clockwise (i.e., towards the positive y axis);
     * negative angles are counter-clockwise (i.e., towards the negative y axis).
     * </p>
     *
     * @return rotation angle in degrees
     */
    @Override
	public double getRotation(){
    	return 0;
    }

    @Override
	public void setFlipHorizontal(boolean flip){
    	throw new IllegalArgumentException("Operation not supported");
    }

    @Override
	public void setFlipVertical(boolean flip){
    	throw new IllegalArgumentException("Operation not supported");
    }

    /**
     * Whether the shape is horizontally flipped
     *
     * @return whether the shape is horizontally flipped
     */
    @Override
	public boolean getFlipHorizontal(){
    	return false;
    }

    @Override
	public boolean getFlipVertical(){
    	return false;
    }

    public boolean hasChart() {
        String uri = getGraphicalData().getUri();
        return uri.equals(DRAWINGML_CHART_URI);
    }

    private CTGraphicalObjectData getGraphicalData() {
        return ((CTGraphicalObjectFrame)getXmlObject()).getGraphic().getGraphicData();
    }

    public XSLFChart getChart() {
        if (hasChart()) {
            String id = null;
            String xpath = "declare namespace c='" + DRAWINGML_CHART_URI + "' c:chart";
            XmlObject[] obj = getGraphicalData().selectPath(xpath);
            if (obj != null && obj.length == 1) {
                XmlCursor c = obj[0].newCursor();
                QName idQualifiedName = new QName(CORE_PROPERTIES_ECMA376_NS, "id");
                id = c.getAttributeText(idQualifiedName);
                c.dispose();
            }
            if (id == null) {
                return null;
            } else {
                return (XSLFChart) getSheet().getRelationById(id);
            }
        } else {
            return null;
        }
    }

    @Override
    void copy(XSLFShape sh){
        super.copy(sh);

        CTGraphicalObjectData data = getGraphicalData();
        String uri = data.getUri();
        if(uri.equals("http://schemas.openxmlformats.org/drawingml/2006/diagram")){
            copyDiagram(data, (XSLFGraphicFrame)sh);
        } if(uri.equals(DRAWINGML_CHART_URI)){
        	copyChart(data, (XSLFGraphicFrame)sh);
        } else {
            // TODO  support other types of objects

        }
    }

    private void copyChart(CTGraphicalObjectData objData, XSLFGraphicFrame srcShape) {
        XSLFSlide slide = (XSLFSlide) getSheet();
        XSLFSheet src = srcShape.getSheet();
        String xpath = "declare namespace c='" + DRAWINGML_CHART_URI + "' c:chart";
        XmlObject[] obj = objData.selectPath(xpath);
        if (obj != null && obj.length == 1) {
            XmlCursor c = obj[0].newCursor();
            try {
                // duplicate chart with embedded workbook
                QName idQualifiedName = new QName(CORE_PROPERTIES_ECMA376_NS, "id");
                String id = c.getAttributeText(idQualifiedName);
                XSLFChart srcChart = (XSLFChart) src.getRelationById(id);
                XSLFChart chartCopy = slide.getSlideShow().createChart(slide);
                chartCopy.importContent(srcChart);
                chartCopy.setWorkbook(srcChart.getWorkbook());
                c.setAttributeText(idQualifiedName, slide.getRelationId(chartCopy));
            } catch (InvalidFormatException | IOException e) {
                throw new POIXMLException(e);
            }
            c.dispose();
        }
    }

    // TODO should be moved to a sub-class
    private void copyDiagram(CTGraphicalObjectData objData, XSLFGraphicFrame srcShape){
        String xpath = "declare namespace dgm='http://schemas.openxmlformats.org/drawingml/2006/diagram' $this//dgm:relIds";
        XmlObject[] obj = objData.selectPath(xpath);
        if(obj != null && obj.length == 1){
            XmlCursor c = obj[0].newCursor();

            XSLFSheet sheet = srcShape.getSheet();
            try {
                String dm = c.getAttributeText(new QName(CORE_PROPERTIES_ECMA376_NS, "dm"));
                PackageRelationship dmRel = sheet.getPackagePart().getRelationship(dm);
                PackagePart dmPart = sheet.getPackagePart().getRelatedPart(dmRel);
                getSheet().importPart(dmRel, dmPart);

                String lo = c.getAttributeText(new QName(CORE_PROPERTIES_ECMA376_NS, "lo"));
                PackageRelationship loRel = sheet.getPackagePart().getRelationship(lo);
                PackagePart loPart = sheet.getPackagePart().getRelatedPart(loRel);
                getSheet().importPart(loRel, loPart);

                String qs = c.getAttributeText(new QName(CORE_PROPERTIES_ECMA376_NS, "qs"));
                PackageRelationship qsRel = sheet.getPackagePart().getRelationship(qs);
                PackagePart qsPart = sheet.getPackagePart().getRelatedPart(qsRel);
                getSheet().importPart(qsRel, qsPart);

                String cs = c.getAttributeText(new QName(CORE_PROPERTIES_ECMA376_NS, "cs"));
                PackageRelationship csRel = sheet.getPackagePart().getRelationship(cs);
                PackagePart csPart = sheet.getPackagePart().getRelatedPart(csRel);
                getSheet().importPart(csRel, csPart);

            } catch (InvalidFormatException e){
                throw new POIXMLException(e);
            }
            c.dispose();
        }
    }

    @Override
    public XSLFPictureShape getFallbackPicture() {
        String xquery =
                  "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main'; "
                + "declare namespace mc='http://schemas.openxmlformats.org/markup-compatibility/2006' "
                + ".//mc:Fallback/*/p:pic"
                ;
        XmlObject xo = selectProperty(XmlObject.class, xquery);
        if (xo == null) {
            return null;
        }

        CTGroupShape gs;
        try {
            gs = CTGroupShape.Factory.parse(xo.newDomNode());
        } catch (XmlException e) {
            LOG.atWarn().withThrowable(e).log("Can't parse fallback picture stream of graphical frame");
            return null;
        }

        if (gs.sizeOfPicArray() == 0) {
            return null;
        }

        return new XSLFPictureShape(gs.getPicArray(0), getSheet());
    }
}
