// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 1997-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.demo.holiday;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Panel;

/**
 * Various graphical borders. The border itself is a Panel so that it can
 * contain other Components (i.e. it borders something). You use the
 * HolidayBorderPanel like any other Panel: you set the layout that you prefer and
 * add Components to it. Beware that a null layout does not obey the insets
 * of the panel so if you use null layouts, adjust your measurements to
 * handle the border by calling insets().
 *
 * @author  Andy Clark, Taligent Inc.
 * @version 1.0
 */
public class HolidayBorderPanel extends Panel {
    /**
     * For serialization
     */
    private static final long serialVersionUID = 4669213306492461159L;
    // Constants

    /** Solid border. */
    public final static int SOLID = 0;
    /** A raised border. */
    public final static int RAISED = 1;
    /** A lowered border. */
    public final static int LOWERED = 2;
    /** An etched in border. */
    public final static int IN = 3;
    /** An etched out border. */
    public final static int OUT = 4;

    /** Left alignment. */
    public final static int LEFT = 0;
    /** Center alignment. */
    public final static int CENTER = 1;
    /** Right alignment. */
    public final static int RIGHT = 2;

    /** Default style (IN). */
    public final static int DEFAULT_STYLE = IN;
    /** Default thickness (10). */
    public final static int DEFAULT_THICKNESS = 10;
    /** Default thickness for solid borders (4). */
    public final static int DEFAULT_SOLID_THICKNESS = 4;
    /** Default thickness for raised borders (2). */
    public final static int DEFAULT_RAISED_THICKNESS = 2;
    /** Default thickness for lowered borders (2). */
    public final static int DEFAULT_LOWERED_THICKNESS = 2;
    /** Default thickness for etched-in borders (10). */
    public final static int DEFAULT_IN_THICKNESS = 10;
    /** Default thickness for etched-out borders (10). */
    public final static int DEFAULT_OUT_THICKNESS = 10;
    /** Default gap between border and contained component (5). */
    public final static int DEFAULT_GAP = 5;
    /** Default color (black). Applies to SOLID and etched borders. */
    public final static Color DEFAULT_COLOR = Color.black;

    /** Default font (TimesRoman,PLAIN,14). Only applies to etched borders. */
    public final static Font DEFAULT_FONT = new Font("TimesRoman", Font.PLAIN, 14);
    /** Default alignment (LEFT). Only applies to etched borders. */
    public final static int DEFAULT_ALIGNMENT = LEFT;

    // Data
    private int style;
    private int thickness;
    private int gap;
    private Color color;

    private Font font;
    private String text;
    private int alignment;

    /**
     * Constructor. Makes default border.
     */
    public HolidayBorderPanel() {

        // initialize data
        style       = DEFAULT_STYLE;
        thickness   = DEFAULT_THICKNESS;
        gap         = DEFAULT_GAP;
        color       = DEFAULT_COLOR;

        text        = null;
        font        = DEFAULT_FONT;
        alignment   = DEFAULT_ALIGNMENT;

        }

    /**
     * Constructor. Makes an etched IN border with given text caption.
     *
     * @param text  Text caption
     */
    public HolidayBorderPanel(String text) {
        this();

        style = IN;
        this.text = text;
        }

    /**
     * Constructor. Makes SOLID border with color and thickness given.
     *
     * @param color     The color for the border.
     * @param thickness The thickness of the border.
     */
    public HolidayBorderPanel(Color color, int thickness) {
        this();

        style = SOLID;
        this.color = color;
        this.thickness = thickness;
        }

    /**
     * Constructor. Makes a border of the given style with the default
     * thickness for that style.
     *
     * @param style The style for this border.
     */
    public HolidayBorderPanel(int style) {
        this();

        // set thickness appropriate to this style
        switch (style) {
            case SOLID: thickness = DEFAULT_SOLID_THICKNESS; break;
            case RAISED: thickness = DEFAULT_RAISED_THICKNESS; break;
            case LOWERED: thickness = DEFAULT_LOWERED_THICKNESS; break;
            case IN: thickness = DEFAULT_IN_THICKNESS; break;
            case OUT: thickness = DEFAULT_OUT_THICKNESS; break;
            default:
                thickness = DEFAULT_THICKNESS;
            }

        this.style = style;
        }

