import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.awt.image.BufferedImage;
import java.math.BigInteger;

/**
  *
  * Beschreibung
  *
  *
  * @version 1.1 vom 30.01.2020
  * @author Thomas Schaller
   * Version 1.1: Hash-Funkion ausgetauscht, damit Hashes unterschiedlicher, Ö/P-Schlüssel in der gleichen Farbe
  */
 import java.util.Timer;

public class ManInTheMiddle extends ChatClient implements MySocketListener {
  // Anfang Attribute
  
  // Ende Attribute
  
  public ManInTheMiddle(String title) {
    // Frame-Initialisierung
    super(title);
    jTFName.setText("ManInTheMiddle");
    jTFName.setEnabled(false);
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
      @Override
      public void run() {
        updateTimes();
      }
    }, 1000, 1000);
  } // end of public ManInTheMiddle
  
  // Anfang Methoden
  public void jBVerbinden_ActionPerformed(ActionEvent evt) {
    String a = jTFAdress.getText();
    int p = jNFPort.getInt();
    if (client != null && client.isAktiv()) {
      jTFAdress.setEnabled(true);
      jNFPort.setEnabled(true);
      jBVerbinden.setText("Verbinden");
      client.trenneVerbindung();
    } else {
      client = new MySocket(a, p, this);
      if (client.isAktiv()) {
        jTFAdress.setEnabled(false);
        jNFPort.setEnabled(false);
        jBVerbinden.setText("Trennen");
        client.sendeNachricht("mitm:");
      }
      
      
    } // end of if-else
    
  } // end of jBVerbinden_ActionPerformed
  
  
  
  
  public void jBSend_ActionPerformed(ActionEvent evt) {
    if (client != null && client.isAktiv()) {
      JMyButton button = (JMyButton) evt.getSource();
      if (button.getEmpfaenger()!=null) {
        button.getNachricht().setEmpfaenger((String) button.getEmpfaenger().getSelectedItem());
      } // end of if
      sendMessage(button.getNachricht());
      this.updateNachrichtenListe();
      
    } else {
      jTFAdress.setEnabled(true);
      jNFPort.setEnabled(true);
      jBVerbinden.setEnabled(true);
    } // end of if
  } // end of jBSend_ActionPerformed
  
  private void sendMessage(Nachricht n) {
    String b = "mess:"+n.getAbsender()+":"+n.getEmpfaenger()+":"+Base64.encode(n.getInhalt())+":"+Base64.encode(n.getHashCode());
    n.setStopped(false);
    n.setSended(true);
    client.sendeNachricht(b);
  }    
  
  
  public void nachrichtEmpfangen(MySocket client) {
    String s = client.holeNachricht();
    String[] ss = s.split(":");
    
    if (ss[0].equals("user")) {
      kontakte.add(ss[1]);
      Nachricht n = new Nachricht("Server","alle","Neuer User: "+ss[1]);
      n.setSended(true);
      nachrichten.add(0,n);
      this.updateNachrichtenListe();
      
    } 
    if(ss[0].equals("mess")) {
      String hash;
      if (ss.length==5) {
        hash = ss[4];
      } else {
        hash = "";
      }// end of if
      Nachricht n = new Nachricht(ss[1],ss[2],Base64.decode(ss[3]),Base64.decode(hash));
      nachrichten.add(0,n);
      this.updateNachrichtenListe();
      
    } // end of if    String s = client.holeNachricht();
    
    
  }
  
  protected void makeMessagePopup(MouseEvent evt, Nachricht n) {
    new MessagePopup2(evt, this, n, keys);
  }  
  
  public void verbindungBeendet(MySocket client) {
    jTFAdress.setEnabled(true);
    jNFPort.setEnabled(true);
    jBVerbinden.setText("Verbinden");
    client = null;
  }
  
  public void jBStopped_ActionPerformed(ActionEvent evt) {
    JMyButton button = (JMyButton) evt.getSource();
    Nachricht n = button.getNachricht();
    n.setStopped(true);
  } // end of jBSend_ActionPerformed
  
  
  public void updateTimes() {
    int i=0;
    Component[] c = jp.getComponents();
    int cnr = 0;
    for (Nachricht n: nachrichten ) {
      if (n.getRestzeit()>0) {
        GridBagConstraints c2 = gbl.getConstraints(c[cnr]);
        while (cnr < c.length-1 && (c2.gridx != 4 || c2.gridy!=i+1)) {
          cnr++; 
          c2 = gbl.getConstraints(c[cnr]);
          
        } // end of while
        JPanel p = (JPanel) (c[cnr]);
        if (p.getComponents()[1] instanceof JLabel) {
          JLabel l = (JLabel) (p.getComponents()[1]);
          l.setText(""+n.getRestzeit()+" sek");
          
        } // end of if
      } else {
        if (!n.getSended() && !n.getStopped() && !n.getEmpfaenger().equals("")) {
          sendMessage(n);
          updateNachrichtenListe();
          break;
        }// end of if-else// end of if
      }
      i++;
    } // end of for
  }
  
  public void updateNachrichtenListe() {                      
    
    GridBagConstraints c = new GridBagConstraints();
    while (jp.getComponentCount()>1) {
      jp.remove(1);
    } // end of while
    //jp.removeAll();
    
    if (jp.getComponentCount()==0) {
      JPanel eingabe = new JPanel();
      eingabe.setBorder(BorderFactory.createBevelBorder(0));
      eingabe.setLayout(null);
      eingabe.setBackground(new Color(250,255,200));
      eingabe.setOpaque(true);
      eingabe.setPreferredSize(new Dimension(150,60));
      
      c.gridx=0; c.gridy = 0; 
      c.gridwidth=5;
      c.fill = GridBagConstraints.BOTH;
      c.weightx = 1.0;
      jTFNachricht.setBounds(100,20,800,20);
      JLabel nn = new JLabel();
      nn.setText("Neue Nachricht");
      nn.setBounds(2,20,90,20);
      eingabe.add(nn);
      eingabe.add(jTFNachricht);
      jp.add(eingabe,c);
    }
    c.weightx=0;
    c.gridwidth=1;
    int xx = 1;
    JLabel name = null;
    for (Nachricht n : nachrichten) {
      
      if (n.getKeys().size()>0 && name != null) {
        GridBagConstraints c2 = gbl.getConstraints(name);
        c2.gridheight++;
        gbl.setConstraints(name,c2);
      } else {
        name = new JLabel();
        name.setText("<html>Von "+n.getAbsender()+"</html>");
        name.setBorder(BorderFactory.createBevelBorder(0));
        name.setBackground(new Color(250,255,200));
        name.setOpaque(true);
        c.gridx=0; c.gridy = xx; 
        c.fill = GridBagConstraints.BOTH;
        jp.add(name,c);
        
      } // end of if-else
      JPanel nnn = new JPanel();
      nnn.setLayout(new GridBagLayout());
      nnn.setBorder(BorderFactory.createBevelBorder(0));
      nnn.setBackground(new Color(250,255,200));
      nnn.setOpaque(true);
      
      PicPanel pp = new PicPanel(n.getKeys());
      pp.setPreferredSize(new Dimension(n.getKeys().size()*32,60));
      pp.setBackground(new Color(250,255,200));
      
      JMyLabel nachricht = new JMyLabel(n,"");
      if (n.getInhaltString().trim().length()>65) {
        nachricht.setText("<html>"+n.getInhaltString().trim().substring(0,62)+"...</html>");
      } else {
        nachricht.setText("<html>"+n.getInhaltString().trim()+"</html>");
      } // end of if-else
      
      c.gridx=0; c.gridy = 0; 
      c.weightx=1.0; c.weighty= 0;
      
      nnn.add(nachricht,c);
      c.gridx=1; c.gridy = 0; 
      c.weightx=0.0; c.weighty= 0;
      
      nnn.add(pp,c);
      c.gridx=1; c.gridy = xx; 
      c.weightx = 1.0;
      jp.add(nnn,c);
      
      nnn = new JPanel();
      nnn.setLayout(new GridBagLayout());
      nnn.setBorder(BorderFactory.createBevelBorder(0));
      nnn.setBackground(new Color(250,255,200));
      nnn.setOpaque(true);
      
      pp = new PicPanel(n.getHashKeys());
      pp.setPreferredSize(new Dimension(n.getHashKeys().size()*32,60));
      pp.setBackground(new Color(250,255,200));
      
      String hc = new String(n.getHashCode());
      if (hc.trim().length()>15) {
        hc = hc.substring(0,15)+"...";
      } //end of if-else
      
      JMyLabel hash = new JMyLabel(n, hc);
      
      
      
      c.gridx=0; c.gridy = 0; 
      c.weightx=1.0; c.weighty= 0;
      
      nnn.add(hash,c);
      c.gridx=1; c.gridy = 0; 
      c.weightx=0.0; c.weighty= 0;
      
      nnn.add(pp,c);
      c.gridx=2; c.gridy = xx; 
      c.weightx = 0.0;
      jp.add(nnn,c);
      
      JPanel abspanel = new JPanel();
      abspanel.setPreferredSize(new Dimension(150,40));
      abspanel.setBorder(BorderFactory.createBevelBorder(0));
      abspanel.setBackground(new Color(250,255,200));
      abspanel.setOpaque(true);
      abspanel.setLayout(new FlowLayout());
      
      if (n.getEmpfaenger().equals("") && n.getSended()==false ) {
        String[] stringlist = new String[100];
        JComboBox cb = new JComboBox(kontakte.toArray(stringlist));
        
        abspanel.add(cb);
        
        ImageIcon water = new ImageIcon("arrow.png");
        JMyButton button = new JMyButton(n, cb, water);
        button.addActionListener(new ActionListener() { 
          public void actionPerformed(ActionEvent evt) { 
            jBSend_ActionPerformed(evt);
          }
        });        
        abspanel.add(button);
        
      } else {
        abspanel.add(new JLabel("an "+n.getEmpfaenger()));
        if (n.getStopped() && n.getSended()==false) {
          ImageIcon water = new ImageIcon("arrow.png");
          JMyButton button = new JMyButton(n,null,water);
          button.addActionListener(new ActionListener() { 
            public void actionPerformed(ActionEvent evt) { 
              jBSend_ActionPerformed(evt);
            }
          });        
          abspanel.add(button);
          
          
        } else {
          if (n.getRestzeit()>0) {
            abspanel.add(new JLabel(" "+n.getRestzeit()+" sek"));
            ImageIcon water = new ImageIcon("stop.png");
            JMyButton button = new JMyButton(n,null,water);
            button.addActionListener(new ActionListener() { 
              public void actionPerformed(ActionEvent evt) { 
                jBStopped_ActionPerformed(evt);
              }
            });        
            abspanel.add(button);
            
            
            
          } // end of if
        }
      }
      c.gridx=4; c.gridy = xx; 
      c.weightx = 0.0;
      jp.add(abspanel,c);
      xx++;
    }
    JPanel dummy = new JPanel();
    dummy.setBorder(BorderFactory.createBevelBorder(0));
    dummy.setLayout(null);
    dummy.setBackground(new Color(250,255,200));
    dummy.setOpaque(true);
    dummy.setPreferredSize(new Dimension(150,60));
    
    c.gridx=0; c.gridy = xx; 
    c.gridwidth=5;
    c.fill = GridBagConstraints.BOTH;
    c.weightx = 1.0;
    c.weighty = 1.0;
    jp.add(dummy,c);
    
    jp.revalidate();
    jp.repaint();
  }
  
  // Ende Methoden
  
  public static void main(String[] args) {
    new ManInTheMiddle("ManInTheMiddle");
  } // end of main
  
} // end of class ManInTheMiddle
  
