
// ScoreClient.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th
/* Testovací klient pro ScoreServer s uživatelským rozhraním.
   Klient může odesílat jméno/skóre a dotazovat se na aktuální
   výšku skóre. Klepnutí na tlačítko pro uzavření okna
   ukončí síťové spojení.

  Server lze také testovat takto:
     telnet localhost 1234
*/

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;


public class ScoreClient extends JFrame implements ActionListener
{
  private static final int PORT = 1234;     // údaje o serveru
  private static final String HOST = "localhost";

  private Socket sock;
  private BufferedReader in;     // vstupně/výstupní buffer klienta
  private PrintWriter out;  

  private JTextArea jtaMesgs;
  private JTextField jtfName, jtfScore;
  private JButton jbGetScores;


  public ScoreClient()
  {
     super( "Klient pro práci se seznamem nejvyšších bodů" );

     initializeGUI();
     makeContact();

     addWindowListener( new WindowAdapter() {
       public void windowClosing(WindowEvent e)
       { closeLink(); }
     });

     setSize(300,450);
     setVisible(true);
  } // konec metody: ScoreClient();


  private void initializeGUI()
  // textová oblast je uprostřed a ovládací prvky dole
  {
    Container c = getContentPane();
    c.setLayout( new BorderLayout() );

    jtaMesgs = new JTextArea(7, 7);
    jtaMesgs.setEditable(false);
    JScrollPane jsp = new JScrollPane( jtaMesgs);
    c.add( jsp, "Center");

    JLabel jlName = new JLabel("Jméno: ");
    jtfName = new JTextField(10);

    JLabel jlScore = new JLabel("Skóre: ");
    jtfScore = new JTextField(5);
    jtfScore.addActionListener(this);    // stisknutí klávesy enter spustí odeslání jména/skóre

    jbGetScores = new JButton("Zobraz skóre");
    jbGetScores.addActionListener(this);

    JPanel p1 = new JPanel( new FlowLayout() );
    p1.add(jlName); p1.add(jtfName);
    p1.add(jlScore); p1.add(jtfScore);

    JPanel p2 = new JPanel( new FlowLayout() );
    p2.add(jbGetScores);

    JPanel p = new JPanel();
    p.setLayout( new BoxLayout(p, BoxLayout.Y_AXIS));
    p.add(p1); p.add(p2);

    c.add(p, "South");

  }  // konec metody: initializeGUI()


  private void closeLink()
  {
    try {
      out.println("bye");    // informuj server, že klient se odpojuje
      sock.close();
    }
    catch(Exception e)
    {  System.out.println( e );  }

    System.exit( 0 ); 
  }

    
  private void makeContact()
  {
    try {
      sock = new Socket(HOST, PORT);
      in  = new BufferedReader( 
		  		new InputStreamReader( sock.getInputStream() ) );
      out = new PrintWriter( sock.getOutputStream(), true );  // autoflush
    }
    catch(Exception e)
    {  System.out.println(e);  }
  }  // konec metody: makeContact()



   public void actionPerformed(ActionEvent e)
   // Buď došlo k odeslání dvojice jméno/skóre nebo 
   // bylo stisknuto tlačítko "Zobraz skóre"
   {
     if (e.getSource() == jbGetScores)
       sendGet();
     else if (e.getSource() == jtfScore)
       sendScore();
   }

   private void sendGet()
   {
   // Odešle příkaz "get", přečte odpověď a zobrazí sekvenci
   // Reakce by být ve tvaru: "HIGH$$ n1 & s1 & .... nN & sN & "
     try {
       out.println("get");
       String line = in.readLine();
       System.out.println(line);
       if ((line.length() >= 7) &&     // "HIGH$$ "
           (line.substring(0,6).equals("HIGH$$")))
         showHigh( line.substring(6).trim() );    
		    // odstraň klíčové slovo HIGH$$ a přilehlé mezery
       else    // nemělo by se stávat
         jtaMesgs.append( line + "\n");
     }
     catch(Exception ex)
     {  
       jtaMesgs.append("Nepodařilo se získat seznam s body\n");
       System.out.println(ex);  
     }
   }  // konec metody: sendGet()


  private void showHigh(String line)
  // Analyzuje tabulku s nejvyšším skóre a pěkně ji zobrazí
  {
    StringTokenizer st = new StringTokenizer(line, "&");
    String name;
    int i, score;
    i = 1;
    try {
      while (st.hasMoreTokens()) {
        name = st.nextToken().trim();
        score = Integer.parseInt( st.nextToken().trim() );
        jtaMesgs.append("" + i + ". " + name + " : " + score + "\n");
        i++;
      }
      jtaMesgs.append("\n");
    }
    catch(Exception e)
    { 
      jtaMesgs.append("Problém při analýze tabulky s nejvyšším skóre\n");
      System.out.println("Problém při analýze tabulky s nejvyšším skóre: \n" + e);  
    }
  }  // konec metody: showHigh()


  private void sendScore()
  // Ověří, zadal-li uživatel jméno a skóre, a poté
  // odešle zprávu "score name & score &" serveru
  // Poznámka: ještě bychom měli zkontrolovat, že skóre je celé číslo
  {
    String name = jtfName.getText().trim();
    String score = jtfScore.getText().trim();
    // System.out.println("'"+name+"'   '"+score+"'");

    if ((name.equals("")) && (score.equals("")))
      JOptionPane.showMessageDialog( null, 
           "No name and score entered", "Send Score Error", 
			JOptionPane.ERROR_MESSAGE);
    else if (name.equals(""))
      JOptionPane.showMessageDialog( null, 
           "No name entered", "Send Score Error", 
			JOptionPane.ERROR_MESSAGE);
    else if (score.equals(""))
      JOptionPane.showMessageDialog( null, 
           "No score entered", "Send Score Error", 
			JOptionPane.ERROR_MESSAGE);
    else {
      out.println("score " + name + " & " + score + " &");
      jtaMesgs.append("Sent " + name + " & " + score + "\n");
    }
  }  // konec metody: sendScore()


  // ------------------------------------

  public static void main(String args[]) 
  {  new ScoreClient();  }

} // konec třídy: ScoreClient

