package com.srbenoit.util;

import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * Provides general access to a set of localized resources for a class. This class assumes that
 * corresponding to a class "foo.bar.Baz" there is a localized resource bundle named
 * "foo.bar.Baz.messages".
 */
public class Messages {

    /** the class for which messages will be retrieved */
    private final transient Class<?> ownerClass;

    /** the loaded resource bundle */
    private final transient ResourceBundle resBundle;

    /**
     * Construct a <code>Messages</code>.
     *
     * @param  clazz  the class of the caller. The resource name is constructed by appending
     *                ".messages" to the class's owning package. Therefore a file called
     *                "messages.properties" (or any localized variant) in the class's package will
     *                be loaded.
     */
    public Messages(final Class<?> clazz) {

        String name;

        this.ownerClass = clazz;

        name = clazz.getPackage().getName() + ".messages";

        this.resBundle = ResourceBundle.getBundle(name);
    }

    /**
     * Tests whether a named string is defined.
     *
     * @param   key  the message key
     * @return  <code>true</code> if a message is defined for the given class and key; <code>
     *          false</code> otherwise
     */
    public boolean exists(final String key) {

        String msgKey;
        boolean found;

        msgKey = this.ownerClass.getSimpleName() + '.' + key;

        try {
            this.resBundle.getString(msgKey);
            found = true;
        } catch (MissingResourceException e) {
            found = false;
        }

        return found;
    }

    /**
     * Gets a named string.
     *
     * @param   key  the message key
     * @return  the <code>String</code>, or a filler <code>String</code> if there was no <code>
     *          String</code> defined with the specified key
     */
    public String getString(final int key) {

        String msgKey;
        String value;

        msgKey = this.ownerClass.getSimpleName() + '.' + key;

        try {
            value = this.resBundle.getString(msgKey);
        } catch (MissingResourceException e) {
            value = '!' + msgKey + '!';
        }

        return value;
    }

    /**
     * Gets a named array of strings.
     *
     * @param   key  the message key
     * @return  the <code>String</code> array, or an empty array if there was not at least one
     *          <code>String</code> defined with the specified key
     */
    public String[] getStrings(final int key) {

        int count;
        String msgKey;
        String[] values;

        // Count the number of indexed strings found
        count = 0;

        for (int i = 1; i < 999; i++) {
            msgKey = this.ownerClass.getSimpleName() + '.' + key + '.' + Integer.toString(i);

            if (exists(msgKey)) {
                count++;
            }
        }

        if (count == 0) {
            msgKey = this.ownerClass.getSimpleName() + '.' + key;

            if (exists(msgKey)) {
                values = new String[1];

                try {
                    values[0] = this.resBundle.getString(msgKey);
                } catch (MissingResourceException e) {
                    values[0] = '!' + msgKey + '!';
                }
            } else {
                values = new String[0];
            }
        } else {
            values = new String[count];

            for (int i = 1; i <= count; i++) {
                msgKey = this.ownerClass.getSimpleName() + '.' + key + '.' + Integer.toString(i);

                try {
                    values[i - 1] = this.resBundle.getString(msgKey);
                } catch (MissingResourceException e) {
                    values[i - 1] = '!' + msgKey + '!';
                }
            }
        }

        return values;
    }
}
