package cutils.delegate;

import javax.swing.*;
import java.awt.*;
import java.util.Vector;

/**
 DelegateFrame class
 @author: Doug Lyon
To replace inheritance with delegation:
 I dentify the super class.
 Make an instance of the super class in the child.
    Using semiautomatic static proxy delegation create
    a proxy for the primordial super-class.
 Remove the extends clause.

 Replace all references to the parent with references to the proxy.
 todo: Use layout manager, below.

 */

public class DelegateFrame  {
  private JFrame jf = new JFrame();

  // member declarations
  private JPanel counterPanel = new JPanel();

  private JList duplicateJList = new JList();
  private JList doJList = new JList();
  private JScrollPane dupscrollPane = new JScrollPane();
  private JScrollPane doscrollPane = new JScrollPane();
  private JButton addButton = new JButton();
  private JButton delButton = new JButton();
  private JButton okButton = getOkButton();
  private JButton topButton = new JButton();
  private JLabel duplicateButton = new JLabel();

  private JLabel doLabel = getDoLabel();

  private JPanel listPanel = getListPanel();
  private JPanel commandPanel = getCommandPanel();

  private DelegateSynthesizer delegateSynthesizer = new DelegateSynthesizer();
  private ReflectUtil reflectUtil = new ReflectUtil(getDelegateSynthesizer());

  public DelegateFrame() {
  }

  public void initComponents() throws Exception {
    // the following code sets the frame's initial state
    init();
    Vector v = new Vector();
    v.addElement(new ip.gui.frames.ClosableFrame("image frame"));
    selectInstances(v);


  }

  private void addListeners() {
    duplicateJList.addListSelectionListener(new ListListener());
    addButton.addActionListener(new AddListener());
    delButton.addActionListener(new DelListener());
    okButton.addActionListener(new OkListener());
    topButton.addActionListener(new TopListener());
    jf.addWindowListener(new CloseListener());
  }

  private void selectInstances(Vector v) {
    DelegateSynthesizer ds = getDelegateSynthesizer();
    for (int i = 0; i < v.size(); i++)
      ds.add(v.elementAt(i));

    ds.process();
    System.out.println(ds.getClassString()
                       + ds.getInterface());

    duplicateJList.setListData(ds.getDupMethodList());
    duplicateButton.setText("Duplicate Methods: "
                       + ds.getDupMethodList().size());
    doLabel.setText("Chosed Method: " + ds.getDoMethodList().size());

    addListeners();
  }

  private void initComponents2() {
    buildScrollPane();
    duplicateJList.setVisible(true);

    initDoScrollPane();
    doJList.setVisible(true);

    initCounterPanel();
    initListPanel();
    initCommanePanel();
    initJButton();
  }

  private void init() {
    initComponents2();
    initDelButton();

    initTopoButton();
    initLDup();
    initCounterPanel2();
    initFrame();
    initContainer();
 }

  private void initFrame() {
    jf.setSize(new Dimension(650, 250));
    jf.setTitle("Disambiguate");
    jf.setLocation(new Point(0, 0));

  }

  private void initContainer() {
    Container c = jf.getContentPane();
    c.setLayout(new BorderLayout(0, 0));
    c.add(counterPanel, "North");
    c.add(listPanel, "Center");
    c.add(commandPanel, "South");
  }

  private JPanel getListPanel() {
    JPanel listPanel = new JPanel();
    listPanel.add(dupscrollPane);
    listPanel.add(doscrollPane);
    return listPanel;
  }

  private void initCounterPanel2() {
    counterPanel.add(duplicateButton);
    counterPanel.add(doLabel);
  }

  private JPanel getCommandPanel() {
    JPanel p = new JPanel();
    p.add(okButton);
    p.add(addButton);
    p.add(delButton);
    p.add(topButton);
    return p;
  }

  private JLabel getDoLabel() {
    JLabel l = new JLabel("Selected Method");
    l.setSize(new Dimension(140, 20));
    l.setVisible(true);
    l.setText("Chosed Method");
    l.setLocation(new Point(450, 10));
    return l;
  }

  private void initLDup() {
    duplicateButton.setSize(new Dimension(180, 20));
    duplicateButton.setVisible(true);
    duplicateButton.setText("Duplicate Methods");
    duplicateButton.setForeground(new Color(0, 255, 0));
    duplicateButton.setLocation(new Point(40, 10));
  }

  private void initTopoButton() {
    topButton.setSize(new Dimension(110, 30));
    topButton.setVisible(true);
    topButton.setText("TopoLogic");
    topButton.setForeground(new Color(0, 0, 255));
    topButton.setLocation(new Point(560, 240));
  }

  private JButton getOkButton() {
    JButton b = new JButton("OK");
    b.setSize(new Dimension(60, 30));
    b.setVisible(true);
    b.setForeground(new Color(0, 0, 255));
    b.setLocation(new Point(10, 240));
    return b;
  }

  private void initDelButton() {
    delButton.setSize(new Dimension(60, 30));
    delButton.setVisible(true);
    delButton.setText("<<");
    delButton.setForeground(new Color(255, 0, 0));
    delButton.setLocation(new Point(310, 120));
    delButton.setFont(new Font("DialogInput", 1, 16));
  }

  private void initJButton() {
    addButton.setSize(new Dimension(60, 30));
    //getJBAdd().setVisible(true);
    addButton.setText(">>");
    //getJBAdd().setForeground(new Color(255, 0, 0));
    addButton.setLocation(new Point(310, 60));
    addButton.setFont(new Font("DialogInput", 1, 16));
  }

  private void initCommanePanel() {
    //getCommandPanel().setVisible(true);
    commandPanel.setLayout(new GridLayout(1, 4));
  }

