/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the
 * License at http://www.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.bebop;

import com.arsdigita.bebop.util.Color;
import com.arsdigita.bebop.util.Size;

/**
 * Abstract class that contain the CSS-like
 * Block Stylable attributes.
 *
 * @author Jim Parsons 
 * @author Justin Ross 
 * @version $Id: //core-platform/dev/src/com/arsdigita/bebop/BlockStylable.java#11 $
 * */
abstract public class BlockStylable extends TextStylable
{

    public static final String versionId = "$Id: //core-platform/dev/src/com/arsdigita/bebop/BlockStylable.java#11 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";

    /**
     * Left-align a component.
     */
    public static final int LEFT = 1 << 0;

    /**
     * Center a component.
     */
    public static final int CENTER = 1 << 1;

    /**
     * Right-align a component.
     */
    public static final int RIGHT = 1 << 2;

    /**
     * Align the top of a component.
     */
    public static final int TOP = 1 << 3;

    /**
     * Align the middle of a component.
     */
    public static final int MIDDLE = 1 << 4;

    /**
     * Align the bottom of a component.
     */
    public static final int BOTTOM = 1 << 5;

    /**
     * Lay out a component across the full width of the panel.
     */
    public static final int FULL_WIDTH = 1 << 6;

    /**
     * Insert the child component assuming it is printed in a table with the
     * same number of columns.
     */
    public static final int INSERT = 1 << 7;

    /**
     *      Constant for specifying ABSMIDDLE alignment of this image input.
     *      See the <a href="http://www.w3.org/TR/html4/present/graphics.html#alignment">W3C HTML 4.01
     *      Specification</a>
     *      for a description of this attribute.
     */
    public static final int ABSMIDDLE = 1 << 8;

    /**
     *      Constant for specifying ABSBOTTOM alignment of this image input.
     *      See the <a href="http://www.w3.org/TR/html4/present/graphics.html#alignment">W3C HTML 4.01
     *      Specification</a>
     *      for a description of this attribute.
     */
    public static final int ABSBOTTOM = 1 << 9;

    /**
     *      Constant for specifying TEXTOP alignment of this image input.
     *      (See the <a href="http://www.w3.org/TR/html4/present/graphics.html#alignment">
     *      W3C HTML 4.01 Specification</a> for a description of this attribute.)
     */
    public static final int TEXTTOP = 1 << 10;

    /**
     *      Constant for specifying BASELINE alignment of this image input.
     *      (See the <a href="http://www.w3.org/TR/html4/present/graphics.html#alignment">
     *      W3C HTML 4.01 Specification</a> for a description of this attribute.)
     */
    public static final int BASELINE = 1 << 11;



    /*
     * This is a helper class for generating attribute names for style
     * attributes in setBorder, setPadding, and setMargin.
     */
    private String getSideStub(int sideEnum) {
        switch (sideEnum) {
        case TOP:
            return "top";
        case BOTTOM:
            return "bottom";
        case LEFT:
            return "left";
        case RIGHT:
            return "right";
            //This fallthrough needs a better guard clause, like
            //catching an IllegalArgumentException
        default:
            return "";
        }
    }

    /**
     * Sets this component's padding.
     *
     * @param size the size for this component's padding
     * @see BlockStylable#setPadding(Size, int)
     * @pre size != null
     */
    public void setPadding(Size size) {
        setPadding(size, TOP);
        setPadding(size, BOTTOM);
        setPadding(size, LEFT);
        setPadding(size, RIGHT);
    }

    /**
     * Sets the padding of one of this component's sides.
     *
     * @param sideEnum the side to set
     * @param size the size to set the padding to
     * @see BlockStylable#setPadding(Size)
     * @pre size != null
     */
    public void setPadding(Size size, int sideEnum) {
        setAttribute(getSideStub(sideEnum) + "Padding", size.toString());
    }

    /**
     * Sets this component's border.
     *
     * @param size the size to set for this component's border
     * @see BlockStylable#setBorder(Size, int)
     * @pre size != null
     */
    public void setBorder(Size size) {
        setBorder(size, TOP);
        setBorder(size, BOTTOM);
        setBorder(size, LEFT);
        setBorder(size, RIGHT);
    }

    /**
     * Sets the border size for one side of this component.
     *
     * @param size the size to set for the border
     * @param sideEnum the side to set
     * @see BlockStylable#setBorder(Size)
     * @pre size != null
     */
    public void setBorder(Size size, int sideEnum) {
        setAttribute(getSideStub(sideEnum) + "Border", size.toString());
    }

    /**
     * Sets the color of this component's border.
     *
     * @param borderColor the color for the border
     * @pre borderColor != null
     */
    public void setBorderColor(Color borderColor) {
        setAttribute("borderColor", borderColor.toString());
    }

    /**
     * Sets this component's margin.
     *
     * @param size the size to set this component's margin to
     * @see BlockStylable#setMargin(Size, int)
     * @pre size != null
     */
    public void setMargin(Size size) {
        setMargin(size, TOP);
        setMargin(size, BOTTOM);
        setMargin(size, LEFT);
        setMargin(size, RIGHT);
    }

    /**
     * Sets the margin of one of this component's sides.
     *
     * @param size the size to set the margin to
     * @param sideEnum the side to set
     * @see BlockStylable#setMargin(Size)
     * @pre size != null
     */
    public void setMargin(Size size, int sideEnum) {
        setAttribute(getSideStub(sideEnum) + "Margin", size.toString());
    }

    /**
     * Sets the horizontal alignment of this component.
     *
     * @param alignmentEnum the horizontal alignment (LEFT, RIGHT, or
     * CENTER)
     */
    public void setHorizontalAlignment(int alignmentEnum) {
        String alignmentLiteral = "";

        switch (alignmentEnum) {
        case LEFT:
            alignmentLiteral = "left";
            break;
        case RIGHT:
            alignmentLiteral = "right";
            break;
        case CENTER:
            alignmentLiteral = "center";
            break;
        default:
            throw new IllegalArgumentException("Undefined Arg in setHorizontalAlignment");
        }

        setAttribute("horizontalAlignment", alignmentLiteral);
    }

    /**
     * Sets the vertical alignment of this component.
     *
     * @param alignmentEnum the vertical alignment (TOP, BOTTOM, or
     * MIDDLE)
     */
    public void setVerticalAlignment(int alignmentEnum) {
        String alignmentLiteral = "";

        switch (alignmentEnum) {
        case TOP:
            alignmentLiteral = "top";
            break;
        case BOTTOM:
            alignmentLiteral = "bottom";
            break;
        case CENTER:
            alignmentLiteral = "center";
            break;
        default:
            throw new IllegalArgumentException("Undefined Arg in setVerticalAlignment");
        }

        setAttribute("verticalAlignment", alignmentLiteral);
    }

}
