/* ====================================================================
   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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;

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.XDDFFillProperties;
import org.apache.poi.xddf.usermodel.XDDFLineProperties;
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt;

/**
 * Base of all XDDF Chart Data
 */
@Beta
public abstract class XDDFChartData {
    protected XDDFChart parent;
    protected List<Series> series;
    private XDDFCategoryAxis categoryAxis;
    private List<XDDFValueAxis> valueAxes;

    protected XDDFChartData(XDDFChart chart) {
        this.parent = chart;
        this.series = new ArrayList<>();
    }

    protected void defineAxes(CTUnsignedInt[] axes, Map<Long, XDDFChartAxis> categories,
            Map<Long, XDDFValueAxis> values) {
        List<XDDFValueAxis> list = new ArrayList<>(axes.length);
        for (CTUnsignedInt axe : axes) {
            Long axisId = axe.getVal();
            XDDFChartAxis category = categories.get(axisId);
            if (category == null) {
                XDDFValueAxis axis = values.get(axisId);
                if (axis != null) {
                    list.add(axis);
                }
            } else if (category instanceof XDDFCategoryAxis) {
                this.categoryAxis = (XDDFCategoryAxis) category;
            }
        }
        this.valueAxes = Collections.unmodifiableList(list);
    }

    public XDDFCategoryAxis getCategoryAxis() {
        return categoryAxis;
    }

    public List<XDDFValueAxis> getValueAxes() {
        return valueAxes;
    }

    /**
     * Calls to <code>getSeries().add(series)</code> or to <code>getSeries().remove(series)</code>
     * may corrupt the workbook.
     *
     * <p>
     * Instead, use the following methods:
     * <ul>
     * <li>{@link #getSeriesCount()}</li>
     * <li>{@link #getSeries(int)}</li>
     * <li>{@link #addSeries(XDDFDataSource,XDDFNumericalDataSource)}</li>
     * <li>{@link #removeSeries(int)}</li>
     * </ul>
     *
     * @deprecated since POI 4.1.1
     * @return
     */
    @Deprecated
    public List<Series> getSeries() {
        return Collections.unmodifiableList(series);
    }

    public final int getSeriesCount() {
        return series.size();
    }

    public final Series getSeries(int n) {
        return series.get(n);
    }

    public final void removeSeries(int n) {
        final String procName = "removeSeries";
        if (n < 0 || series.size() <= n) {
            throw new IllegalArgumentException(String.format(Locale.ROOT, "%s(%d): illegal index", procName, n));
        }
        series.remove(n);
        removeCTSeries(n);
    }

    /**
     * This method should be implemented in every class that extends <code>XDDFChartData</code>.
     * <p>
     * A typical implementation would be
     *
     * <pre><code>
    protected void removeCTSeries(int n) {
        chart.removeSer(n);
    }

     * </code></pre>
     *
     * @param n
     */
    @Internal
    protected abstract void removeCTSeries(int n);

    public abstract void setVaryColors(Boolean varyColors);

    public abstract XDDFChartData.Series addSeries(XDDFDataSource<?> category,
            XDDFNumericalDataSource<? extends Number> values);

    public abstract class Series {
        protected abstract CTSerTx getSeriesText();

        public abstract void setShowLeaderLines(boolean showLeaderLines);
        public abstract XDDFShapeProperties getShapeProperties();
        public abstract void setShapeProperties(XDDFShapeProperties properties);

        protected XDDFDataSource<?> categoryData;
        protected XDDFNumericalDataSource<? extends Number> valuesData;

        protected abstract CTAxDataSource getAxDS();

        protected abstract CTNumDataSource getNumDS();

        protected abstract void setIndex(long index);

        protected abstract void setOrder(long order);

        protected abstract List<CTDPt> getDPtList();

        protected Series(XDDFDataSource<?> category, XDDFNumericalDataSource<? extends Number> values) {
            replaceData(category, values);
        }

        public void replaceData(XDDFDataSource<?> category, XDDFNumericalDataSource<? extends Number> values) {
            if (categoryData != null && values != null) {
                int numOfPoints = category.getPointCount();
                if (numOfPoints != values.getPointCount()) {
                    throw new IllegalStateException("Category and values must have the same point count.");
                }
            }
            this.categoryData = category;
            this.valuesData = values;
        }

        public void setTitle(String title, CellReference titleRef) {
            if (titleRef == null) {
                getSeriesText().setV(title);
            } else {
                CTStrRef ref;
                if (getSeriesText().isSetStrRef()) {
                    ref = getSeriesText().getStrRef();
                } else {
                    ref = getSeriesText().addNewStrRef();
                }
                ref.setF(titleRef.formatAsString());
                if (title != null) {
                    CTStrData cache;
                    if (ref.isSetStrCache()) {
                        cache = ref.getStrCache();
                    } else {
                        cache = ref.addNewStrCache();
                    }
                    if (cache.sizeOfPtArray() < 1) {
                        cache.addNewPtCount().setVal(1);
                        cache.addNewPt().setIdx(0);;
                    }
                    cache.getPtArray(0).setV(title);
                }
            }
        }

        public XDDFDataSource<?> getCategoryData() {
            return categoryData;
        }

        public XDDFNumericalDataSource<? extends Number> getValuesData() {
            return valuesData;
        }

