/* ====================================================================
   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 java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;

import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.FormulaError;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.helpers.RowShifter;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;

/**
 * High level representation of a row of a spreadsheet.
 */
public class XSSFRow implements Row, Comparable<XSSFRow> {
    /**
     * the xml bean containing all cell definitions for this row
     */
    private final CTRow _row;

    /**
     * Cells of this row keyed by their column indexes.
     * The TreeMap ensures that the cells are ordered by columnIndex in the ascending order.
     */
    private final TreeMap<Integer, XSSFCell> _cells;

    /**
     * the parent sheet
     */
    private final XSSFSheet _sheet;

    /**
     * Construct a XSSFRow.
     *
     * @param row the xml bean containing all cell definitions for this row.
     * @param sheet the parent sheet.
     */
    protected XSSFRow(CTRow row, XSSFSheet sheet) {
        _row = row;
        _sheet = sheet;
        _cells = new TreeMap<>();
        for (CTCell c : row.getCArray()) {
            XSSFCell cell = new XSSFCell(this, c);
            // Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory
            final Integer colI = Integer.valueOf(cell.getColumnIndex()); // NOSONAR
            _cells.put(colI, cell);
            sheet.onReadCell(cell);
        }

        if (! row.isSetR()) {
            // Certain file format writers skip the row number
            // Assume no gaps, and give this the next row number
            int nextRowNum = sheet.getLastRowNum()+2;
            if (nextRowNum == 2 && sheet.getPhysicalNumberOfRows() == 0) {
                nextRowNum = 1;
            }
            row.setR(nextRowNum);
        }
    }

    /**
     * Returns the XSSFSheet this row belongs to
     *
     * @return the XSSFSheet that owns this row
     */
    @Override
    public XSSFSheet getSheet() {
        return this._sheet;
    }

    /**
     * Cell iterator over the physically defined cells:
     * <blockquote><pre>
     * for (Iterator<Cell> it = row.cellIterator(); it.hasNext(); ) {
     *     Cell cell = it.next();
     *     ...
     * }
     * </pre></blockquote>
     *
     * @return an iterator over cells in this row.
     */
    @Override
    @SuppressWarnings("unchecked")
    public Iterator<Cell> cellIterator() {
        return (Iterator<Cell>)(Iterator<? extends Cell>)_cells.values().iterator();
    }

    /**
     * Alias for {@link #cellIterator()} to allow  foreach loops:
     * <blockquote><pre>
     * for(Cell cell : row){
     *     ...
     * }
     * </pre></blockquote>
     *
     * @return an iterator over cells in this row.
     */
    @Override
    public Iterator<Cell> iterator() {
        return cellIterator();
    }

    /**
     * Compares two <code>XSSFRow</code> objects.  Two rows are equal if they belong to the same worksheet and
     * their row indexes are equal.
     *
     * @param   other   the <code>XSSFRow</code> to be compared.
     * @return  <ul>
     *      <li>
     *      the value <code>0</code> if the row number of this <code>XSSFRow</code> is
     *      equal to the row number of the argument <code>XSSFRow</code>
     *      </li>
     *      <li>
     *      a value less than <code>0</code> if the row number of this this <code>XSSFRow</code> is
     *      numerically less than the row number of the argument <code>XSSFRow</code>
     *      </li>
     *      <li>
     *      a value greater than <code>0</code> if the row number of this this <code>XSSFRow</code> is
     *      numerically greater than the row number of the argument <code>XSSFRow</code>
     *      </li>
     *      </ul>
     * @throws IllegalArgumentException if the argument row belongs to a different worksheet
     */
    @Override
    public int compareTo(XSSFRow other) {
        if (this.getSheet() != other.getSheet()) {
            throw new IllegalArgumentException("The compared rows must belong to the same sheet");
        }

        int thisRow = this.getRowNum();
        int otherRow = other.getRowNum();
        return Integer.compare(thisRow, otherRow);
    }

