package de.reinhardt_karlheinz.pcc.pc.gui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.ConnectException;
import java.net.UnknownHostException;

import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.border.TitledBorder;

import de.reinhardt_karlheinz.pcc.events.PCCMessageEvent;
import de.reinhardt_karlheinz.pcc.interfaces.PCCConnection;
import de.reinhardt_karlheinz.pcc.interfaces.PluginLoader;
import de.reinhardt_karlheinz.pcc.listeners.PCCMsgListener;
import de.reinhardt_karlheinz.pcc.plugins.PluginInterface;

public class PCC_PCGui extends JFrame implements PCCMsgListener {

  /**
   * 
   */
  private static final long serialVersionUID = 1L;

  private static final String WINDOW_TILE = "PCConnection-PC";

  private PluginLoader pluginManager;

  private PCCConnection server;

  public PCC_PCGui(PluginLoader pluginCtrl, PCCConnection server) {
    super();
    setBounds(new Rectangle(0, 40, 650, 385));
    setResizable(false);
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setTitle(WINDOW_TILE);
    pluginManager = pluginCtrl;
    this.server = server;
    server.addPCCMsgListener(this);
    GridBagLayout gridBagLayout = new GridBagLayout();
    gridBagLayout.columnWidths = new int[] { 411, 244, 0 };
    gridBagLayout.rowHeights = new int[] { 0, 25, 0 };
    gridBagLayout.columnWeights = new double[] { 1.0, 1.0, Double.MIN_VALUE };
    gridBagLayout.rowWeights = new double[] { 1.0, 0.0, Double.MIN_VALUE };
    getContentPane().setLayout(gridBagLayout);

    addMenu();
    addComponents();
    fillPluginList();
  }

