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

import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;

import javax.xml.namespace.QName;

import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLFactory;
import org.apache.poi.ooxml.POIXMLRelation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
import org.apache.poi.xddf.usermodel.text.TextContainer;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTArea3DChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAreaChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBar3DChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDateAx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDoughnutChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTExternalData;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTLine3DChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPie3DChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTRadarChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerAx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurface;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurface3DChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSurfaceChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTView3D;
import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;

@Beta
public abstract class XDDFChart extends POIXMLDocumentPart implements TextContainer {

    /**
     * default width of chart in emu
     */
    public static final int DEFAULT_WIDTH = 500000;

    /**
     * default height of chart in emu
     */
    public static final int DEFAULT_HEIGHT = 500000;

    /**
     * default x-coordinate  of chart in emu
     */
    public static final int DEFAULT_X = 10;

    /**
     * default y-coordinate value of chart in emu
     */
    public static final int DEFAULT_Y = 10;

    /**
     * Underlying workbook
     */
    private XSSFWorkbook workbook;

    private int chartIndex = 0;

    protected List<XDDFChartAxis> axes = new ArrayList<>();

    /**
     * Root element of the Chart part
     */
    protected final CTChartSpace chartSpace;


    /**
     * Construct a chart.
     */
    protected XDDFChart() {
        super();

        chartSpace = CTChartSpace.Factory.newInstance();
        chartSpace.addNewChart().addNewPlotArea();
    }

