/* ====================================================================
   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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataConsolidateFunction;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;

public class XSSFPivotTable extends POIXMLDocumentPart {

    protected final static short CREATED_VERSION = 3;
    protected final static short MIN_REFRESHABLE_VERSION = 3;
    protected final static short UPDATED_VERSION = 3;

    private CTPivotTableDefinition pivotTableDefinition;
    private XSSFPivotCacheDefinition pivotCacheDefinition;
    private XSSFPivotCache pivotCache;
    private XSSFPivotCacheRecords pivotCacheRecords;
    private Sheet parentSheet;
    private Sheet dataSheet;

    @Beta
    protected XSSFPivotTable() {
        super();
        pivotTableDefinition = CTPivotTableDefinition.Factory.newInstance();
        pivotCache = new XSSFPivotCache();
        pivotCacheDefinition = new XSSFPivotCacheDefinition();
        pivotCacheRecords = new XSSFPivotCacheRecords();
    }

     /**
     * Creates an XSSFPivotTable representing the given package part and relationship.
     * Should only be called when reading in an existing file.
     *
     * @param part - The package part that holds xml data representing this pivot table.
     * 
     * @since POI 3.14-Beta1
     */
    @Beta
    protected XSSFPivotTable(PackagePart part) throws IOException {
        super(part);
        readFrom(part.getInputStream());
    }
    
    @Beta
    public void readFrom(InputStream is) throws IOException {
	try {
            XmlOptions options  = new XmlOptions(DEFAULT_XML_OPTIONS);
            //Removing root element
            options.setLoadReplaceDocumentElement(null);
            pivotTableDefinition = CTPivotTableDefinition.Factory.parse(is, options);
        } catch (XmlException e) {
            throw new IOException(e.getLocalizedMessage());
        }
    }

    @Beta
    public void setPivotCache(XSSFPivotCache pivotCache) {
        this.pivotCache = pivotCache;
    }

    @Beta
    public XSSFPivotCache getPivotCache() {
        return pivotCache;
    }

    @Beta
    public Sheet getParentSheet() {
        return parentSheet;
    }

    @Beta
    public void setParentSheet(XSSFSheet parentSheet) {
        this.parentSheet = parentSheet;
    }

    @Beta
    @Internal
    public CTPivotTableDefinition getCTPivotTableDefinition() {
        return pivotTableDefinition;
    }

    @Beta
    @Internal
    public void setCTPivotTableDefinition(CTPivotTableDefinition pivotTableDefinition) {
        this.pivotTableDefinition = pivotTableDefinition;
    }

    @Beta
    public XSSFPivotCacheDefinition getPivotCacheDefinition() {
        return pivotCacheDefinition;
    }

    @Beta
    public void setPivotCacheDefinition(XSSFPivotCacheDefinition pivotCacheDefinition) {
        this.pivotCacheDefinition = pivotCacheDefinition;
    }

    @Beta
    public XSSFPivotCacheRecords getPivotCacheRecords() {
        return pivotCacheRecords;
    }

    @Beta
    public void setPivotCacheRecords(XSSFPivotCacheRecords pivotCacheRecords) {
        this.pivotCacheRecords = pivotCacheRecords;
    }

    @Beta
    public Sheet getDataSheet() {
        return dataSheet;
    }

    @Beta
    private void setDataSheet(Sheet dataSheet) {
        this.dataSheet = dataSheet;
    }

    @Beta
    @Override
    protected void commit() throws IOException {
        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
        //Sets the pivotTableDefinition tag
        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTPivotTableDefinition.type.getName().
                getNamespaceURI(), "pivotTableDefinition"));
        PackagePart part = getPackagePart();
        OutputStream out = part.getOutputStream();
        pivotTableDefinition.save(out, xmlOptions);
        out.close();
    }

    /**
     * Set default values for the table definition.
     */
    @Beta
    protected void setDefaultPivotTableDefinition() {
        //Not more than one until more created
        pivotTableDefinition.setMultipleFieldFilters(false);
        //Indentation increment for compact rows
        pivotTableDefinition.setIndent(0);
        //The pivot version which created the pivot cache set to default value
        pivotTableDefinition.setCreatedVersion(CREATED_VERSION);
        //Minimun version required to update the pivot cache
        pivotTableDefinition.setMinRefreshableVersion(MIN_REFRESHABLE_VERSION);
        //Version of the application which "updated the spreadsheet last"
        pivotTableDefinition.setUpdatedVersion(UPDATED_VERSION);
        //Titles shown at the top of each page when printed
        pivotTableDefinition.setItemPrintTitles(true);
        //Set autoformat properties
        pivotTableDefinition.setUseAutoFormatting(true);
        pivotTableDefinition.setApplyNumberFormats(false);
        pivotTableDefinition.setApplyWidthHeightFormats(true);
        pivotTableDefinition.setApplyAlignmentFormats(false);
        pivotTableDefinition.setApplyPatternFormats(false);
        pivotTableDefinition.setApplyFontFormats(false);
        pivotTableDefinition.setApplyBorderFormats(false);
        pivotTableDefinition.setCacheId(pivotCache.getCTPivotCache().getCacheId());
        pivotTableDefinition.setName("PivotTable"+pivotTableDefinition.getCacheId());
        pivotTableDefinition.setDataCaption("Values");

        //Set the default style for the pivot table
        CTPivotTableStyle style = pivotTableDefinition.addNewPivotTableStyleInfo();
        style.setName("PivotStyleLight16");
        style.setShowLastColumn(true);
        style.setShowColStripes(false);
        style.setShowRowStripes(false);
        style.setShowColHeaders(true);
        style.setShowRowHeaders(true);
    }

    protected AreaReference getPivotArea() {
        final Workbook wb = getDataSheet().getWorkbook();
        AreaReference pivotArea = getPivotCacheDefinition().getPivotArea(wb);
        return pivotArea;
    }
    
    /**
     * Verify column index (relative to first column in pivot area) is within the
     * pivot area
     *
     * @param columnIndex
     * @throws IndexOutOfBoundsException
     */
    private void checkColumnIndex(int columnIndex) throws IndexOutOfBoundsException {
        AreaReference pivotArea = getPivotArea();
        int size = pivotArea.getLastCell().getCol() - pivotArea.getFirstCell().getCol() + 1;

        if (columnIndex < 0 || columnIndex >= size) {
            throw new IndexOutOfBoundsException("Column Index: " + columnIndex + ", Size: " + size);
        }
    }

    /**
     * Add a row label using data from the given column.
     * @param columnIndex the index of the source column to be used as row label.
     * {@code columnIndex} is 0-based indexed and relative to the first column in the source.
     */
    @Beta
    public void addRowLabel(int columnIndex) {
        checkColumnIndex(columnIndex);
        
        AreaReference pivotArea = getPivotArea();
        final int lastRowIndex = pivotArea.getLastCell().getRow() - pivotArea.getFirstCell().getRow();
        CTPivotFields pivotFields = pivotTableDefinition.getPivotFields();

        CTPivotField pivotField = CTPivotField.Factory.newInstance();
        CTItems items = pivotField.addNewItems();

        pivotField.setAxis(STAxis.AXIS_ROW);
        pivotField.setShowAll(false);
        for (int i = 0; i <= lastRowIndex; i++) {
            items.addNewItem().setT(STItemType.DEFAULT);
        }
        items.setCount(items.sizeOfItemArray());
        pivotFields.setPivotFieldArray(columnIndex, pivotField);

        CTRowFields rowFields;
        if(pivotTableDefinition.getRowFields() != null) {
            rowFields = pivotTableDefinition.getRowFields();
        } else {
            rowFields = pivotTableDefinition.addNewRowFields();
        }

        rowFields.addNewField().setX(columnIndex);
        rowFields.setCount(rowFields.sizeOfFieldArray());
    }
    
    @Beta
    public List<Integer> getRowLabelColumns() {
        if (pivotTableDefinition.getRowFields() != null) {
            List<Integer> columnIndexes = new ArrayList<Integer>();
            for (CTField f : pivotTableDefinition.getRowFields().getFieldArray()) {
                columnIndexes.add(f.getX());
            }
            return columnIndexes;
        } else {
            return Collections.emptyList();
        }
    }
    
    /**
     * Add a column label using data from the given column and specified function
     * @param columnIndex the index of the source column to be used as column label.
     * {@code columnIndex} is 0-based indexed and relative to the first column in the source.
     * @param function the function to be used on the data
     * The following functions exists:
     * Sum, Count, Average, Max, Min, Product, Count numbers, StdDev, StdDevp, Var, Varp
     * @param valueFieldName the name of pivot table value field
     */
    @Beta
    public void addColumnLabel(DataConsolidateFunction function, int columnIndex, String valueFieldName) {
        checkColumnIndex(columnIndex);

        addDataColumn(columnIndex, true);
        addDataField(function, columnIndex, valueFieldName);

        // colfield should be added for the second one.
        if (pivotTableDefinition.getDataFields().getCount() == 2) {
            CTColFields colFields;
            if(pivotTableDefinition.getColFields() != null) {
                colFields = pivotTableDefinition.getColFields();
            } else {
                colFields = pivotTableDefinition.addNewColFields();
            }
            colFields.addNewField().setX(-2);
            colFields.setCount(colFields.sizeOfFieldArray());
        }
    }

    /**
     * Add a column label using data from the given column and specified function
     * @param columnIndex the index of the source column to be used as column label
     * {@code columnIndex} is 0-based indexed and relative to the first column in the source..
     * @param function the function to be used on the data
     * The following functions exists:
     * Sum, Count, Average, Max, Min, Product, Count numbers, StdDev, StdDevp, Var, Varp
     */
    @Beta
    public void addColumnLabel(DataConsolidateFunction function, int columnIndex) {
        addColumnLabel(function, columnIndex, function.getName());
    }

    /**
     * Add data field with data from the given column and specified function.
     * @param function the function to be used on the data
     *      The following functions exists:
     *      Sum, Count, Average, Max, Min, Product, Count numbers, StdDev, StdDevp, Var, Varp
     * @param columnIndex the index of the column to be used as column label.
     * @param valueFieldName the name of pivot table value field
     */
    @Beta
    private void addDataField(DataConsolidateFunction function, int columnIndex, String valueFieldName) {
        checkColumnIndex(columnIndex);
        
        AreaReference pivotArea = getPivotArea();
        
        CTDataFields dataFields;
        if(pivotTableDefinition.getDataFields() != null) {
            dataFields = pivotTableDefinition.getDataFields();
        } else {
            dataFields = pivotTableDefinition.addNewDataFields();
        }
        CTDataField dataField = dataFields.addNewDataField();
        dataField.setSubtotal(STDataConsolidateFunction.Enum.forInt(function.getValue()));
        Cell cell = getDataSheet().getRow(pivotArea.getFirstCell().getRow())
                .getCell(pivotArea.getFirstCell().getCol() + columnIndex);
        cell.setCellType(CellType.STRING);
        dataField.setName(valueFieldName);
        dataField.setFld(columnIndex);
        dataFields.setCount(dataFields.sizeOfDataFieldArray());
    }

    /**
     * Add column containing data from the referenced area.
     * @param columnIndex the index of the column containing the data
     * @param isDataField true if the data should be displayed in the pivot table.
     */
    @Beta
    public void addDataColumn(int columnIndex, boolean isDataField) {
        checkColumnIndex(columnIndex);

        CTPivotFields pivotFields = pivotTableDefinition.getPivotFields();
        CTPivotField pivotField = CTPivotField.Factory.newInstance();

        pivotField.setDataField(isDataField);
        pivotField.setShowAll(false);
        pivotFields.setPivotFieldArray(columnIndex, pivotField);
    }

    /**
     * Add filter for the column with the corresponding index and cell value
     * @param columnIndex index of column to filter on
     */
    @Beta
    public void addReportFilter(int columnIndex) {
        checkColumnIndex(columnIndex);
        
        AreaReference pivotArea = getPivotArea();
        int lastRowIndex = pivotArea.getLastCell().getRow() - pivotArea.getFirstCell().getRow();

        CTPivotFields pivotFields = pivotTableDefinition.getPivotFields();

        CTPivotField pivotField = CTPivotField.Factory.newInstance();
        CTItems items = pivotField.addNewItems();

        pivotField.setAxis(STAxis.AXIS_PAGE);
        pivotField.setShowAll(false);
        for(int i = 0; i <= lastRowIndex; i++) {
            items.addNewItem().setT(STItemType.DEFAULT);
        }
        items.setCount(items.sizeOfItemArray());
        pivotFields.setPivotFieldArray(columnIndex, pivotField);

        CTPageFields pageFields;
        if (pivotTableDefinition.getPageFields()!= null) {
            pageFields = pivotTableDefinition.getPageFields();
            //Another filter has already been created
            pivotTableDefinition.setMultipleFieldFilters(true);
        } else {
            pageFields = pivotTableDefinition.addNewPageFields();
        }
        CTPageField pageField = pageFields.addNewPageField();
        pageField.setHier(-1);
        pageField.setFld(columnIndex);

        pageFields.setCount(pageFields.sizeOfPageFieldArray());
        pivotTableDefinition.getLocation().setColPageCount(pageFields.getCount());
    }

    /**
     * Creates cacheSource and workSheetSource for pivot table and sets the source reference as well assets the location of the pivot table
     * @param position Position for pivot table in sheet
     * @param sourceSheet Sheet where the source will be collected from
     * @param refConfig  an configurator that knows how to configure pivot table references
     */
    @Beta
    protected void createSourceReferences(CellReference position, Sheet sourceSheet, PivotTableReferenceConfigurator refConfig){
        
        //Get cell one to the right and one down from position, add both to AreaReference and set pivot table location.
        AreaReference destination = new AreaReference(position, new CellReference(position.getRow()+1, position.getCol()+1));

        CTLocation location;
        if(pivotTableDefinition.getLocation() == null) {
            location = pivotTableDefinition.addNewLocation();
            location.setFirstDataCol(1);
            location.setFirstDataRow(1);
            location.setFirstHeaderRow(1);
        } else {
            location = pivotTableDefinition.getLocation();
        }
        location.setRef(destination.formatAsString());
        pivotTableDefinition.setLocation(location);

        //Set source for the pivot table
        CTPivotCacheDefinition cacheDef = getPivotCacheDefinition().getCTPivotCacheDefinition();
        CTCacheSource cacheSource = cacheDef.addNewCacheSource();
        cacheSource.setType(STSourceType.WORKSHEET);
        CTWorksheetSource worksheetSource = cacheSource.addNewWorksheetSource();
        worksheetSource.setSheet(sourceSheet.getSheetName());
        setDataSheet(sourceSheet);

        refConfig.configureReference(worksheetSource);
        if (worksheetSource.getName() == null && worksheetSource.getRef() == null) throw new IllegalArgumentException("Pivot table source area reference or name must be specified.");
    }

    @Beta
    protected void createDefaultDataColumns() {
        CTPivotFields pivotFields;
        if (pivotTableDefinition.getPivotFields() != null) {
            pivotFields = pivotTableDefinition.getPivotFields();
        } else {
            pivotFields = pivotTableDefinition.addNewPivotFields();
        }
        AreaReference sourceArea = getPivotArea();
        int firstColumn = sourceArea.getFirstCell().getCol();
        int lastColumn = sourceArea.getLastCell().getCol();
        CTPivotField pivotField;
        for(int i = firstColumn; i<=lastColumn; i++) {
            pivotField = pivotFields.addNewPivotField();
            pivotField.setDataField(false);
            pivotField.setShowAll(false);
        }
        pivotFields.setCount(pivotFields.sizeOfPivotFieldArray());
    }
    
    protected static interface PivotTableReferenceConfigurator {
        
        /**
         * Configure the name or area reference for the pivot table 
         * @param wsSource CTWorksheetSource that needs the pivot source reference assignment
         */
        public void configureReference(CTWorksheetSource wsSource);
    }
}
