package org.jcon.ui.easylayout;

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

/**
 * Provides a library of reusable styles, which may be used
 * with an EasyLayout directly or through EasyLayoutRegistery.
 * This class also serves as an example of a standard
 * custom style library.
 *      *** New styles and changes will happen ***
 *
 * We recommend using Left instead of West, Top instead of
 * North, etc. This reduces the number of concepts involved
 * when using EasyLayout. Therefore for example we have
 * BorderTop, not BorderNorth.
 *
 * @author Jack Harich
 */
public class EasyLayoutLibraryStd
    implements EasyLayoutLibrary, java.io.Serializable {

//---------- Protected Fields ----------------------------
// Key = style name, Object = EasyLayoutStyle
protected Hashtable styles = new Hashtable();

//---------- Initialization ------------------------------
/**
 * Initializes the library calling addStandardStyles().
 */
public EasyLayoutLibraryStd() {
    addStandardStyles();
}
//---------- EasyLayoutLibrary Implementation ------------
/**
 * Returns the named style 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.
 */
public EasyLayoutStyle getStyle(String styleName) {
    EasyLayoutStyle style = (EasyLayoutStyle)styles.get(styleName);
    if (style == null) {
        throw new IllegalArgumentException(
            "Style '" + styleName + "' not found.");
    } else {
        return style;
    }
}
/**
 * Returns the number of styles in the library.
 */
public int getStyleCount() {
    return styles.size();
}
/**
 * Returns a String array of all style names in the library.
 */
public String[] getStyleNames() {
    return EasyLayoutRegistry.convertEnumerationToStringArray(
        styles.keys(), styles.size());
}
//---------- Public Methods ------------------------------
//----- Deployment
/**
 * Stores all styles in the provided EasyLayout.
 *
 * NOTE - This is an example of one way to deploy library
 * styles. A better way is by using the registry or calling
 * EasyLayout.setLibrary(EasyLayoutLibrary).
 */
public void storeAllStyles(EasyLayout layout) {
    String[] styleNames = getStyleNames();
    for (int i = 0; i < styleNames.length; i++) {
        String styleName = styleNames[i];
        layout.storeStyle(styleName, getStyle(styleName));
    }
}
//----- Mutators
/**
 * Adds the named style to the library styles. If one by
 * the same name already exists it is overwritten.
 */
public void addStyle(String styleName, EasyLayoutStyle style) {
    styles.put(styleName, style);
}
/**
 * Removes the named style and returns it. Returns null if
 * not found.
 */
public EasyLayoutStyle removeStyle(String styleName) {
    return (EasyLayoutStyle)styles.remove(styleName);
}
/**
 * Removes all the styles.
 */
public void removeAll() {
    styles.clear();
}
/**
 * Adds all the standard styles, which are: <pre>
 *
 *   BorderTop
 *   BorderLeft
 *   BorderCenter
 *   BorderRight
 *   BorderBottom
 *
 *   Gap (all sides)
 *   GapTopBottom
 *   GapTopBottomLeft
 *   GapTopBottomRight
 *   GapBorderBottom
 *   TopBar
 *   BottomBar
 *   SingleColumnEqualWidth
 *
 *   FieldLeft
 *   FieldRight
 *
 *   AlignCenter
 *   AlignTop
 *   AlignLeft
 *   AlignBottom
 *   AlignRight
 *
 *   WidthFiller
 *   StretchBoth
 *   StretchWidth
 *   StretchHeight
 *   </pre>
 */
public void addStandardStyles() {
    addBorderLayoutStyles();

    EasyLayoutStyle style;
    EasyLayoutStyle gapStyle;

    // Gap
    gapStyle = new EasyLayoutStyle("Gap");
    gapStyle.setInsets(4, 4, 4, 4);
    store(gapStyle);

    // GapTopBottom
    style = gapStyle.createClone();
    style.setName("GapTopBottom");
    style.setInsetLeft(0);
    style.setInsetRight(0);
    store(style);

    // GapTopBottomLeft
    style = gapStyle.createClone();
    style.setName("GapTopBottomLeft");
    style.setInsetRight(0);
    store(style);

    // GapTopBottomRight
    style = gapStyle.createClone();
    style.setName("GapTopBottomRight");
    style.setInsetLeft(0);
    store(style);

    // GapBorderBottom
    style = getStyle("BorderBottom").createClone();
    style.setName("GapBorderBottom");
    style.setInsets(4, 4, 4, 4);
    store(style);

    // TopBar
    style = new EasyLayoutStyle("TopBar");
    style.setInsetTop(2);
    style.setInsetRight(1);
    style.setStretch("Width");
    style.setWidthWeight(1);
    style.setHeightWeight(1); // To allow to float up
    style.setAlignment("Top");
    store(style);

    // BottomBar, a variation on TopBar
    style = style.createClone();
    style.setName("BottomBar");
    style.setAlignment("Bottom");
    store(style);

    // SingleColumnEqualWidth
    style = gapStyle.createClone();
    style.setName("SingleColumnEqualWidth");
    style.setGridWidth(0); // For end of row
    style.setStretch("Width"); // All same width
    store(style);

    // Designed for labels and text fields, with gap
    // FieldLeft
    style = gapStyle.createClone();
    style.setName("FieldLeft");
    style.setInsetLeft(0);
    style.setAlignment("Left");
    store(style);
    // FieldRight
    style = gapStyle.createClone();
    style.setName("FieldRight");
    style.setInsetRight(0);
    style.setAlignment("Right");
    store(style);
    
    // AlignCenter
    style = new EasyLayoutStyle("AlignCenter");
    style.setAlignment("Center");
    store(style);    
    
    // AlignTop
    style = new EasyLayoutStyle("AlignTop");
    style.setAlignment("Top");
    store(style);    
    
    // AlignBottom
    style = new EasyLayoutStyle("AlignBottom");
    style.setAlignment("Bottom");
    store(style);
        
    // AlignLeft
    style = new EasyLayoutStyle("AlignLeft");
    style.setAlignment("Left");
    store(style);
        
    // AlignRight
    style = new EasyLayoutStyle("AlignRight");
    style.setAlignment("Right");
    store(style);

    // WidthFiller
    // Use at end of row to get components left aligned
    // Or at beginning of row to get right aligned
    // Or anywhere within row to get full width
    // Was "FillerForLeftAlign"
    style = new EasyLayoutStyle("WidthFiller");
    style.setWidthWeight(1);
    store(style);
    
    // StretchBoth
    style = new EasyLayoutStyle("StretchBoth");
    style.setStretch("Both");
    store(style); 
    
    // StretchWidth
    style = new EasyLayoutStyle("StretchWidth");
    style.setStretch("Width");
    store(style); 
    
    // StretchHeight
    style = new EasyLayoutStyle("StretchHeight");
    style.setStretch("Height");
    store(style);    
}
//---------- Private Methods -----------------------------
private void store(EasyLayoutStyle style) {
    addStyle(style.getName(), style);
}
private void addBorderLayoutStyles() {
    EasyLayoutStyle style;

    // North, South
    style = new EasyLayoutStyle("BorderTop");
    style.setRowColumn(1, 1);
    style.setGridWidthHeight(3, 1);
    style.setStretch("Width");
    store(style);

    style = style.createClone();
    style.setName("BorderBottom");
    style.setRowColumn(3, 1);
    store(style);

    // East, West
    style = new EasyLayoutStyle("BorderRight");
    style.setRowColumn(2, 3);
    style.setHeightWeight(1);
    style.setStretch("Height");
    store(style);

    style = style.createClone();
    style.setName("BorderLeft");
    style.setRowColumn(2, 1);
    store(style);

    // Center
    style = new EasyLayoutStyle("BorderCenter");
    style.setRowColumn(2, 2);
    style.setHeightWeight(1);
    style.setWidthWeight(1);
    style.setStretch("Both");
    store(style);
}
//--- Std
private static void print(String text) {
    System.out.println("EasyLayoutLibraryStd" + text);
}

} // End class
