
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;


import java.util.*;
    // Schreiben einer Instanz von Line und Rectangle
    // Schreiben von Instanzen (Line und Rectangle)
   // bitte beachten: einzeln wird typ gelesen
   //  in liste nicht


  public class Readwrite_int_double_3  extends JFrame {

  private JTextArea editor; // muss global sein, wird zugegriffen

  public Readwrite_int_double_3() {
    setGUI();  // setze GUI
       // wenn x-gedrückt, dann exit
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setSize(800, 500);  
    setLocation(40, 30);  // Position top, left
    setTitle("Einlesen und schreiben in Binärdatei, mit CDataInputStream, CDataOutputStream");  
  } // create

	// setzt die grafischen Elemente
  private void setGUI() {
    getContentPane().setLayout ( new BorderLayout(3,1) );  // 3,1 Rand
			// erzeugen der Schalter
    JButton bnwrite1 = new JButton("schreiben1");
    JButton bnread1 = new JButton("lesen1");
    JButton bnwrite2 = new JButton("schreiben2");
    JButton bnread2 = new JButton("lesen2");
    JButton bnclear = new JButton("löschen");
    JButton bnesc = new JButton("Abbruch");

		// erzeugen der zusätzlichen Pinwand für die Schalter
    JPanel pnButtons = new JPanel();
    pnButtons.setLayout( new FlowLayout() );
    pnButtons.setBackground( Color.red);
    pnButtons.add(bnwrite1);
    pnButtons.add(bnread1); 
    pnButtons.add(bnwrite2);
    pnButtons.add(bnread2); 
    pnButtons.add(bnclear);
    pnButtons.add(bnesc);
			// schrift setzen
    bnread1.setFont(new Font("Arial", Font.BOLD,20));
    bnwrite1.setFont( new Font("Arial", Font.BOLD,20));
    bnread2.setFont(new Font("Arial", Font.BOLD,20));
    bnwrite2.setFont( new Font("Arial", Font.BOLD,20));
    bnclear.setFont( new Font("Arial", Font.BOLD,20));
    bnesc.setFont( new Font("Arial", Font.BOLD,20));

		// Pinwand ins Hauptfenster eintragen
    getContentPane().add(pnButtons,BorderLayout.SOUTH);
    editor = new JTextArea();
    editor.setFont( new Font("Courier New", Font.BOLD,20));

    getContentPane().add( new JScrollPane(editor) ,BorderLayout.CENTER);
    editor.setText("");  // löschen des Editors (Inhalt)

		// Verknüpfung Schalter mit Methode
    bnread1.addActionListener(
      new java.awt.event.ActionListener() {
       public void actionPerformed(ActionEvent e) {
        bn_read1();
      }
    });

    bnwrite1.addActionListener(  
        new java.awt.event.ActionListener() {
		  public void actionPerformed(ActionEvent e) {
                      bn_write1();
		  }
    }
    );

    bnread2.addActionListener(
      new java.awt.event.ActionListener() {
       public void actionPerformed(ActionEvent e) {
        bn_read2();
      }
    });

    bnwrite2.addActionListener(  
        new java.awt.event.ActionListener() {
		  public void actionPerformed(ActionEvent e) {
                      bn_write2();
		  }
    }
    );

		// Verknüpfung Schalter mit "Methode"
    bnclear.addActionListener(
      new java.awt.event.ActionListener() {
       public void actionPerformed(ActionEvent e) {
             editor.setText(""); // so geht es auch
      }
    });

    bnesc.addActionListener(
      new java.awt.event.ActionListener() {
       public void actionPerformed(ActionEvent e) {
        System.exit(0);
      }
    });

  }// setGUI


  private void bn_write1() {
    try {
       FileOutputStream fout = new FileOutputStream("grafik.bin");
       DataOutputStream dout = new DataOutputStream(fout);
       Line line1 = new Line(10,10,300,400);
       line1.save(dout);
       dout.close();
       editor.append("write1  Line1: "+line1+"\n");
    }
     catch (IOException ee) {
         System.err.println("IOException: " + ee);
     }
  }  // write1

  private void bn_read1() {
    try {
       FileInputStream fin = new FileInputStream("grafik.bin");
       DataInputStream din = new DataInputStream(fin);
       Line line1 = new Line(0,0,0,0);
       line1.load(din,true);
       din.close();
       editor.append("read1  Line1: "+line1+"\n");
    }
     catch (IOException ee) {
         System.err.println("IOException: " + ee);
     }
  }  // read1



  private void bn_write2() {
    Line line1 = new Line(10,10,300,400);
    Rectangle rect1 = new Rectangle(10,10,200,500);
    Line line2 = new Line(10,10,300,400);
    Rectangle rect2 = new Rectangle(100,100,20,50);
    BildContainer cont = new BildContainer();
    cont.liste.add(line1);
    cont.liste.add(rect1);
    cont.liste.add(line2);
    cont.liste.add(rect2);
    cont.save("grafiken.bin");
    editor.append("\n\nContainer speichern" );
    editor.append(cont.toString() );
  }  // write2

  private void bn_read2() {
    BildContainer cont = new BildContainer();
    cont.load("grafiken.bin");
    editor.append("\n\nContainer laden" );
    editor.append(cont.toString() );
  }  // read2


  public static void main(String argv[]) {
      Readwrite_int_double_3  main = new Readwrite_int_double_3();
      main.setVisible(true);
  }  // main

}


