import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.ArrayList;
import javax.swing.filechooser.*;

/**
  *
  * ScoreSaver: Nimmt Ergebnisse vom BinärSpiel entgegen und speichert sie als CSV-Datei
  * Erzeugt damit Datengrundlage für Highscore-Tabelle 
  * V1.1: Rundenzeit vom Server steuerbar, Fehlerkorrektur
  * V1.2: Gesamtzeit vom Server steuerbar 
  *
  * @version 1.2 vom 18.02.2019
  * @author  Thomas Schaller
  * cc0-Lizenz ZPG IMP Klasse 9
  */

public class ScoreSaver extends JFrame implements MyServerSocketListener  {
  // Anfang Attribute
  private ArrayList<MySocket> clients;
  private ArrayList<String> names;
  private Table csvDaten = new Table();
  private static boolean ende;
  private MyServer server;
  private JLabel jLabel1 = new JLabel();
  private JButton jBServerStarten = new JButton();
  private JButton jBSpielStarten = new JButton();
  //private JNumberField jNFPort = new JNumberField();
  private JList jList1 = new JList();
  private DefaultListModel jList1Model = new DefaultListModel();
  private JScrollPane jList1ScrollPane = new JScrollPane(jList1);
  private JLabel jLabel2 = new JLabel();
  private JTextArea jTAPunkte = new JTextArea();
  private JScrollPane jList2ScrollPane = new JScrollPane(jTAPunkte);
  private JLabel jLabel4 = new JLabel();
  private int changeClientListAktiv = 0;
  private JLabel jLabel3 = new JLabel();
  private JButton jBSave = new JButton();
  private JButton jBClear = new JButton();
  private JTextField jTFTrennzeichen = new JTextField();
  private JLabel jLabel5 = new JLabel();
  private JLabel jLabel6 = new JLabel();
  private JLabel jLIPAdresse = new JLabel();
  private JNumberField jNFRundenzeit = new JNumberField();
  private JNumberField jNFSpielzeit = new JNumberField();
  private Timer timer1 = new Timer(1000, null);
  private int spielzeit = 300;
  // Ende Attribute
   