    /**
     * Construct a DrawingML chart from a package part.
     *
     * @param part
     *            the package part holding the chart data, the content type must
     *            be
     *            <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
     * @since POI 3.14-Beta1
     */
    protected XDDFChart(PackagePart part) throws IOException, XmlException {
        super(part);

        chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream(), DEFAULT_XML_OPTIONS).getChartSpace();
    }

    /**
     * Return the underlying CTChartSpace bean, the root element of the Chart
     * part.
     *
     * @return the underlying CTChartSpace bean
     */
    @Internal
    public CTChartSpace getCTChartSpace() {
        return chartSpace;
    }

    /**
     * Return the underlying CTChart bean, within the Chart Space
     *
     * @return the underlying CTChart bean
     */
    @Internal
    public CTChart getCTChart() {
        return chartSpace.getChart();
    }

    /**
     * Return the underlying CTPlotArea bean, within the Chart
     *
     * @return the underlying CTPlotArea bean
     */
    @Internal
    protected CTPlotArea getCTPlotArea() {
        return getCTChart().getPlotArea();
    }

    /**
     * Clear all properties, as if a new instance had just been created.
     * @since POI 4.1.2
     */
    public void clear() {
        axes.clear();
        seriesCount = 0;
        if (workbook != null) {
            workbook.removeSheetAt(0);
            workbook.createSheet();
        }
        getCTChart().set(CTChart.Factory.newInstance());
        getCTChart().addNewPlotArea();
    }

    /**
     * @return true if only visible cells will be present on the chart, false
     *         otherwise
     */
    public boolean isPlotOnlyVisibleCells() {
        if (getCTChart().isSetPlotVisOnly()) {
            return getCTChart().getPlotVisOnly().getVal();
        } else {
            return false;
        }
    }

    /**
     * @param only
     *            a flag specifying if only visible cells should be present on
     *            the chart
     */
    public void setPlotOnlyVisibleCells(boolean only) {
        if (!getCTChart().isSetPlotVisOnly()) {
            getCTChart().setPlotVisOnly(CTBoolean.Factory.newInstance());
        }
        getCTChart().getPlotVisOnly().setVal(only);
    }

    public void setFloor(int thickness) {
        if (!getCTChart().isSetFloor()) {
            getCTChart().setFloor(CTSurface.Factory.newInstance());
        }
        getCTChart().getFloor().getThickness().setVal(thickness);
    }

    public void setBackWall(int thickness) {
        if (!getCTChart().isSetBackWall()) {
            getCTChart().setBackWall(CTSurface.Factory.newInstance());
        }
        getCTChart().getBackWall().getThickness().setVal(thickness);
    }

    public void setSideWall(int thickness) {
        if (!getCTChart().isSetSideWall()) {
            getCTChart().setSideWall(CTSurface.Factory.newInstance());
        }
        getCTChart().getSideWall().getThickness().setVal(thickness);
    }

    public void setAutoTitleDeleted(boolean deleted) {
        if (!getCTChart().isSetAutoTitleDeleted()) {
            getCTChart().setAutoTitleDeleted(CTBoolean.Factory.newInstance());
        }
        getCTChart().getAutoTitleDeleted().setVal(deleted);
        if (deleted && getCTChart().isSetTitle()) {
            getCTChart().unsetTitle();
        }
    }

    /**
     * @since 4.0.1
     *
     */
    public void displayBlanksAs(DisplayBlanks as) {
        if (as == null){
            if (getCTChart().isSetDispBlanksAs()) {
                getCTChart().unsetDispBlanksAs();
            }
        } else {
            if (getCTChart().isSetDispBlanksAs()) {
              getCTChart().getDispBlanksAs().setVal(as.underlying);
            } else {
                getCTChart().addNewDispBlanksAs().setVal(as.underlying);
            }
        }
    }

    /**
     * @since 4.0.1
     */
    public Boolean getTitleOverlay() {
        if (getCTChart().isSetTitle()) {
            CTTitle title = getCTChart().getTitle();
            if (title.isSetOverlay()) {
                return title.getOverlay().getVal();
            }
        }
        return null;
    }

    /**
     * @since 4.0.1
     */
    public void setTitleOverlay(boolean overlay) {
        if (!getCTChart().isSetTitle()) {
            getCTChart().addNewTitle();
        }
        new XDDFTitle(this, getCTChart().getTitle()).setOverlay(overlay);
    }

    /**
     * Sets the title text as a static string.
     *
     * @param text
     *            to use as new title
     * @since 4.0.1
     */
    public void setTitleText(String text) {
        if (!getCTChart().isSetTitle()) {
            getCTChart().addNewTitle();
        }
        new XDDFTitle(this, getCTChart().getTitle()).setText(text);
    }

    /**
     * @since 4.0.1
     */
    public XDDFTitle getTitle() {
        if (getCTChart().isSetTitle()) {
            return new XDDFTitle(this, getCTChart().getTitle());
        } else {
            return null;
        }
    }

    /**
     * Remove the chart title.
     * @since POI 5.0.0
     */
    public void removeTitle() {
        setAutoTitleDeleted(true);
    }

    /**
    * Get or Add chart 3D view into chart
    *
    * @return this method will add 3D view
    */
   public XDDFView3D getOrAddView3D() {
      CTView3D view3D;
      if (getCTChart().isSetView3D()) {
         view3D = getCTChart().getView3D();
      } else {
         view3D = getCTChart().addNewView3D();
      }
      return new XDDFView3D(view3D);
   }

    /**
     * Get the chart title body if there is one, i.e. title is set and is not a
     * formula.
     *
     * @return text body or null, if title is a formula or no title is set.
     */
    @Beta
    public XDDFTextBody getFormattedTitle() {
        if (!getCTChart().isSetTitle()) {
            return null;
        }
        return new XDDFTitle(this, getCTChart().getTitle()).getBody();
    }

    @Override
    public <R> Optional<R> findDefinedParagraphProperty(Predicate<CTTextParagraphProperties> isSet,
        Function<CTTextParagraphProperties, R> getter) {
        // TODO Auto-generated method stub
        return Optional.empty();
    }

    @Override
    public <R> Optional<R> findDefinedRunProperty(Predicate<CTTextCharacterProperties> isSet,
        Function<CTTextCharacterProperties, R> getter) {
        // TODO Auto-generated method stub
        return Optional.empty();
    }

    public XDDFShapeProperties getOrAddShapeProperties() {
        CTPlotArea plotArea = getCTPlotArea();
        CTShapeProperties properties;
        if (plotArea.isSetSpPr()) {
            properties = plotArea.getSpPr();
        } else {
            properties = plotArea.addNewSpPr();
        }
        return new XDDFShapeProperties(properties);
    }

    public void deleteShapeProperties() {
        if (getCTPlotArea().isSetSpPr()) {
            getCTPlotArea().unsetSpPr();
        }
    }

    public XDDFChartLegend getOrAddLegend() {
        return new XDDFChartLegend(getCTChart());
    }

    public void deleteLegend() {
        if (getCTChart().isSetLegend()) {
            getCTChart().unsetLegend();
        }
    }

    public XDDFManualLayout getOrAddManualLayout() {
        return new XDDFManualLayout(getCTPlotArea());
    }

    private long seriesCount = 0;
    protected long incrementSeriesCount() {
        return seriesCount++;
    }

    public void plot(XDDFChartData data) {
        XSSFSheet sheet = getSheet();
        for (int idx = 0; idx < data.getSeriesCount(); idx++) {
            XDDFChartData.Series series = data.getSeries(idx);
            series.plot();
            XDDFDataSource<?> categoryDS = series.getCategoryData();
            XDDFNumericalDataSource<? extends Number> valuesDS = series.getValuesData();
            if (categoryDS == null || valuesDS == null
                    || categoryDS.isCellRange() || valuesDS.isCellRange()
                    || categoryDS.isLiteral() || valuesDS.isLiteral()) {
                // let's assume the data is already in the sheet
            } else {
                fillSheet(sheet, categoryDS, valuesDS);
            }
        }
    }

    public List<XDDFChartData> getChartSeries() {
        List<XDDFChartData> series = new LinkedList<>();
        CTPlotArea plotArea = getCTPlotArea();
        Map<Long, XDDFChartAxis> categories = getCategoryAxes();
        Map<Long, XDDFValueAxis> values = getValueAxes();

        for (int i = 0; i < plotArea.sizeOfAreaChartArray(); i++) {
            CTAreaChart areaChart = plotArea.getAreaChartArray(i);
            series.add(new XDDFAreaChartData(this, areaChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfArea3DChartArray(); i++) {
            CTArea3DChart areaChart = plotArea.getArea3DChartArray(i);
            series.add(new XDDFArea3DChartData(this, areaChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfBarChartArray(); i++) {
            CTBarChart barChart = plotArea.getBarChartArray(i);
            series.add(new XDDFBarChartData(this, barChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfBar3DChartArray(); i++) {
            CTBar3DChart barChart = plotArea.getBar3DChartArray(i);
            series.add(new XDDFBar3DChartData(this, barChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfDoughnutChartArray(); i++) {
            CTDoughnutChart doughnutChart = plotArea.getDoughnutChartArray(i);
            series.add(new XDDFDoughnutChartData(this, doughnutChart));
        }

        for (int i = 0; i < plotArea.sizeOfLineChartArray(); i++) {
            CTLineChart lineChart = plotArea.getLineChartArray(i);
            series.add(new XDDFLineChartData(this, lineChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfLine3DChartArray(); i++) {
            CTLine3DChart lineChart = plotArea.getLine3DChartArray(i);
            series.add(new XDDFLine3DChartData(this, lineChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfPieChartArray(); i++) {
            CTPieChart pieChart = plotArea.getPieChartArray(i);
            series.add(new XDDFPieChartData(this, pieChart));
        }

        for (int i = 0; i < plotArea.sizeOfPie3DChartArray(); i++) {
            CTPie3DChart pieChart = plotArea.getPie3DChartArray(i);
            series.add(new XDDFPie3DChartData(this, pieChart));
        }

        for (int i = 0; i < plotArea.sizeOfRadarChartArray(); i++) {
            CTRadarChart radarChart = plotArea.getRadarChartArray(i);
            series.add(new XDDFRadarChartData(this, radarChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfScatterChartArray(); i++) {
            CTScatterChart scatterChart = plotArea.getScatterChartArray(i);
            series.add(new XDDFScatterChartData(this, scatterChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfSurfaceChartArray(); i++) {
            CTSurfaceChart surfaceChart = plotArea.getSurfaceChartArray(i);
            series.add(new XDDFSurfaceChartData(this, surfaceChart, categories, values));
        }

        for (int i = 0; i < plotArea.sizeOfSurface3DChartArray(); i++) {
            CTSurface3DChart surfaceChart = plotArea.getSurface3DChartArray(i);
            series.add(new XDDFSurface3DChartData(this, surfaceChart, categories, values));
        }
        // TODO repeat above code for missing charts: Bubble, OfPie and Stock

        seriesCount = series.size();
        return series;
    }

    /**
     * Clear all chart series, as if a new instance had just been created.
     * @since POI 4.1.2
     */
    public void clearChartSeries() {
        CTPlotArea plotArea = getCTPlotArea();

        for (int i = plotArea.sizeOfAreaChartArray(); i > 0; i--) {
            plotArea.removeAreaChart(i - 1);
        }

        for (int i = plotArea.sizeOfArea3DChartArray(); i > 0; i--) {
            plotArea.removeArea3DChart(i - 1);
        }

        for (int i = plotArea.sizeOfBarChartArray(); i > 0; i--) {
            plotArea.removeBarChart(i - 1);
        }

        for (int i = plotArea.sizeOfBar3DChartArray(); i > 0; i--) {
            plotArea.removeBar3DChart(i - 1);
        }

        for (int i = plotArea.sizeOfBubbleChartArray(); i > 0; i--) {
            plotArea.removeBubbleChart(i - 1);
        }

        for (int i = plotArea.sizeOfDoughnutChartArray(); i > 0; i--) {
            plotArea.removeDoughnutChart(i - 1);
        }

        for (int i = plotArea.sizeOfLineChartArray(); i > 0; i--) {
            plotArea.removeLineChart(i - 1);
        }

        for (int i = plotArea.sizeOfLine3DChartArray(); i > 0; i--) {
            plotArea.removeLine3DChart(i - 1);
        }

        for (int i = plotArea.sizeOfOfPieChartArray(); i > 0; i--) {
            plotArea.removeOfPieChart(i - 1);
        }

        for (int i = plotArea.sizeOfPieChartArray(); i > 0; i--) {
            plotArea.removePieChart(i - 1);
        }

        for (int i = plotArea.sizeOfPie3DChartArray(); i > 0; i--) {
            plotArea.removePie3DChart(i - 1);
        }

        for (int i = plotArea.sizeOfRadarChartArray(); i > 0; i--) {
            plotArea.removeRadarChart(i - 1);
        }

        for (int i = plotArea.sizeOfScatterChartArray(); i > 0; i--) {
            plotArea.removeScatterChart(i - 1);
        }

        for (int i = plotArea.sizeOfStockChartArray(); i > 0; i--) {
            plotArea.removeStockChart(i - 1);
        }

        for (int i = plotArea.sizeOfSurfaceChartArray(); i > 0; i--) {
            plotArea.removeSurfaceChart(i - 1);
        }

        for (int i = plotArea.sizeOfSurface3DChartArray(); i > 0; i--) {
            plotArea.removeSurface3DChart(i - 1);
        }
    }

    private Map<Long, XDDFChartAxis> getCategoryAxes() {
        CTPlotArea plotArea = getCTPlotArea();
        int sizeOfArray = plotArea.sizeOfCatAxArray();
        Map<Long, XDDFChartAxis> axesMap = new HashMap<>(sizeOfArray);
        for (int i = 0; i < sizeOfArray; i++) {
            CTCatAx category = plotArea.getCatAxArray(i);
            axesMap.put(category.getAxId().getVal(), new XDDFCategoryAxis(category));
        }
        return axesMap;
    }

    private Map<Long, XDDFValueAxis> getValueAxes() {
        CTPlotArea plotArea = getCTPlotArea();
        int sizeOfArray = plotArea.sizeOfValAxArray();
        Map<Long, XDDFValueAxis> axesMap = new HashMap<>(sizeOfArray);
        for (int i = 0; i < sizeOfArray; i++) {
            CTValAx values = plotArea.getValAxArray(i);
            axesMap.put(values.getAxId().getVal(), new XDDFValueAxis(values));
        }
        return axesMap;
    }

    public XDDFValueAxis createValueAxis(AxisPosition pos) {
        XDDFValueAxis valueAxis = new XDDFValueAxis(getCTPlotArea(), pos);
        addAxis(valueAxis);
        return valueAxis;
    }

    /**
     * this method will return series axis with specified position
     *
     * @param pos axis position Left, Right, Top, Bottom
     * @return series axis with specified position
     */
    public XDDFSeriesAxis createSeriesAxis(AxisPosition pos) {
        XDDFSeriesAxis seriesAxis = new XDDFSeriesAxis(getCTPlotArea(), pos);
        addAxis(seriesAxis);
        return seriesAxis;
    }

    public XDDFCategoryAxis createCategoryAxis(AxisPosition pos) {
        XDDFCategoryAxis categoryAxis = new XDDFCategoryAxis(getCTPlotArea(), pos);
        addAxis(categoryAxis);
        return categoryAxis;
    }

    public XDDFDateAxis createDateAxis(AxisPosition pos) {
        XDDFDateAxis dateAxis = new XDDFDateAxis(getCTPlotArea(), pos);
        addAxis(dateAxis);
        return dateAxis;
    }

    private void addAxis(XDDFChartAxis newAxis) {
        if (axes.size() == 1) {
            XDDFChartAxis axis = axes.get(0);
            axis.crossAxis(newAxis);
            newAxis.crossAxis(axis);
            axis.setCrosses(AxisCrosses.AUTO_ZERO);
            newAxis.setCrosses(AxisCrosses.AUTO_ZERO);
        }
        axes.add(newAxis);
    }

    /**
     * this method will return specified chart data with category and series values
     *
     * @param type chart type
     * @param category category values of chart
     * @param values series values of chart
     * @return specified chart data.
     */
    public XDDFChartData createData(ChartTypes type, XDDFChartAxis category, XDDFValueAxis values) {
        Map<Long, XDDFChartAxis> categories = null;
        Map<Long, XDDFValueAxis> mapValues = null;

        if (ChartTypes.PIE != type && ChartTypes.PIE3D != type && ChartTypes.DOUGHNUT != type) {
            categories = Collections.singletonMap(category.getId(), category);
            mapValues = Collections.singletonMap(values.getId(), values);
        }

        final CTPlotArea plotArea = getCTPlotArea();
        switch (type) {
        case AREA:
            return new XDDFAreaChartData(this, plotArea.addNewAreaChart(), categories, mapValues);
        case AREA3D:
            return new XDDFArea3DChartData(this, plotArea.addNewArea3DChart(), categories, mapValues);
        case BAR:
            return new XDDFBarChartData(this, plotArea.addNewBarChart(), categories, mapValues);
        case BAR3D:
            return new XDDFBar3DChartData(this, plotArea.addNewBar3DChart(), categories, mapValues);
        case DOUGHNUT:
            return new XDDFDoughnutChartData(this, plotArea.addNewDoughnutChart());
        case LINE:
            return new XDDFLineChartData(this, plotArea.addNewLineChart(), categories, mapValues);
        case LINE3D:
            return new XDDFLine3DChartData(this, plotArea.addNewLine3DChart(), categories, mapValues);
        case PIE:
            return new XDDFPieChartData(this, plotArea.addNewPieChart());
        case PIE3D:
            return new XDDFPie3DChartData(this, plotArea.addNewPie3DChart());
        case RADAR:
            return new XDDFRadarChartData(this, plotArea.addNewRadarChart(), categories, mapValues);
        case SCATTER:
            return new XDDFScatterChartData(this, plotArea.addNewScatterChart(), categories, mapValues);
        case SURFACE:
            return new XDDFSurfaceChartData(this, plotArea.addNewSurfaceChart(), categories, mapValues);
        case SURFACE3D:
            return new XDDFSurface3DChartData(this, plotArea.addNewSurface3DChart(), categories, mapValues);
        // TODO repeat above code for missing charts: Bubble, OfPie and Stock
        default:
            return null;
        }
    }

    public List<? extends XDDFChartAxis> getAxes() {
        if (axes.isEmpty() && hasAxes()) {
            parseAxes();
        }
        return axes;
    }

    private boolean hasAxes() {
        CTPlotArea ctPlotArea = getCTPlotArea();
        int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea
            .sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray();
        return totalAxisCount > 0;
    }

    private void parseAxes() {
        for (CTCatAx catAx : getCTPlotArea().getCatAxArray()) {
            axes.add(new XDDFCategoryAxis(catAx));
        }
        for (CTDateAx dateAx : getCTPlotArea().getDateAxArray()) {
            axes.add(new XDDFDateAxis(dateAx));
        }
        for (CTSerAx serAx : getCTPlotArea().getSerAxArray()) {
            axes.add(new XDDFSeriesAxis(serAx));
        }
        for (CTValAx valAx : getCTPlotArea().getValAxArray()) {
            axes.add(new XDDFValueAxis(valAx));
        }
    }

    /**
     * Set value range (basic Axis Options)
     *
     * @param axisIndex
     *            0 - primary axis, 1 - secondary axis
     * @param minimum
     *            minimum value; Double.NaN - automatic; null - no change
     * @param maximum
     *            maximum value; Double.NaN - automatic; null - no change
     * @param majorUnit
     *            major unit value; Double.NaN - automatic; null - no change
     * @param minorUnit
     *            minor unit value; Double.NaN - automatic; null - no change
     */
    public void setValueRange(int axisIndex, Double minimum, Double maximum, Double majorUnit, Double minorUnit) {
        XDDFChartAxis axis = getAxes().get(axisIndex);
        if (axis == null) {
            return;
        }
        if (minimum != null) {
            axis.setMinimum(minimum);
        }
        if (maximum != null) {
            axis.setMaximum(maximum);
        }
        if (majorUnit != null) {
            axis.setMajorUnit(majorUnit);
        }
        if (minorUnit != null) {
            axis.setMinorUnit(minorUnit);
        }
    }

    /**
     * method to create relationship with embedded part for example writing xlsx
     * file stream into output stream
     *
     * @param chartRelation
     *            relationship object
     * @param chartFactory
     *            ChartFactory object
     * @param chartIndex
     *            index used to suffix on file
     * @return return relation part which used to write relation in .rels file
     *         and get relation id
     * @since POI 4.0.0
     */
    public PackageRelationship createRelationshipInChart(POIXMLRelation chartRelation, POIXMLFactory chartFactory,
        int chartIndex) {
        POIXMLDocumentPart documentPart =
                createRelationship(chartRelation, chartFactory, chartIndex, true).getDocumentPart();
        return addRelation(null, chartRelation, documentPart).getRelationship();
    }

    /**
     * if embedded part was null then create new part
     *
     * @param chartWorkbookRelation
     *            chart workbook relation object
     * @param chartFactory
     *            factory object of POIXMLFactory (XWPFFactory/XSLFFactory)
     * @return return the new package part
     * @throws InvalidFormatException
     * @since POI 4.0.0
     */
    private PackagePart createWorksheetPart(POIXMLRelation chartWorkbookRelation, POIXMLFactory chartFactory)
            throws InvalidFormatException {
        PackageRelationship xlsx = createRelationshipInChart(chartWorkbookRelation, chartFactory, chartIndex);
        setExternalId(xlsx.getId());
        return getTargetPart(xlsx);
    }

    /**
     * this method write the XSSFWorkbook object data into embedded excel file
     *
     * @param workbook
     *            XSSFworkbook object
     * @throws IOException
     * @throws InvalidFormatException
     * @since POI 4.0.0
     */
    public void saveWorkbook(XSSFWorkbook workbook) throws IOException, InvalidFormatException {
        PackagePart worksheetPart = getWorksheetPart();
        if (worksheetPart == null) {
            POIXMLRelation chartWorkbookRelation = getChartWorkbookRelation();
            POIXMLFactory chartFactory = getChartFactory();
            if (chartWorkbookRelation != null && chartFactory != null) {
                worksheetPart = createWorksheetPart(chartWorkbookRelation, chartFactory);
            } else {
                throw new InvalidFormatException("unable to determine chart relations");
            }
        }
        try (OutputStream xlsOut = worksheetPart.getOutputStream()) {
            setWorksheetPartCommitted();
            workbook.write(xlsOut);
        }
    }

    /**
     *
     * @return the chart relation in the implementing subclass.
     * @since POI 4.0.0
     */
    protected abstract POIXMLRelation getChartRelation();

    /**
     *
     * @return the chart workbook relation in the implementing subclass.
     * @since POI 4.0.0
     */
    protected abstract POIXMLRelation getChartWorkbookRelation();

    /**
     *
     * @return the chart factory in the implementing subclass.
     * @since POI 4.0.0
     */
    protected abstract POIXMLFactory getChartFactory();

    /**
     * this method writes the data into sheet
     *
     * @param sheet
     *            sheet of embedded excel
     * @param categoryData
     *            category values
     * @param valuesData
     *            data values
     * @since POI 4.0.0
     */
    protected void fillSheet(XSSFSheet sheet, XDDFDataSource<?> categoryData, XDDFNumericalDataSource<?> valuesData) {
        int numOfPoints = categoryData.getPointCount();
        for (int i = 0; i < numOfPoints; i++) {
            XSSFRow row = getRow(sheet, i + 1); // first row is for title
            Object category = categoryData.getPointAt(i);
            if (category != null) {
                getCell(row, categoryData.getColIndex()).setCellValue(category.toString());
            }
            Number value = valuesData.getPointAt(i);
            if (value != null) {
                getCell(row, valuesData.getColIndex()).setCellValue(value.doubleValue());
            }
        }
    }

    /**
     * this method return row on given index if row is null then create new row
     *
     * @param sheet
     *            current sheet object
     * @param index
     *            index of current row
     * @return this method return sheet row on given index
     * @since POI 4.0.0
     */
    private XSSFRow getRow(XSSFSheet sheet, int index) {
        XSSFRow row = sheet.getRow(index);
        if (row == null) {
            return sheet.createRow(index);
        } else {
            return row;
        }
    }

    /**
     * this method return cell on given index if cell is null then create new
     * cell
     *
     * @param row
     *            current row object
     * @param index
     *            index of current cell
     * @return this method return sheet cell on given index
     * @since POI 4.0.0
     */
    private XSSFCell getCell(XSSFRow row, int index) {
        XSSFCell cell = row.getCell(index);
        if (cell == null) {
            return row.createCell(index);
        } else {
            return cell;
        }
    }

    /**
     * import content from other chart to created chart
     *
     * @param other
     *            chart object
     * @since POI 4.0.0
     */
    public void importContent(XDDFChart other) {
        getCTChartSpace().set(other.getCTChartSpace());
    }

    /**
     * save chart xml
     */
    @Override
    protected void commit() throws IOException {
        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
        xmlOptions.setSaveSyntheticDocumentElement(
            new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));

        if (workbook != null) {
            try {
                saveWorkbook(workbook);
            } catch (InvalidFormatException e) {
                throw new POIXMLException(e);
            }
        }

        PackagePart part = getPackagePart();
        try (OutputStream out = part.getOutputStream()) {
            chartSpace.save(out, xmlOptions);
        }
    }

    /**
     * set sheet title in excel file
     *
     * @param title
     *            title of sheet
     * @param column
     *            column index
     * @return return cell reference
     * @since POI 4.0.0
     */
    public CellReference setSheetTitle(String title, int column) {
        XSSFSheet sheet = getSheet();
        if (sheet == null) {
            return null;
        }
        XSSFRow row = getRow(sheet, 0);
        XSSFCell cell = getCell(row, column);
        cell.setCellValue(title);

        return new CellReference(sheet.getSheetName(), 0, column, true, true);
    }

    /**
     * @param range
     * @return
     * @since POI 4.0.0
     */
    public String formatRange(CellRangeAddress range) {
        final XSSFSheet sheet = getSheet();
        return (sheet == null) ? null : range.formatAsString(sheet.getSheetName(), true);
    }

    /**
     * get sheet object of embedded excel file
     *
     * @return excel sheet object
     * @since POI 4.0.0
     */
    private XSSFSheet getSheet() {
        XSSFSheet sheet = null;
        try {
            sheet = getWorkbook().getSheetAt(0);
        } catch (InvalidFormatException | IOException ife) {
        }
        return sheet;
    }

    /**
     * this method is used to get worksheet part if call is from saveworkbook
     * method then check isCommitted isCommitted variable shows that we are
     * writing xssfworkbook object into output stream of embedded part
     *
     * @return returns the packagepart of embedded file
     * @throws InvalidFormatException
     * @since POI 4.0.0
     */
    private PackagePart getWorksheetPart() throws InvalidFormatException {
        for (RelationPart part : getRelationParts()) {
            if (POIXMLDocument.PACK_OBJECT_REL_TYPE.equals(part.getRelationship().getRelationshipType())) {
                return getTargetPart(part.getRelationship());
            }
        }
        return null;
    }

    private void setWorksheetPartCommitted() {
        for (RelationPart part : getRelationParts()) {
            if (POIXMLDocument.PACK_OBJECT_REL_TYPE.equals(part.getRelationship().getRelationshipType())) {
                part.getDocumentPart().setCommitted(true);
                break;
            }
        }
    }

    /**
     * @return returns the workbook object of embedded excel file
     * @throws IOException
     * @throws InvalidFormatException
     * @since POI 4.0.0
     */
    public XSSFWorkbook getWorkbook() throws IOException, InvalidFormatException {
        if (workbook == null) {
            try {
                PackagePart worksheetPart = getWorksheetPart();
                if (worksheetPart == null) {
                    workbook = new XSSFWorkbook();
                    workbook.createSheet();
                } else {
                    workbook = new XSSFWorkbook(worksheetPart.getInputStream());
                }
            } catch (NotOfficeXmlFileException e) {
                workbook = new XSSFWorkbook();
                workbook.createSheet();
            }
        }
        return workbook;
    }

    /**
     * while reading chart from template file then we need to parse and store
     * embedded excel file in chart object show that we can modify value
     * according to use
     *
     * @param workbook
     *            workbook object which we read from chart embedded part
     * @since POI 4.0.0
     */
    public void setWorkbook(XSSFWorkbook workbook) {
        this.workbook = workbook;
    }

    /**
     * set the relation id of embedded excel relation id into external data
     * relation tag
     *
     * @param id
     *            relation id of embedded excel relation id into external data
     *            relation tag
     * @since POI 4.0.0
     */
    public void setExternalId(String id) {
        getCTChartSpace().addNewExternalData().setId(id);
        CTChartSpace ctChartSpace = getCTChartSpace();
        CTExternalData externalData = ctChartSpace.isSetExternalData()
                ? ctChartSpace.getExternalData()
                : ctChartSpace.addNewExternalData();
        externalData.setId(id);
    }

    /**
     * @return method return chart index
     * @since POI 4.0.0
     */
    protected int getChartIndex() {
        return chartIndex;
    }

    /**
     * Set chart index which can be used for relation part.
     *
     * @param chartIndex
     *            chart index which can be used for relation part.
     */
    public void setChartIndex(int chartIndex) {
        this.chartIndex = chartIndex;
    }

    /**
     * Replace references to the sheet name in the data supporting the chart.
     *
     * @param newSheet
     *          sheet to be used in the data references.
     *
     * @since POI 5.0.1
     */
    public void replaceReferences(XSSFSheet newSheet) {
        for (XDDFChartData data : getChartSeries()) {
            for (XDDFChartData.Series series : data.series) {
                XDDFDataSource newCategory = series.categoryData;
                XDDFNumericalDataSource newValues = series.valuesData;
                try {
                    if (series.categoryData != null && series.categoryData.isReference()) {
                        String ref = series.categoryData.getDataRangeReference();
                        CellRangeAddress rangeAddress = CellRangeAddress.valueOf(ref.substring(ref.indexOf('!') + 1));
                        newCategory = series.categoryData.isNumeric()
                                ? XDDFDataSourcesFactory.fromNumericCellRange(newSheet, rangeAddress)
                                : XDDFDataSourcesFactory.fromStringCellRange(newSheet, rangeAddress);
                        if (newCategory.isNumeric()) {
                            ((XDDFNumericalDataSource) newCategory).setFormatCode(series.categoryData.getFormatCode());
                        }
                    }
                    if (series.valuesData!= null && series.valuesData.isReference()) {
                        String ref = series.valuesData.getDataRangeReference();
                        CellRangeAddress rangeAddress = CellRangeAddress.valueOf(ref.substring(ref.indexOf('!') + 1));
                        newValues = XDDFDataSourcesFactory.fromNumericCellRange(newSheet, rangeAddress);
                        newValues.setFormatCode(series.valuesData.getFormatCode());
                    }
                } catch (IllegalArgumentException iae) {
                    // keep old values when cell range cannot be parsed
                }
                series.replaceData(newCategory, newValues);
                series.plot();
            }
        }
    }
}
