/**
 * Problem14_3.java ST/HRS/EL 2003-03-04
 *
 * This exercise is a modified version of the program list 14.1. Besides the
 * fact that we now make an application in preference to an applet, we also
 * make use of files to save the input from the user.
 *
 * A file named 'text.txt' has to exist. This file may be empty.
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.io.*;

public class Problem14_3 {
  public static void main(String[] args) {
    MyWindow window = new MyWindow("Problem14_3", "text.txt");
    window.pack();
    window.setVisible(true);
  }
}

/*
 * The class MyWindow
 */
class MyWindow extends JFrame {

  private static final String standardtext =
    "If you enter a correct password, you'll be able to write here.";
  private JTextField userNameField     = new JTextField(15);
  private JPasswordField passwordField = new JPasswordField(15);
  private JTextArea textfield    = new JTextArea(10, 20);
  private JButton printingButton = new JButton("Print");
  private String filename;

  public MyWindow(String title, String initFilename) {
    super(title);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    filename = initFilename;

    Container guiContainer = getContentPane();
    guiContainer.setLayout(new BorderLayout(5, 5)); // we desire spaces between the panels

    guiContainer.add(new LoggInPanel(), BorderLayout.NORTH);
    guiContainer.add(new TextareaPanel(), BorderLayout.CENTER);
    guiContainer.add(new ButtonPanel(), BorderLayout.SOUTH);

    userNameField.requestFocus();
    pack();
  }

  public String readFromFile() {
    String text = "";
    BufferedReader reader = null;
    try {
      FileReader fileConn = new FileReader(filename);
      reader = new BufferedReader(fileConn);

      String line = reader.readLine();
      while (line != null) {
        text += line + "\n";
        line = reader.readLine();
      }
    } catch(IOException e) {
      JOptionPane.showMessageDialog(MyWindow.this, "Error by opening/reading file: " + e +
                                    "\nWe use the standard text");
      text = standardtext;
    } finally {
      if (reader != null) {
        try {
         reader.close();
        } catch (IOException e) {
        }
      }
    }
    return text;
  }


  /* Describes the panel in north */
  private class LoggInPanel extends JPanel {
    public LoggInPanel() {
      setLayout(new GridLayout(2, 2, 5, 5));
      add(new JLabel("Username:", JLabel.RIGHT));
      add(userNameField);
      add(new JLabel("Password:", JLabel.RIGHT));
      add(passwordField);
      PasswordListener passwordlistener = new PasswordListener();
      passwordField.addFocusListener(passwordlistener);
    }
  }

  /* Describes the panel in the middle */
  private class TextareaPanel extends JPanel {
    public TextareaPanel() {
      textfield.setLineWrap(true);
      textfield.setWrapStyleWord(true);
      textfield.setEditable(false);
      textfield.setText(readFromFile());
      JScrollPane scroller = new JScrollPane(textfield);
      add(scroller);
    }
  }

  /* Describes the panel in south */
  private class ButtonPanel extends JPanel {
    public ButtonPanel() {
      ButtonListener buttonlistener = new ButtonListener();
      printingButton.addActionListener(buttonlistener);
      printingButton.setEnabled(false);
      printingButton.setMnemonic('S');
      add(printingButton);
    }
  }

  /**
   * This class is a listener that listens to changes in focus.
   *
   * The program reacts after the user has written the password. Username
   * and password has to be checked. If it's ok, the focus has to be moved
   * to the text area so the user could change the text. If it's not ok, the
   * focus has to be moved to the username field so that the user could
   * rewrite the username and password.
   */
  private class PasswordListener implements FocusListener {
    public void focusLost(FocusEvent event) {
      String userName = userNameField.getText();
      char[] password = passwordField.getPassword();
      if (okPassword(userName, password)) {
        printingButton.setEnabled(true);
        textfield.setEditable(true);
        textfield.requestFocus();
        JOptionPane.showMessageDialog(MyWindow.this, "Ok. You may edit the text.");
      } else {
        JOptionPane.showMessageDialog(MyWindow.this, "Not a valid username/password.");
        printingButton.setEnabled(false);
        textfield.setEditable(false);
        userNameField.requestFocus();
      }
    }

    public void focusGained(FocusEvent event) {
    }

    private boolean okPassword(String userName, char[] password) {
      /*
       * We have put the password into the code, without encryption. Normalcy
       * this kind of information should have been saved onto a file and
       * encrypted in a secure method.
       */
      char[] correctPassword = {'t', 'e', 's', 't'};
      if (userName.equals("test") && Arrays.equals(password, correctPassword)) {
        Arrays.fill(password, ' ');  // removes the password from the password field
        passwordField.setText("");
        return true;
      }
      else return false;
    }
  }

  private class ButtonListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {
      String text = textfield.getText();
      PrintWriter writer = null;
      try {
        /* Writes text to file. */
        FileWriter fileConnection = new FileWriter(filename, false);
        writer = new PrintWriter(new BufferedWriter(fileConnection));

        writer.println(text);
        writer.close();
      } catch(IOException e) {
        JOptionPane.showMessageDialog(MyWindow.this, "Problems, saving data to file: " + e.toString());
      } finally {
        if (writer != null) writer.close();
      }
    }
  }
}