package network;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import other.ConnectionNotifier;

/**
 * DBModule Klasse
 * Stellt das DataAccessObject für die Kommunikation mit der
 * Datenbank dar, handelt daher die Verbindung und führt den gesamten
 * Datentransfer durch
 */
public class DBModule {
	
	 // Attribute
	 private Statement stmt;
	 private ResultSet rs;	
	 private String sQuery;
	 private boolean bIsConnected = false;

	 private String sUser;
	 private String sPassword;
	 
	 private ConnectionNotifier networkHandler;
	
	 /**
	  * Konstruktor
	  * @param netH NetworkHandler Objekt zur Statusmeldung
	  */
	public DBModule(ConnectionNotifier netH){
		networkHandler=netH;
	}

	/* ##########################################################################
	 * 						CONNECTION METHODEN
	 * ##########################################################################*/	
	
    /**
     * Liefert zurück, ob man gerade verbunden ist
     * @return true, wenn verbunden, sonst false
     */
    public boolean isConnected(){
    	return bIsConnected;
    }
	
	/**
	 * Stellt eine Verbindung mit dem SQL Server her
	 * @param ip IP Adresse des Servers zu dem verbunden werden soll
	 */
	public void connect(String ip){
		// Sicherheitsabfrage
		if(bIsConnected){
			System.out.println("Fehler DBModule.connect(): bereits verbunden");
			return;
		}
		// Treiber laden
		try{
			Class.forName("com.mysql.jdbc.Driver").newInstance();
		} 
		catch (Exception ex){
			System.out.println("MySQL-Treiber konnte nicht geladen werden!");
			return;
		}
		// Verbindung aufbauen
		Connection conn;
		try{
			// Mit Username
			conn = DriverManager.getConnection("jdbc:mysql://" + ip + "/Robotix", sUser, sPassword);
			stmt = conn.createStatement();
		}
		catch(SQLException ex){
			// Fehler.
			// Vielleicht läuft das Programm, deshalb
			// im Anschluss ohne Username probieren
			// ex.printStackTrace();
			stmt = null;
		}
		if(stmt!=null){
			bIsConnected=true;
			networkHandler.connectionNotification();
			return;
		}
		
		// Jetzt ohne Username bzw. mit lokalen Einstellungen probieren
		try{
			conn = DriverManager.getConnection("jdbc:mysql://" + ip + "/robotix","root","");
			stmt = conn.createStatement();
		}
		catch(SQLException ex){
			// Wieder Fehler => Fehlermeldung
			System.out.println("Die Verbindung konnte nicht hergestellt werden.");
			return;
		}
		// es hat funktioniert
		bIsConnected=true;
		networkHandler.connectionNotification();
	}
	
	/**
	 * Trennt die Verbindung zum Server.
	 */
	public void disconnect(){
		rs=null;
		stmt=null;
		bIsConnected=false;
		networkHandler.connectionNotification();
	}
	
	/**
	 * Überprüft die Verbindung
	 * Macht eine kleine Abfrage und schaut ob diese erfolgreich ist
	 */
	public void checkConnection(){
		try{
			rs=stmt.executeQuery("SELECT Nr FROM ttransobj LIMIT 0,0;");
		}catch(SQLException e){
			System.out.println("checkConnection SQL failed: " + e.getMessage());
			disconnect();
		}
	}

	/* ##########################################################################
	 * 						ÖFFENTLICHE METHODEN
	 * ##########################################################################*/		

	/**
	 * Legt die Daten für das Einloggen fest
	 * @param user Benutzername für die Anmeldung am MySQL Server
	 * @param passw Passwort für die Anmeldung am MySQL Server
	 */
	public void setLoginData(String user, String passw){
		sUser = user;
		sPassword = passw;
	}	
	
	/**
	 * Veranlasst, dass eine ConnectionNotification
	 * ausgelöst wird.
	 */
	public void raiseNotification(){
		networkHandler.connectionNotification();
	}
	