    @Override
    public boolean equals(Object obj)
    {
        if (!(obj instanceof XSSFRow))
        {
            return false;
        }
        XSSFRow other = (XSSFRow) obj;

        return (this.getRowNum() == other.getRowNum()) &&
               (this.getSheet() == other.getSheet());
    }

    @Override
    public int hashCode() {
        return _row.hashCode();
    }

    /**
     * Use this to create new cells within the row and return it.
     * <p>
     * The cell that is returned is a {@link CellType#BLANK}. The type can be changed
     * either through calling <code>setCellValue</code> or <code>setCellType</code>.
     * </p>
     * @param columnIndex - the column number this cell represents
     * @return Cell a high level representation of the created cell.
     * @throws IllegalArgumentException if columnIndex < 0 or greater than 16384,
     *   the maximum number of columns supported by the SpreadsheetML format (.xlsx)
     */
    @Override
    public XSSFCell createCell(int columnIndex) {
        return createCell(columnIndex, CellType.BLANK);
    }

    /**
     * Use this to create new cells within the row and return it.
     *
     * @param columnIndex - the column number this cell represents
     * @param type - the cell's data type
     * @return XSSFCell a high level representation of the created cell.
     * @throws IllegalArgumentException if the specified cell type is invalid, columnIndex < 0
     *   or greater than 16384, the maximum number of columns supported by the SpreadsheetML format (.xlsx)
     */
    @Override
    public XSSFCell createCell(int columnIndex, CellType type) {
        // Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory
        final Integer colI = Integer.valueOf(columnIndex); // NOSONAR
        CTCell ctCell;
        XSSFCell prev = _cells.get(colI);
        if(prev != null){
            ctCell = prev.getCTCell();
            ctCell.set(CTCell.Factory.newInstance());
        } else {
            ctCell = _row.addNewC();
        }
        XSSFCell xcell = new XSSFCell(this, ctCell);
        try {
            xcell.setCellNum(columnIndex);
        } catch (IllegalArgumentException e) {
            // we need to undo adding the CTCell in _row if something fails here, e.g.
            // cell-limits are exceeded
            _row.removeC(_row.getCList().size()-1);

            throw e;
        }
        if (type != CellType.BLANK && type != CellType.FORMULA) {
            setDefaultValue(xcell, type);
        }

        _cells.put(colI, xcell);
        return xcell;
    }

    private static void setDefaultValue(XSSFCell cell, CellType type) {
        switch (type) {
            case NUMERIC:
                cell.setCellValue(0);
                break;
            case STRING:
                cell.setCellValue("");
                break;
            case BOOLEAN:
                cell.setCellValue(false);
                break;
            case ERROR:
                cell.setCellErrorValue(FormulaError._NO_ERROR);
                break;
            default:
                throw new AssertionError("Unknown cell-type specified: " + type);
        }
    }

    /**
     * Returns the cell at the given (0 based) index,
     *  with the {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy} from the parent Workbook.
     *
     * @return the cell at the given (0 based) index
     */
    @Override
    public XSSFCell getCell(int cellnum) {
        return getCell(cellnum, _sheet.getWorkbook().getMissingCellPolicy());
    }

    /**
     * Returns the cell at the given (0 based) index, with the specified {@link org.apache.poi.ss.usermodel.Row.MissingCellPolicy}
     *
     * @return the cell at the given (0 based) index
     * @throws IllegalArgumentException if cellnum &lt; 0 or the specified MissingCellPolicy is invalid
     */
    @Override
    public XSSFCell getCell(int cellnum, MissingCellPolicy policy) {
        if(cellnum < 0) {
            throw new IllegalArgumentException("Cell index must be >= 0");
        }

        // Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory
        final Integer colI = Integer.valueOf(cellnum); // NOSONAR
        XSSFCell cell = _cells.get(colI);
        switch (policy) {
            case RETURN_NULL_AND_BLANK:
                return cell;
            case RETURN_BLANK_AS_NULL:
                boolean isBlank = (cell != null && cell.getCellType() == CellType.BLANK);
                return (isBlank) ? null : cell;
            case CREATE_NULL_AS_BLANK:
                return (cell == null) ? createCell(cellnum, CellType.BLANK) : cell;
            default:
                throw new IllegalArgumentException("Illegal policy " + policy);
        }
    }

