package kuchenBasar;

import java.awt.*;
import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.event.*;

import util.*;

/**
 * Frame zur Verwaltung der Felder eines Gastes
 * 
 * @author Bernd Schubert
 * 
 */
public class GaesteForm extends JDialog implements ActionListener, KeyListener,
    DocumentListener, FocusListener, WindowListener, ItemListener
{
  /**
   * 
   */
  private static final long              serialVersionUID = 20150305L;
  private JLabel                         jLabelDummy;
  private JTextField                     tfGastname, tfVorname, tfKurzname, tfTelefon;
  private JButton                        btnOK, btnAbbrechen;
  private JComboBox<ListItem>            cboEinrichtung;
  private DefaultComboBoxModel<ListItem> cboEinrichtungModel;

  private Component                      owner;
  private KeyboardFocusManager           kbFocusManager;

  private int                            aktID            = -1;
  private boolean                        hasChanged       = false;
  private boolean                        isVorhanden      = false;

  private String                         aktTelefon;
  private String                         aktGastname;
  private String                         aktVorname;
  private String                         aktKurzname;
  private int                            aktEinrichtung;

  public GaesteForm()
  {
    initializeComponent();
  }

  /**
   * 
   * @param ID
   */
  public GaesteForm( int ID )
  {
    this();
    this.aktID = ID;
  }

  private void initializeComponent()
  {
    aktVorname = "vorname";
    aktGastname = "name";
    aktKurzname = "";
    aktEinrichtung = 0;
    aktTelefon = "telefon";

    this.setTitle( "Gast" );
    this.setLayout( null );
    this.setSize( new Dimension( 380, 430 ) );
    this.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE );
    this.setResizable( false );
    this.addWindowListener( this );

    jLabelDummy = new JLabel( "Name" );
    jLabelDummy.setBounds( 20, 10, 100, 25 );
    this.add( jLabelDummy );

    tfGastname = new JTextField();
    tfGastname.setBounds( 20, 35, 300, 25 );
    tfGastname.setMargin( new Insets( 0, 2, 0, 0 ) );
    tfGastname.addKeyListener( this );
    tfGastname.addFocusListener( this );
    tfGastname.getDocument().addDocumentListener( this );
    this.add( tfGastname );

    jLabelDummy = new JLabel( "Vorname" );
    jLabelDummy.setBounds( 20, 65, 100, 25 );
    this.add( jLabelDummy );

    tfVorname = new JTextField();
    tfVorname.setBounds( 20, 90, 300, 25 );
    tfVorname.setMargin( new Insets( 0, 2, 0, 0 ) );
    tfVorname.addKeyListener( this );
    tfVorname.addFocusListener( this );
    tfVorname.getDocument().addDocumentListener( this );
    this.add( tfVorname );

    jLabelDummy = new JLabel( "Kurzname" );
    jLabelDummy.setBounds( 20, 120, 100, 25 );
    this.add( jLabelDummy );

    tfKurzname = new JTextField();
    tfKurzname.setBounds( 20, 145, 300, 25 );
    tfKurzname.setMargin( new Insets( 0, 2, 0, 0 ) );
    tfKurzname.addKeyListener( this );
    tfKurzname.addFocusListener( this );
    tfKurzname.getDocument().addDocumentListener( this );
    this.add( tfKurzname );

    jLabelDummy = new JLabel( "Telefon" );
    jLabelDummy.setBounds( 20, 175, 100, 25 );
    this.add( jLabelDummy );

    tfTelefon = new JTextField();
    tfTelefon.setBounds( 20, 200, 100, 25 );
    tfTelefon.setMargin( new Insets( 0, 2, 0, 0 ) );
    tfTelefon.addKeyListener( this );
    tfTelefon.addFocusListener( this );
    tfTelefon.getDocument().addDocumentListener( this );
    this.add( tfTelefon );

    jLabelDummy = new JLabel( "Einrichtung" );
    jLabelDummy.setBounds( 20, 230, 100, 25 );
    this.add( jLabelDummy );

    cboEinrichtungModel = new DefaultComboBoxModel<ListItem>();
    cboEinrichtung = new JComboBox<ListItem>( cboEinrichtungModel );
    cboEinrichtung.setBounds( 20, 255, 300, 25 );
    cboEinrichtung.setBackground( Color.WHITE );
    cboEinrichtung.addItemListener( this );
    this.add( cboEinrichtung );

    btnOK = new JButton( "OK" );
    btnOK.setBounds( 50, 350, 120, 25 );
    btnOK.addActionListener( this );
    btnOK.setFocusable( false );
    this.add( btnOK );

    btnAbbrechen = new JButton( "Abbrechen" );
    btnAbbrechen.setBounds( 210, 350, 120, 25 );
    btnAbbrechen.addActionListener( this );
    btnAbbrechen.setFocusable( false );
    this.add( btnAbbrechen );
  }

  /**
   * 
   * @param owner
   * @return ID des bearbeiteten (neuen/vorhandenen) Gastes
   */
  public int showDialog( Component owner )
  {
    this.owner = owner;
    return showDialog();
  }

  /**
   * 
   * @param owner
   * @return ID des bearbeiteten (neuen/vorhandenen) Gastes
   */
  public int showDialog()
  {
    initDialog();
    this.setVisible( true );

    //weil der Dialog modal ist, kann hier der Rückgabewert bestimmt werden:
    //welche ID wurde upgedatet bzw. keine (-1)
    if ( hasChanged )
      return aktID;
    else
      return -1;
  }

  private void initDialog()
  {
    this.setModal( true );
    this.setLocationRelativeTo( owner );

    kbFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();

    isVorhanden = ( aktID > -1 );
    if ( isVorhanden )
      readEntry();

    initFrame();

    hasChanged = !isVorhanden;
  }

  private void initFrame()
  {
    tfGastname.setText( aktGastname );
    tfVorname.setText( aktVorname );
    tfKurzname.setText( aktKurzname );
    tfTelefon.setText( aktTelefon );

    ArrayList<ListItem> einrichtungenListe = EinrichtungenDB.getEinrichtungenListe();
    for ( ListItem item : einrichtungenListe )
    {
      if ( !isVorhanden || (int)item.getValueMember() > 0 )
        cboEinrichtungModel.addElement( item );
      if ( (int)item.getValueMember() == aktEinrichtung )
        cboEinrichtung.setSelectedItem( item );
    }
  }

  private void readEntry()
  {
    Gast gast = GaesteDB.getGast( aktID );

    if ( gast == null )
      return;

    aktVorname = gast.getVorname();
    aktGastname = gast.getName();
    aktKurzname = gast.getKurzname();
    aktEinrichtung = gast.getEinrichtung();
    aktTelefon = gast.getTelefon();
  }

  private boolean updateEntry()
  {
    Gast gast = new Gast();
    gast.setID( aktID );
    gast.setName( aktGastname );
    gast.setVorname( aktVorname );
    gast.setKurzname( aktKurzname );
    gast.setTelefon( aktTelefon );
    gast.setEinrichtung( aktEinrichtung );

    return GaesteDB.updateGast( aktID, gast );
  }

  private boolean insertEntry()
  {
    Gast gast = new Gast();
    gast.setName( aktGastname );
    gast.setVorname( aktVorname );
    gast.setKurzname( aktKurzname );
    gast.setTelefon( aktTelefon );
    gast.setEinrichtung( aktEinrichtung );

    aktID = GaesteDB.insertGast( gast );

    return ( aktID > -1 );
  }

  private boolean queryExit()
  {
    if ( !hasChanged )
      return true;

    if ( !plausi() )
      return false;

    Object[] options =
    { "Ja", "Nein", "Abbrechen" };

    int retValue = JOptionPane.showOptionDialog(
        this,
        "Daten wurden geändert\nÄnderungen speichern?",
        "Frage",
        JOptionPane.YES_NO_CANCEL_OPTION,
        JOptionPane.WARNING_MESSAGE,
        null,
        options,
        options[2]
        );

    switch ( retValue )
    {
    // Nein - nicht speichern und Form schließen
      case JOptionPane.NO_OPTION:
        return true;

        // Abbruch - nicht speichern und Form geöffnet lassen
      case JOptionPane.CANCEL_OPTION:
        return false;

        // Ja - Speichern ( Insert / Update )
      case JOptionPane.YES_OPTION:
        return saveEntry();

      default:
        break;

    }
    return false;
  }

  private boolean saveEntry()
  {
    if ( isVorhanden )
      return updateEntry();
    else
      return insertEntry();
  }

  private boolean plausi()
  {
    if ( tfKurzname.getText().length() == 0 )
      tfKurzname.setText( tfVorname.getText() + " " + tfGastname.getText() );

    aktGastname = tfGastname.getText();
    if ( aktGastname.length() < 2 )
      return fehler( tfGastname, "Name muß mind.2 Zeichen haben" );

    aktVorname = tfVorname.getText();
    if ( aktVorname.length() < 2 )
      return fehler( tfVorname, "Vorname muß mind.2 Zeichen haben" );

    aktKurzname = tfKurzname.getText();
    if ( aktKurzname.length() < 2 )
      return fehler( tfKurzname, "Kurzname muß mind.2 Zeichen haben" );

    aktTelefon = tfTelefon.getText();

    aktEinrichtung = (int)( (ListItem)cboEinrichtung.getSelectedItem() ).getValueMember();

    return true;
  }

  private boolean fehler( Component c, String ursache )
  {
    JOptionPane.showMessageDialog(
        this,
        "Fehler, " + ursache,
        "Plausi Prüfung",
        JOptionPane.ERROR_MESSAGE );
    c.requestFocusInWindow();

    return false;
  }

  @Override
  public void windowOpened( WindowEvent e )
  {
  }

  @Override
  public void windowClosing( WindowEvent e )
  {
    if ( queryExit() )
      this.dispose();
  }

  @Override
  public void windowClosed( WindowEvent e )
  {
  }

  @Override
  public void windowIconified( WindowEvent e )
  {
  }

  @Override
  public void windowDeiconified( WindowEvent e )
  {
  }

  @Override
  public void windowActivated( WindowEvent e )
  {
  }

  @Override
  public void windowDeactivated( WindowEvent e )
  {
  }

  @Override
  public void focusGained( FocusEvent e )
  {
    Object o = e.getSource();
    JTextField tf;
    if ( o instanceof JTextField )
    {
      tf = (JTextField)o;
      tf.selectAll();
    }
  }

  @Override
  public void focusLost( FocusEvent e )
  {
  }

  @Override
  public void insertUpdate( DocumentEvent e )
  {
    hasChanged = true;
  }

  @Override
  public void removeUpdate( DocumentEvent e )
  {
    hasChanged = true;
  }

  @Override
  public void changedUpdate( DocumentEvent e )
  {
  }

  @Override
  public void keyTyped( KeyEvent e )
  {
    int kc = e.getKeyChar();
    Object o = e.getSource();
    JTextField tf = (JTextField)o;

    if ( o == tfTelefon )
    {
      if ( !( Character.isDigit( kc ) || kc == ' ' || kc == '/' || kc == '-' ) )
      {
        e.consume();
        return;
      }

      tf.replaceSelection( "" );
      if ( tf.getText().length() >= 10 )
      {
        e.consume();
        return;
      }
    }
  }

  @Override
  public void keyPressed( KeyEvent e )
  {
    int kc = e.getKeyCode();
    Object o = e.getSource();

    if ( o == tfGastname && kc == KeyEvent.VK_ENTER
        && tfGastname.getText().length() > 0 )
      kbFocusManager.focusNextComponent();
    else if ( o == tfVorname && kc == KeyEvent.VK_ENTER )
      kbFocusManager.focusNextComponent();
    else if ( o == tfKurzname && kc == KeyEvent.VK_ENTER
        && tfKurzname.getText().length() > 0 )
      kbFocusManager.focusNextComponent();
    else if ( o == tfTelefon && kc == KeyEvent.VK_ENTER
        && tfTelefon.getText().length() > 0 )
      kbFocusManager.focusNextComponent();
  }

  @Override
  public void keyReleased( KeyEvent e )
  {
    int kc = e.getKeyCode();
    if ( kc == 27 ) //ESC
    {
      windowClosing( new WindowEvent( this, WindowEvent.WINDOW_CLOSING ) );
    }
  }

  @Override
  public void actionPerformed( ActionEvent e )
  {
    Object o = e.getSource();

    if ( o == btnOK )
      windowClosing( new WindowEvent( this, WindowEvent.WINDOW_CLOSING ) );
    if ( o == btnAbbrechen )
    {
      hasChanged = false;
      windowClosing( new WindowEvent( this, WindowEvent.WINDOW_CLOSING ) );
    }
  }

  @Override
  public void itemStateChanged( ItemEvent e )
  {
    hasChanged = true;
  }
}
