/*
 * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package javax.swing.text;

import java.awt.Color;
import java.awt.Component;
import java.awt.Toolkit;
import javax.swing.Icon;

/**
 * <p>
 * A collection of <em>well known</em> or common attribute keys
 * and methods to apply to an AttributeSet or MutableAttributeSet
 * to get/set the properties in a typesafe manner.
 * <p>
 * The paragraph attributes form the definition of a paragraph to be rendered.
 * All sizes are specified in points (such as found in postscript), a
 * device independent measure.
 * </p>
 * <p align=center><img src="doc-files/paragraph.gif"
 * alt="Diagram shows SpaceAbove, FirstLineIndent, LeftIndent, RightIndent,
 *      and SpaceBelow a paragraph."></p>
 * <p>
 *
 * @author  Timothy Prinzing
 */
public class StyleConstants {

    /**
     * Name of elements used to represent components.
     */
    public static final String ComponentElementName = "component";

    /**
     * Name of elements used to represent icons.
     */
    public static final String IconElementName = "icon";

    /**
     * Attribute name used to name the collection of
     * attributes.
     */
    public static final Object NameAttribute = new StyleConstants("name");

    /**
     * Attribute name used to identifiy the resolving parent
     * set of attributes, if one is defined.
     */
    public static final Object ResolveAttribute = new StyleConstants("resolver");

    /**
     * Attribute used to identify the model for embedded
     * objects that have a model view separation.
     */
    public static final Object ModelAttribute = new StyleConstants("model");

    /**
     * Returns the string representation.
     *
     * @return the string
     */
    public String toString() {
        return representation;
    }

    // ---- character constants -----------------------------------

    /**
     * Bidirectional level of a character as assigned by the Unicode bidi
     * algorithm.
     */
    public static final Object BidiLevel = new CharacterConstants("bidiLevel");

    /**
     * Name of the font family.
     */
    public static final Object FontFamily = new FontConstants("family");

    /**
     * Name of the font family.
     *
     * @since 1.5
     */
    public static final Object Family = FontFamily;

    /**
     * Name of the font size.
     */
    public static final Object FontSize = new FontConstants("size");

    /**
     * Name of the font size.
     *
     * @since 1.5
     */
    public static final Object Size = FontSize;

    /**
     * Name of the bold attribute.
     */
    public static final Object Bold = new FontConstants("bold");

    /**
     * Name of the italic attribute.
     */
    public static final Object Italic = new FontConstants("italic");

    /**
     * Name of the underline attribute.
     */
    public static final Object Underline = new CharacterConstants("underline");

    /**
     * Name of the Strikethrough attribute.
     */
    public static final Object StrikeThrough = new CharacterConstants("strikethrough");

    /**
     * Name of the Superscript attribute.
     */
    public static final Object Superscript = new CharacterConstants("superscript");

    /**
     * Name of the Subscript attribute.
     */
    public static final Object Subscript = new CharacterConstants("subscript");

    /**
     * Name of the foreground color attribute.
     */
    public static final Object Foreground = new ColorConstants("foreground");

    /**
     * Name of the background color attribute.
     */
    public static final Object Background = new ColorConstants("background");

    /**
     * Name of the component attribute.
     */
    public static final Object ComponentAttribute = new CharacterConstants("component");

    /**
     * Name of the icon attribute.
     */
    public static final Object IconAttribute = new CharacterConstants("icon");

    /**
     * Name of the input method composed text attribute. The value of
     * this attribute is an instance of AttributedString which represents
     * the composed text.
     */
    public static final Object ComposedTextAttribute = new StyleConstants("composed text");

    /**
     * The amount of space to indent the first
     * line of the paragraph.  This value may be negative
     * to offset in the reverse direction.  The type
     * is Float and specifies the size of the space
     * in points.
     */
    public static final Object FirstLineIndent = new ParagraphConstants("FirstLineIndent");

    /**
     * The amount to indent the left side
     * of the paragraph.
     * Type is float and specifies the size in points.
     */
    public static final Object LeftIndent = new ParagraphConstants("LeftIndent");

