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

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.util.POIXMLUnits;
import org.apache.poi.util.Internal;
import org.apache.poi.util.Units;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJcTable;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblCellMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJcTable;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;

/**
 * <p>Sketch of XWPFTable class. Only table's text is being hold.</p>
 * <p>Specifies the contents of a table present in the document. A table is a set
 * of paragraphs (and other block-level content) arranged in rows and columns.</p>
 */
@SuppressWarnings("WeakerAccess")
public class XWPFTable implements IBodyElement, ISDTContents {

    public static final String REGEX_PERCENTAGE = "[0-9]+(\\.[0-9]+)?%";
    public static final String DEFAULT_PERCENTAGE_WIDTH = "100%";
    static final String NS_OOXML_WP_MAIN = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
    public static final String REGEX_WIDTH_VALUE = "auto|[0-9]+|" + REGEX_PERCENTAGE;

    // Create a map from this XWPF-level enum to the STBorder.Enum values
    public enum XWPFBorderType {
        NIL, NONE, SINGLE, THICK, DOUBLE, DOTTED, DASHED, DOT_DASH, DOT_DOT_DASH, TRIPLE,
        THIN_THICK_SMALL_GAP, THICK_THIN_SMALL_GAP, THIN_THICK_THIN_SMALL_GAP,
        THIN_THICK_MEDIUM_GAP, THICK_THIN_MEDIUM_GAP, THIN_THICK_THIN_MEDIUM_GAP,
        THIN_THICK_LARGE_GAP, THICK_THIN_LARGE_GAP, THIN_THICK_THIN_LARGE_GAP,
        WAVE, DOUBLE_WAVE, DASH_SMALL_GAP, DASH_DOT_STROKED, THREE_D_EMBOSS, THREE_D_ENGRAVE,
        OUTSET, INSET
    }

    private enum Border { INSIDE_V, INSIDE_H, LEFT, TOP, BOTTOM, RIGHT }

    private static final EnumMap<XWPFBorderType, STBorder.Enum> xwpfBorderTypeMap;
    // Create a map from the STBorder.Enum values to the XWPF-level enums
    private static final HashMap<Integer, XWPFBorderType> stBorderTypeMap;

