package com.capgemini.reports.templates;

import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

/**
 * Represents a column for a .jrxml dynamic table template.<br>
 * A {@link Column} specifies a series of content Dynamic field {@link Cell Cells}, and may (optionally) specify some Header {@link Cell Cells}. These header cells may contain static text, or a reference to a report parameter key.
 */
@Getter
public class Column {

    private final List<Cell> headers;
    private final Cell field;
    private final int width;
    private final int xPosition;
    /** The total height of all the headers. grows whenever a new header {@link Cell} is added. */
    private int totalHeaderHeight;



    /**
     * Creates a {@link Column} object. Field cells are always transparent.
     * 
     * @param fieldKey The field key to put into the table body
     * @param width The Column width, in pixels. All {@link Cell Cells} inside this column will have the same width
     * @param stretchWithOverflow if true, the cell will expand downwards to shall all the text inside it
     * @param xPosition the Column's horizontal position, in pixels
     * @param contentHeight the height of any field cell in the table's body
     * @param fieldFormat the format of this field
     */
    public Column(final String fieldKey, final int width, final int xPosition, final boolean stretchWithOverflow, final int contentHeight,
            final CellFormat fieldFormat) {
        this.headers = new ArrayList<>();
        this.field = Cell.makeFieldCell(fieldKey, contentHeight, width, stretchWithOverflow, xPosition, 0, fieldFormat);
        this.width = width;
        this.xPosition = xPosition;
        this.totalHeaderHeight = 0;
    }

    /**
     * Adds a Header {@link Cell} to this column. This Cell is added as the last header cell, right before the table body.
     * 
     * @param dynamic if true, then this header clel will contain a reference to a report parameter using the content argument as a key
     * @param content the Header content. If this header is dynamic, it is the name of the paremeter key. If it is not dynamic, this content will be the raw static text to display in the cell.
     * @param height this header cell's height
     * @param stretchWithOverflow if true, the cell will expand downwards to shall all the text inside it. Ignored if the cell is Static
     * @param format This header line's format
     */
    public void addHeader(final String content, final boolean dynamic, final int height, final boolean stretchWithOverflow, final CellFormat format) {
        if (dynamic) {
            headers.add(Cell.makeParameterCell(content, height, width, stretchWithOverflow, xPosition, totalHeaderHeight, format));
        }
        else {
            headers.add(Cell.makeStaticCell(content, height, width, xPosition, totalHeaderHeight, format));
        }
        totalHeaderHeight += height;
    }

    /**
     * Lengthens the previous header Cell (if any). To be used to fuse cells istead of creating a new one.
     * 
     * @param heightPx the height to add to the previous header cell, in pixels
     */
    public void addToPreviousHeaderCellHeight(final int heightPx) {
        if (!headers.isEmpty()) {
            headers.get(headers.size() - 1).addHeight(heightPx);
            totalHeaderHeight += heightPx;
        }
    }

    /**
     * Generates the .jrxml code for this column's headers.
     * 
     * @return a String containing the text to put in the template
     */
    public String makeHeaders() {
        StringBuilder output = new StringBuilder();
        for (Cell header : headers) {
            output.append(header.makeCell());
        }
        return output.toString();
    }

    /**
     * Generates the .jrxml code for this column's body field.
     * 
     * @return a String containing the text to put in the template
     */
    public String makeContent() {
        return field.makeCell();
    }

    /**
     * Returns a declaration of this Column's Field key, if it is a dynamic field.
     * 
     * @return the {@link String} key
     */
    public String getFieldsDeclaration() {
        return field.getFieldsDeclaration();
    }

    /**
     * Returns all the declarations of this Column's Parameter keys, if any.
     * 
     * @return the {@link String} declarations, or an empty string if none are required
     */
    public String getParametersDeclaration() {
        StringBuilder stringBuilder = new StringBuilder();
        for (Cell header : headers) {
            if (header.isDynamic()) {
                stringBuilder.append(header.getParametersDeclaration());
            }
        }
        return stringBuilder.toString();
    }



}
