/* ====================================================================
   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.ss.util;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.BorderExtent;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

/**
 * <p>
 * A {@link PropertyTemplate} is a template that can be applied to any sheet in
 * a project. It contains all the border type and color attributes needed to
 * draw all the borders for a single sheet. That template can be applied to any
 * sheet in any workbook.
 * 
 * This class requires the full spreadsheet to be in memory, so 
 * {@link org.apache.poi.xssf.streaming.SXSSFWorkbook} Spreadsheets are not
 * supported. The same {@link PropertyTemplate} can, however, be applied to both
 * {@link HSSFWorkbook} and {@link org.apache.poi.xssf.usermodel.XSSFWorkbook}
 * objects if necessary. Portions of the border that fall outside the max range
 * of the {@link Workbook} sheet are ignored.
 * </p>
 * 
 * <p>
 * This would replace {@link RegionUtil}.
 * </p>
 */
public final class PropertyTemplate {

    /**
     * This is a list of cell properties for one shot application to a range of
     * cells at a later time.
     */
    private Map<CellAddress, Map<String, Object>> _propertyTemplate;

    /**
     * Create a PropertyTemplate object
     */
    public PropertyTemplate() {
        _propertyTemplate = new HashMap<CellAddress, Map<String, Object>>();
    }
    
    /**
     * Create a PropertyTemplate object from another PropertyTemplate
     *
     * @param template a PropertyTemplate object
     */
    public PropertyTemplate(PropertyTemplate template) {
        this();
        for(Map.Entry<CellAddress, Map<String, Object>> entry : template.getTemplate().entrySet()) {
            _propertyTemplate.put(new CellAddress(entry.getKey()), cloneCellProperties(entry.getValue()));
        }
    }
    
    private Map<CellAddress,Map<String, Object>> getTemplate() {
        return _propertyTemplate;
    }
    
    private static Map<String, Object> cloneCellProperties(Map<String, Object> properties) {
        Map<String, Object> newProperties = new HashMap<String, Object>(); 
        for(Map.Entry<String, Object> entry : properties.entrySet()) {
            newProperties.put(entry.getKey(), entry.getValue());
        }
        return newProperties;
    }
    
    /**
     * Draws a group of cell borders for a cell range. The borders are not
     * applied to the cells at this time, just the template is drawn. To apply
     * the drawn borders to a sheet, use {@link #applyBorders}.
     * 
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     * @param extent
     *            - {@link BorderExtent} of the borders to be
     *            applied.
     */
    public void drawBorders(CellRangeAddress range, BorderStyle borderType,
            BorderExtent extent) {
        switch (extent) {
        case NONE:
            removeBorders(range);
            break;
        case ALL:
            drawHorizontalBorders(range, borderType, BorderExtent.ALL);
            drawVerticalBorders(range, borderType, BorderExtent.ALL);
            break;
        case INSIDE:
            drawHorizontalBorders(range, borderType, BorderExtent.INSIDE);
            drawVerticalBorders(range, borderType, BorderExtent.INSIDE);
            break;
        case OUTSIDE:
            drawOutsideBorders(range, borderType, BorderExtent.ALL);
            break;
        case TOP:
            drawTopBorder(range, borderType);
            break;
        case BOTTOM:
            drawBottomBorder(range, borderType);
            break;
        case LEFT:
            drawLeftBorder(range, borderType);
            break;
        case RIGHT:
            drawRightBorder(range, borderType);
            break;
        case HORIZONTAL:
            drawHorizontalBorders(range, borderType, BorderExtent.ALL);
            break;
        case INSIDE_HORIZONTAL:
            drawHorizontalBorders(range, borderType, BorderExtent.INSIDE);
            break;
        case OUTSIDE_HORIZONTAL:
            drawOutsideBorders(range, borderType, BorderExtent.HORIZONTAL);
            break;
        case VERTICAL:
            drawVerticalBorders(range, borderType, BorderExtent.ALL);
            break;
        case INSIDE_VERTICAL:
            drawVerticalBorders(range, borderType, BorderExtent.INSIDE);
            break;
        case OUTSIDE_VERTICAL:
            drawOutsideBorders(range, borderType, BorderExtent.VERTICAL);
            break;
        }
    }