    /**
     * The amount to indent the right side
     * of the paragraph.
     * Type is float and specifies the size in points.
     */
    public static final Object RightIndent = new ParagraphConstants("RightIndent");

    /**
     * The amount of space between lines
     * of the paragraph.
     * Type is float and specifies the size as a factor of the line height
     */
    public static final Object LineSpacing = new ParagraphConstants("LineSpacing");

    /**
     * The amount of space above the paragraph.
     * Type is float and specifies the size in points.
     */
    public static final Object SpaceAbove = new ParagraphConstants("SpaceAbove");

    /**
     * The amount of space below the paragraph.
     * Type is float and specifies the size in points.
     */
    public static final Object SpaceBelow = new ParagraphConstants("SpaceBelow");

    /**
     * Alignment for the paragraph.  The type is
     * Integer.  Valid values are:
     * <ul>
     * <li>ALIGN_LEFT
     * <li>ALIGN_RIGHT
     * <li>ALIGN_CENTER
     * <li>ALIGN_JUSTIFED
     * </ul>
     *
     */
    public static final Object Alignment = new ParagraphConstants("Alignment");

    /**
     * TabSet for the paragraph, type is a TabSet containing
     * TabStops.
     */
    public static final Object TabSet = new ParagraphConstants("TabSet");

    /**
     * Orientation for a paragraph.
     */
    public static final Object Orientation = new ParagraphConstants("Orientation");
    /**
     * A possible value for paragraph alignment.  This
     * specifies that the text is aligned to the left
     * indent and extra whitespace should be placed on
     * the right.
     */
    public static final int ALIGN_LEFT = 0;

    /**
     * A possible value for paragraph alignment.  This
     * specifies that the text is aligned to the center
     * and extra whitespace should be placed equally on
     * the left and right.
     */
    public static final int ALIGN_CENTER = 1;

    /**
     * A possible value for paragraph alignment.  This
     * specifies that the text is aligned to the right
     * indent and extra whitespace should be placed on
     * the left.
     */
    public static final int ALIGN_RIGHT = 2;

    /**
     * A possible value for paragraph alignment.  This
     * specifies that extra whitespace should be spread
     * out through the rows of the paragraph with the
     * text lined up with the left and right indent
     * except on the last line which should be aligned
     * to the left.
     */
    public static final int ALIGN_JUSTIFIED = 3;

    // --- character attribute accessors ---------------------------

    /**
     * Gets the BidiLevel setting.
     *
     * @param a the attribute set
     * @return the value
     */
    public static int getBidiLevel(AttributeSet a) {
        Integer o = (Integer) a.getAttribute(BidiLevel);
        if (o != null) {
            return o.intValue();
        }
        return 0;  // Level 0 is base level (non-embedded) left-to-right
    }

    /**
     * Sets the BidiLevel.
     *
     * @param a the attribute set
     * @param o the bidi level value
     */
    public static void setBidiLevel(MutableAttributeSet a, int o) {
        a.addAttribute(BidiLevel, new Integer(o));
    }

    /**
     * Gets the component setting from the attribute list.
     *
     * @param a the attribute set
     * @return the component, null if none
     */
    public static Component getComponent(AttributeSet a) {
        return (Component) a.getAttribute(ComponentAttribute);
    }

    /**
     * Sets the component attribute.
     *
     * @param a the attribute set
     * @param c the component
     */
    public static void setComponent(MutableAttributeSet a, Component c) {
        a.addAttribute(AbstractDocument.ElementNameAttribute, ComponentElementName);
        a.addAttribute(ComponentAttribute, c);
    }

    /**
     * Gets the icon setting from the attribute list.
     *
     * @param a the attribute set
     * @return the icon, null if none
     */
    public static Icon getIcon(AttributeSet a) {
        return (Icon) a.getAttribute(IconAttribute);
    }

    /**
     * Sets the icon attribute.
     *
     * @param a the attribute set
     * @param c the icon
     */
    public static void setIcon(MutableAttributeSet a, Icon c) {
        a.addAttribute(AbstractDocument.ElementNameAttribute, IconElementName);
        a.addAttribute(IconAttribute, c);
    }

