package org.jcon.inspect;

import org.jcon.util.Hub;
import org.jcon.util.msg.Message;
import org.jcon.util.msg.MessageDef;
import org.jcon.util.msg.MessageListener;
import org.jcon.util.msg.MessageRouter;
import org.jcon.util.msg.MessageSource;
import org.jcon.ba.system.Item;
import java.util.Hashtable;
import java.util.Vector;
import java.beans.*;
import java.lang.reflect.Method;

import javax.swing.JComponent;
import javax.swing.JTable;

/**
 * Provides a panel showing the Message related state and
 * behavior for an instance.
 *
 * @author Jack Harich
 */
public class MessageSheet {

//---------- Private Fields ------------------------------
private View             inspectorView;
private MessageSheetView view = new MessageSheetView(this);
private Object instance;
private Vector signalMessageDefs;

// MessageDef if signal name, description if signal property
private Vector signals = new Vector();

//---------- Initialization ------------------------------
public MessageSheet(View inspectorView) {
    this.inspectorView = inspectorView;
}
//---------- Public Methods ------------------------------
public void setHub(Hub hub) {
    view.setHub(hub);
}
public JComponent getComponent() {
    return view.getComponent();
}
public void load(Object instance) {
    this.instance = instance;
    refresh();
}
public void refresh() {
    view.emptyData();
    // Load interests
    if (instance instanceof MessageListener) {
        String[] interests = ((MessageListener)instance)
            .loadMessageInterests();
        if (interests.length == 0) {
            view.addInterest("(none)");
        } else {
            for (int i = 0; i < interests.length; i++) {
                view.addInterest(interests[i]);
            }
        }
    } else {
        view.addInterest("(not a MessageListener)");
    }
    // Load MessageDefs and listeners
    if (instance instanceof MessageSource) {
        MessageSource source = (MessageSource)instance;
        addSignals(source);
        addListeners(source);
    } else {
        view.addSignal("(not a MessageSource)");
        view.addListener("(not a MessageSource)");
    }
}
//---------- Package Methods -----------------------------
void signalSelected(int index) {
    if (signals.isEmpty()) return;
    Object signal = signals.elementAt(index);

    if (signal instanceof MessageDef) {
        view.setSignalText(null);
        String eventName = ((MessageDef)signal).getEventName();
        refreshEventChain(eventName);

    } else if (signal instanceof String) {
        view.setSignalText((String)signal);
    }
}
void showSignalPropertiesChanged() {
    refreshSignals();
}
//---------- Private Methods -----------------------------
private void refreshEventChain(String eventName) {
    view.emptyEventChainData();
    Vector chain = inspectorView.loadSignalChain(
        eventName, instance);
    for (int i = 0; i < chain.size(); i++) {
        view.addEventChainLine((String)chain.elementAt(i));
    }
    // ********* fake for now
    /** view.addEventChainLine("Signal - ItemSelected");
    view.addEventChainLine("0 tree.inspectMgr (fires)");
    view.addEventChainLine("1 tree");
    view.addEventChainLine("2 edit");
    view.addEventChainLine("   3 edit.inspectMgr");
    view.addEventChainLine("   3 edit.configMgr"); */

}
private void addSignals(MessageSource source) { // 99
    signalMessageDefs = source.getMessageDefs();
    refreshSignals();
}
private void refreshSignals() {
    Vector defs = signalMessageDefs; // Shorter name
    boolean propertiesWanted = view.isShowSignalProperties();
    signals.removeAllElements();
    view.emptySignalData();

    if (defs.isEmpty()) {
        view.addSignal("(none)");
        return;
    }
    for (int i = 0; i < defs.size(); i++) {
        MessageDef def = (MessageDef)defs.elementAt(i);
        view.addSignal(def.getEventName());
        signals.addElement(def);
        if (! propertiesWanted) continue;

        String[] propertyNames = def.getPropertyNames();
        for (int j = 0; j < propertyNames.length; j++) {
            String propertyName = propertyNames[j];
            String propertyType = def.getPropertyType(propertyName).getName();
            String description = def.getPropertyDescription(propertyName);
            view.addSignal("   " + propertyName + " - "
                + propertyType);
            signals.addElement(description);
        }
    }
}
private void addListeners(MessageSource source) {
    MessageRouter router = source.getMessageRouter();
    // Add each event
    String[] eventNames = router.getEventNames();
    if (eventNames.length == 0) {
        view.addListener("(none)");
        return;
    }
    for (int i = 0; i < eventNames.length; i++) {
        String eventName = eventNames[i];
        Vector listeners = router.getEventListeners(eventName);
        for (int j = 0; j < listeners.size(); j++) {
            Object listener = listeners.elementAt(j);
            String className = listener.getClass().getName();
            String itemName = "";
            if (listener instanceof Item) {
                itemName = ((Item)listener).getItemName() + " - ";
            }
            view.addListener(eventName + " - " + itemName
                + className);
        }
    }
}
//--- Std
private static void print(String text) {
    System.out.println("MessageSheet" + text);
}

} // End class