    /**
     * Draws a group of cell borders for a cell range. The borders are not
     * applied to the cells at this time, just the template is drawn. To apply
     * the drawn borders to a sheet, use {@link #applyBorders}.
     * 
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     * @param extent
     *            - {@link BorderExtent} of the borders to be
     *            applied.
     */
    public void drawBorders(CellRangeAddress range, BorderStyle borderType,
            short color, BorderExtent extent) {
        drawBorders(range, borderType, extent);
        if (borderType != BorderStyle.NONE) {
            drawBorderColors(range, color, extent);
        }
    }

    /**
     * <p>
     * Draws the top border for a range of cells
     * </p>
     * 
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     */
    private void drawTopBorder(CellRangeAddress range, BorderStyle borderType) {
        int row = range.getFirstRow();
        int firstCol = range.getFirstColumn();
        int lastCol = range.getLastColumn();
        for (int i = firstCol; i <= lastCol; i++) {
            addProperty(row, i, CellUtil.BORDER_TOP, borderType);
            if (borderType == BorderStyle.NONE && row > 0) {
                addProperty(row - 1, i, CellUtil.BORDER_BOTTOM, borderType);
            }
        }
    }

    /**
     * <p>
     * Draws the bottom border for a range of cells
     * </p>
     * 
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     */
    private void drawBottomBorder(CellRangeAddress range,
            BorderStyle borderType) {
        int row = range.getLastRow();
        int firstCol = range.getFirstColumn();
        int lastCol = range.getLastColumn();
        for (int i = firstCol; i <= lastCol; i++) {
            addProperty(row, i, CellUtil.BORDER_BOTTOM, borderType);
            if (borderType == BorderStyle.NONE
                    && row < SpreadsheetVersion.EXCEL2007.getMaxRows() - 1) {
                addProperty(row + 1, i, CellUtil.BORDER_TOP, borderType);
            }
        }
    }

    /**
     * <p>
     * Draws the left border for a range of cells
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     */
    private void drawLeftBorder(CellRangeAddress range,
            BorderStyle borderType) {
        int firstRow = range.getFirstRow();
        int lastRow = range.getLastRow();
        int col = range.getFirstColumn();
        for (int i = firstRow; i <= lastRow; i++) {
            addProperty(i, col, CellUtil.BORDER_LEFT, borderType);
            if (borderType == BorderStyle.NONE && col > 0) {
                addProperty(i, col - 1, CellUtil.BORDER_RIGHT, borderType);
            }
        }
    }

    /**
     * <p>
     * Draws the right border for a range of cells
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     */
    private void drawRightBorder(CellRangeAddress range,
            BorderStyle borderType) {
        int firstRow = range.getFirstRow();
        int lastRow = range.getLastRow();
        int col = range.getLastColumn();
        for (int i = firstRow; i <= lastRow; i++) {
            addProperty(i, col, CellUtil.BORDER_RIGHT, borderType);
            if (borderType == BorderStyle.NONE
                    && col < SpreadsheetVersion.EXCEL2007.getMaxColumns() - 1) {
                addProperty(i, col + 1, CellUtil.BORDER_LEFT, borderType);
            }
        }
    }