    /**
     * Constructor. Makes border with given style and thickness.
     *
     * @param style     The style for this border.
     * @param thickness The thickness for this border.
     */
    public HolidayBorderPanel(int style, int thickness) {
        this();

        this.style = style;
        this.thickness = thickness;
        }

    /**
     * Returns the insets of this panel..
     */
    public Insets getInsets() {
        int adjustment = 0;

        // adjust for text string
        if (style == IN || style == OUT) {
            if (text != null && text.length() > 0) {
                try {
                    // set font and get info
                    int height = getGraphics().getFontMetrics(font).getHeight();
                    if (height > thickness)
                        adjustment = height - thickness;
                    }
                catch (Exception e) {
                    // nothing: just in case there is no graphics context
                    //   at the beginning.
                    System.out.print("");
                    }
                }
            }

        // return appropriate insets
        int dist = thickness + gap;
        return new Insets(dist + adjustment, dist, dist, dist);
        }

    /**
     * Sets the style of the border
     *
     * @param style The new style.
     */
    public HolidayBorderPanel setStyle(int style) {

        // set the style and re-layout the panel
        this.style = style;
        doLayout();
        repaint();

        return this;
        }

    /**
     * Gets the style of the border
     */
    public int getStyle() {

        return style;
        }

    /**
     * Sets the thickness of the border.
     *
     * @param thickness The new thickness
     */
    public HolidayBorderPanel setThickness(int thickness) {

        if (thickness > 0) {
            this.thickness = thickness;
            doLayout();
            repaint();
            }

        return this;
        }

    /**
     * Gets the thickness of the border.
     */
    public int getThickness() {

        return thickness;
        }

    /**
     * Sets the gap between the border and the contained Component.
     *
     * @param gap The new gap, in pixels.
     */
    public HolidayBorderPanel setGap(int gap) {

        if (gap > -1) {
            this.gap = gap;
            doLayout();
            repaint();
            }

        return this;
        }

    /**
     * Gets the gap between the border and the contained Component.
     */
    public int getGap() {

        return gap;
        }

    /**
     * Sets the current color for SOLID borders and the caption text
     * color for etched borders.
     *
     * @param color The new color.
     */
    public HolidayBorderPanel setColor(Color color) {

        this.color = color;
        if (style == SOLID || style == IN || style == OUT)
            repaint();

        return this;
        }

    /**
     * Gets the current color for SOLID borders and the caption
     * text color for etched borders.
     */
    public Color getColor() {

        return color;
        }

    /**
     * Sets the font. Only applies to etched borders.
     */
    public HolidayBorderPanel setTextFont(Font font) {

        // set font
        if (font != null) {
            this.font = font;
            if (style == IN || style == OUT) {
                doLayout();
                repaint();
                }
            }

        return this;
        }

    /**
     * Gets the font of the text. Only applies to etched borders.
     */
    public Font getTextFont() {

        return font;
        }

    /**
     * Sets the text. Only applies to etched borders.
     *
     * @param text  The new text.
     */
    public HolidayBorderPanel setText(String text) {

        this.text = text;
        if (style == IN || style == OUT) {
            doLayout();
            repaint();
            }

        return this;
        }

    /**
     * Gets the text. Only applies to etched borders.
     */
    public String getText() {

        return text;
        }

    /**
     * Sets the text alignment. Only applies to etched borders.
     *
     * @param alignment The new alignment.
     */
    public HolidayBorderPanel setAlignment(int alignment) {

        this.alignment = alignment;
        if (style == IN || style == OUT) {
            doLayout();
            repaint();
            }

        return this;
        }

    /**
     * Gets the text alignment.
     */
    public int getAlignment() {

        return alignment;
        }

