package CH.ifa.draw.util;

import java.awt.Font;


/**
 * A class that extends Font to add underlines to a font.
 */
public class ExtendedFont extends Font {
    /**
     * Specification of how prominent the underline will be.
     */
    public static final int UNDERLINED = Font.ITALIC * 2;
    /**
     * Indicates whether the font is underlined. Possible values:<br>
     * <code>0</code> for not underlined or<br>
     * <code>UNDERLINED</code> as bitmask
     */
    private final int _underlined;

    /**
     * Constructs a new ExtendedFont in one of three font styles
     * in the specified size with a custom name.
     *
     * @param name the <code>name</code> of the font
     * @param style an integer bitmask that can have values of <code>PLAIN</code>, <code>BOLD</code>
     *              or <code>ITALIC</code>
     * @param size point size of the font
     */
    public ExtendedFont(String name, int style, int size) {
        super(name, style & ~UNDERLINED, size);
        _underlined = style & UNDERLINED;
    }

    @Override
    public int getStyle() {
        return super.getStyle() | _underlined;
    }

    @Override
    public boolean isPlain() {
        return super.isPlain() && _underlined == 0;
    }

    /**
     * Checks whether the font is underlined.
     *
     * @return <code>true</code> if font is underlined
     */
    public boolean isUnderlined() {
        return _underlined != 0;
    }

    /**
     * Compares this <code>ExtendedFont</code> object to the specified
     * <code>Object</code>.
     * Two <code>ExtendedFont</code> instances are equal only if they are
     * equal like defined in {@link Font#equals Font.equals} <i>and</i>
     * share the same value for the <code>underlined</code> property.
     * When compared to a <code>Font</code> object that is not an
     * <code>ExtendedFont</code>, the value of the <code>underlined</code>
     * property is ignored in the comparison.
     *
     * @param that the <code>Object</code> to compare.
     * @return <code>true</code> if the argument is a <code>Font</code>
     * object describing the same font as this object and (in case of
     * <code>ExtendedFont</code> objects) has the same
     * <code>underlined</code> property.
     **/
    @Override
    public boolean equals(Object that) {
        if (super.equals(that)) {
            if (that instanceof ExtendedFont) {
                return ((ExtendedFont) that)._underlined == _underlined;
            }


            // At this point the original author wanted to check that
            // <code>underlined == 0</code>, but this condition would
            // violate the symmetry of the equivalence relation (other
            // <code>Font</code> implementations would not know about this
            // difference). So we have to return <code>true</code>
            // regardless of the <code>underlined</code> attribute.
            return true;
        }
        return false;
    }

    /**
     * Returns a hashcode for this <code>ExtendedFont</code>.
     * @return a hashcode value for this <code>ExtendedFont</code>.
     **/
    @Override
    public int hashCode() {
        // We must use the hash code from the superclass, otherwise we
        // would violate the general equals/hashCode contract (see comment
        // within the equals method for arguments).
        return super.hashCode();
    }
}