Column.java

/*
 * CSVeed (https://github.com/42BV/CSVeed)
 *
 * Copyright 2013-2023 CSVeed.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of The Apache Software License,
 * Version 2.0 which accompanies this distribution, and is available at
 * https://www.apache.org/licenses/LICENSE-2.0.txt
 */
package org.csveed.common;

import java.util.Locale;

import org.csveed.api.Header;
import org.csveed.report.CsvException;
import org.csveed.report.GeneralError;

/**
 * The Class Column.
 */
public class Column implements Comparable<Column> {

    /** The Constant FIRST_COLUMN_INDEX. */
    public static final int FIRST_COLUMN_INDEX = 1;

    /** The column index. */
    private int columnIndex = -1;

    /** The column name. */
    private String columnName;

    /** The header. */
    private Header header;

    /** The key. */
    private ColumnKey key;

    /**
     * Instantiates a new column.
     *
     * @param columnName
     *            the column name
     */
    public Column(String columnName) {
        setColumnName(columnName);
    }

    /**
     * Instantiates a new column.
     */
    public Column() {
        this(FIRST_COLUMN_INDEX);
    }

    /**
     * Instantiates a new column.
     *
     * @param column
     *            the column
     */
    public Column(Column column) {
        setColumnIndex(column.getColumnIndex());
    }

    /**
     * Instantiates a new column.
     *
     * @param columnIndex
     *            the column index
     */
    public Column(int columnIndex) {
        if (columnIndex <= 0) {
            throw new CsvException(
                    new GeneralError("Column index cannot be set at 0 or lower. Column indexes are 1-based"));
        }
        setColumnIndex(columnIndex);
    }

    /**
     * Column index to excel column.
     *
     * @param columnIndex
     *            the column index
     *
     * @return the string
     */
    private String columnIndexToExcelColumn(int columnIndex) {
        StringBuilder excelColumn = new StringBuilder();
        while (columnIndex % 26 > 0) {
            excelColumn.insert(0, (char) (columnIndex % 26 + 'A' - 1));
            columnIndex /= 26;
        }
        return excelColumn.toString();
    }

    /**
     * Sets the header.
     *
     * @param header
     *            the header
     *
     * @return the column
     */
    public Column setHeader(Header header) {
        this.header = header;
        if (this.header != null) {
            setColumnName(header.getName(this.columnIndex));
        }
        return this;
    }

    /**
     * Sets the column index.
     *
     * @param columnIndex
     *            the new column index
     */
    public void setColumnIndex(int columnIndex) {
        this.columnIndex = columnIndex;
        setKey(new ColumnIndexKey(this.columnIndex));
    }

    /**
     * Sets the column name.
     *
     * @param columnName
     *            the new column name
     */
    public void setColumnName(String columnName) {
        this.columnName = columnName.toLowerCase(Locale.getDefault());
        setKey(new ColumnNameKey(this.columnName));
    }

    /**
     * Sets the key.
     *
     * @param key
     *            the new key
     */
    public void setKey(ColumnKey key) {
        this.key = key;
    }

    /**
     * Gets the excel column.
     *
     * @return the excel column
     */
    public String getExcelColumn() {
        return columnIndexToExcelColumn(this.columnIndex);
    }

    /**
     * Gets the column index.
     *
     * @return the column index
     */
    public int getColumnIndex() {
        return this.columnIndex;
    }

    /**
     * Gets the column name.
     *
     * @return the column name
     */
    public String getColumnName() {
        return this.columnName;
    }

    /**
     * Next column.
     *
     * @return the column
     */
    public Column nextColumn() {
        return new Column(this.getColumnIndex() + 1).setHeader(header);
    }

    /**
     * Next line.
     *
     * @return the column
     */
    public Column nextLine() {
        return new Column().setHeader(header);
    }

    /**
     * Gets the column text.
     *
     * @return the column text
     */
    public String getColumnText() {
        return (columnIndex == -1 ? "" : " index " + columnIndex + " (" + getExcelColumn() + ")")
                + (columnName == null ? "" : " name \"" + columnName + "\"");
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Column)) {
            return false;
        }
        return this.key.equals(((Column) obj).key);
    }

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

    @Override
    public String toString() {
        return this.key.toString();
    }

    @Override
    public int compareTo(Column column) {
        return this.key.compareTo(column.key);
    }
}