  private void addMenu() {
    {
      JMenuBar menuBar = new JMenuBar();
      setJMenuBar(menuBar);
      {
        JMenu mnNewMenu = new JMenu("Settings");
        menuBar.add(mnNewMenu);
        {
          JMenuItem mntm_startServer = new JMenuItem("start server");
          mntm_startServer.addActionListener(new ActionListener() {
            @Override
            @SuppressWarnings("synthetic-access")
            public void actionPerformed(ActionEvent arg0) {
              serverRunnable = new Runnable() {
                @Override
                public void run() {
                  if (pluginManager.getServer() != null) {
                    if (pluginManager.getServer().isConnected() == true) {
                      addLogMsg("PCC", "Server already running!");
                    } else {
                      try {
                        if (pluginManager.getServer().startServer() == true) {
                          addLogMsg("PCC", "Server started!");
                        } else {
                          addLogMsg("PCC", "Server could not be started!");
                          addLogMsg("PCC",
                              "Is the Anroid-PCControl app running?");

                        }
                      } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                      }
                      System.out.println("e");
                    }

                  }
                }
              };
              serverThread = new Thread(serverRunnable);
              serverThread.start();
              // try {
              // if (pluginManager.getServer().startServer() == true) {
              // System.out.println("server started");
              // } else {
              // System.out.println("server NOT started");
              // System.exit(0);
              // }
              // } catch (ConnectException e) {
              // // TODO Auto-generated catch block
              // e.printStackTrace();
              // } catch (UnknownHostException e) {
              // // TODO Auto-generated catch block
              // e.printStackTrace();
              // } catch (IOException e) {
              // // TODO Auto-generated catch block
              // e.printStackTrace();
              // }
            }
          });
          mnNewMenu.add(mntm_startServer);
        }
        {
          JMenuItem mntm_closeServer = new JMenuItem("close server");
          mntm_closeServer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
              // TODO own method
              if (pluginManager.getServer() != null) {
                if (pluginManager.getServer().isConnected() == true) {
                  try {
                    pluginManager.getServer().stopServer();
                  } catch (IOException e) {
                    addLogMsg("PCC", "Error by closing server!");
                    e.printStackTrace();
                  }
                } else {
                  addLogMsg("PCC", "Server not running!");
                }
              }
            }
          });
          mnNewMenu.add(mntm_closeServer);
        }
        {
          JMenuItem mntmNewMenuItem_1 = new JMenuItem("reload plugins");
          mnNewMenu.add(mntmNewMenuItem_1);
        }
        {
          JSeparator separator = new JSeparator();
          mnNewMenu.add(separator);
        }
        {
          JMenuItem mntmNewMenuItem_2 = new JMenuItem("exit");
          mntmNewMenuItem_2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              // close server //TODO own method
              if (pluginManager.getServer() != null) {
                if (pluginManager.getServer().isConnected() == true) {
                  try {
                    pluginManager.getServer().stopServer();
                  } catch (IOException ioe) {
                    addLogMsg("PCC", "Error by closing server!");
                    ioe.printStackTrace();
                  }
                } else {
                  addLogMsg("PCC", "Server not running!");
                }
              }
              // close plugins
              // pluginManager.closeAllPlugins(); // FIXME curren mod error
              System.exit(0);
            }
          });
          mnNewMenu.add(mntmNewMenuItem_2);
        }
      }
      {
        JMenu mnNewMenu_1 = new JMenu("?");
        menuBar.add(mnNewMenu_1);
        {
          JMenuItem mntmNewMenuItem = new JMenuItem("About");
          mnNewMenu_1.add(mntmNewMenuItem);
        }
      }
    }
  }

  private JEditorPane traffic_txtArea;

  private Runnable serverRunnable;

  private Runnable trkfTxtRunnable;

  private Thread serverThread;

  private Thread trkfTxtThread;

  private JTextField sndTxtField;

  private JList pluginList;

  private JScrollBar vertscrb;

  private void addComponents() {
    {
      JPanel panel = new JPanel();
      panel.setBorder(new TitledBorder(null, "TRAFFIC", TitledBorder.LEADING,
          TitledBorder.TOP, null, null));
      getContentPane().add(
          panel,
          new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
              GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,
                  0, 5, 5), 0, 0));
      GridBagLayout gbl_panel = new GridBagLayout();
      gbl_panel.columnWidths = new int[] { 406, 0 };
      gbl_panel.rowHeights = new int[] { 307, 25, 0 };
      gbl_panel.columnWeights = new double[] { 1.0, Double.MIN_VALUE };
      gbl_panel.rowWeights = new double[] { 1.0, 0.0, Double.MIN_VALUE };
      panel.setLayout(gbl_panel);
      {
        JScrollPane trafficScrollPane = new JScrollPane();
        panel.add(trafficScrollPane, new GridBagConstraints(0, 0, 1, 1, 0.0,
            0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
            new Insets(0, 0, 5, 0), 0, 0));
        {
          traffic_txtArea = new JEditorPane();
          traffic_txtArea.setEditable(false);
          trafficScrollPane.setViewportView(traffic_txtArea);
          vertscrb = trafficScrollPane.getVerticalScrollBar();

        }
      }
      {
        sndTxtField = new JTextField();
        sndTxtField.addActionListener(new ActionListener() {
          @SuppressWarnings("synthetic-access")
          public void actionPerformed(ActionEvent arg0) {
            addLogMsg("send", sndTxtField.getText());
            server.sendMsg(sndTxtField.getText());
            sndTxtField.setText("");
            vertscrb.setValue(vertscrb.getMaximum());
          }
        });
        sndTxtField.setText("");
        sndTxtField.setColumns(10);
        panel.add(sndTxtField, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
            GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,
                0, 0, 0), 0, 0));
      }
    }
    {
      JPanel pluginPanel = new JPanel();
      pluginPanel.setBorder(new TitledBorder(null, "PLUGINS",
          TitledBorder.LEADING, TitledBorder.TOP, null, null));
      getContentPane().add(
          pluginPanel,
          new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
              GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,
                  0, 5, 0), 0, 0));
      GridBagLayout gbl_pluginPanel = new GridBagLayout();
      gbl_pluginPanel.columnWidths = new int[] { 0, 0 };
      gbl_pluginPanel.rowHeights = new int[] { 0, 0 };
      gbl_pluginPanel.columnWeights = new double[] { 1.0, Double.MIN_VALUE };
      gbl_pluginPanel.rowWeights = new double[] { 1.0, Double.MIN_VALUE };
      pluginPanel.setLayout(gbl_pluginPanel);
      {
        pluginList = new JList();
        pluginList.setVisibleRowCount(5);
        pluginPanel.add(pluginList, new GridBagConstraints(0, 0, 1, 1, 0.0,
            0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
            new Insets(0, 0, 0, 0), 0, 0));
      }
    }
  }

  private void addLogMsg(final String tag, final String msg) {
    trkfTxtRunnable = new Runnable() {
      @Override
      public void run() {
        if (msg.isEmpty() == false) {
          traffic_txtArea.setText(traffic_txtArea.getText() + "\n" + tag + ": "
              + msg);
          vertscrb.setValue(vertscrb.getMaximum());
        }
      }
    };
    trkfTxtThread = new Thread(trkfTxtRunnable);
    trkfTxtThread.start();

  }

  private void fillPluginList() {
    pluginList.setCellRenderer(new MyPluginCellRenderer());
    pluginList.setListData(pluginManager.getLoadedPlugins().toArray());
    // TODO
  }

  // #######################
  // ###### LISTENERS ######
  // #######################

  @Override
  public void onMsgReceived(PCCMessageEvent e) {
    addLogMsg("msg", e.getMessage());
  }

  @Override
  public void onCommandReceived(PCCMessageEvent e) {
    addLogMsg("cmd", e.getMessage());

  }
}