    /**
     * Get the 0-based number of the first cell contained in this row.
     *
     * @return short representing the first logical cell in the row,
     *  or -1 if the row does not contain any cells.
     */
    @Override
    public short getFirstCellNum() {
        return (short)(_cells.size() == 0 ? -1 : _cells.firstKey());
    }

    /**
     * Gets the index of the last cell contained in this row <b>PLUS ONE</b>. The result also
     * happens to be the 1-based column number of the last cell.  This value can be used as a
     * standard upper bound when iterating over cells:
     * <pre>
     * short minColIx = row.getFirstCellNum();
     * short maxColIx = row.getLastCellNum();
     * for(short colIx=minColIx; colIx&lt;maxColIx; colIx++) {
     *   XSSFCell cell = row.getCell(colIx);
     *   if(cell == null) {
     *     continue;
     *   }
     *   //... do something with cell
     * }
     * </pre>
     *
     * @return short representing the last logical cell in the row <b>PLUS ONE</b>,
     *   or -1 if the row does not contain any cells.
     */
    @Override
    public short getLastCellNum() {
        return (short)(_cells.size() == 0 ? -1 : (_cells.lastKey() + 1));
    }

    /**
     * Get the row's height measured in twips (1/20th of a point). If the height is not set, the default worksheet value is returned,
     * See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()}
     *
     * @return row height measured in twips (1/20th of a point)
     */
    @Override
    public short getHeight() {
        return (short)(getHeightInPoints()*20);
    }

    /**
     * Returns row height measured in point size. If the height is not set, the default worksheet value is returned,
     * See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()}
     *
     * @return row height measured in point size
     * @see org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()
     */
    @Override
    public float getHeightInPoints() {
        if (this._row.isSetHt()) {
            return (float) this._row.getHt();
        }
        return _sheet.getDefaultRowHeightInPoints();
    }

    /**
     *  Set the height in "twips" or  1/20th of a point.
     *
     * @param height the height in "twips" or  1/20th of a point. <code>-1</code>  resets to the default height
     */
    @Override
    public void setHeight(short height) {
        if (height == -1) {
            if (_row.isSetHt()) {
                _row.unsetHt();
            }
            if (_row.isSetCustomHeight()) {
                _row.unsetCustomHeight();
            }
        } else {
            _row.setHt((double) height / 20);
            _row.setCustomHeight(true);

        }
    }

    /**
     * Set the row's height in points.
     *
     * @param height the height in points. <code>-1</code>  resets to the default height
     */
    @Override
    public void setHeightInPoints(float height) {
        setHeight((short)(height == -1 ? -1 : (height*20)));
    }

    /**
     * Gets the number of defined cells (NOT number of cells in the actual row!).
     * That is to say if only columns 0,4,5 have values then there would be 3.
     *
     * @return int representing the number of defined cells in the row.
     */
    @Override
    public int getPhysicalNumberOfCells() {
        return _cells.size();
    }

    /**
     * Get row number this row represents
     *
     * @return the row number (0 based)
     */
    @Override
    public int getRowNum() {
        return Math.toIntExact(_row.getR() - 1);
    }

    /**
     * Set the row number of this row.
     *
     * @param rowIndex  the row number (0-based)
     * @throws IllegalArgumentException if rowNum < 0 or greater than 1048575
     */
    @Override
    public void setRowNum(int rowIndex) {
        int maxrow = SpreadsheetVersion.EXCEL2007.getLastRowIndex();
        if (rowIndex < 0 || rowIndex > maxrow) {
            throw new IllegalArgumentException("Invalid row number (" + rowIndex
                    + ") outside allowable range (0.." + maxrow + ")");
        }
        _row.setR(rowIndex + 1L);
    }

