/*
 * 
 * Datei:   Ausgabe.java
 * 
 * ---------------------------------
 * 
 * Datum:           $Date: 2004/05/13 13:21:23 $
 * Autor:           Simon Tiffert 
 * Prüfungsnummer:  40
 * Firma:           T-Systems
 * eMail-Adresse:   simon.tiffert@t-systems.com
 * Version:         $Revision: 1.15 $
 * 
 * ---------------------------------
 * 
 */

package main.ausgabe;

import java.io.BufferedWriter;
import java.io.IOException;

import main.Main;
import main.verarbeitung.Matrix;

/**
 * Die Klasse formatiert den Inhalt der Matrix für die grafische 
 * Ausgabe und gibt diese auf den angegebenen Ausgabestrom aus. Dabei 
 * wird sowohl die initiale Matrix, sowie die Matrix mit dem gesuchten 
 * Wert ausgegeben.
 *
 * @version $Revision: 1.15 $
 * @author Simon Tiffert
 */
public class Ausgabe
{
  /** Die zentrale Datenstruktur mit der Matrix */
  private Matrix matrix;

  /**
   * Konstruktor, der die Ausgabe erzeugt.
   * Übergeben werden die Matrix und der BufferedWriter der 
   * Ausgabedatei. Erzeugt wird dann einmal die Eingabe in 
   * Matrixansicht, sowie die durch Verarbeitung gewonnene Matrix mit 
   * Wegdaten.
   * 
   * 
   * @param matrix Zentrale Datenstruktur mit Matrix
   * @param bw BufferedWriter der Ausgabedatei
   * @throws IOException Ausgabedatei konnte nicht geschrieben werden
   */
  public Ausgabe(Matrix matrix, BufferedWriter bw) throws IOException
  {
    // setze das Attribut matrix
    this.matrix = matrix;

    // Matrix im Anfangszustand ausgeben; Zustand 'false'
    this.ausgabe(bw, false);

    // wenn ein Weg gefunden wurde, dann wird die Matrix im Endzustand 
    // ausgegeben; Zustand 'true'
    if (matrix.isWegGefunden())
    {
      this.ausgabe(bw, true);
    }
    // ansonsten erfolgt die Ausgabe, dass kein Weg gefunden wurde
    else
    {
      this.keinWegGefundenAusgabe(bw);
    }
  }

  /**
   * Funktion, die ausgibt, dass keine Sprungfolge gefunden wurde
   * 
   * @param bw BufferedWriter der Ausgabedatei
   * @throws IOException Fehler beim Schreiben auf Datei
   */
  private void keinWegGefundenAusgabe(BufferedWriter bw)
    throws IOException
  {
    String s = "    Keine Sprungfolge gefunden - Aufgabe unlösbar";

    // gib im Debugmodus die Information auch auf dem Bildschirm aus
    if (Main.debug)
    {
      System.out.println(s);
    }

    // schreibe die Meldung in die Ausgabedatei
    bw.write(System.getProperty("line.separator"));
    bw.write(s);
  }

  /**
   * Diese Funktion gibt die Matrix grafisch auf dem angegebenen 
   * Ausgabestrom aus. 
   * Dabei gibt es zwei Zustände, einmal den Anfangszustand der Matrix,
   * der aus den Eingabedaten erzeugt wird, sowie den Endzustand, der
   * einen gefundenen Weg ausgibt.
   * 
   * @param bw BufferedWriter für die Ausgabedatei
   * @param zustand <code>false</code>: Anfangszustand, 
   *                <code>true</code>:  Endzustand
   * @throws IOException Fehler beim Schreiben auf Datei
   */
  private void ausgabe(BufferedWriter bw, boolean zustand)
    throws IOException
  {
    // Hier wird die Ausgabe zusammengebaut
    StringBuffer ausgabeString = new StringBuffer();

    // Zeilenumbruch nach Betriebssystem anpassen
    String lineEnd = System.getProperty("line.separator");
    
    // Falls dies scheitert, setze Standard Zeilenumbruch
    if (lineEnd == null)
    {
      lineEnd = "\n";
    }

    // Tabulator
    String tabulator = "    ";

    // Matrixdimensionen lesen 
    int y = matrix.getYDimension();
    int x = matrix.getXDimension();

    // Trennzeichen für formatierte Ausgabe ermitteln
    String trennzeichen = "+";
    
    for( int i=0; i<x; i++ )
    {
      trennzeichen+=" -- +";
    }
    
    // Gib noch einen Header nach Zustand aus
    if (zustand)
    {
      ausgabeString.append(
        lineEnd + lineEnd + tabulator + "Ausgabedatei: " + lineEnd);
      ausgabeString.append(tabulator + "*************" + lineEnd);
    }
    else
    {
      ausgabeString.append(
        lineEnd + tabulator + "Eingabedaten: " + lineEnd);
      ausgabeString.append(tabulator + "*************" + lineEnd);
    }

    // Ausgabe in einer zweifach-geschachtelten for-Schleife
    // y-Werte durchlaufen
    for (int i = 0; i < y; i++)
    {
      // erste Zeile der Matrix ausgeben
      ausgabeString.append(lineEnd + tabulator);
      ausgabeString.append(trennzeichen);
      ausgabeString.append(lineEnd + tabulator);

      // x-Werte durchlaufen
      for (int j = 0; j < x; j++)
      {
        // Zeichen an aktueller Matrixposition lesen
        // und entsprechend formatieren
        String zeichen = " ";
        int wert = matrix.getWert(i, j);

        switch (wert)
        {
          // Gesperrte Felder
          case -1 :
            zeichen = "X";
            break;
            // Leere Felder
          case 0 :
            zeichen = matrix.isStartpunkt(i,j) ? "1" : " ";
            break;
            // Startpunkt
          case 1 :
            zeichen = "1";
            break;
            // Nummern der Sprungfolge
          default :
            if (zustand)
              zeichen = "" + wert;
            else
              zeichen = " ";
        }

        // Zeichen ausgeben
        ausgabeString.append(
          "| " + (zeichen.length() < 2 ? " " : "") + zeichen + " ");
      }
      ausgabeString.append("|");
    }
    // letzte Formatierungszeile ausgeben
    ausgabeString.append(lineEnd + tabulator);
    ausgabeString.append(trennzeichen);
    ausgabeString.append(lineEnd);

    // ist der Debugmodus gesetzt, dann gib die Fehlermeldung
    // zusätzlich auf dem Bildschirm aus
    if (Main.debug)
    {
      System.out.println(ausgabeString);
    }

    // schreibe in die Ausgabedatei
    bw.write(ausgabeString.toString());
  }
}
