package com.srbenoit.font;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;

/**
 * A frame that displays a tabbed pane with one tab per bundled font. Within each tab are the
 * font's glyphs in various sizes.
 */
public class BundledFontViewer extends JFrame {

    /** version number for serialization */
    private static final long serialVersionUID = 4624550107266295327L;

    /** the font sizes to view */
    private static final int[] SIZES = { 10, 12, 14, 18, 24 };

    /**
     * Constructs a new <code>BundledFontViewer</code>.
     */
    public BundledFontViewer() {

        super("Bundled Fonts Viewer");

        setBackground(new Color(220, 220, 255));
    }

    /**
     * Generates the user interface, which consists of a tabbed pane where each tab is a different
     * font, and within the tab is a set of text boxes showing the font's glyphs in various sizes.
     *
     * @param  mgr  the font manager used to obtain the fonts
     */
    public void createUI(final BundledFontManager mgr) {

        JTabbedPane tabs;
        String[] names;
        JPanel[] panes;
        int inx;

        names = mgr.fontNames();

        tabs = new JTabbedPane(SwingConstants.BOTTOM);
        tabs.setOpaque(true);

        tabs.setBackground(new Color(220, 220, 255));
        tabs.setPreferredSize(new Dimension(740, 500));
        tabs.setFont(new Font("Dialog", Font.PLAIN, 10));
        setContentPane(tabs);

        panes = new JPanel[names.length];

        for (inx = 0; inx < panes.length; inx++) {
            panes[inx] = new JPanel(); // NOPMD SRB
            tabs.addTab(names[inx], panes[inx]);
            populateTab(mgr, names[inx], panes[inx]);
        }
    }

    /**
     * Generates the contents of a font tab, including text boxes that use the font at varying
     * sizes.
     *
     * @param  mgr   the font manager from which to retrieve fonts
     * @param  name  the name of the font
     * @param  pane  the panel in which to install the text boxes
     */
    private void populateTab(final BundledFontManager mgr, final String name, final JPanel pane) {

        JTextArea area;
        Font fnt;
        int inx;
        int num;
        StringBuilder buf;
        int cnt;
        char chr;

        pane.setLayout(new GridLayout(SIZES.length, 1, 5, 5));
        pane.setBackground(new Color(220, 220, 220));
        pane.setBorder(BorderFactory.createEtchedBorder());

        buf = new StringBuilder(500);

        for (inx = 0; inx < SIZES.length; inx++) {
            area = new JTextArea(); // NOPMD SRB
            fnt = mgr.getFont(name, SIZES[inx], Font.PLAIN);
            area.setFont(fnt);

            // Determine the font glyphs and set that in each text area.
            num = fnt.getNumGlyphs();
            cnt = 0;
            chr = 1;

            buf.setLength(0);

            while ((cnt < num) && (chr < Character.MAX_VALUE)) {

                if (fnt.canDisplay(chr)) {
                    buf.append(chr);
                    cnt++;

                    if ((cnt % ((num / 5) + 1)) == 0) {
                        buf.append('\n');
                    }
                }

                chr++;
            }

            area.setText(buf.toString());
            area.setWrapStyleWord(true);

            pane.add(area);
        }
    }

    /**
     * An implementation of main for testing.
     *
     * @param  args  command-line arguments
     */
    public static void main(final String... args) {

        BundledFontViewer obj;
        BundledFontManager mgr;

        obj = new BundledFontViewer();
        mgr = BundledFontManager.getInstance();

        obj.createUI(mgr);
        obj.pack();
        obj.setVisible(true);
        obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