    /**
     * <p>
     * Draws the outside borders for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     * @param extent
     *            - {@link BorderExtent} of the borders to be
     *            applied. Valid Values are:
     *            <ul>
     *            <li>BorderExtent.ALL</li>
     *            <li>BorderExtent.HORIZONTAL</li>
     *            <li>BorderExtent.VERTICAL</li>
     *            </ul>
     */
    private void drawOutsideBorders(CellRangeAddress range,
            BorderStyle borderType, BorderExtent extent) {
        switch (extent) {
        case ALL:
        case HORIZONTAL:
        case VERTICAL:
            if (extent == BorderExtent.ALL || extent == BorderExtent.HORIZONTAL) {
                drawTopBorder(range, borderType);
                drawBottomBorder(range, borderType);
            }
            if (extent == BorderExtent.ALL || extent == BorderExtent.VERTICAL) {
                drawLeftBorder(range, borderType);
                drawRightBorder(range, borderType);
            }
            break;
        default:
            throw new IllegalArgumentException(
                    "Unsupported PropertyTemplate.Extent, valid Extents are ALL, HORIZONTAL, and VERTICAL");
        }
    }

    /**
     * <p>
     * Draws the horizontal borders for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     * @param extent
     *            - {@link BorderExtent} of the borders to be
     *            applied. Valid Values are:
     *            <ul>
     *            <li>BorderExtent.ALL</li>
     *            <li>BorderExtent.INSIDE</li>
     *            </ul>
     */
    private void drawHorizontalBorders(CellRangeAddress range,
            BorderStyle borderType, BorderExtent extent) {
        switch (extent) {
        case ALL:
        case INSIDE:
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            int firstCol = range.getFirstColumn();
            int lastCol = range.getLastColumn();
            for (int i = firstRow; i <= lastRow; i++) {
                CellRangeAddress row = new CellRangeAddress(i, i, firstCol,
                        lastCol);
                if (extent == BorderExtent.ALL || i > firstRow) {
                    drawTopBorder(row, borderType);
                }
                if (extent == BorderExtent.ALL || i < lastRow) {
                    drawBottomBorder(row, borderType);
                }
            }
            break;
        default:
            throw new IllegalArgumentException(
                    "Unsupported PropertyTemplate.Extent, valid Extents are ALL and INSIDE");
        }
    }

    /**
     * <p>
     * Draws the vertical borders for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which borders are
     *            drawn.
     * @param borderType
     *            - Type of border to draw. {@link BorderStyle}.
     * @param extent
     *            - {@link BorderExtent} of the borders to be
     *            applied. Valid Values are:
     *            <ul>
     *            <li>BorderExtent.ALL</li>
     *            <li>BorderExtent.INSIDE</li>
     *            </ul>
     */
    private void drawVerticalBorders(CellRangeAddress range,
            BorderStyle borderType, BorderExtent extent) {
        switch (extent) {
        case ALL:
        case INSIDE:
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            int firstCol = range.getFirstColumn();
            int lastCol = range.getLastColumn();
            for (int i = firstCol; i <= lastCol; i++) {
                CellRangeAddress row = new CellRangeAddress(firstRow, lastRow,
                        i, i);
                if (extent == BorderExtent.ALL || i > firstCol) {
                    drawLeftBorder(row, borderType);
                }
                if (extent == BorderExtent.ALL || i < lastCol) {
                    drawRightBorder(row, borderType);
                }
            }
            break;
        default:
            throw new IllegalArgumentException(
                    "Unsupported PropertyTemplate.Extent, valid Extents are ALL and INSIDE");
        }
    }

    /**
     * Removes all border properties from this {@link PropertyTemplate} for the
     * specified range.
     * 
     * @parm range - {@link CellRangeAddress} range of cells to remove borders.
     */
    private void removeBorders(CellRangeAddress range) {
        Set<String> properties = new HashSet<String>();
        properties.add(CellUtil.BORDER_TOP);
        properties.add(CellUtil.BORDER_BOTTOM);
        properties.add(CellUtil.BORDER_LEFT);
        properties.add(CellUtil.BORDER_RIGHT);
        for (int row = range.getFirstRow(); row <= range.getLastRow(); row++) {
            for (int col = range.getFirstColumn(); col <= range
                    .getLastColumn(); col++) {
                removeProperties(row, col, properties);
            }
        }
        removeBorderColors(range);
    }

