package org.jcon.inspect;

import org.jcon.util.GenLib;
import org.jcon.util.Hub;
import org.jcon.util.msg.Message;
import org.jcon.util.msg.MessageListener;
import org.jcon.util.msg.MessageRouter;
import java.awt.Rectangle;

/**
 * An inspector state machine. Initially no states.
 * The purpose of this class is to reduce the Inspector's
 * responsibilities and allow a state machine eventually,
 * such as when dragging.
 *
 * @author Jack Harich
 */
public class Machine implements MessageListener {

//---------- Private Fields ------------------------------
private Hub              hub;
private MessageRouter    router;
private PropertyExplorer propertyExplorer = new PropertyExplorer();
private Inspector        inspector;

//---------- Initialization ------------------------------
// (none)

//---------- MessageListener Implementation --------------
public void processMessage(Message message) {
    String event = message.getName();

    if (event.equals("CloseViewWindowRequest")) {
        inspector.viewWindowClosing();

    } else if (event.equals("NewInspector")) {
        // Shallow clone inspector, set cascade location
        Inspector newInspector = (Inspector)inspector.clone();
        cascadeInspector(newInspector);
        newInspector.setVisible(true);

    } else if (event.equals("ExploreProperty")) {
        propertyExplorer.explore(
            (BeanProperty)message.get("Property") );

    } else if (event.equals("ReturnFromProperty")) {
        propertyExplorer.returnFromProperty();

    } else if (event.equals("InspectClipboard")) {
        inspectClipboard();
    }
}
public String[] loadMessageInterests() {
    return new String[] {"CloseViewWindowRequest",
        "NewInspector", "ExploreProperty",
        "ReturnFromProperty", "InspectClipboard"};
}
private void cascadeInspector(Inspector anotherInspector) {
    Rectangle a = inspector.getBounds();
    Rectangle b = anotherInspector.getBounds();
    // *** Need to get offset = frame titlebar height
    anotherInspector.setBounds(a.x + 20, a.y + 20, b.width, b.height);
}
//---------- Public Methods ------------------------------
public void setHub(Hub hub) {
    this.hub = hub;
    router = hub.getRouter();
    router.addListener("CloseViewWindowRequest", this);
    router.addListener("NewInspector", this);
    router.addListener("ExploreProperty", this);
    router.addListener("ReturnFromProperty", this);
    router.addListener("InspectClipboard", this);
    propertyExplorer.setHub(hub);
}
public void setInspector(Inspector inspector) {
    this.inspector = inspector;
    propertyExplorer.setInspector(inspector);
}
//---------- Private Methods -----------------------------
private void inspectClipboard() {
    InspectClipboard clipboard = getClipboard();
    // *** We have DUPECODE in MethodArgumentMgr ***
    // Assert we have something to explore
    if (clipboard.isEmpty() ) {
        print("Machine - Clipboard empty");
        GenLib.beep();
        return;
    }
    // Assert MethodArgument on clipboard
    Object clipValue = clipboard.getValue();
    if (! (clipValue instanceof MethodArgument)) {
        print("Machine - Clipboard value is not MethodArgument");
        GenLib.beep();
        return;
    }
    // Cannot explore primitive or array now
    MethodArgument argument = (MethodArgument)clipValue;
    Object value = argument.getValue();
    if (value.getClass().isPrimitive() ||
            value.getClass().isArray() ) {
        print("Machine - Cannot explore primitive or array.");
        GenLib.beep();
        return;
    }
    // Assertions complete. Inspect value.
    // *** Need name here, will be confusing without it
    Inspector newInspector = new Inspector(value, "Inspect Clipboard");
    cascadeInspector(newInspector);
}
private InspectClipboard getClipboard() {
    return (InspectClipboard)hub.getNaming().get("Clipboard");
}
//--- Std
private static void print(String text) {
    System.out.println(text);
}

} // End class
