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

import javax.xml.namespace.QName;

import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrameNonVisual;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Represents DrawingML GraphicalObjectFrame.
 *
 * @author Roman Kashitsyn
 */
public final class XSSFGraphicFrame extends XSSFShape {

	private static CTGraphicalObjectFrame prototype;

	private CTGraphicalObjectFrame graphicFrame;

	/**
	 * Construct a new XSSFGraphicFrame object.
	 *
	 * @param drawing the XSSFDrawing that owns this frame
	 * @param ctGraphicFrame the XML bean that stores this frame content
	 */
	protected XSSFGraphicFrame(XSSFDrawing drawing, CTGraphicalObjectFrame ctGraphicFrame) {
		this.drawing = drawing; // protected field on XSSFShape
		this.graphicFrame = ctGraphicFrame;
		// TODO: there may be a better way to delegate this
		CTGraphicalObjectData graphicData = graphicFrame.getGraphic().getGraphicData();
        if (graphicData != null) {
            NodeList nodes = graphicData.getDomNode().getChildNodes();
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node node = nodes.item(i);
                // if the frame references a chart, associate the chart with this instance
                if (node.getNodeName().equals("c:chart")) {
                    // this better succeed or the document is invalid
                    POIXMLDocumentPart relation = drawing.getRelationById(node.getAttributes().getNamedItem("r:id").getNodeValue());
                    // Do XWPF charts need similar treatment?
                    if (relation instanceof XSSFChart) {
                        ((XSSFChart) relation).setGraphicFrame(this);
                    }
                }
            }
        }
	}

	@Internal
	public CTGraphicalObjectFrame getCTGraphicalObjectFrame() {
		return graphicFrame;
	}

	/**
	 * Initialize default structure of a new graphic frame
	 */
	protected static CTGraphicalObjectFrame prototype() {
		if (prototype == null) {
			CTGraphicalObjectFrame graphicFrame = CTGraphicalObjectFrame.Factory.newInstance();

			CTGraphicalObjectFrameNonVisual nvGraphic = graphicFrame.addNewNvGraphicFramePr();
			CTNonVisualDrawingProps props = nvGraphic.addNewCNvPr();
			props.setId(0);
			props.setName("Diagramm 1");
			nvGraphic.addNewCNvGraphicFramePr();

			CTTransform2D transform = graphicFrame.addNewXfrm();
			CTPositiveSize2D extPoint = transform.addNewExt();
			CTPoint2D offPoint = transform.addNewOff();

			extPoint.setCx(0);
			extPoint.setCy(0);
			offPoint.setX(0);
			offPoint.setY(0);

			/* CTGraphicalObject graphic = */ graphicFrame.addNewGraphic();

			prototype = graphicFrame;
		}
		return prototype;
	}

	/**
	 * Sets the frame macro.
	 */
	public void setMacro(String macro) {
		graphicFrame.setMacro(macro);
	}

	/**
	 * Sets the frame name.
	 */
	public void setName(String name) {
		getNonVisualProperties().setName(name);
	}

	/**
	 * Returns the frame name.
	 * @return name of the frame
	 */
	public String getName() {
		return getNonVisualProperties().getName();
	}

	private CTNonVisualDrawingProps getNonVisualProperties() {
		CTGraphicalObjectFrameNonVisual nvGraphic = graphicFrame.getNvGraphicFramePr();
		return nvGraphic.getCNvPr();
	}

	/**
	 * Attaches frame to an anchor.
	 */
	protected void setAnchor(XSSFClientAnchor anchor) {
		this.anchor = anchor;
	}

	/**
	 * Returns the frame anchor.
	 * @return the XSSFClientAnchor anchor this frame is attached to
	 */
	public XSSFClientAnchor getAnchor() {
		return (XSSFClientAnchor) anchor;
	}

	/**
	 * Assign a DrawingML chart to the graphic frame.
	 */
	protected void setChart(XSSFChart chart, String relId) {
		CTGraphicalObjectData data = graphicFrame.getGraphic().addNewGraphicData();
		appendChartElement(data, relId);
		chart.setGraphicFrame(this);
	}

	/**
	 * Gets the frame id.
	 */
	public long getId() {
		return graphicFrame.getNvGraphicFramePr().getCNvPr().getId();
	}

	/**
	 * Sets the frame id.
	 */
	protected void setId(long id) {
		graphicFrame.getNvGraphicFramePr().getCNvPr().setId(id);
	}

	/**
	 * The low level code to insert {@code <c:chart>} tag into
	 * {@code<a:graphicData>}.
	 *
	 * Here is the schema (ECMA-376):
	 * <pre>
	 * {@code
	 * <complexType name="CT_GraphicalObjectData">
	 *   <sequence>
	 *     <any minOccurs="0" maxOccurs="unbounded" processContents="strict"/>
	 *   </sequence>
	 *   <attribute name="uri" type="xsd:token"/>
	 * </complexType>
	 * }
	 * </pre>
	 */
	private void appendChartElement(CTGraphicalObjectData data, String id) {
		String r_namespaceUri = STRelationshipId.type.getName().getNamespaceURI();
		String c_namespaceUri = XSSFDrawing.NAMESPACE_C;
		XmlCursor cursor = data.newCursor();
		cursor.toNextToken();
		cursor.beginElement(new QName(c_namespaceUri, "chart", "c"));
		cursor.insertAttributeWithValue(new QName(r_namespaceUri, "id", "r"), id);
		cursor.dispose();
		data.setUri(c_namespaceUri);
	}

    @Override
    protected CTShapeProperties getShapeProperties(){
        return null;
    }

    @Override
    public String getShapeName() {
        return graphicFrame.getNvGraphicFramePr().getCNvPr().getName();
    }
}