    /**
     * Get whether or not to display this row with 0 height
     *
     * @return - height is zero or not.
     */
    @Override
    public boolean getZeroHeight() {
        return this._row.getHidden();
    }

    /**
     * Set whether or not to display this row with 0 height
     *
     * @param height  height is zero or not.
     */
    @Override
    public void setZeroHeight(boolean height) {
        this._row.setHidden(height);

    }

    /**
     * Is this row formatted? Most aren't, but some rows
     *  do have whole-row styles. For those that do, you
     *  can get the formatting from {@link #getRowStyle()}
     */
    @Override
    public boolean isFormatted() {
        return _row.isSetS();
    }
    /**
     * Returns the whole-row cell style. Most rows won't
     *  have one of these, so will return null. Call
     *  {@link #isFormatted()} to check first.
     */
    @Override
    public XSSFCellStyle getRowStyle() {
       if(!isFormatted()) {
        return null;
    }

       StylesTable stylesSource = getSheet().getWorkbook().getStylesSource();
       if(stylesSource.getNumCellStyles() > 0) {
           return stylesSource.getStyleAt(Math.toIntExact(_row.getS()));
       } else {
          return null;
       }
    }

    /**
     * Applies a whole-row cell styling to the row.
     * If the value is null then the style information is removed,
     *  causing the cell to used the default workbook style.
     */
    @Override
    public void setRowStyle(CellStyle style) {
        if(style == null) {
           if(_row.isSetS()) {
              _row.unsetS();
              _row.unsetCustomFormat();
           }
        } else {
            StylesTable styleSource = getSheet().getWorkbook().getStylesSource();

            XSSFCellStyle xStyle = (XSSFCellStyle)style;
            xStyle.verifyBelongsToStylesSource(styleSource);

            long idx = styleSource.putStyle(xStyle);
            _row.setS(idx);
            _row.setCustomFormat(true);
        }
    }

    /**
     * Remove the Cell from this row.
     *
     * @param cell the cell to remove
     */
    @Override
    public void removeCell(Cell cell) {
        if (cell.getRow() != this) {
            throw new IllegalArgumentException("Specified cell does not belong to this row");
        }
        //noinspection SuspiciousMethodCalls
        if(!_cells.containsValue(cell)) {
            throw new IllegalArgumentException("the row does not contain this cell");
        }

        XSSFCell xcell = (XSSFCell)cell;
        if(xcell.isPartOfArrayFormulaGroup()) {
            xcell.setCellFormula(null); // to remove the array formula
        }
        if(cell.getCellType() == CellType.FORMULA) {
           _sheet.getWorkbook().onDeleteFormula(xcell);
        }
        // Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory
        final Integer colI = Integer.valueOf(cell.getColumnIndex()); // NOSONAR
        XSSFCell removed = _cells.remove(colI);

        // also remove the corresponding CTCell from the _row.cArray,
        // it may not be at the same position right now
        // thus search for it
        int i = 0;
        for (CTCell ctCell : _row.getCArray()) {
            if(ctCell == removed.getCTCell()) {
                _row.removeC(i);
            }
            i++;
        }
    }

    /**
     * Returns the underlying CTRow xml bean containing all cell definitions in this row
     *
     * @return the underlying CTRow xml bean
     */
    @Internal
    public CTRow getCTRow(){
        return _row;
    }

    /**
     * Fired when the document is written to an output stream.
     *
     * @see org.apache.poi.xssf.usermodel.XSSFSheet#write(java.io.OutputStream) ()
     */
    protected void onDocumentWrite() {
        // _row.cArray and _cells.getCTCell might be out of sync after adding/removing cells,
        // thus we need to re-order it here to make the resulting file correct

        // do a quick check if there is work to do to not incur the overhead if not necessary anyway
        CTCell[] cArrayOrig = _row.getCArray();
        if(cArrayOrig.length == _cells.size()) {
            boolean allEqual = true;
            Iterator<XSSFCell> it = _cells.values().iterator();
            for (CTCell ctCell : cArrayOrig) {
                XSSFCell cell = it.next();

                // we want to compare on identity here on purpose
                // as we want to ensure that both lists contain the
                // same documents, not copies!
                if (ctCell != cell.getCTCell()) {
                    allEqual = false;
                    break;
                }
            }

            // we did not find any difference, so we can skip the work
            if(allEqual) {
                return;
            }
        }

        fixupCTCells(cArrayOrig);
    }

