package org.jcon.ba.tree;

// import org.jcon.util.GenLib;
import org.jcon.ba.system.*;
import org.jcon.util.TNode;
import org.jcon.ui.JPopupMenuHelper;
import org.jcon.ui.VisualLib;
import org.jcon.ui.WindowLib;
import org.jcon.ui.WindowMgr;
import org.jcon.ui.tree.BTree;
import java.awt.*;
import java.awt.event.*;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;

/**
 * The VIEW for a tree, containing a hierarchial tree and
 * status bar.
 *
 * @author Jack Harich
 */
public class TreeView implements ActionListener,
    MouseListener, TreeSelectionListener, WindowListener {

//---------- Private Fields ------------------------------
private TreeMgr    controller;
private JFrame     window = new JFrame();
private BTree treePanel  = new BTree();

// Fails in Swing 0.7 with JTextField ***
// java.lang.Error: can't load javax.swing.windows.WindowsLookAndFeel
private JTextField statusBar = new JTextField();
// *** private JToggleButton preferContainerToggleBtn = new JToggleButton("Container Preferred");
private boolean    isBATree = false;
private boolean    unitTesting = false;

private JPopupMenuHelper popupHelper = new JPopupMenuHelper();

//---------- Initialization ------------------------------
public TreeView() {

    WindowMgr.registerFrame((Frame)window);
    window.setBackground(Color.lightGray);
    //window.setBounds(0, 150, 250, 400);
    window.setSize(275, 400);
    WindowLib.position(window, "ActiveLowerAlignLeft");

    // *** window.getContentPane().add("North",  prepareButtonBar());
    window.getContentPane().add("Center", treePanel.getComponent());
    window.getContentPane().add("South",  statusBar);
    window.addWindowListener(this);
    statusBar.setBackground(Color.lightGray);

    initPopup();
}
/** private JPanel prepareButtonBar() {
    JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));

    panel.add(preferContainerToggleBtn);
    preferContainerToggleBtn.addActionListener(this);
    preferContainerToggleBtn.setActionCommand("ToggleContainer");

    return panel;
} */
//---------- ActionListener Implementation ---------------
public void actionPerformed(ActionEvent evt) {
    String command = evt.getActionCommand().intern();
    //print(".actionPerformed() - command " + command);

    //----- ItemState commands
    if (command == "StartItem") {
        controller.startItem(this);

    } else if (command == "PauseItem") {
        controller.pauseItem(this);

    } else if (command == "ResumeItem") {
        controller.resumeItem(this);

    } else if (command == "CloseItem") {
        controller.closeItem(this);

    //----- Open commands
    } else if (command == "OpenChildren") {
        controller.openNode(this, false);

    } else if (command == "OpenBranch") {
        controller.openNode(this, true);

    //----- Tool commands
    } else if (command == "EditParam") {
        controller.editParam(this);

    } else if (command == "InspectItem") {
        controller.inspectItem(this);

    //----- EditNode commands
    } else if (command == "AddNode" ||
               command == "DeleteNode") {
        controller.editNode(command, this);

    //----- Tree commands
    } else if (command == "RefreshTree") {
        refresh();

    //----- Button bar commands
    } else if (command == "ToggleContainer") {
        // Ignore - A property is used instead
    }
}
//---------- MouseListener Implementation ----------------
// Per Graphic Java, page 321, we catch all 3 for portablity
// This is a weakness we may see changed
// Currently only chicking mouseReleased(), may not be portable
public void mouseClicked(MouseEvent evt) {
    //print(".mouseClicked()");
    //checkPopup(evt);
}
public void mousePressed(MouseEvent evt) {
    //print(".mousePressed()");
    //checkPopup(evt);
}
public void mouseReleased(MouseEvent evt) {
    //print(".mouseReleased()");
    checkPopup(evt);
}
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }

//---------- TreeSelectionListener Implementation --------
public void valueChanged(TreeSelectionEvent evt) {
    Item item = getSelectedItem();
    if (item == null) {
        setStatusText("");
    } else {
        controller.itemSelected(item, this);
    }
}
//---------- WindowListener Implementatons ---------------
public void windowClosing(WindowEvent evt) {
    // User clicked on X or chose window Close
    controller.closeTreeRequested(this);
}
public void windowClosed(WindowEvent evt) { }
public void windowDeiconified(WindowEvent evt) { }
public void windowIconified(WindowEvent evt) { }
public void windowOpened(WindowEvent evt) { }
public void windowActivated(WindowEvent evt) {  }
public void windowDeactivated(WindowEvent evt) { }

