package kuchenBasar;

import java.sql.*;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import util.*;

/**
 * Datenbankzugriffsmodul Gaeste
 * 
 * @author Bernd Schubert
 * 
 */
public class GaesteDB
{
  private GaesteDB()
  {
  }

  /**
   * 
   * @return Aktuelle ID (z.B. gerade beim Insert erzeugt)
   */
  private static int getMaxID()
  {
    String sql = " SELECT MAX(ID) ";
          sql += " FROM gaeste ";

    int retValue = -1;

    try
    {
      Object obj = DBConnection.executeScalar( sql );

      if ( obj != null )
        retValue = (int)obj;
    }

    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim MAX-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @param ID
   * @return ist (noch) vorhanden?
   */
  public static boolean isGastVorhanden( int ID )
  {
    String sql = " SELECT COUNT(*) ";
          sql += " FROM gaeste";
          sql += " WHERE ID = ? ";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    ResultSet result = null;
    boolean retValue = false;

    try
    {
      prepStatement.setInt( 1, ID );

      result = prepStatement.executeQuery();

      if ( result != null )
      {
        result.next();
        retValue = ( result.getInt( 1 ) > 0 );
      }
    }

    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Exist-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @return Anzahl der vorhandenen Gaeste Der technische Satz ID wird nicht mitgezählt
   */
  public static int getGaesteAnzahl()
  {
    String sql = " SELECT COUNT(*) ";
          sql += " FROM gaeste ";
          sql += " WHERE ID > 0 ";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    ResultSet result = null;
    int retValue = -1;

    try
    {
      result = prepStatement.executeQuery();

      if ( result != null )
      {
        result.next();
        retValue = result.getInt( 1 );
      }
    }

    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Count-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @param ID
   * @return Gast-Objekt zur ID
   */
  public static Gast getGast( int ID )
  {
    String sql = " SELECT ID, gastname, vorname, kurzgast, ";
          sql += " einrichtung, telefon, letzterzugriff ";
          sql += " FROM gaeste ";
          sql += " WHERE ID = ? ";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    ResultSet result = null;
    Gast retValue = new Gast();

    try
    {
      prepStatement.setInt( 1, ID );

      result = prepStatement.executeQuery();

      if ( result != null )
      {
        result.next();
        retValue.setID( result.getInt( 1 ) );
        retValue.setName( result.getString( 2 ) );
        retValue.setVorname( result.getString( 3 ) );
        retValue.setKurzname( result.getString( 4 ) );
        retValue.setEinrichtung( result.getInt( 5 ) );
        Object test = result.getObject( 6 );
        if ( test != null )
          retValue.setTelefon( result.getString( 6 ) );
        retValue.setLetzterzugriff( result.getString( 7 ) );
      }
    }

    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim ID-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @param ID
   * @return Einrichtung des Gastes zur ID
   */
  public static String getEinrichtung( int ID )
  {
    String sql = " SELECT einrichtung ";
          sql += " FROM gaesteview ";
          sql += " WHERE ID = ? ";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    ResultSet result = null;
    String retValue = "";

    try
    {
      prepStatement.setInt( 1, ID );

      result = prepStatement.executeQuery();

      if ( result != null )
      {
        result.next();
        retValue = result.getString( 1 );
      }
    }

    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Einrichtung-Zugriff auf die View GaesteView: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @return Liste aller Gaeste mit <ID und Name>
   */
  public static ArrayList<ListItem> getGaesteListe()
  {
    String sql = " SELECT ID, kurzgast ";
          sql += " FROM gaesteview ";
    //    sql += " WHERE ID > 0";

    //Auch wenn keine Parameter zu versorgen sind, 
    //gebe ich dem PreparedStatement den Vorzug

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    ResultSet result = null;
    ArrayList<ListItem> retValue = new ArrayList<ListItem>();

    try
    {
      result = prepStatement.executeQuery();

      while ( result.next() )
      {
        ListItem listitem = new ListItem( result.getInt( 1 ), result.getString( 2 ) );
        retValue.add( listitem );
      }
    }

    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Liste-Zugriff auf die View GaesteView: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @return Liste aller Gaeste-Objekte
   */
  public static ArrayList<Gast> getGaesteTabelle()
  {
    String sql = " SELECT ID, gastname, vorname, kurzgast, ";
          sql += " einrichtung, telefon, letzterzugriff ";
          sql += " FROM gaeste ";
    //    sql += " WHERE ID > 0 ";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    ResultSet result = null;
    ArrayList<Gast> retValue = new ArrayList<Gast>();

    try
    {
      result = prepStatement.executeQuery();

      while ( result.next() )
      {
        Gast gast = new Gast();
        gast.setID( result.getInt( 1 ) );
        gast.setName( result.getString( 2 ) );
        gast.setVorname( result.getString( 3 ) );
        gast.setKurzname( result.getString( 4 ) );
        gast.setEinrichtung( result.getInt( 5 ) );
        Object test = result.getObject( 6 );
        if ( test != null )
          gast.setTelefon( result.getString( 6 ) );
        gast.setLetzterzugriff( result.getString( 7 ) );
        retValue.add( gast );
      }
    }

    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Tabelle-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @return Liste aller Gaeste als ResultSet für die JTable Diese kann die ResultSet-Felder selber
   *         und besser (da anonym) auswerten
   */
  public static ResultSet getGaesteSet()
  {
    String sql = " SELECT ID ID, ";
          sql += " gastname AS Name, vorname AS Vorname, einrichtung AS Einrichtung, ";
          sql += " telefon AS Telefon ";
          sql += " FROM gaesteview ";
          sql += " WHERE ID > 0 ";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    ResultSet retValue = null;

    try
    {
      retValue = prepStatement.executeQuery();
    }

    catch ( Exception ex )
    {
      JOptionPane.showMessageDialog(
          null,
          "Fehler beim RSet-Zugriff auf die View GaesteView: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @param gast
   * @return ID des erzeugten und eingefügten neuen Gastes
   */
  public static int insertGast( Gast gast )
  {
    String sql = " INSERT INTO gaeste ";
          sql += " (gastname, vorname, kurzgast, ";
          sql += " einrichtung, telefon, letzterzugriff) ";
          sql += " VALUES ( ?, ?, ?, ?, ?, CURRENT_TIMESTAMP )";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    int retValue = -1;

    try
    {
      prepStatement.setString( 1, gast.getName() );
      prepStatement.setString( 2, gast.getVorname() );
      prepStatement.setString( 3, gast.getKurzname() );
      prepStatement.setInt( 4, gast.getEinrichtung() );
      prepStatement.setString( 5, gast.getTelefon() );

      DBConnection.beginTransaction();

      prepStatement.executeUpdate();

      //Wichtig! In der laufenden Transaktion nach dem gerade eingefügten
      //Satz fahnden
      retValue = getMaxID();

      DBConnection.commitTransaction();
    }

    catch ( Exception ex )
    {
      DBConnection.rollbackTransaction();

      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Insert-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @param ID
   * @param gast
   * @return erfolgreich
   */
  public static boolean updateGast( int ID, Gast gast )
  {
    String sql = " UPDATE gaeste ";
          sql += " SET gastname = ?, vorname = ?, kurzgast = ?, ";
          sql += " einrichtung = ?, telefon = ?, ";
          sql += " letzterzugriff = CURRENT_TIMESTAMP ";
          sql += " WHERE ID = ? ";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    boolean retValue = false;

    try
    {
      prepStatement.setString( 1, gast.getName() );
      prepStatement.setString( 2, gast.getVorname() );
      prepStatement.setString( 3, gast.getKurzname() );
      prepStatement.setInt( 4, gast.getEinrichtung() );
      prepStatement.setString( 5, gast.getTelefon() );
      prepStatement.setInt( 6, ID );

      DBConnection.beginTransaction();

      prepStatement.executeUpdate();

      DBConnection.commitTransaction();

      retValue = true;
    }

    catch ( Exception ex )
    {
      DBConnection.rollbackTransaction();

      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Update-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * 
   * @param ID
   * @return erfolgreich
   */
  public static boolean deleteGast( int ID )
  {
    String sql = " DELETE FROM gaeste ";
          sql += " WHERE ID = ? ";

    PreparedStatement prepStatement = DBConnection.prepareStatement( sql );
    boolean retValue = false;

    try
    {
      prepStatement.setInt( 1, ID );

      DBConnection.beginTransaction();

      prepStatement.executeUpdate();

      DBConnection.commitTransaction();

      retValue = true;
    }

    catch ( Exception ex )
    {
      DBConnection.rollbackTransaction();

      JOptionPane.showMessageDialog(
          null,
          "Fehler beim Delete-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }

  /**
   * Leeren der Gaeste-Tabelle
   * 
   * @return erfolgreich
   */
  public static boolean zapGaeste()
  {
    //Entwurfsentscheidung: wir lassen den technischen 0-Satz mal leben...
    String sql = " DELETE FROM gaeste ";
          sql += " WHERE ID > 0 ";

    boolean retValue = false;

    try
    {
      DBConnection.beginTransaction();

      DBConnection.executeNoneQuery( sql );

      DBConnection.commitTransaction();

      retValue = true;
    }

    catch ( Exception ex )
    {
      DBConnection.rollbackTransaction();

      JOptionPane.showMessageDialog(
          null,
          "Fehler beim ZAP-Zugriff auf die Tabelle Gaeste: " + ex.getMessage(),
          "db-Fehler",
          JOptionPane.ERROR_MESSAGE
          );
    }

    return retValue;
  }
}