    private void fixupCTCells(CTCell[] cArrayOrig) {
        // copy all values to 2nd array and a map for lookup of index
        CTCell[] cArrayCopy = new CTCell[cArrayOrig.length];
        IdentityHashMap<CTCell, Integer> map = new IdentityHashMap<>(_cells.size());
        int i = 0;
        for (CTCell ctCell : cArrayOrig) {
            cArrayCopy[i] = (CTCell) ctCell.copy();
            map.put(ctCell, i);
            i++;
        }

        // populate _row.cArray correctly
        i = 0;
        for (XSSFCell cell : _cells.values()) {
            // no need to change anything if position is correct
            Integer correctPosition = map.get(cell.getCTCell());
            Objects.requireNonNull(correctPosition, "Should find CTCell in _row");
            if(correctPosition != i) {
                // we need to re-populate this CTCell
                _row.setCArray(i, cArrayCopy[correctPosition]);
                cell.setCTCell(_row.getCArray(i));
            }
            i++;
        }

        // remove any remaining illegal references in _rows.cArray
        while(cArrayOrig.length > _cells.size()) {
            _row.removeC(_cells.size());
        }
    }

    /**
     * @return formatted xml representation of this row
     */
    @Override
    public String toString(){
        return _row.toString();
    }

    /**
     * update cell references when shifting rows
     *
     * @param n the number of rows to move
     */
    protected void shift(int n) {
        int rownum = getRowNum() + n;
        String msg = "Row[rownum=" + getRowNum() + "] contains cell(s) included in a multi-cell array formula. " +
                "You cannot change part of an array.";
        setRowNum(rownum);
        for(Cell c : this){
            ((XSSFCell)c).updateCellReferencesForShifting(msg);
        }

    }

    /**
     * Copy the cells from srcRow to this row
     * If this row is not a blank row, this will merge the two rows, overwriting
     * the cells in this row with the cells in srcRow
     * If srcRow is null, overwrite cells in destination row with blank values, styles, etc per cell copy policy
     * srcRow may be from a different sheet in the same workbook
     * @param srcRow the rows to copy from
     * @param policy the policy to determine what gets copied
     */
    @Beta
    public void copyRowFrom(Row srcRow, CellCopyPolicy policy) {
        if (srcRow == null) {
            // srcRow is blank. Overwrite cells with blank values, blank styles, etc per cell copy policy
            for (Cell destCell : this) {
                final XSSFCell srcCell = null;
                // FIXME: remove type casting when copyCellFrom(Cell, CellCopyPolicy) is added to Cell interface
                ((XSSFCell)destCell).copyCellFrom(srcCell, policy);
            }

            if (policy.isCopyMergedRegions()) {
                // Remove MergedRegions in dest row
                final int destRowNum = getRowNum();
                int index = 0;
                final Set<Integer> indices = new HashSet<>();
                for (CellRangeAddress destRegion : getSheet().getMergedRegions()) {
                    if (destRowNum == destRegion.getFirstRow() && destRowNum == destRegion.getLastRow()) {
                        indices.add(index);
                    }
                    index++;
                }
                getSheet().removeMergedRegions(indices);
            }

            if (policy.isCopyRowHeight()) {
                // clear row height
                setHeight((short)-1);
            }

        }
        else {
            for (final Cell c : srcRow){
                final XSSFCell srcCell = (XSSFCell)c;
                final XSSFCell destCell = createCell(srcCell.getColumnIndex());
                destCell.copyCellFrom(srcCell, policy);
            }

            final int sheetIndex = _sheet.getWorkbook().getSheetIndex(_sheet);
            final String sheetName = _sheet.getWorkbook().getSheetName(sheetIndex);
            final int srcRowNum = srcRow.getRowNum();
            final int destRowNum = getRowNum();
            final int rowDifference = destRowNum - srcRowNum;

            final FormulaShifter formulaShifter = FormulaShifter.createForRowCopy(sheetIndex, sheetName, srcRowNum, srcRowNum, rowDifference, SpreadsheetVersion.EXCEL2007);
            final XSSFRowShifter rowShifter = new XSSFRowShifter(_sheet);
            rowShifter.updateRowFormulas(this, formulaShifter);

            // Copy merged regions that are fully contained on the row
            // FIXME: is this something that rowShifter could be doing?
            if (policy.isCopyMergedRegions()) {
                for (CellRangeAddress srcRegion : srcRow.getSheet().getMergedRegions()) {
                    if (srcRowNum == srcRegion.getFirstRow() && srcRowNum == srcRegion.getLastRow()) {
                        CellRangeAddress destRegion = srcRegion.copy();
                        destRegion.setFirstRow(destRowNum);
                        destRegion.setLastRow(destRowNum);
                        getSheet().addMergedRegion(destRegion);
                    }
                }
            }

            if (policy.isCopyRowHeight()) {
                setHeight(srcRow.getHeight());
            }
        }
    }