//---------- Properties ----------------------------------
//----- rootNode
public void setRootNode(TNode rootNode) {
    treePanel.removeMouseListener(this);
    treePanel.setRootNode(rootNode);
    treePanel.addMouseListener(this);
    treePanel.addTreeSelectionListener(this);
    // The cell renderer
    if (! unitTesting) {
        treePanel.setCellRenderer(new TreeViewCellRenderer());
    }
}
public TNode getRootNode() {
    return treePanel.getRootNode();
}
//----- title
public void setTitle(String title) {
    window.setTitle(title);
}
public String getTitle() {
    return window.getTitle();
}
//----- visible
public void setVisible(boolean isVisible) {
    window.setVisible(true);
}
public boolean isVisible() {
    return window.isVisible();
}
//----- isBATree
public void setBATree(boolean isBATree) {
    this.isBATree = isBATree;
}
public boolean isBATree() {
    return isBATree;
}
//----- Other
public boolean isContainerPreferred() {
    // *** return preferContainerToggleBtn.isSelected();
    return popupHelper.isSelected("ToggleContainer");
}
//---------- Public Methods ------------------------------
public void setController(TreeMgr controller) {
    this.controller = controller;
}
public void refresh() {
    treePanel.refresh();
}
public void refreshSelectedNode() {
    refresh(); // *** Not yet supported by JTree ***
}
public void refreshNode(TNode node) {
    refresh(); // *** Not yet supported by JTree ***
}
public void setStatusText(String text) {
    statusBar.setText(" " + text);
}
public Item getSelectedItem() {
    return (Item)treePanel.getSelectedUserObject();
}
public void dispose() {
    window.dispose();
    window = null;
}
//---------- Private Methods -----------------------------
private void checkPopup(MouseEvent evt) {
    if (! treePanel.rowIsBeneathMouse(evt)) return;

    // The following is required for correct behavior on Linux and Windows
    if (VisualLib.isRightClick(evt)) {
        Item item = getSelectedItem();
        controller.configItemPopup(popupHelper, item, this);
        treePanel.showPopup(popupHelper.getPopup(), evt);
    }
}
private void initPopup() {
    
popupHelper.setActionListener(this);

popupHelper.addItem("Start",  "StartItem");
popupHelper.addItem("Pause",  "PauseItem");
popupHelper.addItem("Resume", "ResumeItem");
popupHelper.addItem("Close",  "CloseItem");
popupHelper.addSeparator();

popupHelper.addItem("Open Children", "OpenChildren");
popupHelper.addItem("Open Branch",   "OpenBranch");
popupHelper.addSeparator();

popupHelper.addItem("Edit Parameters", "EditParam");
popupHelper.addItem("Inspect",    "InspectItem");
// later popupHelper.addItem("Diagram *",  "DiagramItem");
popupHelper.addSeparator();

//----- 
popupHelper.addMenu("Tree", "TreeMenu");
popupHelper.addItemToMenu("Refresh", "RefreshTree", "TreeMenu");
popupHelper.addCheckBoxToMenu("Container Preferred", "ToggleContainer", "TreeMenu");
popupHelper.addItemToMenu("Undo *", "UndoTree", "TreeMenu");
popupHelper.addItemToMenu("Redo *", "RedoTree", "TreeMenu");

popupHelper.addMenu("Edit Node", "EditMenu");
popupHelper.addItemToMenu("Add Node *", "AddNode", "EditMenu");
popupHelper.addItemToMenu("Delete Node *", "DeleteNode", "EditMenu");
popupHelper.addItemToMenu("Rename Node *", "RenameNode", "EditMenu");

popupHelper.addMenu("Clipboard", "ClipMenu");
popupHelper.addItemToMenu("Copy *", "CopyNode", "ClipMenu");
popupHelper.addItemToMenu("Paste *", "PasteNode", "ClipMenu");
popupHelper.addItemToMenu("Cut *", "CutNode", "ClipMenu");

treePanel.getContentPane().add(popupHelper.getPopup());
} // End method
    
//--- Std
private static void print(String text) {
    System.out.println("TreeView" + text);
}

} // End class