class BildContainer  {
   public ArrayList<Grafik>  liste = new ArrayList<>();

   public BildContainer() {
   }

   public void save(String filename ) {
    try {
      FileOutputStream fout = new FileOutputStream(filename);
      DataOutputStream dout = new DataOutputStream(fout);
      dout.writeInt(liste.size());
      for (Grafik g : liste) {
         g.save(dout);
      }
      dout.close();
    }
    catch (IOException ee) {
         System.err.println("IOException: " + ee);
     }
   }

   public void load(String filename) {
    try {
      FileInputStream fin = new FileInputStream(filename);
      DataInputStream din = new DataInputStream(fin);
      liste.clear();
      int n= din.readInt();
      for (int i=0; i<n; i++)  {
         int typ = din.readInt();
         switch (typ) {
           case Grafik.LINE: Line line = new Line(0,0,0,0);
                                       line.load(din,false);
                                       liste.add(line);
                                      break;
           case Grafik.RECTANGLE: Rectangle rect = new Rectangle(0,0,0,0);
                                       rect.load(din,false);
                                       liste.add(rect);
                                      break;
         }
      }
      din.close();
    }
    catch (IOException ee) {
         System.err.println("IOException: " + ee);
     }
   }

  public String toString() {
   String s ="";
      for (Grafik g: liste) {
        s+=g+"\n";
      }
    return s+"\n\n";
  }

}


abstract class Grafik {
   public abstract void save(DataOutputStream dout );
   public abstract void load(DataInputStream din, boolean mitTyp );
   public final static int LINE=1;
   public final static int RECTANGLE=2;
}


class Line extends Grafik {
  private final int version=1;

   private int x1=0;
   private int y1=0;
   private int x2=0;
   private int y2=0;

   public Line(int x1, int y1, int x2, int y2) {
     this.x1=x1;
     this.y1=y1;
     this.x2=x2;
     this.y2=y2;
   }


  public int getx1() {
    return x1;
  }   //  getx1

  public void setx1 (int value) {
    x1=value;
  }   //  setx1



  public int gety1() {
    return y1;
  }   //  gety1

  public void sety1 (int value) {
    y1=value;
  }   //  sety1


  public int getx2() {
    return x2;
  }   //  getx2

  public void setx2 (int value) {
    x2=value;
  }   //  setx2



  public int gety2() {
    return y2;
  }   //  gety2

  public void sety2 (int value) {
    y2=value;
  }   //  sety2

  public String toString() {
    return "Linie: "+x1+"/"+y1+"      "+x2+"/"+y2;
  }

   public void save(DataOutputStream dout ) {
    try {
     dout.writeInt(Grafik.LINE);
     dout.writeInt(version);
     dout.writeInt(x1);
     dout.writeInt(y1);
     dout.writeInt(x2);
     dout.writeInt(y2);
    }
    catch (IOException ee) {
         System.err.println("IOException: " + ee);
     }
   }

   public void load(DataInputStream din, boolean mitTyp ) {
    try {
       int typ;
       if (mitTyp)  typ = din.readInt();
       int version=din.readInt();
       x1=din.readInt();
       y1=din.readInt();
       x2=din.readInt();
       y2=din.readInt();
    }
    catch (IOException ee) {
         System.err.println("IOException: " + ee);
     }
   }
}



class Rectangle extends Grafik {
  private final int version=1;
   private int x=0;
   private int y=0;
   private int w=0;
   private int h=0;

   public Rectangle(int x, int y, int w, int h) {
     this.x=x;
     this.y=y;
     this.w=w;
     this.h=h;
   }


  public int getx() {
    return x;
  }   //  getx

  public void setx (int value) {
    x=value;
  }   //  setx



  public int gety() {
    return y;
  }   //  gety

  public void sety (int value) {
    y=value;
  }   //  sety


  public int getw() {
    return w;
  }   //  getw

  public void setw (int value) {
    w=value;
  }   //  setw



  public int geth() {
    return h;
  }   //  geth

  public void seth (int value) {
    h=value;
  }   //  seth



  public String toString() {
    return "Rechteck: "+x+"/"+y+"      "+w+"/"+h;
  }

   public void save(DataOutputStream dout ) {
    try {
     dout.writeInt(Grafik.RECTANGLE);
     dout.writeInt(version);
     dout.writeInt(x);
     dout.writeInt(y);
     dout.writeInt(w);
     dout.writeInt(h);
    }
    catch (IOException ee) {
         System.err.println("IOException: " + ee);
     }
   }
   public void load(DataInputStream din, boolean mitTyp ) {
    try {
       int typ;
       if (mitTyp)  typ = din.readInt();
       int version=din.readInt();
       x=din.readInt();
       y=din.readInt();
       w=din.readInt();
       h=din.readInt();
    }
    catch (IOException ee) {
         System.err.println("IOException: " + ee);
     }
   }
}