    /**
     * Applies the drawn borders to a Sheet. The borders that are applied are
     * the ones that have been drawn by the {@link #drawBorders} and
     * {@link #drawBorderColors} methods.
     *
     * @param sheet
     *            - {@link Sheet} on which to apply borders
     */
    public void applyBorders(Sheet sheet) {
        Workbook wb = sheet.getWorkbook();
        for (Map.Entry<CellAddress, Map<String, Object>> entry : _propertyTemplate
                .entrySet()) {
            CellAddress cellAddress = entry.getKey();
            if (cellAddress.getRow() < wb.getSpreadsheetVersion().getMaxRows()
                    && cellAddress.getColumn() < wb.getSpreadsheetVersion()
                            .getMaxColumns()) {
                Map<String, Object> properties = entry.getValue();
                Row row = CellUtil.getRow(cellAddress.getRow(), sheet);
                Cell cell = CellUtil.getCell(row, cellAddress.getColumn());
                CellUtil.setCellStyleProperties(cell, properties);
            }
        }
    }

    /**
     * Sets the color for a group of cell borders for a cell range. The borders
     * are not applied to the cells at this time, just the template is drawn. If
     * the borders do not exist, a BORDER_THIN border is used. To apply the
     * drawn borders to a sheet, use {@link #applyBorders}.
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which colors are
     *            set.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     * @param extent
     *            - {@link BorderExtent} of the borders for which
     *            colors are set.
     */
    public void drawBorderColors(CellRangeAddress range, short color,
            BorderExtent extent) {
        switch (extent) {
        case NONE:
            removeBorderColors(range);
            break;
        case ALL:
            drawHorizontalBorderColors(range, color, BorderExtent.ALL);
            drawVerticalBorderColors(range, color, BorderExtent.ALL);
            break;
        case INSIDE:
            drawHorizontalBorderColors(range, color, BorderExtent.INSIDE);
            drawVerticalBorderColors(range, color, BorderExtent.INSIDE);
            break;
        case OUTSIDE:
            drawOutsideBorderColors(range, color, BorderExtent.ALL);
            break;
        case TOP:
            drawTopBorderColor(range, color);
            break;
        case BOTTOM:
            drawBottomBorderColor(range, color);
            break;
        case LEFT:
            drawLeftBorderColor(range, color);
            break;
        case RIGHT:
            drawRightBorderColor(range, color);
            break;
        case HORIZONTAL:
            drawHorizontalBorderColors(range, color, BorderExtent.ALL);
            break;
        case INSIDE_HORIZONTAL:
            drawHorizontalBorderColors(range, color, BorderExtent.INSIDE);
            break;
        case OUTSIDE_HORIZONTAL:
            drawOutsideBorderColors(range, color, BorderExtent.HORIZONTAL);
            break;
        case VERTICAL:
            drawVerticalBorderColors(range, color, BorderExtent.ALL);
            break;
        case INSIDE_VERTICAL:
            drawVerticalBorderColors(range, color, BorderExtent.INSIDE);
            break;
        case OUTSIDE_VERTICAL:
            drawOutsideBorderColors(range, color, BorderExtent.VERTICAL);
            break;
        }
    }

    /**
     * <p>
     * Sets the color of the top border for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which colors are
     *            set.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     */
    private void drawTopBorderColor(CellRangeAddress range, short color) {
        int row = range.getFirstRow();
        int firstCol = range.getFirstColumn();
        int lastCol = range.getLastColumn();
        for (int i = firstCol; i <= lastCol; i++) {
            if (getBorderStyle(row, i,
                    CellUtil.BORDER_TOP) == BorderStyle.NONE) {
                drawTopBorder(new CellRangeAddress(row, row, i, i),
                        BorderStyle.THIN);
            }
            addProperty(row, i, CellUtil.TOP_BORDER_COLOR, color);
        }
    }