    /**
     * Gets the font family setting from the attribute list.
     *
     * @param a the attribute set
     * @return the font family, "Monospaced" as the default
     */
    public static String getFontFamily(AttributeSet a) {
        String family = (String) a.getAttribute(FontFamily);
        if (family == null) {
            family = "Monospaced";
        }
        return family;
    }

    /**
     * Sets the font attribute.
     *
     * @param a the attribute set
     * @param fam the font
     */
    public static void setFontFamily(MutableAttributeSet a, String fam) {
        a.addAttribute(FontFamily, fam);
    }

    /**
     * Gets the font size setting from the attribute list.
     *
     * @param a the attribute set
     * @return the font size, 12 as the default
     */
    public static int getFontSize(AttributeSet a) {
        Integer size = (Integer) a.getAttribute(FontSize);
        if (size != null) {
            return size.intValue();
        }
        return 12;
    }

    /**
     * Sets the font size attribute.
     *
     * @param a the attribute set
     * @param s the font size
     */
    public static void setFontSize(MutableAttributeSet a, int s) {
        a.addAttribute(FontSize, new Integer(s));
    }

    /**
     * Checks whether the bold attribute is set.
     *
     * @param a the attribute set
     * @return true if set else false
     */
    public static boolean isBold(AttributeSet a) {
        Boolean bold = (Boolean) a.getAttribute(Bold);
        if (bold != null) {
            return bold.booleanValue();
        }
        return false;
    }

    /**
     * Sets the bold attribute.
     *
     * @param a the attribute set
     * @param b specifies true/false for setting the attribute
     */
    public static void setBold(MutableAttributeSet a, boolean b) {
        a.addAttribute(Bold, Boolean.valueOf(b));
    }

    /**
     * Checks whether the italic attribute is set.
     *
     * @param a the attribute set
     * @return true if set else false
     */
    public static boolean isItalic(AttributeSet a) {
        Boolean italic = (Boolean) a.getAttribute(Italic);
        if (italic != null) {
            return italic.booleanValue();
        }
        return false;
    }

    /**
     * Sets the italic attribute.
     *
     * @param a the attribute set
     * @param b specifies true/false for setting the attribute
     */
    public static void setItalic(MutableAttributeSet a, boolean b) {
        a.addAttribute(Italic, Boolean.valueOf(b));
    }

    /**
     * Checks whether the underline attribute is set.
     *
     * @param a the attribute set
     * @return true if set else false
     */
    public static boolean isUnderline(AttributeSet a) {
        Boolean underline = (Boolean) a.getAttribute(Underline);
        if (underline != null) {
            return underline.booleanValue();
        }
        return false;
    }

    /**
     * Checks whether the strikethrough attribute is set.
     *
     * @param a the attribute set
     * @return true if set else false
     */
    public static boolean isStrikeThrough(AttributeSet a) {
        Boolean strike = (Boolean) a.getAttribute(StrikeThrough);
        if (strike != null) {
            return strike.booleanValue();
        }
        return false;
    }


    /**
     * Checks whether the superscript attribute is set.
     *
     * @param a the attribute set
     * @return true if set else false
     */
    public static boolean isSuperscript(AttributeSet a) {
        Boolean superscript = (Boolean) a.getAttribute(Superscript);
        if (superscript != null) {
            return superscript.booleanValue();
        }
        return false;
    }


    /**
     * Checks whether the subscript attribute is set.
     *
     * @param a the attribute set
     * @return true if set else false
     */
    public static boolean isSubscript(AttributeSet a) {
        Boolean subscript = (Boolean) a.getAttribute(Subscript);
        if (subscript != null) {
            return subscript.booleanValue();
        }
        return false;
    }


    /**
     * Sets the underline attribute.
     *
     * @param a the attribute set
     * @param b specifies true/false for setting the attribute
     */
    public static void setUnderline(MutableAttributeSet a, boolean b) {
        a.addAttribute(Underline, Boolean.valueOf(b));
    }

    /**
     * Sets the strikethrough attribute.
     *
     * @param a the attribute set
     * @param b specifies true/false for setting the attribute
     */
    public static void setStrikeThrough(MutableAttributeSet a, boolean b) {
        a.addAttribute(StrikeThrough, Boolean.valueOf(b));
    }

