package org.jcon.ui.easylayout;

import java.util.Enumeration;
import java.util.Hashtable;

/**
 * Provides a global registry of styles. This
 * allows easy deployment of carefully designed suites of
 * styles. All static methods. Threadsafe.
 *
 * The registry contains zero or more named libraries.
 * Each library has zero or more named styles. Naturally
 * the libraries must be registered before they can be used,
 * generally in system or application initialization.
 *
 * Choose library names with care. To avoid name space
 * conflicts, consider prepending your backwards domain
 * name to the library name, just like class names. For
 * example a library name might be "gov.cdc.atsdr.Standard".
 *
 * @author Jack Harich
 */
public class EasyLayoutRegistry implements java.io.Serializable {

//---------- Private Fields ------------------------------
// Key = library name, Object = EasyLayoutLibrary
private static Hashtable libraries = new Hashtable();

//---------- Public Methods ------------------------------
//----- Mutators
/**
 * Adds the named library. If one by the same name is already
 * registered it is replaced.
 */
public static void addLibrary(String libraryName,
        EasyLayoutLibrary library) {
    libraries.put(libraryName, library);
}
/**
 * Removes the library and returns whatever was removed.
 * No effect if not found.
 */
public static Object removeLibrary(String libraryName) {
    return libraries.remove(libraryName);
}
//----- Readers
/**
 * Returns the named style from the named library or throws
 * an IllegalArgumentException if not found.
 *
 * We throw an exception rather than return
 * null since this usually indicates a bug, and throwing
 * the exception makes it easier to pinpoint the cause.
 * This is different behavior from Hashtable, which returns
 * null if not found.
 */
public static EasyLayoutStyle getStyle(String libraryName,
        String styleName) {
    EasyLayoutLibrary library = getLibrary(libraryName);
    EasyLayoutStyle style = library.getStyle(styleName);
    if (style == null) {
        throw new IllegalArgumentException(
            "Style '" + styleName + "' not found.");
    } else {
        return style;
    }
}
/**
 * Returns the number of styles in the library.
 */
public static int getStyleCount(String libraryName) {
    EasyLayoutLibrary library = getLibrary(libraryName);
    return library.getStyleCount();
}
/**
 * Returns true if the library has the named style or
 * false if not.
 */
public static boolean hasStyle(String libraryName, String styleName) {
    EasyLayoutLibrary library = getLibrary(libraryName);
    return (library.getStyle(styleName) != null ? true : false);
}
/**
 * Returns true if the registry has the named library or
 * false if not.
 */
public static boolean hasLibrary(String libraryName) {
    return libraries.containsKey(libraryName);
}
/**
 * Returns an unsorted String array of all library names.
 */
public static String[] getLibraryNames() {
    return convertEnumerationToStringArray(
        libraries.keys(), libraries.size());
}
/**
 * Returns an unsorted String array of all style names in
 * libraryName. Throws an IllegalArgumentExcpetion if the
 * library is not found.
 */
public static String[] getStyleNames(String libraryName) {
    EasyLayoutLibrary library = getLibrary(libraryName);
    return library.getStyleNames();
}
/**
 * Returns the named library, throwing an IllegalArgumentException
 * if not found.
 */
public static EasyLayoutLibrary getLibrary(String libraryName) {
    EasyLayoutLibrary library = (EasyLayoutLibrary)libraries.get(libraryName);
    if (library == null) {
        throw new IllegalArgumentException("Library named '"
            + libraryName + "' not found.");
    } else {
        return library;
    }
}
/**
 * Creates and returns a layout that uses libraryName.
 * This is a concise way to use your libraries.
 */
public static EasyLayout createLayout(String libraryName) {
    EasyLayout layout = new EasyLayout();
    layout.setLibrary(getLibrary(libraryName));
    return layout;
}
//----- Utilities
/**
 * Converts the Enumeration to a String array. If an
 * Enumeration object is not a String it's toString()
 * method is used to convert it to a String. The @param
 * size must be the size of the Enumeration.
 * (*** could mod so that that if size < 0 then it first
 * fills a Vector and then coverts that.)
 *
 * This method is in DataLib but is also here to eliminate
 * coupling, allowing easy layout to be a standalone
 * subsystem.
 */
public static String[] convertEnumerationToStringArray(
            Enumeration enum, int size) {
    String[] items = new String[size];
    int index = 0;
    while (enum.hasMoreElements()) {
        Object item = enum.nextElement();
        if (item instanceof String) {
            items[index++] = (String)item;
        } else {
            items[index++] = item.toString();
        }
    }
    return items;
}
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("EasyLayoutRegistry" + text);
}

} // End class