    static {
        // populate enum maps
        xwpfBorderTypeMap = new EnumMap<>(XWPFBorderType.class);
        xwpfBorderTypeMap.put(XWPFBorderType.NIL, STBorder.Enum.forInt(STBorder.INT_NIL));
        xwpfBorderTypeMap.put(XWPFBorderType.NONE, STBorder.Enum.forInt(STBorder.INT_NONE));
        xwpfBorderTypeMap.put(XWPFBorderType.SINGLE, STBorder.Enum.forInt(STBorder.INT_SINGLE));
        xwpfBorderTypeMap.put(XWPFBorderType.THICK, STBorder.Enum.forInt(STBorder.INT_THICK));
        xwpfBorderTypeMap.put(XWPFBorderType.DOUBLE, STBorder.Enum.forInt(STBorder.INT_DOUBLE));
        xwpfBorderTypeMap.put(XWPFBorderType.DOTTED, STBorder.Enum.forInt(STBorder.INT_DOTTED));
        xwpfBorderTypeMap.put(XWPFBorderType.DASHED, STBorder.Enum.forInt(STBorder.INT_DASHED));
        xwpfBorderTypeMap.put(XWPFBorderType.DOT_DASH, STBorder.Enum.forInt(STBorder.INT_DOT_DASH));
        xwpfBorderTypeMap.put(XWPFBorderType.DOT_DOT_DASH, STBorder.Enum.forInt(STBorder.INT_DOT_DOT_DASH));
        xwpfBorderTypeMap.put(XWPFBorderType.TRIPLE, STBorder.Enum.forInt(STBorder.INT_TRIPLE));
        xwpfBorderTypeMap.put(XWPFBorderType.THIN_THICK_SMALL_GAP, STBorder.Enum.forInt(STBorder.INT_THIN_THICK_SMALL_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.THICK_THIN_SMALL_GAP, STBorder.Enum.forInt(STBorder.INT_THICK_THIN_SMALL_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.THIN_THICK_THIN_SMALL_GAP, STBorder.Enum.forInt(STBorder.INT_THIN_THICK_THIN_SMALL_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.THIN_THICK_MEDIUM_GAP, STBorder.Enum.forInt(STBorder.INT_THIN_THICK_MEDIUM_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.THICK_THIN_MEDIUM_GAP, STBorder.Enum.forInt(STBorder.INT_THICK_THIN_MEDIUM_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.THIN_THICK_THIN_MEDIUM_GAP, STBorder.Enum.forInt(STBorder.INT_THIN_THICK_THIN_MEDIUM_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.THIN_THICK_LARGE_GAP, STBorder.Enum.forInt(STBorder.INT_THIN_THICK_LARGE_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.THICK_THIN_LARGE_GAP, STBorder.Enum.forInt(STBorder.INT_THICK_THIN_LARGE_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.THIN_THICK_THIN_LARGE_GAP, STBorder.Enum.forInt(STBorder.INT_THIN_THICK_THIN_LARGE_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.WAVE, STBorder.Enum.forInt(STBorder.INT_WAVE));
        xwpfBorderTypeMap.put(XWPFBorderType.DOUBLE_WAVE, STBorder.Enum.forInt(STBorder.INT_DOUBLE_WAVE));
        xwpfBorderTypeMap.put(XWPFBorderType.DASH_SMALL_GAP, STBorder.Enum.forInt(STBorder.INT_DASH_SMALL_GAP));
        xwpfBorderTypeMap.put(XWPFBorderType.DASH_DOT_STROKED, STBorder.Enum.forInt(STBorder.INT_DASH_DOT_STROKED));
        xwpfBorderTypeMap.put(XWPFBorderType.THREE_D_EMBOSS, STBorder.Enum.forInt(STBorder.INT_THREE_D_EMBOSS));
        xwpfBorderTypeMap.put(XWPFBorderType.THREE_D_ENGRAVE, STBorder.Enum.forInt(STBorder.INT_THREE_D_ENGRAVE));
        xwpfBorderTypeMap.put(XWPFBorderType.OUTSET, STBorder.Enum.forInt(STBorder.INT_OUTSET));
        xwpfBorderTypeMap.put(XWPFBorderType.INSET, STBorder.Enum.forInt(STBorder.INT_INSET));

        stBorderTypeMap = new HashMap<>();
        stBorderTypeMap.put(STBorder.INT_NIL, XWPFBorderType.NIL);
        stBorderTypeMap.put(STBorder.INT_NONE, XWPFBorderType.NONE);
        stBorderTypeMap.put(STBorder.INT_SINGLE, XWPFBorderType.SINGLE);
        stBorderTypeMap.put(STBorder.INT_THICK, XWPFBorderType.THICK);
        stBorderTypeMap.put(STBorder.INT_DOUBLE, XWPFBorderType.DOUBLE);
        stBorderTypeMap.put(STBorder.INT_DOTTED, XWPFBorderType.DOTTED);
        stBorderTypeMap.put(STBorder.INT_DASHED, XWPFBorderType.DASHED);
        stBorderTypeMap.put(STBorder.INT_DOT_DASH, XWPFBorderType.DOT_DASH);
        stBorderTypeMap.put(STBorder.INT_DOT_DOT_DASH, XWPFBorderType.DOT_DOT_DASH);
        stBorderTypeMap.put(STBorder.INT_TRIPLE, XWPFBorderType.TRIPLE);
        stBorderTypeMap.put(STBorder.INT_THIN_THICK_SMALL_GAP, XWPFBorderType.THIN_THICK_SMALL_GAP);
        stBorderTypeMap.put(STBorder.INT_THICK_THIN_SMALL_GAP, XWPFBorderType.THICK_THIN_SMALL_GAP);
        stBorderTypeMap.put(STBorder.INT_THIN_THICK_THIN_SMALL_GAP, XWPFBorderType.THIN_THICK_THIN_SMALL_GAP);
        stBorderTypeMap.put(STBorder.INT_THIN_THICK_MEDIUM_GAP, XWPFBorderType.THIN_THICK_MEDIUM_GAP);
        stBorderTypeMap.put(STBorder.INT_THICK_THIN_MEDIUM_GAP, XWPFBorderType.THICK_THIN_MEDIUM_GAP);
        stBorderTypeMap.put(STBorder.INT_THIN_THICK_THIN_MEDIUM_GAP, XWPFBorderType.THIN_THICK_THIN_MEDIUM_GAP);
        stBorderTypeMap.put(STBorder.INT_THIN_THICK_LARGE_GAP, XWPFBorderType.THIN_THICK_LARGE_GAP);
        stBorderTypeMap.put(STBorder.INT_THICK_THIN_LARGE_GAP, XWPFBorderType.THICK_THIN_LARGE_GAP);
        stBorderTypeMap.put(STBorder.INT_THIN_THICK_THIN_LARGE_GAP, XWPFBorderType.THIN_THICK_THIN_LARGE_GAP);
        stBorderTypeMap.put(STBorder.INT_WAVE, XWPFBorderType.WAVE);
        stBorderTypeMap.put(STBorder.INT_DOUBLE_WAVE, XWPFBorderType.DOUBLE_WAVE);
        stBorderTypeMap.put(STBorder.INT_DASH_SMALL_GAP, XWPFBorderType.DASH_SMALL_GAP);
        stBorderTypeMap.put(STBorder.INT_DASH_DOT_STROKED, XWPFBorderType.DASH_DOT_STROKED);
        stBorderTypeMap.put(STBorder.INT_THREE_D_EMBOSS, XWPFBorderType.THREE_D_EMBOSS);
        stBorderTypeMap.put(STBorder.INT_THREE_D_ENGRAVE, XWPFBorderType.THREE_D_ENGRAVE);
        stBorderTypeMap.put(STBorder.INT_OUTSET, XWPFBorderType.OUTSET);
        stBorderTypeMap.put(STBorder.INT_INSET, XWPFBorderType.INSET);
    }

    protected StringBuilder text = new StringBuilder(64);
    protected final List<XWPFTableRow> tableRows = new ArrayList<>();

    // Unused: UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD
    //protected List<String> styleIDs;
    protected IBody part;
    private CTTbl ctTbl;

    public XWPFTable(CTTbl table, IBody part, int row, int col) {
        this(table, part);

        for (int i = 0; i < row; i++) {
            XWPFTableRow tabRow = (getRow(i) == null) ? createRow() : getRow(i);
            for (int k = 0; k < col; k++) {
                if (tabRow.getCell(k) == null) {
                    tabRow.createCell();
                }
            }
        }
    }

    public XWPFTable(CTTbl table, IBody part) {
        this.part = part;
        this.ctTbl = table;

        // is an empty table: I add one row and one column as default
        if (table.sizeOfTrArray() == 0) {
            createEmptyTable(table);
        }

        for (CTRow row : table.getTrList()) {
            StringBuilder rowText = new StringBuilder();
            XWPFTableRow tabRow = new XWPFTableRow(row, this);
            tableRows.add(tabRow);
            for (CTTc cell : row.getTcList()) {
                for (CTP ctp : cell.getPList()) {
                    XWPFParagraph p = new XWPFParagraph(ctp, part);
                    if (rowText.length() > 0) {
                        rowText.append('\t');
                    }
                    rowText.append(p.getText());
                }
            }
            if (rowText.length() > 0) {
                this.text.append(rowText);
                this.text.append('\n');
            }
        }
    }

    private void createEmptyTable(CTTbl table) {
        // MINIMUM ELEMENTS FOR A TABLE
        table.addNewTr().addNewTc().addNewP();

        CTTblPr tblpro = table.addNewTblPr();
        tblpro.addNewTblW().setW(BigInteger.valueOf(0));
        tblpro.getTblW().setType(STTblWidth.AUTO);

        // layout
        // tblpro.addNewTblLayout().setType(STTblLayoutType.AUTOFIT);

        // borders
        CTTblBorders borders = tblpro.addNewTblBorders();
        borders.addNewBottom().setVal(STBorder.SINGLE);
        borders.addNewInsideH().setVal(STBorder.SINGLE);
        borders.addNewInsideV().setVal(STBorder.SINGLE);
        borders.addNewLeft().setVal(STBorder.SINGLE);
        borders.addNewRight().setVal(STBorder.SINGLE);
        borders.addNewTop().setVal(STBorder.SINGLE);

        /*
         * CTTblGrid tblgrid=table.addNewTblGrid();
         * tblgrid.addNewGridCol().setW(new BigInteger("2000"));
         */
        //getRows();
    }

    /**
     * @return ctTbl object
     */
    @Internal
    public CTTbl getCTTbl() {
        return ctTbl;
    }

    /**
     * Convenience method to extract text in cells.  This
     * does not extract text recursively in cells, and it does not
     * currently include text in SDT (form) components.
     * <p>
     * To get all text within a table, see XWPFWordExtractor's appendTableText
     * as an example.
     *
     * @return text
     */
    public String getText() {
        return text.toString();
    }

    /**
     * Add a new cell at the end of each row in this table, creating a new column.
     * If rows have different numbers of columns, will still append a cell to each row.
     * Currently does not match the width of existing columns.
     */
    public void addNewCol() {
        if (tableRows.size() == 0) {
            createRow();
        }
        for (int i = 0; i < tableRows.size(); i++) {
            tableRows.get(i).createCell();
        }
    }

    /**
     * create a new XWPFTableRow object with as many cells as the number of columns defined in that moment
     *
     * @return tableRow
     */
    public XWPFTableRow createRow() {
        int sizeCol = ctTbl.sizeOfTrArray() > 0 ? ctTbl.getTrArray(0)
                .sizeOfTcArray() : 0;
        XWPFTableRow tabRow = new XWPFTableRow(ctTbl.addNewTr(), this);
        addColumn(tabRow, sizeCol);
        tableRows.add(tabRow);
        return tabRow;
    }

    /**
     * @param pos - index of the row
     * @return the row at the position specified or null if no rows is defined or if the position is greather than the max size of rows array
     */
    public XWPFTableRow getRow(int pos) {
        if (pos >= 0 && pos < ctTbl.sizeOfTrArray()) {
            //return new XWPFTableRow(ctTbl.getTrArray(pos));
            return getRows().get(pos);
        }
        return null;
    }

    /**
     * Get the width value as an integer.
     * <p>If the width type is AUTO, DXA, or NIL, the value is 20ths of a point. If
     * the width type is PCT, the value is the percentage times 50 (e.g., 2500 for 50%).</p>
     * @return width value as an integer
     */
    public int getWidth() {
        CTTblPr tblPr = getTblPr();
        return tblPr.isSetTblW() ? (int)Units.toDXA(POIXMLUnits.parseLength(tblPr.getTblW().xgetW())) : -1;
    }

    /**
     * Set the width in 20ths of a point (twips).
     * @param width Width value (20ths of a point)
     */
    public void setWidth(int width) {
        CTTblPr tblPr = getTblPr();
        CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
        tblWidth.setW(new BigInteger(Integer.toString(width)));
        tblWidth.setType(STTblWidth.DXA);
    }

    /**
     * @return number of rows in table
     */
    public int getNumberOfRows() {
        return ctTbl.sizeOfTrArray();
    }

    /**
     * Returns CTTblPr object for table. Creates it if it does not exist.
     */
    private CTTblPr getTblPr() {
        return getTblPr(true);
    }

    /**
     * Returns CTTblPr object for table. If force parameter is true, will
     * create the element if necessary. If force parameter is false, returns
     * null when CTTblPr element is missing.
     *
     * @param force - force creation of CTTblPr element if necessary
     */
    private CTTblPr getTblPr(boolean force) {
        return (ctTbl.getTblPr() != null) ? ctTbl.getTblPr()
                : (force ? ctTbl.addNewTblPr() : null);
    }

    /**
     * Return CTTblBorders object for table. If force parameter is true, will
     * create the element if necessary. If force parameter is false, returns
     * null when CTTblBorders element is missing.
     *
     * @param force - force creation of CTTblBorders element if necessary
     */
    private CTTblBorders getTblBorders(boolean force) {
        CTTblPr tblPr = getTblPr(force);
        return tblPr == null ? null
               : tblPr.isSetTblBorders() ? tblPr.getTblBorders()
               : force ? tblPr.addNewTblBorders()
               : null;
    }


    /**
     * Return CTBorder object for given border. If force parameter is true,
     * will create the element if necessary. If force parameter is false, returns
     * null when the border element is missing.
     *
     * @param force - force creation of border if necessary.
     */
    private CTBorder getTblBorder(boolean force, Border border) {
        final Function<CTTblBorders,Boolean> isSet;
        final Function<CTTblBorders,CTBorder> get;
        final Function<CTTblBorders,CTBorder> addNew;
        switch (border) {
            case INSIDE_V:
                isSet = CTTblBorders::isSetInsideV;
                get = CTTblBorders::getInsideV;
                addNew = CTTblBorders::addNewInsideV;
                break;
            case INSIDE_H:
                isSet = CTTblBorders::isSetInsideH;
                get = CTTblBorders::getInsideH;
                addNew = CTTblBorders::addNewInsideH;
                break;
            case LEFT:
                isSet = CTTblBorders::isSetLeft;
                get = CTTblBorders::getLeft;
                addNew = CTTblBorders::addNewLeft;
                break;
            case TOP:
                isSet = CTTblBorders::isSetTop;
                get = CTTblBorders::getTop;
                addNew = CTTblBorders::addNewTop;
                break;
            case RIGHT:
                isSet = CTTblBorders::isSetRight;
                get = CTTblBorders::getRight;
                addNew = CTTblBorders::addNewRight;
                break;
            case BOTTOM:
                isSet = CTTblBorders::isSetBottom;
                get = CTTblBorders::getBottom;
                addNew = CTTblBorders::addNewBottom;
                break;
            default:
                return null;
        }

        CTTblBorders ctb = getTblBorders(force);
        return ctb == null ? null
                : isSet.apply(ctb) ? get.apply(ctb)
                : force ? addNew.apply(ctb)
                : null;
    }

    /**
     * Returns the current table alignment or NULL
     *
     * @return Table Alignment as a {@link TableRowAlign} enum
     */
    public TableRowAlign getTableAlignment() {
        CTTblPr tPr = getTblPr(false);
        return tPr == null ? null
                : tPr.isSetJc() ? TableRowAlign.valueOf(tPr.getJc().getVal().intValue())
                : null;
    }

    /**
     * Set table alignment to specified {@link TableRowAlign}
     *
     * @param tra {@link TableRowAlign} to set
     */
    public void setTableAlignment(TableRowAlign tra) {
        CTTblPr tPr = getTblPr(true);
        CTJcTable jc = tPr.isSetJc() ? tPr.getJc() : tPr.addNewJc();
        jc.setVal(STJcTable.Enum.forInt(tra.getValue()));
    }

    /**
     * Removes the table alignment attribute from a table
     */
    public void removeTableAlignment() {
        CTTblPr tPr = getTblPr(false);
        if (tPr != null && tPr.isSetJc()) {
            tPr.unsetJc();
        }
    }

    private void addColumn(XWPFTableRow tabRow, int sizeCol) {
        if (sizeCol > 0) {
            for (int i = 0; i < sizeCol; i++) {
                tabRow.createCell();
            }
        }
    }

    /**
     * get the StyleID of the table
     *
     * @return style-ID of the table
     */
    public String getStyleID() {
        String styleId = null;
        CTTblPr tblPr = ctTbl.getTblPr();
        if (tblPr != null) {
            CTString styleStr = tblPr.getTblStyle();
            if (styleStr != null) {
                styleId = styleStr.getVal();
            }
        }
        return styleId;
    }

    /**
     * Set the table style. If the style is not defined in the document, MS Word
     * will set the table style to "Normal".
     *
     * @param styleName - the style name to apply to this table
     */
    public void setStyleID(String styleName) {
        CTTblPr tblPr = getTblPr();
        CTString styleStr = tblPr.getTblStyle();
        if (styleStr == null) {
            styleStr = tblPr.addNewTblStyle();
        }
        styleStr.setVal(styleName);
    }

    /**
     * Get inside horizontal border type
     *
     * @return {@link XWPFBorderType} of the inside horizontal borders or null if missing
     */
    public XWPFBorderType getInsideHBorderType() {
        return getBorderType(Border.INSIDE_H);
    }

    /**
     * Get inside horizontal border size
     *
     * @return The width of the Inside Horizontal borders in 1/8th points,
     * -1 if missing.
     */
    public int getInsideHBorderSize() {
        return getBorderSize(Border.INSIDE_H);
    }

    /**
     * Get inside horizontal border spacing
     *
     * @return The offset to the Inside Horizontal borders in points,
     * -1 if missing.
     */
    public int getInsideHBorderSpace() {
        return getBorderSpace(Border.INSIDE_H);
    }

    /**
     * Get inside horizontal border color
     *
     * @return The color of the Inside Horizontal borders, null if missing.
     */
    public String getInsideHBorderColor() {
        return getBorderColor(Border.INSIDE_H);
    }

    /**
     * Get inside vertical border type
     *
     * @return {@link XWPFBorderType} of the inside vertical borders or null if missing
     */
    public XWPFBorderType getInsideVBorderType() {
        return getBorderType(Border.INSIDE_V);
    }

    /**
     * Get inside vertical border size
     *
     * @return The width of the Inside vertical borders in 1/8th points,
     * -1 if missing.
     */
    public int getInsideVBorderSize() {
        return getBorderSize(Border.INSIDE_V);
    }

    /**
     * Get inside vertical border spacing
     *
     * @return The offset to the Inside vertical borders in points,
     * -1 if missing.
     */
    public int getInsideVBorderSpace() {
        return getBorderSpace(Border.INSIDE_V);
    }

    /**
     * Get inside vertical border color
     *
     * @return The color of the Inside vertical borders, null if missing.
     */
    public String getInsideVBorderColor() {
        return getBorderColor(Border.INSIDE_V);
    }

    /**
     * Get top border type
     *
     * @return {@link XWPFBorderType} of the top borders or null if missing
     */
    public XWPFBorderType getTopBorderType() {
        return getBorderType(Border.TOP);
    }

    /**
     * Get top border size
     *
     * @return The width of the top borders in 1/8th points,
     * -1 if missing.
     */
    public int getTopBorderSize() {
        return getBorderSize(Border.TOP);
    }

    /**
     * Get top border spacing
     *
     * @return The offset to the top borders in points,
     * -1 if missing.
     */
    public int getTopBorderSpace() {
        return getBorderSpace(Border.TOP);
    }

    /**
     * Get top border color
     *
     * @return The color of the top borders, null if missing.
     */
    public String getTopBorderColor() {
        return getBorderColor(Border.TOP);
    }

    /**
     * Get bottom border type
     *
     * @return {@link XWPFBorderType} of the bottom borders or null if missing
     */
    public XWPFBorderType getBottomBorderType() {
        return getBorderType(Border.BOTTOM);
    }

    /**
     * Get bottom border size
     *
     * @return The width of the bottom borders in 1/8th points,
     * -1 if missing.
     */
    public int getBottomBorderSize() {
        return getBorderSize(Border.BOTTOM);
    }

    /**
     * Get bottom border spacing
     *
     * @return The offset to the bottom borders in points,
     * -1 if missing.
     */
    public int getBottomBorderSpace() {
        return getBorderSpace(Border.BOTTOM);
    }

    /**
     * Get bottom border color
     *
     * @return The color of the bottom borders, null if missing.
     */
    public String getBottomBorderColor() {
        return getBorderColor(Border.BOTTOM);
    }

    /**
     * Get Left border type
     *
     * @return {@link XWPFBorderType} of the Left borders or null if missing
     */
    public XWPFBorderType getLeftBorderType() {
        return getBorderType(Border.LEFT);
    }

    /**
     * Get Left border size
     *
     * @return The width of the Left borders in 1/8th points,
     * -1 if missing.
     */
    public int getLeftBorderSize() {
        return getBorderSize(Border.LEFT);
    }

    /**
     * Get Left border spacing
     *
     * @return The offset to the Left borders in points,
     * -1 if missing.
     */
    public int getLeftBorderSpace() {
        return getBorderSpace(Border.LEFT);
    }

    /**
     * Get Left border color
     *
     * @return The color of the Left borders, null if missing.
     */
    public String getLeftBorderColor() {
        return getBorderColor(Border.LEFT);
    }

    /**
     * Get Right border type
     *
     * @return {@link XWPFBorderType} of the Right borders or null if missing
     */
    public XWPFBorderType getRightBorderType() {
        return getBorderType(Border.RIGHT);
    }

    /**
     * Get Right border size
     *
     * @return The width of the Right borders in 1/8th points,
     * -1 if missing.
     */
    public int getRightBorderSize() {
        return getBorderSize(Border.RIGHT);
    }

    /**
     * Get Right border spacing
     *
     * @return The offset to the Right borders in points,
     * -1 if missing.
     */
    public int getRightBorderSpace() {
        return getBorderSpace(Border.RIGHT);
    }

    /**
     * Get Right border color
     *
     * @return The color of the Right borders, null if missing.
     */
    public String getRightBorderColor() {
        return getBorderColor(Border.RIGHT);
    }

    private XWPFBorderType getBorderType(Border border) {
        final CTBorder b = getTblBorder(false, border);
        return (b != null) ? stBorderTypeMap.get(b.getVal().intValue()) : null;
    }

    private int getBorderSize(Border border) {
        final CTBorder b = getTblBorder(false, border);
        return (b != null)
                ? (b.isSetSz() ? b.getSz().intValue() : -1)
                : -1;
    }

    private int getBorderSpace(Border border) {
        final CTBorder b = getTblBorder(false, border);
        return (b != null)
                ? (b.isSetSpace() ? b.getSpace().intValue() : -1)
                : -1;
    }

    private String getBorderColor(Border border) {
        final CTBorder b = getTblBorder(false, border);
        return (b != null)
                ? (b.isSetColor() ? b.xgetColor().getStringValue() : null)
                : null;
    }

    public int getRowBandSize() {
        int size = 0;
        CTTblPr tblPr = getTblPr();
        if (tblPr.isSetTblStyleRowBandSize()) {
            CTDecimalNumber rowSize = tblPr.getTblStyleRowBandSize();
            size = rowSize.getVal().intValue();
        }
        return size;
    }

    public void setRowBandSize(int size) {
        CTTblPr tblPr = getTblPr();
        CTDecimalNumber rowSize = tblPr.isSetTblStyleRowBandSize() ? tblPr.getTblStyleRowBandSize() : tblPr.addNewTblStyleRowBandSize();
        rowSize.setVal(BigInteger.valueOf(size));
    }

    public int getColBandSize() {
        int size = 0;
        CTTblPr tblPr = getTblPr();
        if (tblPr.isSetTblStyleColBandSize()) {
            CTDecimalNumber colSize = tblPr.getTblStyleColBandSize();
            size = colSize.getVal().intValue();
        }
        return size;
    }

    public void setColBandSize(int size) {
        CTTblPr tblPr = getTblPr();
        CTDecimalNumber colSize = tblPr.isSetTblStyleColBandSize() ? tblPr.getTblStyleColBandSize() : tblPr.addNewTblStyleColBandSize();
        colSize.setVal(BigInteger.valueOf(size));
    }

    /**
     * Set Inside horizontal borders for a table
     *
     * @param type - {@link XWPFBorderType} e.g. single, double, thick
     * @param size - Specifies the width of the current border. The width of this border is
     *      specified in measurements of eighths of a point, with a minimum value of two (onefourth
     *      of a point) and a maximum value of 96 (twelve points). Any values outside this
     *      range may be reassigned to a more appropriate value.
     * @param space - Specifies the spacing offset that shall be used to place this border on the table
     * @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
     *      or auto to allow a consumer to automatically determine the border color as appropriate.
     */
    public void setInsideHBorder(XWPFBorderType type, int size, int space, String rgbColor) {
        setBorder(Border.INSIDE_H, type, size, space, rgbColor);
    }

    /**
     * Set Inside Vertical borders for table
     *
     * @param type - {@link XWPFBorderType} e.g. single, double, thick
     * @param size - Specifies the width of the current border. The width of this border is
     *      specified in measurements of eighths of a point, with a minimum value of two (onefourth
     *      of a point) and a maximum value of 96 (twelve points). Any values outside this
     *      range may be reassigned to a more appropriate value.
     * @param space - Specifies the spacing offset that shall be used to place this border on the table
     * @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
     *      or auto to allow a consumer to automatically determine the border color as appropriate.
     */
    public void setInsideVBorder(XWPFBorderType type, int size, int space, String rgbColor) {
        setBorder(Border.INSIDE_V, type, size, space, rgbColor);
    }

    /**
     * Set Top borders for table
     *
     * @param type - {@link XWPFBorderType} e.g. single, double, thick
     * @param size - Specifies the width of the current border. The width of this border is
     *      specified in measurements of eighths of a point, with a minimum value of two (onefourth
     *      of a point) and a maximum value of 96 (twelve points). Any values outside this
     *      range may be reassigned to a more appropriate value.
     * @param space - Specifies the spacing offset that shall be used to place this border on the table
     * @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
     *      or auto to allow a consumer to automatically determine the border color as appropriate.
     */
    public void setTopBorder(XWPFBorderType type, int size, int space, String rgbColor) {
        setBorder(Border.TOP, type, size, space, rgbColor);
    }

    /**
     * Set Bottom borders for table
     *
     * @param type - {@link XWPFBorderType} e.g. single, double, thick
     * @param size - Specifies the width of the current border. The width of this border is
     *      specified in measurements of eighths of a point, with a minimum value of two (onefourth
     *      of a point) and a maximum value of 96 (twelve points). Any values outside this
     *      range may be reassigned to a more appropriate value.
     * @param space - Specifies the spacing offset that shall be used to place this border on the table
     * @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
     *      or auto to allow a consumer to automatically determine the border color as appropriate.
     */
    public void setBottomBorder(XWPFBorderType type, int size, int space, String rgbColor) {
        setBorder(Border.BOTTOM, type, size, space, rgbColor);
    }

    /**
     * Set Left borders for table
     *
     * @param type - {@link XWPFBorderType} e.g. single, double, thick
     * @param size - Specifies the width of the current border. The width of this border is
     *      specified in measurements of eighths of a point, with a minimum value of two (onefourth
     *      of a point) and a maximum value of 96 (twelve points). Any values outside this
     *      range may be reassigned to a more appropriate value.
     * @param space - Specifies the spacing offset that shall be used to place this border on the table
     * @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
     *      or auto to allow a consumer to automatically determine the border color as appropriate.
     */
    public void setLeftBorder(XWPFBorderType type, int size, int space, String rgbColor) {
        setBorder(Border.LEFT, type, size, space, rgbColor);
    }

    /**
     * Set Right borders for table
     *
     * @param type - {@link XWPFBorderType} e.g. single, double, thick
     * @param size - Specifies the width of the current border. The width of this border is
     *      specified in measurements of eighths of a point, with a minimum value of two (onefourth
     *      of a point) and a maximum value of 96 (twelve points). Any values outside this
     *      range may be reassigned to a more appropriate value.
     * @param space - Specifies the spacing offset that shall be used to place this border on the table
     * @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
     *      or auto to allow a consumer to automatically determine the border color as appropriate.
     */
    public void setRightBorder(XWPFBorderType type, int size, int space, String rgbColor) {
        setBorder(Border.RIGHT, type, size, space, rgbColor);
    }

    private void setBorder(Border border, XWPFBorderType type, int size, int space, String rgbColor) {
        final CTBorder b = getTblBorder(true, border);
        assert(b != null);
        b.setVal(xwpfBorderTypeMap.get(type));
        b.setSz(BigInteger.valueOf(size));
        b.setSpace(BigInteger.valueOf(space));
        b.setColor(rgbColor);
    }

    /**
     * Remove inside horizontal borders for table
     */
    public void removeInsideHBorder() {
        removeBorder(Border.INSIDE_H);
    }

    /**
     * Remove inside vertical borders for table
     */
    public void removeInsideVBorder() {
        removeBorder(Border.INSIDE_V);
    }

    /**
     * Remove top borders for table
     */
    public void removeTopBorder() {
        removeBorder(Border.TOP);
    }

    /**
     * Remove bottom borders for table
     */
    public void removeBottomBorder() {
        removeBorder(Border.BOTTOM);
    }

    /**
     * Remove left borders for table
     */
    public void removeLeftBorder() {
        removeBorder(Border.LEFT);
    }

    /**
     * Remove right borders for table
     */
    public void removeRightBorder() {
        removeBorder(Border.RIGHT);
    }

    /**
     * Remove all borders from table
     */
    public void removeBorders() {
        final CTTblPr pr = getTblPr(false);
        if (pr != null && pr.isSetTblBorders()) {
            pr.unsetTblBorders();
        }
    }

    private void removeBorder(final Border border) {
        final Function<CTTblBorders,Boolean> isSet;
        final Consumer<CTTblBorders> unSet;
        switch (border) {
            case INSIDE_H:
                isSet = CTTblBorders::isSetInsideH;
                unSet = CTTblBorders::unsetInsideH;
                break;
            case INSIDE_V:
                isSet = CTTblBorders::isSetInsideV;
                unSet = CTTblBorders::unsetInsideV;
                break;
            case LEFT:
                isSet = CTTblBorders::isSetLeft;
                unSet = CTTblBorders::unsetLeft;
                break;
            case TOP:
                isSet = CTTblBorders::isSetTop;
                unSet = CTTblBorders::unsetTop;
                break;
            case RIGHT:
                isSet = CTTblBorders::isSetRight;
                unSet = CTTblBorders::unsetRight;
                break;
            case BOTTOM:
                isSet = CTTblBorders::isSetBottom;
                unSet = CTTblBorders::unsetBottom;
                break;
            default:
                return;
        }

        final CTTblBorders tbl = getTblBorders(false);
        if (tbl != null && isSet.apply(tbl)) {
            unSet.accept(tbl);
            cleanupTblBorders();
        }

    }

    /**
     * removes the Borders node from Table properties if there are
     * no border elements
     */
    private void cleanupTblBorders() {
        final CTTblPr pr = getTblPr(false);
        if (pr != null && pr.isSetTblBorders()) {
            final CTTblBorders b = pr.getTblBorders();
            if (!(b.isSetInsideH() ||
                b.isSetInsideV() ||
                b.isSetTop() ||
                b.isSetBottom() ||
                b.isSetLeft() ||
                b.isSetRight())) {
                pr.unsetTblBorders();
            }
        }
    }

    public int getCellMarginTop() {
        return getCellMargin(CTTblCellMar::getTop);
    }

    public int getCellMarginLeft() {
        return getCellMargin(CTTblCellMar::getLeft);
    }

    public int getCellMarginBottom() {
        return getCellMargin(CTTblCellMar::getBottom);
    }

    public int getCellMarginRight() {
        return getCellMargin(CTTblCellMar::getRight);
    }

    private int getCellMargin(Function<CTTblCellMar,CTTblWidth> margin) {
        CTTblPr tblPr = getTblPr();
        CTTblCellMar tcm = tblPr.getTblCellMar();
        if (tcm != null) {
            CTTblWidth tw = margin.apply(tcm);
            if (tw != null) {
                return (int) Units.toDXA(POIXMLUnits.parseLength(tw.xgetW()));
            }
        }
        return 0;
    }

    public void setCellMargins(int top, int left, int bottom, int right) {
        CTTblPr tblPr = getTblPr();
        CTTblCellMar tcm = tblPr.isSetTblCellMar() ? tblPr.getTblCellMar() : tblPr.addNewTblCellMar();

        setCellMargin(tcm, CTTblCellMar::isSetTop, CTTblCellMar::getTop, CTTblCellMar::addNewTop, CTTblCellMar::unsetTop, top);
        setCellMargin(tcm, CTTblCellMar::isSetLeft, CTTblCellMar::getLeft, CTTblCellMar::addNewLeft, CTTblCellMar::unsetLeft, left);
        setCellMargin(tcm, CTTblCellMar::isSetBottom, CTTblCellMar::getBottom, CTTblCellMar::addNewBottom, CTTblCellMar::unsetBottom, bottom);
        setCellMargin(tcm, CTTblCellMar::isSetRight, CTTblCellMar::getRight, CTTblCellMar::addNewRight, CTTblCellMar::unsetRight, right);
    }

    private void setCellMargin(CTTblCellMar tcm, Function<CTTblCellMar,Boolean> isSet, Function<CTTblCellMar,CTTblWidth> get, Function<CTTblCellMar,CTTblWidth> addNew, Consumer<CTTblCellMar> unSet, int margin) {
        if (margin == 0) {
            if (isSet.apply(tcm)) {
                unSet.accept(tcm);
            }
        } else {
            CTTblWidth tw = (isSet.apply(tcm) ? get : addNew).apply(tcm);
            tw.setType(STTblWidth.DXA);
            tw.setW(BigInteger.valueOf(margin));
        }
    }

    /**
     * add a new Row to the table
     *
     * @param row the row which should be added
     */
    public void addRow(XWPFTableRow row) {
        ctTbl.addNewTr();
        ctTbl.setTrArray(getNumberOfRows() - 1, row.getCtRow());
        tableRows.add(row);
    }

    /**
     * add a new Row to the table
     * at position pos
     *
     * @param row the row which should be added
     */
    public boolean addRow(XWPFTableRow row, int pos) {
        if (pos >= 0 && pos <= tableRows.size()) {
            ctTbl.insertNewTr(pos);
            ctTbl.setTrArray(pos, row.getCtRow());
            tableRows.add(pos, row);
            return true;
        }
        return false;
    }

    /**
     * inserts a new tablerow
     *
     * @param pos
     * @return the inserted row
     */
    public XWPFTableRow insertNewTableRow(int pos) {
        if (pos >= 0 && pos <= tableRows.size()) {
            CTRow row = ctTbl.insertNewTr(pos);
            XWPFTableRow tableRow = new XWPFTableRow(row, this);
            tableRows.add(pos, tableRow);
            return tableRow;
        }
        return null;
    }

    /**
     * Remove a row at position pos from the table
     *
     * @param pos position the Row in the Table
     */
    public boolean removeRow(int pos) throws IndexOutOfBoundsException {
        if (pos >= 0 && pos < tableRows.size()) {
            if (ctTbl.sizeOfTrArray() > 0) {
                ctTbl.removeTr(pos);
            }
            tableRows.remove(pos);
            return true;
        }
        return false;
    }

    public List<XWPFTableRow> getRows() {
        return Collections.unmodifiableList(tableRows);
    }

    /**
     * returns the type of the BodyElement Table
     *
     * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
     */
    @Override
    public BodyElementType getElementType() {
        return BodyElementType.TABLE;
    }

    @Override
    public IBody getBody() {
        return part;
    }

    /**
     * returns the part of the bodyElement
     *
     * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
     */
    @Override
    public POIXMLDocumentPart getPart() {
        if (part != null) {
            return part.getPart();
        }
        return null;
    }

    /**
     * returns the partType of the bodyPart which owns the bodyElement
     *
     * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
     */
    @Override
    public BodyType getPartType() {
        return part.getPartType();
    }

    /**
     * returns the XWPFRow which belongs to the CTRow row
     * if this row is not existing in the table null will be returned
     */
    public XWPFTableRow getRow(CTRow row) {
        for (int i = 0; i < getRows().size(); i++) {
            if (getRows().get(i).getCtRow() == row) {
                return getRow(i);
            }
        }
        return null;
    }

    /**
     * Get the table width as a decimal value.
     * <p>If the width type is DXA or AUTO, then the value will always have
     * a fractional part of zero (because these values are really integers).
     * If the with type is percentage, then value may have a non-zero fractional
     * part.
     *
     * @return Width value as a double-precision decimal.
     * @since 4.0.0
     */
    public double getWidthDecimal() {
        return getWidthDecimal(getTblPr().getTblW());
    }

    /**
     * Get the width as a decimal value.
     * <p>This method is also used by table cells.
     * @param ctWidth Width value to evaluate.
     * @return Width value as a decimal
     * @since 4.0.0
     */
    protected static double getWidthDecimal(CTTblWidth ctWidth) {
        double result = 0.0;
        STTblWidth.Enum typeValue = ctWidth.getType();
        if (typeValue == STTblWidth.DXA
                || typeValue == STTblWidth.AUTO
                || typeValue == STTblWidth.NIL) {
            result = 0.0 + Units.toDXA(POIXMLUnits.parseLength(ctWidth.xgetW()));
        } else if (typeValue == STTblWidth.PCT) {
            // Percentage values are stored as integers that are 50 times
            // percentage.
            result = Units.toDXA(POIXMLUnits.parseLength(ctWidth.xgetW())) / 50.0;
        } else {
            // Should never get here
        }
        return result;
    }

    /**
     * Get the width type for the table, as an {@link STTblWidth.Enum} value.
     * A table width can be specified as an absolute measurement (an integer
     * number of twips), a percentage, or the value "AUTO".
     *
     * @return The width type.
     * @since 4.0.0
     */
    public TableWidthType getWidthType() {
        return getWidthType(getTblPr().getTblW());
    }

    /**
     * Get the width type from the width value
     * @param ctWidth CTTblWidth to evalute
     * @return The table width type
     * @since 4.0.0
     */
    protected static TableWidthType getWidthType(CTTblWidth ctWidth) {
        STTblWidth.Enum typeValue = ctWidth.getType();
        if (typeValue == null) {
            typeValue = STTblWidth.NIL;
            ctWidth.setType(typeValue);
        }
        switch (typeValue.intValue()) {
        case STTblWidth.INT_NIL:
            return TableWidthType.NIL;
        case STTblWidth.INT_AUTO:
            return TableWidthType.AUTO;
        case STTblWidth.INT_DXA:
            return TableWidthType.DXA;
        case STTblWidth.INT_PCT:
            return TableWidthType.PCT;
        default:
            // Should never get here
            return TableWidthType.AUTO;
        }
    }

    /**
     * Set the width to the value "auto", an integer value (20ths of a point), or a percentage ("nn.nn%").
     *
     * @param widthValue String matching one of "auto", [0-9]+, or [0-9]+(\.[0-9]+)%.
     * @since 4.0.0
     */
    public void setWidth(String widthValue) {
        setWidthValue(widthValue, getTblPr().getTblW());
    }

    /**
     * Set the width value from a string
     * @param widthValue The width value string
     * @param ctWidth CTTblWidth to set the value on.
     */
    protected static void setWidthValue(String widthValue, CTTblWidth ctWidth) {
        if (!widthValue.matches(REGEX_WIDTH_VALUE)) {
            throw new RuntimeException("Table width value \"" + widthValue + "\" "
                    + "must match regular expression \"" + REGEX_WIDTH_VALUE + "\".");
        }
        if (widthValue.matches("auto")) {
            ctWidth.setType(STTblWidth.AUTO);
            ctWidth.setW(BigInteger.ZERO);
        } else if (widthValue.matches(REGEX_PERCENTAGE)) {
            setWidthPercentage(ctWidth, widthValue);
        } else {
            // Must be an integer
            ctWidth.setW(new BigInteger(widthValue));
            ctWidth.setType(STTblWidth.DXA);
        }
    }

    /**
     * Set the underlying table width value to a percentage value.
     * @param ctWidth The CTTblWidth to set the value on
     * @param widthValue String width value in form "33.3%" or an integer that is 50 times desired percentage value (e.g,
     * 2500 for 50%)
     * @since 4.0.0
     */
    protected static void setWidthPercentage(CTTblWidth ctWidth, String widthValue) {
        ctWidth.setType(STTblWidth.PCT);
        if (widthValue.matches(REGEX_PERCENTAGE)) {
            String numberPart = widthValue.substring(0,  widthValue.length() - 1);
            double percentage = Double.parseDouble(numberPart) * 50;
            long intValue = Math.round(percentage);
            ctWidth.setW(BigInteger.valueOf(intValue));
        } else if (widthValue.matches("[0-9]+")) {
            ctWidth.setW(new BigInteger(widthValue));
        } else {
            throw new RuntimeException("setWidthPercentage(): Width value must be a percentage (\"33.3%\" or an integer, was \"" + widthValue + "\"");
        }
    }

    /**
     * Set the width value type for the table.
     * <p>If the width type is changed from the current type and the currently-set value
     * is not consistent with the new width type, the value is reset to the default value
     * for the specified width type.</p>
     *
     * @param widthType Width type
     * @since 4.0.0
     */
    public void setWidthType(TableWidthType widthType) {
        setWidthType(widthType, getTblPr().getTblW());
    }

    /**
     * Set the width type if different from current width type
     * @param widthType The new width type
     * @param ctWidth CTTblWidth to set the type on
     * @since 4.0.0
     */
    protected static void setWidthType(TableWidthType widthType, CTTblWidth ctWidth) {
        TableWidthType currentType = getWidthType(ctWidth);
        if (!currentType.equals(widthType)) {
            STTblWidth.Enum stWidthType = widthType.getStWidthType();
            ctWidth.setType(stWidthType);
            switch (stWidthType.intValue()) {
            case STTblWidth.INT_PCT:
                setWidthPercentage(ctWidth, DEFAULT_PERCENTAGE_WIDTH);
                break;
            default:
                ctWidth.setW(BigInteger.ZERO);
            }
        }
    }
}