    /**
     * Sets the superscript attribute.
     *
     * @param a the attribute set
     * @param b specifies true/false for setting the attribute
     */
    public static void setSuperscript(MutableAttributeSet a, boolean b) {
        a.addAttribute(Superscript, Boolean.valueOf(b));
    }

    /**
     * Sets the subscript attribute.
     *
     * @param a the attribute set
     * @param b specifies true/false for setting the attribute
     */
    public static void setSubscript(MutableAttributeSet a, boolean b) {
        a.addAttribute(Subscript, Boolean.valueOf(b));
    }


    /**
     * Gets the foreground color setting from the attribute list.
     *
     * @param a the attribute set
     * @return the color, Color.black as the default
     */
    public static Color getForeground(AttributeSet a) {
        Color fg = (Color) a.getAttribute(Foreground);
        if (fg == null) {
            fg = Color.black;
        }
        return fg;
    }

    /**
     * Sets the foreground color.
     *
     * @param a the attribute set
     * @param fg the color
     */
    public static void setForeground(MutableAttributeSet a, Color fg) {
        a.addAttribute(Foreground, fg);
    }

    /**
     * Gets the background color setting from the attribute list.
     *
     * @param a the attribute set
     * @return the color, Color.black as the default
     */
    public static Color getBackground(AttributeSet a) {
        Color fg = (Color) a.getAttribute(Background);
        if (fg == null) {
            fg = Color.black;
        }
        return fg;
    }

    /**
     * Sets the background color.
     *
     * @param a the attribute set
     * @param fg the color
     */
    public static void setBackground(MutableAttributeSet a, Color fg) {
        a.addAttribute(Background, fg);
    }


    // --- paragraph attribute accessors ----------------------------

    /**
     * Gets the first line indent setting.
     *
     * @param a the attribute set
     * @return the value, 0 if not set
     */
    public static float getFirstLineIndent(AttributeSet a) {
        Float indent = (Float) a.getAttribute(FirstLineIndent);
        if (indent != null) {
            return indent.floatValue();
        }
        return 0;
    }

    /**
     * Sets the first line indent.
     *
     * @param a the attribute set
     * @param i the value
     */
    public static void setFirstLineIndent(MutableAttributeSet a, float i) {
        a.addAttribute(FirstLineIndent, new Float(i));
    }

    /**
     * Gets the right indent setting.
     *
     * @param a the attribute set
     * @return the value, 0 if not set
     */
    public static float getRightIndent(AttributeSet a) {
        Float indent = (Float) a.getAttribute(RightIndent);
        if (indent != null) {
            return indent.floatValue();
        }
        return 0;
    }

    /**
     * Sets right indent.
     *
     * @param a the attribute set
     * @param i the value
     */
    public static void setRightIndent(MutableAttributeSet a, float i) {
        a.addAttribute(RightIndent, new Float(i));
    }

    /**
     * Gets the left indent setting.
     *
     * @param a the attribute set
     * @return the value, 0 if not set
     */
    public static float getLeftIndent(AttributeSet a) {
        Float indent = (Float) a.getAttribute(LeftIndent);
        if (indent != null) {
            return indent.floatValue();
        }
        return 0;
    }

    /**
     * Sets left indent.
     *
     * @param a the attribute set
     * @param i the value
     */
    public static void setLeftIndent(MutableAttributeSet a, float i) {
        a.addAttribute(LeftIndent, new Float(i));
    }

    /**
     * Gets the line spacing setting.
     *
     * @param a the attribute set
     * @return the value, 0 if not set
     */
    public static float getLineSpacing(AttributeSet a) {
        Float space = (Float) a.getAttribute(LineSpacing);
        if (space != null) {
            return space.floatValue();
        }
        return 0;
    }

    /**
     * Sets line spacing.
     *
     * @param a the attribute set
     * @param i the value
     */
    public static void setLineSpacing(MutableAttributeSet a, float i) {
        a.addAttribute(LineSpacing, new Float(i));
    }

    /**
     * Gets the space above setting.
     *
     * @param a the attribute set
     * @return the value, 0 if not set
     */
    public static float getSpaceAbove(AttributeSet a) {
        Float space = (Float) a.getAttribute(SpaceAbove);
        if (space != null) {
            return space.floatValue();
        }
        return 0;
    }

