/**
@author Martin Klossek, Martin Meedt und Fabian Wleklinski
letzte Bearbeitung: 29.05.99 | 14:00 
*/

import java.awt.*;
import java.io.*;


/** Beinhaltet den Arbeitsbereich und auch die Programmeinstellungen des
Zeichenprogrammes */
public class TPaint {
  
  public TPaint() {
    FPaintWorkplace = new TPaintWorkplace();
    FPaintSettings = new TPaintSettings();
  }

  /** Liefert die Instanz der Programmeinstellungen zurück */
  public TPaintSettings PaintSettings() {
    return FPaintSettings;
  }

  /** Liefert die Instanz des Arbeitsbereiches zurück */
  public TPaintWorkplace PaintWorkplace() {
    return FPaintWorkplace;
  }

  /** Speichert den Arbeitsbereich und die Programmeinstellungen in einer Datei */
  public void saveToFile( String filename ) throws java.io.FileNotFoundException, java.io.IOException {
    FileOutputStream fileOutputStream = new FileOutputStream( filename );
    ObjectOutputStream objectOutputStream = new ObjectOutputStream( fileOutputStream );

    objectOutputStream.writeObject( FPaintWorkplace );
    objectOutputStream.writeObject( FPaintSettings );
    objectOutputStream.flush();

    fileOutputStream.close();
  }

  /** Restauriert den Arbeitsbereich und die Programmeinstellungen aus einer Datei */
  public void loadFromFile( String filename ) throws java.io.StreamCorruptedException, java.io.IOException, java.lang.ClassNotFoundException {
    FileInputStream fileInputStream = new FileInputStream( filename );
    ObjectInputStream objectInputStream = new ObjectInputStream( fileInputStream );

    FPaintWorkplace = (TPaintWorkplace) objectInputStream.readObject();
    FPaintSettings = (TPaintSettings) objectInputStream.readObject();

    fileInputStream.close();
  }

  // Der Arbeitsbereich
  private TPaintWorkplace FPaintWorkplace;

  // Die Programmeinstellungen
  private TPaintSettings FPaintSettings;
}

/** Beinhaltet einen Arbeitsbereich für beliebig viele Zeichenobjekte */
class TPaintWorkplace implements java.io.Serializable{

  /** Erzeugt einen Arbeitsbereich */
  public TPaintWorkplace() {
    // vererbten Konstruktor aufrufen
    super();

    // Den Container für die Elemente anlegen. Für das erste benutzen wir mal 10 Elemente
    items = new Object[ 10 ];
  }

  /** löscht alle Elemente */
  public void clear(  ) {
    for (int itemI=0; itemI < FCount; itemI++) {
      items[ itemI ] = null;
    }
    FCount = 0;
  }

  /** Fügt ein Grafikelement hinzu.
  @param item Das hinzuzufügende Grafikelement
  */
  public void add( TGraphic item ) {
    // sicherstellen, daß genügend Platz vorhanden ist
    ensureCapacity( FCount + 1 );
    // Das neue Element aufnehmen
    items[ FCount ] = item;
    // Elementzähler erhöhen
    FCount++;
  }

  /** Liefert ein Grafikelement zurück
  @param index Der Index des Grafikelementes
  */
  public TGraphic getItem( int index ) {
    TGraphic result = null;
    if (index < FCount) {
      result = (TGraphic) items[ index ];
    }

    return result;
  }

  /** Liefert den Index eines bestimmten Grafikelementes zurück
  @param item Das Grafikelement, für das der Index gesucht wird
  */
  public int indexOf( TGraphic graphic ) {
    int result = -1;
    for (int itemI=0; itemI < FCount; itemI++) {
      if ( ((TGraphic) items[ itemI ]) == graphic ) {
        result = itemI;
        break;
      }
    }
    return result;
  }

  /** löscht ein bestimmtes Grafikelement
  @param index Der Index des zu löschenden Elementes
  */
  public void delete( int index ) {
    // wenn Index außerhalb derGrenzen -> raus
    if ((index < 0) || (index >= FCount)) {
      return;
    }

    // Alle folgenden Elemente aufrücken
    for (int itemI = index; itemI < FCount-1; itemI++) {
      items[ itemI ] = items[ itemI+1 ];
    }

    FCount--;
  }

  /** Liefert die Anzahl der Elemente zurück, die im Moment vorhanden sind */
  public int count() {
    return FCount;
  }

  /* Stellt sicher, daß Platz für die übergebene Anzahl an Elementen ist. Wenn nicht,
  wird Platz geschaffen */
  private void ensureCapacity( int count ) {
    // Wenn genügend Platz ist -> raus
    if (items.length >= count) {
      return;
    }

    // Ein neues Array anlegen, mit der doppelten, gewünschten Größe
    Object[] tempArray = new Object[ count * 2 ];
    // Die bestehenden Elemente dort hineinkopieren
    System.arraycopy( items, 0, tempArray, 0, items.length );
    // Das temporäre Array übernehmen
    items = tempArray;
  }

  /* Hält die Anzahl der Elemente, die momentan zugewiesen sind */
  private int FCount;

  /* Hält alle Grafikelemente */
  public Object[] items;
}

/** Beinhaltet die Programmoptionen */
class TPaintSettings implements java.io.Serializable {
  /** Die Größe des Workplace */
  public double maxX, maxY; 
  /** Die Startkoordinaten des sichtbaren Workplace-Ausschnittes */
  public double mapStartX, mapStartY;
  /** Die Endkoordinaten des sichtbaren Workplace-Ausschnittes */
  public double Xratio, Yratio;
  /** Die Größe des Fensters */
  public int frameWidth, frameHeight;  
  /** Aktuelle Zeichenfarbe */
  public Color currentColor;
  /** Aktuelle Hintergrundfarbe */
  public Color currentBGColor;
} 