        public void plot() {
            if (categoryData != null) {
                if (categoryData.isNumeric()) {
                    CTNumData cache = retrieveNumCache(getAxDS(), categoryData);
                    categoryData.fillNumericalCache(cache);
                } else {
                    CTStrData cache = retrieveStrCache(getAxDS(), categoryData);
                    categoryData.fillStringCache(cache);
                }
            }
            if (valuesData != null) {
                CTNumData cache = retrieveNumCache(getNumDS(), valuesData);
                valuesData.fillNumericalCache(cache);
            }
        }

        /**
         * @param fill
         *      fill property for the shape representing the series.
         * @since POI 4.1.1
         */
        public void setFillProperties(XDDFFillProperties fill) {
            XDDFShapeProperties properties = getShapeProperties();
            if (properties == null) {
                properties = new XDDFShapeProperties();
            }
            properties.setFillProperties(fill);
            setShapeProperties(properties);
        }

        /**
         * @param line
         *      line property for the shape representing the series.
         * @since POI 4.1.1
         */
        public void setLineProperties(XDDFLineProperties line) {
            XDDFShapeProperties properties = getShapeProperties();
            if (properties == null) {
                properties = new XDDFShapeProperties();
            }
            properties.setLineProperties(line);
            setShapeProperties(properties);
        }

        /**
         * If a data point definition with the given <code>index</code> exists, then remove it.
         * Otherwise do nothing.
         *
         * @param index
         *      data point index.
         * @since POI 5.0.1
         */
        public void clearDataPoint(long index) {
            List<CTDPt> points = getDPtList();
            for (int i = 0; i < points.size(); i++) {
                if (points.get(i).getIdx().getVal() == index) {
                    points.remove(i);
                    i = points.size();
                }
            }
        }

        /**
         * If a data point definition with the given <code>index</code> exists, then return it.
         * Otherwise create a new data point definition and return it.
         *
         * @param index
         *      data point index.
         * @return
         *      the data point with the given <code>index</code>.
         * @since POI 5.0.1
         */
        public XDDFDataPoint getDataPoint(long index) {
            List<CTDPt> points = getDPtList();
            for (int i = 0; i < points.size(); i++) {
                if (points.get(i).getIdx().getVal() == index) {
                    return new XDDFDataPoint(points.get(i));
                }
                if (points.get(i).getIdx().getVal() > index) {
                    points.add(i, CTDPt.Factory.newInstance());
                    CTDPt point = points.get(i);
                    point.addNewIdx().setVal(index);
                    return new XDDFDataPoint(point);
                }
            }
            points.add(CTDPt.Factory.newInstance());
            CTDPt point = points.get(points.size() - 1);
            point.addNewIdx().setVal(index);
            return new XDDFDataPoint(point);
        }

        private CTNumData retrieveNumCache(final CTAxDataSource axDataSource, XDDFDataSource<?> data) {
            CTNumData numCache;
            if (data.isReference()) {
                CTNumRef numRef;
                if (axDataSource.isSetNumRef()) {
                    numRef = axDataSource.getNumRef();
                } else {
                    numRef = axDataSource.addNewNumRef();
                }
                if (numRef.isSetNumCache()) {
                    numCache = numRef.getNumCache();
                } else {
                    numCache = numRef.addNewNumCache();
                }
                numRef.setF(data.getDataRangeReference());
                if (axDataSource.isSetNumLit()) {
                    axDataSource.unsetNumLit();
                }
            } else {
                if (axDataSource.isSetNumLit()) {
                    numCache = axDataSource.getNumLit();
                } else {
                    numCache = axDataSource.addNewNumLit();
                }
                if (axDataSource.isSetNumRef()) {
                    axDataSource.unsetNumRef();
                }
            }
            return numCache;
        }

        private CTStrData retrieveStrCache(final CTAxDataSource axDataSource, XDDFDataSource<?> data) {
            CTStrData strCache;
            if (data.isReference()) {
                CTStrRef strRef;
                if (axDataSource.isSetStrRef()) {
                    strRef = axDataSource.getStrRef();
                } else {
                    strRef = axDataSource.addNewStrRef();
                }
                if (strRef.isSetStrCache()) {
                    strCache = strRef.getStrCache();
                } else {
                    strCache = strRef.addNewStrCache();
                }
                strRef.setF(data.getDataRangeReference());
                if (axDataSource.isSetStrLit()) {
                    axDataSource.unsetStrLit();
                }
            } else {
                if (axDataSource.isSetStrLit()) {
                    strCache = axDataSource.getStrLit();
                } else {
                    strCache = axDataSource.addNewStrLit();
                }
                if (axDataSource.isSetStrRef()) {
                    axDataSource.unsetStrRef();
                }
            }
            return strCache;
        }

        private CTNumData retrieveNumCache(final CTNumDataSource numDataSource, XDDFDataSource<?> data) {
            CTNumData numCache;
            if (data.isReference()) {
                CTNumRef numRef;
                if (numDataSource.isSetNumRef()) {
                    numRef = numDataSource.getNumRef();
                } else {
                    numRef = numDataSource.addNewNumRef();
                }
                if (numRef.isSetNumCache()) {
                    numCache = numRef.getNumCache();
                } else {
                    numCache = numRef.addNewNumCache();
                }
                numRef.setF(data.getDataRangeReference());
                if (numDataSource.isSetNumLit()) {
                    numDataSource.unsetNumLit();
                }
            } else {
                if (numDataSource.isSetNumLit()) {
                    numCache = numDataSource.getNumLit();
                } else {
                    numCache = numDataSource.addNewNumLit();
                }
                if (numDataSource.isSetNumRef()) {
                    numDataSource.unsetNumRef();
                }
            }
            return numCache;
        }
    }
}