    /**
     * <p>
     * Sets the color of the bottom border for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which colors are
     *            set.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     */
    private void drawBottomBorderColor(CellRangeAddress range, short color) {
        int row = range.getLastRow();
        int firstCol = range.getFirstColumn();
        int lastCol = range.getLastColumn();
        for (int i = firstCol; i <= lastCol; i++) {
            if (getBorderStyle(row, i,
                    CellUtil.BORDER_BOTTOM) == BorderStyle.NONE) {
                drawBottomBorder(new CellRangeAddress(row, row, i, i),
                        BorderStyle.THIN);
            }
            addProperty(row, i, CellUtil.BOTTOM_BORDER_COLOR, color);
        }
    }

    /**
     * <p>
     * Sets the color of the left border for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which colors are
     *            set.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     */
    private void drawLeftBorderColor(CellRangeAddress range, short color) {
        int firstRow = range.getFirstRow();
        int lastRow = range.getLastRow();
        int col = range.getFirstColumn();
        for (int i = firstRow; i <= lastRow; i++) {
            if (getBorderStyle(i, col,
                    CellUtil.BORDER_LEFT) == BorderStyle.NONE) {
                drawLeftBorder(new CellRangeAddress(i, i, col, col),
                        BorderStyle.THIN);
            }
            addProperty(i, col, CellUtil.LEFT_BORDER_COLOR, color);
        }
    }

    /**
     * <p>
     * Sets the color of the right border for a range of cells. If the border is
     * not drawn, it defaults to BORDER_THIN
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which colors are
     *            set.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     */
    private void drawRightBorderColor(CellRangeAddress range, short color) {
        int firstRow = range.getFirstRow();
        int lastRow = range.getLastRow();
        int col = range.getLastColumn();
        for (int i = firstRow; i <= lastRow; i++) {
            if (getBorderStyle(i, col,
                    CellUtil.BORDER_RIGHT) == BorderStyle.NONE) {
                drawRightBorder(new CellRangeAddress(i, i, col, col),
                        BorderStyle.THIN);
            }
            addProperty(i, col, CellUtil.RIGHT_BORDER_COLOR, color);
        }
    }

    /**
     * <p>
     * Sets the color of the outside borders for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which colors are
     *            set.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     * @param extent
     *            - {@link BorderExtent} of the borders for which
     *            colors are set. Valid Values are:
     *            <ul>
     *            <li>BorderExtent.ALL</li>
     *            <li>BorderExtent.HORIZONTAL</li>
     *            <li>BorderExtent.VERTICAL</li>
     *            </ul>
     */
    private void drawOutsideBorderColors(CellRangeAddress range, short color,
            BorderExtent extent) {
        switch (extent) {
        case ALL:
        case HORIZONTAL:
        case VERTICAL:
            if (extent == BorderExtent.ALL || extent == BorderExtent.HORIZONTAL) {
                drawTopBorderColor(range, color);
                drawBottomBorderColor(range, color);
            }
            if (extent == BorderExtent.ALL || extent == BorderExtent.VERTICAL) {
                drawLeftBorderColor(range, color);
                drawRightBorderColor(range, color);
            }
            break;
        default:
            throw new IllegalArgumentException(
                    "Unsupported PropertyTemplate.Extent, valid Extents are ALL, HORIZONTAL, and VERTICAL");
        }
    }

    /**
     * <p>
     * Sets the color of the horizontal borders for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which colors are
     *            set.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     * @param extent
     *            - {@link BorderExtent} of the borders for which
     *            colors are set. Valid Values are:
     *            <ul>
     *            <li>BorderExtent.ALL</li>
     *            <li>BorderExtent.INSIDE</li>
     *            </ul>
     */
    private void drawHorizontalBorderColors(CellRangeAddress range, short color,
            BorderExtent extent) {
        switch (extent) {
        case ALL:
        case INSIDE:
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            int firstCol = range.getFirstColumn();
            int lastCol = range.getLastColumn();
            for (int i = firstRow; i <= lastRow; i++) {
                CellRangeAddress row = new CellRangeAddress(i, i, firstCol,
                        lastCol);
                if (extent == BorderExtent.ALL || i > firstRow) {
                    drawTopBorderColor(row, color);
                }
                if (extent == BorderExtent.ALL || i < lastRow) {
                    drawBottomBorderColor(row, color);
                }
            }
            break;
        default:
            throw new IllegalArgumentException(
                    "Unsupported PropertyTemplate.Extent, valid Extents are ALL and INSIDE");
        }
    }