  private void initListPanel() {
    //getListPanel().setVisible(true);
    listPanel.setLayout(new GridLayout(1, 2));
  }

  private void initCounterPanel() {
    //getCounterPanel().setVisible(true);
    counterPanel.setLayout(new GridLayout(1, 2));
  }

  private void initDoScrollPane() {
    doscrollPane.setSize(
        new Dimension(300, 190));
    doscrollPane.setVisible(true);
    doscrollPane.setLocation(new Point(370, 30));
    doscrollPane.getViewport().add(doJList);
  }

  private void buildScrollPane() {
    dupscrollPane.setSize(new Dimension(300, 190));
    //getDupscrollPane().setVisible(true);
    dupscrollPane.setLocation(new Point(10, 30));
    dupscrollPane.getViewport().add(duplicateJList);
  }

  private boolean isShowing = false;

  public void addNotify() {
    jf.addNotify();

    if (isShowing) return;

    // move components to account for insets
    Insets insets = jf.getInsets();
    Component[] components = jf.getComponents();
    for (int i = 0; i < components.length; i++) {
      Point location = components[i].getLocation();
      location.move(location.x, location.y + insets.top);
      components[i].setLocation(location);
    }

    isShowing = true;
  }

  void exit() {
    int choice =
        JOptionPane.showConfirmDialog(null,
                                      "Choose yes to exit, No to continue", "Exit this application ", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
    if (choice == 0) {
      jf.setVisible(false);
      jf.dispose();
      System.exit(0);
    }
  }


  public void dupListValueChanged(
      javax.swing.event.ListSelectionEvent e) {
  }

  public void jButtonActionPerformed(
      java.awt.event.ActionEvent e) {

  }

  public void doListValueChanged(
      javax.swing.event.ListSelectionEvent e) {
  }

  private DelegateSynthesizer getDelegateSynthesizer() {
    return delegateSynthesizer;
  }

  private ReflectUtil getReflectUtil() {
    return reflectUtil;
  }

  private class AddListener implements
      java.awt.event.ActionListener {
    public void actionPerformed(
        java.awt.event.ActionEvent e) {
      Object o;
      //delete from the duplicate list
      o = duplicateJList.getSelectedValue();
      int i = duplicateJList.getSelectedIndex();
      if (getDelegateSynthesizer().getDupMethodList().size() == 0 || i == -1) {
        JOptionPane.showMessageDialog(null,
                                      "Please select a method"
                                      + " from Duplicate Methods window",
                                      "STOP",
                                      JOptionPane.ERROR_MESSAGE);
        System.out.println("No selection");
        return;
      }

      System.out.println("Add " + o);
      getDelegateSynthesizer().removeDupMethod(o);
      // add to do list
      getDelegateSynthesizer().addDoMethod(o);
      //re-display the duplicate list
      duplicateJList.setListData(getDelegateSynthesizer().getDupMethodList());
      //refresh the do list
      doJList.setListData(getDelegateSynthesizer().getDoMethodList());
      duplicateButton.setText("Duplicate Methods: " + getDelegateSynthesizer().getDupMethodList().size());
      doLabel.setText("Chosed Method: " + getDelegateSynthesizer().getDoMethodList().size());
    }
  }

  private class DelListener implements java.awt.event.ActionListener {
    public void actionPerformed(java.awt.event.ActionEvent e) {
      Object o;
      o = doJList.getSelectedValue();
      int i = doJList.getSelectedIndex();
      if (getDelegateSynthesizer().getDoMethodList().size() == 0 || i == -1) {
        JOptionPane.showMessageDialog(null, "Please select a method from Chosed Methods Window", "STOP",
                                      JOptionPane.ERROR_MESSAGE);
        System.out.println("No selection");
        return;
      }
      System.out.println("Del " + o);
      //delete from the do list
      getDelegateSynthesizer().removeDoMethod(o);
      // add to dup list
      getDelegateSynthesizer().addDupMethod(o);
      //re-display the duplicate list
      duplicateJList.setListData(getDelegateSynthesizer().getDupMethodList());
      //refresh the do list
      doJList.setListData(getDelegateSynthesizer().getDoMethodList());
      duplicateButton.setText("Duplicate Methods: " + getDelegateSynthesizer().getDupMethodList().size());
      doLabel.setText("Chosed Method: " + getDelegateSynthesizer().getDoMethodList().size());
    }
  }

  private class OkListener implements java.awt.event.ActionListener {
    public void actionPerformed(java.awt.event.ActionEvent e) {
      System.out.println("creating user chosen sorting file");
      getDelegateSynthesizer().chooseToplogic(false);
      getDelegateSynthesizer().createFile();
      System.out.println(getDelegateSynthesizer().getClassString() + getDelegateSynthesizer().getInterface());
    }
  }

  public void generateTopologicFile() {
    System.out.println(
        "creating topologic sorting file");
    DelegateSynthesizer ds =
        getDelegateSynthesizer();
    ds.chooseToplogic(true);
    ds.createFile();
    System.out.println(
        ds.getClassString()
        + ds.getInterface());
  }

  private class TopListener implements java.awt.event.ActionListener {
    public void actionPerformed(java.awt.event.ActionEvent e) {
      generateTopologicFile();
    }
  }

  private class CloseListener extends java.awt.event.WindowAdapter {
    public void windowClosing(java.awt.event.WindowEvent e) {
      exit();
    }
  }

  private class ListListener implements javax.swing.event.ListSelectionListener {
    public void valueChanged(javax.swing.event.ListSelectionEvent e) {
      dupListValueChanged(e);
      System.out.println("value changed");
    }
  }
}