package netmatch.qtool;

import edu.umd.cs.piccolo.PLayer;
import edu.umd.cs.piccolo.PCanvas;

import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.*;

public class QPopupMenu extends JPopupMenu implements ActionListener {
  private QToolFrame frame;
  private QElement popupElement;
  private PLayer nodeLayer;
  private PLayer edgeLayer;
  private String[] constrains = {netmatch.algorithm.Common.GT,netmatch.algorithm.Common.GE
      ,netmatch.algorithm.Common.LT,netmatch.algorithm.Common.LE,netmatch.algorithm.Common.EQ};

  public QPopupMenu(QToolFrame frame) {
    this.frame = frame;
    JMenuItem mItem = new JMenuItem("Edit Attribute...", frame.menu[14]);
    mItem.addActionListener(this);
    this.add(mItem);
    mItem = new JMenuItem("Delete", frame.menu[13]);
    mItem.addActionListener(this);
    this.add(mItem);
  }

  public void actionPerformed(ActionEvent e) {
    String command = e.getActionCommand();
    String newLabel;

    if(command.equals("Edit Attribute...")) {
      String oldLabel = popupElement.getAttr();
      if(popupElement instanceof QPath)
        newLabel = editPath(oldLabel);
      else
        newLabel = editAttr(oldLabel);
      if(newLabel != null) {
        popupElement.setAttr(newLabel);
        popupElement.update();
        frame.isModif = true;
        frame.setTitleModif();
      }
    }
    else if(command.equals("Delete")) {
      popupElement.delete(nodeLayer, edgeLayer);
      frame.isModif = true;
      frame.setTitleModif();
      if(popupElement instanceof QNode)
        Network.nCount--;
      else if(popupElement instanceof QLoop)
        Network.lCount--;
      else if(popupElement instanceof QEdge)
        Network.eCount--;
      else if(popupElement instanceof QPath)
        Network.pCount--;
      frame.updateStatus();

    }
  }

  private int parseConstrain(String attr) {
    String c = attr.substring(1, 3);
    if(constrains[1].equals(c))
      return 1;
    if(constrains[3].equals(c))
      return 3;
    c = attr.substring(1, 2);
    if(constrains[0].equals(c))
      return 0;
    if(constrains[2].equals(c))
      return 2;
    if(constrains[4].equals(c))
      return 4;
    return -1;
  }

  private int parseNumber(int constrainIndex, String attr) {
    int beginIndex = 1/*?*/ + constrains[constrainIndex].length();
    return (Integer.parseInt(attr.substring(beginIndex)));
  }

  public void show(Component invoker, int x, int y, QElement popupElement) {
    this.popupElement = popupElement;
    this.nodeLayer = ((PCanvas) invoker).getCamera().getLayer(1);
    this.edgeLayer = ((PCanvas) invoker).getCamera().getLayer(0);
    super.show(invoker, x, y);
  }

  private String editAttr(String oldattr) {
    Object[] message = new Object[3];

    final JTextField textField = new JTextField(25);
    //final QuickFindPanel q = new QuickFindPanel();
    // q.disableComboBox();
    JRadioButton inexButton = new JRadioButton("Unlabeled.");
    inexButton.setAlignmentX(Component.LEFT_ALIGNMENT);
    inexButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JRadioButton o = (JRadioButton) e.getSource();
        if(o.isSelected())
          textField.setEnabled(false);
          //q.disableComboBox();
      }
    });
    JRadioButton exButton = new JRadioButton("Labeled: ");
    exButton.setAlignmentX(Component.LEFT_ALIGNMENT);
    exButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JRadioButton o = (JRadioButton) e.getSource();
        if(o.isSelected())
          textField.setEnabled(true);
          //q.enableComboBox();
      }
    });
    if(oldattr.charAt(0) == '?') {
      inexButton.setSelected(true);
      textField.setEnabled(false);
      //q.disableComboBox();
    }
    else {
      exButton.setSelected(true);
      textField.setEnabled(true);
      textField.setText(oldattr);
      //q.enableComboBox();
      //q.setText(oldattr);
    }
    ButtonGroup group = new ButtonGroup();
    group.add(inexButton);
    group.add(exButton);
    JPanel p = new JPanel(new BorderLayout(5, 5));
    p.add(exButton, BorderLayout.WEST);
    p.add(textField, BorderLayout.CENTER);
    //p.add(q);
    message[0] = "Please enter attribute:";
    message[1] = inexButton;
    message[2] = p;
    String[] options = {"Ok","Cancel"};
    int result = JOptionPane.showOptionDialog(
        frame, // the parent that the dialog blocks
        message, // the dialog message array
        "Edit Attribute", // the title of the dialog window
        JOptionPane.DEFAULT_OPTION, // option type
        JOptionPane.INFORMATION_MESSAGE, // message type
        frame.menu[16], // optional icon, use null to use the default icon
        options,   // options string array, will be made into buttons
        options[0] // option that should be made into a default button
    );
    switch(result) {
      case 0:// Ok
        if(inexButton.isSelected())
          return "?";
        else {
          if(textField.getText().equals(""))
          //if(q.getText().equals(""))
            return "?";
          return textField.getText();
          //return q.getText();
        }
    }
    return null;
  }

  private String editPath(String oldattr) {
    Object[] message = new Object[2];
    JComboBox list = new JComboBox(constrains);
    int ci = parseConstrain(oldattr);
    list.setSelectedIndex(ci);
    JSpinner spinner = new JSpinner(new SpinnerNumberModel(parseNumber(ci, oldattr), 0, Integer.MAX_VALUE, 1));
    spinner.setValue(new Integer(parseNumber(ci, oldattr)));
    JPanel p = new JPanel(new BorderLayout(5, 5));
    p.add(list, BorderLayout.WEST);
    p.add(spinner, BorderLayout.CENTER);
    message[0] = "Please set the path length:";
    message[1] = p;
    String[] options = {"Ok","Cancel"};
    int result = JOptionPane.showOptionDialog(
        frame, // the parent that the dialog blocks
        message, // the dialog message array
        "Approximate Path Attribute", // the title of the dialog window
        JOptionPane.DEFAULT_OPTION, // option type
        JOptionPane.INFORMATION_MESSAGE, // message type
        frame.menu[16], // optional icon, use null to use the default icon
        options, // options string array, will be made into buttons
        options[0]// option that should be made into a default button
    );
    switch(result) {
      case 0:// Ok
        return "?" + constrains[list.getSelectedIndex()] + ((Integer) spinner.getValue()).intValue();
    }
    return null;
  }
}

