package com.jscape.inet.terminal;

/**
 * Represents screen cell. Contains char value with attributes and boolean flag
 * which shows if this object has tabstop.
 * May be used for further screen rendering.
 * This class uses shared attributes represented by
 * <code>CellAttributes</code> class to reduce memory usage
 * (pattern "Flyweight" [Gamma94]).
 */
public class Cell {

    private char value = 0;
    private CellAttributes attributes;
    private boolean tabstop = false;

    //----------------------------------------------------------------------------

    /**
     * Creates <code>Cell</code> object giving value and attributes.
     *
     * @param value      char value of created <code>Cell</code> object.
     * @param attributes <code>Cell</code> object attributes.
     */
    public Cell(char value, CellAttributes attributes) {
        if (attributes == null) {
            throw new NullPointerException("Cell.constructor(): null passed");
        }

        this.value = value;
        this.attributes = attributes;
    }

    //----------------------------------------------------------------------------

    /**
     * Creates <code>Cell</code> object giving it's value.
     *
     * @param value char value of created <code>Cell</code> object.
     */
    public Cell(char value) {
        this(value, CellAttributes.getInstance());
    }

    //----------------------------------------------------------------------------

    /**
     * Creates <code>Cell</code> object having '\000' value
     * with default attributes.
     */
    public Cell() {
        this((char) 0);
    }

    //----------------------------------------------------------------------------

    /**
     * Copy constructor.
     *
     * @param cell <code>Cell</code> object to be copied.
     */
    public Cell(Cell cell) {
        if (cell == null) {
            throw new NullPointerException("Cell.constructor(): null passed");
        }

        this.value = cell.value;
        this.attributes = cell.attributes;
        this.tabstop = cell.tabstop;
    }

    //----------------------------------------------------------------------------

    /**
     * Resets value and attributes to default.
     */
    public void reset() {
        this.value = 0;
        this.attributes = CellAttributes.getInstance();
        this.tabstop = false;
    }

    //----------------------------------------------------------------------------

    /**
     * Returns current value of <code>Cell</code> object.
     *
     * @return char value of this object.
     */
    public char getValue() {
        return value;
    }

    //----------------------------------------------------------------------------

    /**
     * Sets value of <code>Cell</code> object.
     *
     * @param value new char value.
     */
    public void setValue(char value) {
        this.value = value;
    }

    //----------------------------------------------------------------------------

    /**
     * Returns current attributes of <code>Cell</code> object.
     *
     * @return <code>CellAttributes</code> object that represent current
     *         <code>Cell</code> object attributes.
     */
    public CellAttributes getAttributes() {
        return attributes;
    }

    //----------------------------------------------------------------------------

    /**
     * Sets current <code>Cell</code> object attributes.
     *
     * @param attributes <code>CellAttributes</code> object that must be used.
     */
    public void setAttributes(CellAttributes attributes) {
        if (attributes == null) {
            throw new NullPointerException("Cell.setAttributes(): null passed");
        }

        this.attributes = attributes;
    }

    //----------------------------------------------------------------------------

    /**
     * Checks if this <code>Cell</code> object has tabstop.
     *
     * @return true if if this <code>Cell</code> object has tabstop.
     */
    public boolean isTabstop() {
        return tabstop;
    }

    //----------------------------------------------------------------------------

    /**
     * Sets tabstop to this <code>Cell</code> object.
     *
     * @param tabstop true if this <code>Cell</code> object must have tabstop.
     */
    public void setTabstop(boolean tabstop) {
        this.tabstop = tabstop;
    }

}