package org.jcon.ba.edit;

import org.jcon.ba.system.Item;
import org.jcon.ba.system.ItemSystem;
import org.jcon.util.msg.MessageSource;
import java.util.Vector;

/**
 * Provides "message chains" on demand.
 *
 * @author Jack Harich
 */
public class MessageChain {

//---------- Private Fields ------------------------------
private static final String INDENT = "  ";
private ItemSystem itemSystem;

//---------- Public Methods ------------------------------
/**
 * Returns a Vector loaded with Strings, each describing
 * a link in the Message chain starting at the signal named
 * eventName in the message source. The source is probably
 * a MessageSource.
 */
public synchronized Vector loadSignalChain(String eventName,
        ItemSystem itemSystem, Object source) {

    this.itemSystem = itemSystem;

    // Build a chain for the signal
    MessageNode rootNode = new MessageNode(eventName, source, null);

    // Convert to human readable form
    Vector nodes = rootNode.loadBranch();
    return buildChainLines(nodes);
}
//---------- Private Methods -----------------------------
/**
 * Returns a MessageNode containing the "message chain" for
 * the signal named eventName coming from the item. The
 * item's instance should be a MessageSource firing the
 * eventName, otherwise this call makes no sense.
 */
private MessageNode newChainForSignal(String eventName,
        MessageSource source) {

    // null for root
    return new MessageNode(eventName, source, null);
}
/**
 * Returns an array of human readable lines representing
 * the message chain, starting at the rootNode. In the
 * example B stands for Bean, C stands for Container:
 *
 * 0 tree.treeMgr.B
 * 1 tree.C
 * 2 edit.C
 *   3 edit.inspectMgr.B
 *   3 edit.configMgr.B
 */
private Vector buildChainLines(Vector nodes) {
    Vector lines = new Vector();
    String indent = "";
    for (int i = 0; i < nodes.size(); i++) {
        MessageNode node = (MessageNode)nodes.elementAt(i);
        String line = indent + buildOneLine(node.getLevel(),
            node.getInstance());
        lines.addElement(line);
        if (node.getListeners().size() > 1) indent += INDENT;
    }
    return lines;
}
/**
 * Returns level and path portion of line, not indented
 */
private String buildOneLine(int level, Object instance) {
    Item item = itemSystem.getItemForInstance(instance);
    String suffix = "#Error#";
    if (item.isContainer() && item.getBasket() == instance) {
        suffix = ".C"; // Container
    } else {
        suffix = ".B"; // Bean
    }

    //String path = getItemNamePathWithoutRoot(item);
    String path = item.getPath(false); // false is without root
    return level + " " + path + suffix;
}
/**
 * Returns a period delimited String of items names,
 * excluding the root. ITEM LIBRARY ??? ***
 */
/** public static String getItemNamePathWithoutRoot(Item startItem) {
    String path = "";
    TNode[] nodes = startItem.getNode().getPathNodes();
    // Start at 1 to skip root
    for (int i = 1; i < nodes.length; i++) {
        if (i > 1) path += ".";
        Item item = (Item)nodes[i].getUserObject();
        path += item.getItemName();
    }
    return path;
} */
//--- Std
private static void print(String text) {
    System.out.println("MessageChain" + text);
}

} // End class