    @Override
    public int getOutlineLevel() {
        return _row.getOutlineLevel();
    }

    /**
     * Shifts column range [firstShiftColumnIndex-lastShiftColumnIndex] step places to the right.
     * @param firstShiftColumnIndex the column to start shifting
     * @param lastShiftColumnIndex the column to end shifting
     * @param step length of the shifting step
     */
    @Override
    public void shiftCellsRight(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) {
        RowShifter.validateShiftParameters(firstShiftColumnIndex, lastShiftColumnIndex, step);

        for (int columnIndex = lastShiftColumnIndex; columnIndex >= firstShiftColumnIndex; columnIndex--){ // process cells backwards, because of shifting
            shiftCell(columnIndex, step);
        }
        for (int columnIndex = firstShiftColumnIndex; columnIndex <= firstShiftColumnIndex+step-1; columnIndex++)
        {
            _cells.remove(columnIndex);
            XSSFCell targetCell = getCell(columnIndex);
            if(targetCell != null) {
                targetCell.getCTCell().set(CTCell.Factory.newInstance());
            }
        }
    }

    /**
     * Shifts column range [firstShiftColumnIndex-lastShiftColumnIndex] step places to the left.
     * @param firstShiftColumnIndex the column to start shifting
     * @param lastShiftColumnIndex the column to end shifting
     * @param step length of the shifting step
     */
    @Override
    public void shiftCellsLeft(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) {
        RowShifter.validateShiftLeftParameters(firstShiftColumnIndex, lastShiftColumnIndex, step);

        for (int columnIndex = firstShiftColumnIndex; columnIndex <= lastShiftColumnIndex; columnIndex++){
            shiftCell(columnIndex, -step);
        }
        for (int columnIndex = lastShiftColumnIndex-step+1; columnIndex <= lastShiftColumnIndex; columnIndex++){
            _cells.remove(columnIndex);
            XSSFCell targetCell = getCell(columnIndex);
            if(targetCell != null) {
                targetCell.getCTCell().set(CTCell.Factory.newInstance());
            }
        }
    }

    private void shiftCell(int columnIndex, int step/*pass negative value for left shift*/){
        if(columnIndex + step < 0) {
            throw new IllegalStateException("Column index less than zero : " + (Integer.valueOf(columnIndex + step)));
        }

        XSSFCell currentCell = getCell(columnIndex);
        if(currentCell != null){
            currentCell.setCellNum(columnIndex+step);
            _cells.put(columnIndex+step, currentCell);
        }
        else {
            _cells.remove(columnIndex+step);
            XSSFCell targetCell = getCell(columnIndex+step);
            if(targetCell != null) {
                targetCell.getCTCell().set(CTCell.Factory.newInstance());
            }
        }
    }
}