  public ScoreSaver() { 
    // Frame-Initialisierung
    super();
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    int frameWidth = 618; 
    int frameHeight = 441;
    setSize(frameWidth, frameHeight);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);
    setTitle("Score-Saver");
    setResizable(false);
    Container cp = getContentPane();
    cp.setLayout(null);
    // Anfang Komponenten
    jLIPAdresse.setBounds(20,8, 590,50 );
    jLIPAdresse.setText("IP-Adresse: Server inaktiv");
    jLIPAdresse.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 44 ));
    jLIPAdresse.setHorizontalAlignment(JLabel.CENTER);
    jLIPAdresse.setForeground(new Color(150,0,0));
    cp.add(jLIPAdresse);
    
    jLabel5.setBounds(20,68, 150,25 );
    jLabel5.setText("Dauer einer Runde (sek)");
    cp.add(jLabel5);
    
    jNFRundenzeit.setBounds(210, 68, 50, 25);    
    jNFRundenzeit.setInt(60);
    cp.add(jNFRundenzeit);
    
    jLabel6.setBounds(320,68, 150,25 );
    jLabel6.setText("Gesamte Spielzeit (sek)");
    cp.add(jLabel6);
    
    jNFSpielzeit.setBounds(510, 68, 50, 25);    
    jNFSpielzeit.setInt(300);
    cp.add(jNFSpielzeit);


    jBServerStarten.setBounds(8, 98, 290, 25);
    jBServerStarten.setText("Server ist inaktiv  -   Server starten?");
    jBServerStarten.setMargin(new Insets(2, 2, 2, 2));
    jBServerStarten.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
    jBServerStarten_ActionPerformed(evt);
    }
    });
    cp.add(jBServerStarten);


    jBSpielStarten.setBounds(304, 98, 285, 25);
    jBSpielStarten.setText("Spiel starten");
    jBSpielStarten.setMargin(new Insets(2, 2, 2, 2));
    jBSpielStarten.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
    jBSpielStarten_ActionPerformed(evt);
    }
    });
    cp.add(jBSpielStarten);
    
    // Spielteilnehmer
    jList1.setModel(jList1Model);
    
    jList1ScrollPane.setBounds(8, 153, 290, 185);
    cp.add(jList1ScrollPane);
    jLabel2.setBounds(8, 130, 110, 20);
    jLabel2.setText("Spielteilnehmer");
    cp.add(jLabel2);
    
    // Scores
    jTAPunkte.setEditable(false);
    jList2ScrollPane.setBounds(304, 153, 285, 185);
    cp.add(jList2ScrollPane);
    jLabel3.setBounds(304, 1300, 110, 20);
    jLabel3.setText("Ergebnisse");
    cp.add(jLabel3);

    JLabel l = new JLabel();
    l.setBounds(20,342, 80,25 );
    l.setText("Trennzeichen");
    cp.add(l);
    jTFTrennzeichen.setText(";");
    jTFTrennzeichen.setBounds(110,342,20,25);
    jTFTrennzeichen.setHorizontalAlignment(JTextField.CENTER);
    cp.add(jTFTrennzeichen);
    
    
    jBSave.setBounds(150, 342,  190, 25);
    jBSave.setText("Daten speichern");
    jBSave.setMargin(new Insets(2, 2, 2, 2));
    jBSave.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
    jBSave_ActionPerformed(evt);
    }
    });
    cp.add(jBSave);

    jBClear.setBounds(370, 342,  190, 25);
    jBClear.setText("Ergebnisse löschen");
    jBClear.setMargin(new Insets(2, 2, 2, 2));
    jBClear.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
    jBClear_ActionPerformed(evt);
    }
    });
    cp.add(jBClear);
    
    addWindowListener(new WindowAdapter() { 
    public void windowClosing(WindowEvent evt) { 
    ChatServerGUI_WindowClosing(evt);
    }
    });
    jLabel4.setBounds(185, 382, 229, 20);
    jLabel4.setText("(cc) 2018, Thomas Schaller, Version 1.2");
    jLabel4.setForeground(Color.GRAY);
    cp.add(jLabel4);
    
    timer1.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        timer1_ActionPerformed(evt);
      }
    });
    timer1.setRepeats(true);
    timer1.setInitialDelay(0);
    
    // Spielteilnehmer

    // Ende Komponenten
    
    setVisible(true);
    
    clients    = new ArrayList<MySocket>();
    names      = new ArrayList<String>();
    server     = null;
    csvDaten.addColumn("Name");
    csvDaten.addColumn("Punkte");
  } // end of public ScoreSaver
  
 
  
  // Anfang Methoden
  public void jBSave_ActionPerformed(ActionEvent evt) {
    JFileChooser chooser = new JFileChooser();
    FileFilter filter = new FileNameExtensionFilter("csv-Dateien", 
    "csv");         
    // Filter wird unserem JFileChooser hinzugefügt
    chooser.addChoosableFileFilter(filter);
    chooser.setAcceptAllFileFilterUsed(false);
    // Dialog zum Oeffnen von Dateien anzeigen
    int rueckgabeWert =chooser.showDialog(null, "Punkte speichern");
    
    
    /* Abfrage, ob auf "Speichern" geklickt wurde */
    if(rueckgabeWert == JFileChooser.APPROVE_OPTION)
    {
      char separator = ';';
      if(jTFTrennzeichen.getText().length()>0 && jTFTrennzeichen.getText().trim().charAt(0)!= ' '){
        separator = jTFTrennzeichen.getText().trim().charAt(0);
      }

      csvDaten.saveCSV(chooser.getSelectedFile().getAbsolutePath(),"header",separator,'"');
    }
  }

  public void neuerClient(MySocket client) {
    this.clients.add(client);
    this.names.add("?");
  }
  
  public void changeClientList() {
    changeClientListAktiv++;
    if (changeClientListAktiv == 1) {
      do{
        changeClientListAktiv--;
        DefaultListModel newListModel = new DefaultListModel();
        for (int i = 0; i < clients.size() ; i++ ) {
          MySocket s = clients.get(i);
          String   n = names.get(i);
          newListModel.addElement(n+"("+s.getSocket().getInetAddress()+":"+s.getSocket().getPort()+")");
        } // end of for
        jList1.setModel(newListModel);
        jList1.validate();  
      }
      while (changeClientListAktiv > 0 );
    } // end of if
  }
      
  public void nachrichtEmpfangen(MySocket client) {
    String s = client.holeNachricht();
    System.out.println("Habe Nachricht empfangen:"+s);
    String[] ss = s.split(":");
    int i = clients.indexOf(client);
    
    if (ss[0].equals("exit")) {
      s = s+names.get(i);
      clients.remove(i);
      names.remove(i);
      client.trenneVerbindung();
      changeClientList();
      return;
    } 
    
    if (ss[0].equals("user")) {
      names.set(i,ss[1]);
      if(timer1.isRunning()) {
      client.sendeNachricht("round "+jNFRundenzeit.getText());
      client.sendeNachricht("game "+jNFSpielzeit.getText());
      }

      changeClientList();
      return;
    }   
    
    if (ss[0].equals("punkte") && jNFSpielzeit.getInt()>0) {
      jTAPunkte.append(names.get(i)+";"+ss[1]+"\n");
      TableRow tr = csvDaten.addRow();
      tr.setString("Name",names.get(i));
      tr.setString("Punkte",ss[1]);
      
    } // end of if
  } // end of if
    
    
  public void timer1_ActionPerformed(ActionEvent evt) {
    int rest = jNFSpielzeit.getInt();
    if(rest > 0) {
    jNFSpielzeit.setInt(jNFSpielzeit.getInt()-1);
    for (MySocket c: clients) {
      c.sendeNachricht("game "+jNFSpielzeit.getText());
    
    } // end of for
      
    } else {
      timer1.stop();
      jBSpielStarten.setEnabled(true);
      jNFSpielzeit.setInt(spielzeit);
      jNFSpielzeit.setEnabled(true);
      jNFRundenzeit.setEnabled(true);
      jBServerStarten.setEnabled(true);
      
    } // end of if-else

  }
   
    
  public void verbindungBeendet(MySocket client) {
    if (clients.contains(client)) {
      
      int i = clients.indexOf(client);
      
      clients.remove(i);
      System.out.println("Verbindung mit "+client.getSocket().getInetAddress()+" Port: "+client.getSocket().getPort()+" verloren.");
      for (MySocket c: clients) {
        if (c!=client) {
          c.sendeNachricht(("exit:"+names.get(i)+":alle"));
        } // end of if
      }
      names.remove(i);
      changeClientList();
    } // end of if
    
  }
    
    
      
  public static void main(String[] args) {
    new ScoreSaver();
  } // end of main
    
  public void jBServerStarten_ActionPerformed(ActionEvent evt) {
    if (jBServerStarten.getText().equals("Server ist inaktiv  -   Server starten?")) {
      server = new MyServer(this, 44444);
      server.starten();  
      jBServerStarten.setText("Server läuft - Server stoppen?");
      jLIPAdresse.setText("IP-Server: "+server.getIP());

    } else {
      server.stoppen();
      server = null;
      jBServerStarten.setText("Server ist inaktiv  -   Server starten?");        
      jLIPAdresse.setText("IP-Server: inaktiv");
    } // end of if-else
  } // end of jBStarten_ActionPerformed
  
  public void jBSpielStarten_ActionPerformed(ActionEvent evt) {
    spielzeit = jNFSpielzeit.getInt();
    timer1.start();
    jBServerStarten.setEnabled(false);
    jBSpielStarten.setEnabled(false);
    jNFSpielzeit.setEnabled(false);
    jNFRundenzeit.setEnabled(false);
    for (MySocket c: clients) {
      c.sendeNachricht("round "+jNFRundenzeit.getText());
      c.sendeNachricht("game "+jNFSpielzeit.getText());
    
    } // end of for
    
  } // end of jBStarten_ActionPerformed

  public void jBClear_ActionPerformed(ActionEvent evt) {
    csvDaten.clearRows();
    jTAPunkte.setText("");
  } // end of jBStarten_ActionPerformed

    
  public void ChatServerGUI_WindowClosing(WindowEvent evt) {
    if (server != null) server.stoppen();
  } // end of ChatServerGUI_WindowClosing

    // Ende Methoden
} // end of class ScoreSaver