	/**
	 * lädt die Transportobjkete aus der Datenbank u. fügt sie
	 * zur TransObjData hinzu
	 * @return ein ResultSet Objekt, das alle Datensätze aus der Tabelle TTransObj enthält
	 */
	public ResultSet loadData(){
	  try{
	   rs=stmt.executeQuery("SELECT * FROM ttransobj ORDER BY Nr;");
	  }catch(SQLException e){
		  System.out.println("SQLException: " + e.getMessage());
      	  disconnect();
	  }
	 return rs;	
	}
	
	 /**
	  * Löscht eine Datei (Transportobjekt) aus dem config Ordner
	  * @param pNr Nummer bzw. Dateiname des zu löschenden Objekts
	  */
	 public void deleteObjInDB(int pNr){

	  //SQL-Abfrage
	  sQuery = "DELETE FROM ttransobj WHERE Nr='"+pNr+"';";
	  try{
	   stmt.executeUpdate(sQuery);
	  }catch(SQLException e){
		  System.out.println("Transport Objekt konnte nicht gelöscht werden!");
    	  disconnect();
	  }
	 }
	 
	 /**
	  * Ändert die Werte eines Transportobjekts in Db
	  * @param t Transportobjekt mit den geänderten Werten
	  */
	 public void updateObjInDB(TransObj t){

	  //SQL-Abfrage
	  sQuery = "UPDATE ttransobj SET Name='"+t.getName()+"',Radius='"+t.getRad()+"',Height='"+t.getHeight()+"' WHERE Nr='"+t.getNr()+"';";
	  try{
		  	stmt.executeUpdate(sQuery);
	  }catch(SQLException e){
		  	System.out.println("TransObj konnte nicht geändert werden!");
  	    	disconnect();
	  }
	 }
	 
	 /**
	  * Speichert ein Transportobjekt in der Datenbank
	  * @param t das zu speichernde TransObj
	  */
	 public void defineObjInDB(TransObj t){

	  //SQL-Abfrage
	  sQuery="INSERT INTO ttransobj VALUES ('"+t.getNr()+"','"+t.getName()+"','"+t.getRad()+"','"+t.getHeight()+"');";
	  try{
		  	stmt.executeUpdate(sQuery);
	  }catch(SQLException e){
		    System.out.println("TransObj konnte nicht eingefügt werden!");
		  	disconnect();
	  }
	 }
	 
	 /**
	  * Sucht die nächste freie Nummer
	  * @return Nummer die zum Speichern der .obj Datei verwendet werden kann
	  */
	 public int getFreeFile(){
		 int i=1;

		 //SQL-Abfrage
		 try{
			 rs=stmt.executeQuery("SELECT Nr FROM ttransobj ORDER BY Nr;"); 

			 while(rs.next()){ //Daten aus ResultSet auslesen u. überflüssige Zeichen abschneiden
				 if(Integer.parseInt(rs.getString("Nr").trim())>i) return i;
				 i++;
			 }
		}catch(SQLException e){
			System.out.println("Nächstes freies File konnte nicht gefunden werden!");
		  	disconnect();
		}
		return i;
	 }

	 /**
	  * schaut, ob ein TransObj in der Datenbank vorhanden ist
	  * od. nicht
	  * @param iNr Nummer des TransObj
	  * @return true wenn vorhanden, sonst false
	  */
	 public boolean isInDB(int iNr){
 	  //SQL-Abfrage
	  try{
	  	rs=stmt.executeQuery("SELECT Name FROM ttransobj WHERE Nr='"+iNr+"';");
	  	if(rs.next()){
	  	 return true;	
	  	}
	  }catch(SQLException e){
		  	System.out.println("TransObj konnte nicht geladen werden!");
		  	System.out.println("SQLException: " + e.getMessage());
		  	disconnect();
	  }
	  return false;
	 }
 }