    /**
     * Sets space above.
     *
     * @param a the attribute set
     * @param i the value
     */
    public static void setSpaceAbove(MutableAttributeSet a, float i) {
        a.addAttribute(SpaceAbove, new Float(i));
    }

    /**
     * Gets the space below setting.
     *
     * @param a the attribute set
     * @return the value, 0 if not set
     */
    public static float getSpaceBelow(AttributeSet a) {
        Float space = (Float) a.getAttribute(SpaceBelow);
        if (space != null) {
            return space.floatValue();
        }
        return 0;
    }

    /**
     * Sets space below.
     *
     * @param a the attribute set
     * @param i the value
     */
    public static void setSpaceBelow(MutableAttributeSet a, float i) {
        a.addAttribute(SpaceBelow, new Float(i));
    }

    /**
     * Gets the alignment setting.
     *
     * @param a the attribute set
     * @return the value <code>StyleConstants.ALIGN_LEFT</code> if not set
     */
    public static int getAlignment(AttributeSet a) {
        Integer align = (Integer) a.getAttribute(Alignment);
        if (align != null) {
            return align.intValue();
        }
        return ALIGN_LEFT;
    }

    /**
     * Sets alignment.
     *
     * @param a the attribute set
     * @param align the alignment value
     */
    public static void setAlignment(MutableAttributeSet a, int align) {
        a.addAttribute(Alignment, new Integer(align));
    }

    /**
     * Gets the TabSet.
     *
     * @param a the attribute set
     * @return the <code>TabSet</code>
     */
    public static TabSet getTabSet(AttributeSet a) {
        TabSet tabs = (TabSet)a.getAttribute(TabSet);
        // PENDING: should this return a default?
        return tabs;
    }

    /**
     * Sets the TabSet.
     *
     * @param a the attribute set.
     * @param tabs the TabSet
     */
    public static void setTabSet(MutableAttributeSet a, TabSet tabs) {
        a.addAttribute(TabSet, tabs);
    }

    // --- privates ---------------------------------------------

    static Object[] keys = {
        NameAttribute, ResolveAttribute, BidiLevel,
        FontFamily, FontSize, Bold, Italic, Underline,
        StrikeThrough, Superscript, Subscript, Foreground,
        Background, ComponentAttribute, IconAttribute,
        FirstLineIndent, LeftIndent, RightIndent, LineSpacing,
        SpaceAbove, SpaceBelow, Alignment, TabSet, Orientation,
        ModelAttribute, ComposedTextAttribute
    };

    StyleConstants(String representation) {
        this.representation = representation;
    }

    private String representation;

    /**
     * This is a typesafe enumeration of the <em>well-known</em>
     * attributes that contribute to a paragraph style.  These are
     * aliased by the outer class for general presentation.
     */
    public static class ParagraphConstants extends StyleConstants
        implements AttributeSet.ParagraphAttribute {

        private ParagraphConstants(String representation) {
            super(representation);
        }
    }

    /**
     * This is a typesafe enumeration of the <em>well-known</em>
     * attributes that contribute to a character style.  These are
     * aliased by the outer class for general presentation.
     */
    public static class CharacterConstants extends StyleConstants
        implements AttributeSet.CharacterAttribute {

        private CharacterConstants(String representation) {
            super(representation);
        }
    }

    /**
     * This is a typesafe enumeration of the <em>well-known</em>
     * attributes that contribute to a color.  These are aliased
     * by the outer class for general presentation.
     */
    public static class ColorConstants extends StyleConstants
        implements AttributeSet.ColorAttribute,  AttributeSet.CharacterAttribute {

        private ColorConstants(String representation) {
            super(representation);
        }
    }

    /**
     * This is a typesafe enumeration of the <em>well-known</em>
     * attributes that contribute to a font.  These are aliased
     * by the outer class for general presentation.
     */
    public static class FontConstants extends StyleConstants
        implements AttributeSet.FontAttribute, AttributeSet.CharacterAttribute {

        private FontConstants(String representation) {
            super(representation);
        }
    }


}