    /**
     * Repaints the border.
     *
     * @param g The graphics context.
     */
    public void paint(Graphics g) {

        // get current dimensions
        Dimension size = getSize();
        int width = size.width;
        int height = size.height;

        // set colors
        Color light = getBackground().brighter().brighter().brighter();
        Color dark = getBackground().darker().darker().darker();

        // Draw border
        switch (style) {
            case RAISED:    // 3D Border (in or out)
            case LOWERED:
                Color topleft = null;
                Color bottomright = null;

                // set colors
                if (style == RAISED) {
                    topleft = light;
                    bottomright = dark;
                    }
                else {
                    topleft = dark;
                    bottomright = light;
                    }

                // draw border
                g.setColor(topleft);
                for (int i = 0; i < thickness; i++) {
                    g.drawLine(i, i, width - i - 2, i);
                    g.drawLine(i, i + 1, i, height - i - 1);
                    }
                g.setColor(bottomright);
                for (int i = 0; i < thickness; i++) {
                    g.drawLine(i + 1, height - i - 1, width - i - 1, height - i - 1);
                    g.drawLine(width - i - 1, i, width - i - 1, height - i - 2);
                    }
                break;

            case IN:    // Etched Border (in or out)
            case OUT:
                int adjust1 = 0;
                int adjust2 = 0;

                // set font and get info
                Font oldfont = g.getFont();
                g.setFont(font);
                FontMetrics fm = g.getFontMetrics();
                int ascent = fm.getAscent();

                // set adjustment
                if (style == IN)
                    adjust1 = 1;
                else
                    adjust2 = 1;

                // Calculate adjustment for text
                int adjustment = 0;
                if (text != null && text.length() > 0) {
                    if (ascent > thickness)
                        adjustment = (ascent - thickness) / 2;
                    }

                // The adjustment is there so that we always draw the
                // light rectangle first. Otherwise, your eye picks up
                // the discrepancy where the light rect. passes over
                // the darker rect.
                int x = thickness / 2;
                int y = thickness / 2 + adjustment;
                int w = width - thickness - 1;
                int h = height - thickness - 1 - adjustment;

                // draw rectangles
                g.setColor(light);
                g.drawRect(x + adjust1, y + adjust1, w, h);
                g.setColor(dark);
                g.drawRect(x + adjust2, y + adjust2, w, h);

                // draw text, if applicable
                if (text != null && text.length() > 0) {
                    // calculate drawing area
                    int fontheight = fm.getHeight();
                    int strwidth = fm.stringWidth(text);

                    int textwidth = width - 2 * (thickness + 5);
                    if (strwidth > textwidth)
                        strwidth = textwidth;

                    // calculate offset for alignment
                    int offset;
                    switch (alignment) {
                        case CENTER:
                            offset = (width - strwidth) / 2;
                            break;
                        case RIGHT:
                            offset = width - strwidth - thickness - 5;
                            break;
                        case LEFT:
                        default: // assume left alignment if invalid
                            offset = thickness + 5;
                            break;
                        }

                    // clear drawing area and set clipping region
                    g.clearRect(offset - 5, 0, strwidth  + 10, fontheight);
                    g.clipRect(offset, 0, strwidth, fontheight);

                    // draw text
                    g.setColor(color);
                    g.drawString(text, offset, ascent);

                    // restore old clipping area
                    g.clipRect(0, 0, width, height);
                    }

                g.setFont(oldfont);
                break;

            case SOLID:
            default: // assume SOLID
                g.setColor(color);
                for (int i = 0; i < thickness; i++)
                    g.drawRect(i, i, width - 2 * i - 1, height - 2 * i - 1);
            }

        }

    /**
     * Returns the settings of this HolidayBorderPanel instance as a string.
     */
    public String toString() {
        StringBuffer str = new StringBuffer("HolidayBorderPanel[");

        // style
        str.append("style=");
        switch (style) {
            case SOLID: str.append("SOLID"); break;
            case RAISED: str.append("RAISED"); break;
            case LOWERED: str.append("LOWERED"); break;
            case IN: str.append("IN"); break;
            case OUT: str.append("OUT"); break;
            default: str.append("unknown");
            }
        str.append(",");

        // thickness
        str.append("thickness=");
        str.append(thickness);
        str.append(",");

        // gap
        str.append("gap=");
        str.append(gap);
        str.append(",");

        // color
        str.append(color);
        str.append(",");

        // font
        str.append(font);
        str.append(",");

        // text
        str.append("text=");
        str.append(text);
        str.append(",");

        // alignment
        str.append("alignment=");
        switch (alignment) {
            case LEFT: str.append("LEFT"); break;
            case CENTER: str.append("CENTER"); break;
            case RIGHT: str.append("RIGHT"); break;
            default: str.append("unknown");
            }

        str.append("]");

        return str.toString();
        }

    }