    /**
     * <p>
     * Sets the color of the vertical borders for a range of cells.
     * </p>
     *
     * @param range
     *            - {@link CellRangeAddress} range of cells on which colors are
     *            set.
     * @param color
     *            - Color index from {@link IndexedColors} used to draw the
     *            borders.
     * @param extent
     *            - {@link BorderExtent} of the borders for which
     *            colors are set. Valid Values are:
     *            <ul>
     *            <li>BorderExtent.ALL</li>
     *            <li>BorderExtent.INSIDE</li>
     *            </ul>
     */
    private void drawVerticalBorderColors(CellRangeAddress range, short color,
            BorderExtent extent) {
        switch (extent) {
        case ALL:
        case INSIDE:
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            int firstCol = range.getFirstColumn();
            int lastCol = range.getLastColumn();
            for (int i = firstCol; i <= lastCol; i++) {
                CellRangeAddress row = new CellRangeAddress(firstRow, lastRow,
                        i, i);
                if (extent == BorderExtent.ALL || i > firstCol) {
                    drawLeftBorderColor(row, color);
                }
                if (extent == BorderExtent.ALL || i < lastCol) {
                    drawRightBorderColor(row, color);
                }
            }
            break;
        default:
            throw new IllegalArgumentException(
                    "Unsupported PropertyTemplate.Extent, valid Extents are ALL and INSIDE");
        }
    }

    /**
     * Removes all border properties from this {@link PropertyTemplate} for the
     * specified range.
     * 
     * @parm range - {@link CellRangeAddress} range of cells to remove borders.
     */
    private void removeBorderColors(CellRangeAddress range) {
        Set<String> properties = new HashSet<String>();
        properties.add(CellUtil.TOP_BORDER_COLOR);
        properties.add(CellUtil.BOTTOM_BORDER_COLOR);
        properties.add(CellUtil.LEFT_BORDER_COLOR);
        properties.add(CellUtil.RIGHT_BORDER_COLOR);
        for (int row = range.getFirstRow(); row <= range.getLastRow(); row++) {
            for (int col = range.getFirstColumn(); col <= range
                    .getLastColumn(); col++) {
                removeProperties(row, col, properties);
            }
        }
    }

    /**
     * Adds a property to this {@link PropertyTemplate} for a given cell
     *
     * @param row
     * @param col
     * @param property
     * @param value
     */
    private void addProperty(int row, int col, String property, short value) {
        addProperty(row, col, property, Short.valueOf(value));
    }

    /**
     * Adds a property to this {@link PropertyTemplate} for a given cell
     *
     * @param row
     * @param col
     * @param property
     * @param value
     */
    private void addProperty(int row, int col, String property, Object value) {
        CellAddress cell = new CellAddress(row, col);
        Map<String, Object> cellProperties = _propertyTemplate.get(cell);
        if (cellProperties == null) {
            cellProperties = new HashMap<String, Object>();
        }
        cellProperties.put(property, value);
        _propertyTemplate.put(cell, cellProperties);
    }

    /**
     * Removes a set of properties from this {@link PropertyTemplate} for a
     * given cell
     *
     * @param row
     * @param col
     * @param properties
     */
    private void removeProperties(int row, int col, Set<String> properties) {
        CellAddress cell = new CellAddress(row, col);
        Map<String, Object> cellProperties = _propertyTemplate.get(cell);
        if (cellProperties != null) {
            cellProperties.keySet().removeAll(properties);
            if (cellProperties.isEmpty()) {
                _propertyTemplate.remove(cell);
            } else {
                _propertyTemplate.put(cell, cellProperties);
            }
        }
    }

    /**
     * Retrieves the number of borders assigned to a cell
     *
     * @param cell
     */
    public int getNumBorders(CellAddress cell) {
        Map<String, Object> cellProperties = _propertyTemplate.get(cell);
        if (cellProperties == null) {
            return 0;
        }

        int count = 0;
        for (String property : cellProperties.keySet()) {
            if (property.equals(CellUtil.BORDER_TOP))
                count += 1;
            if (property.equals(CellUtil.BORDER_BOTTOM))
                count += 1;
            if (property.equals(CellUtil.BORDER_LEFT))
                count += 1;
            if (property.equals(CellUtil.BORDER_RIGHT))
                count += 1;
        }
        return count;
    }

    /**
     * Retrieves the number of borders assigned to a cell
     *
     * @param row
     * @param col
     */
    public int getNumBorders(int row, int col) {
        return getNumBorders(new CellAddress(row, col));
    }

    /**
     * Retrieves the number of border colors assigned to a cell
     *
     * @param cell
     */
    public int getNumBorderColors(CellAddress cell) {
        Map<String, Object> cellProperties = _propertyTemplate.get(cell);
        if (cellProperties == null) {
            return 0;
        }

        int count = 0;
        for (String property : cellProperties.keySet()) {
            if (property.equals(CellUtil.TOP_BORDER_COLOR))
                count += 1;
            if (property.equals(CellUtil.BOTTOM_BORDER_COLOR))
                count += 1;
            if (property.equals(CellUtil.LEFT_BORDER_COLOR))
                count += 1;
            if (property.equals(CellUtil.RIGHT_BORDER_COLOR))
                count += 1;
        }
        return count;
    }

    /**
     * Retrieves the number of border colors assigned to a cell
     *
     * @param row
     * @param col
     */
    public int getNumBorderColors(int row, int col) {
        return getNumBorderColors(new CellAddress(row, col));
    }

    /**
     * Retrieves the border style for a given cell
     * 
     * @param cell
     * @param property
     */
    public BorderStyle getBorderStyle(CellAddress cell, String property) {
        BorderStyle value = BorderStyle.NONE;
        Map<String, Object> cellProperties = _propertyTemplate.get(cell);
        if (cellProperties != null) {
            Object obj = cellProperties.get(property);
            if (obj instanceof BorderStyle) {
                value = (BorderStyle) obj;
            }
        }
        return value;
    }

    /**
     * Retrieves the border style for a given cell
     * 
     * @param row
     * @param col
     * @param property
     */
    public BorderStyle getBorderStyle(int row, int col, String property) {
        return getBorderStyle(new CellAddress(row, col), property);
    }

    /**
     * Retrieves the border style for a given cell
     * 
     * @param cell
     * @param property
     */
    public short getTemplateProperty(CellAddress cell, String property) {
        short value = 0;
        Map<String, Object> cellProperties = _propertyTemplate.get(cell);
        if (cellProperties != null) {
            Object obj = cellProperties.get(property);
            if (obj != null) {
                value = getShort(obj);
            }
        }
        return value;
    }

    /**
     * Retrieves the border style for a given cell
     * 
     * @param row
     * @param col
     * @param property
     */
    public short getTemplateProperty(int row, int col, String property) {
        return getTemplateProperty(new CellAddress(row, col), property);
    }

    /**
     * Converts a Short object to a short value or 0 if the object is not a
     * Short
     *
     * @param value Potentially short value to convert
     * @return short value, or 0 if not a short
     */
    private static short getShort(Object value) {
        if (value instanceof Short) {
            return ((Short) value).shortValue();
        }
        return 0;
    }
}
