/**
*
* Das Hauptprogramm
*
* @version 1.0 vom 03.06.02
* @author Xenia Rendtel
*/


import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.lang.*;

public class Fenster extends Canvas {

    public Color farbe, ffarbe;
    public Vector elemente = new Vector();
    public Class objektauswahl;
    public final String[] figuren = {"Punkt", "Strecke", "Rechteck", "Oval", "Rechteckgef", "Ovalgef"};
    public final String[] befehle = {"Neu", "Oeffnen", "Speichern", "Beenden",
                                     "Rueckgaengig", "Verschieben", "Loeschen",
                                     "Punkt", "Linie", "Rechteck", "Oval", "Rechteck gefuellt",
                                     "Oval gefuellt",
                                     "Rot", "Blau", "Gruen", "Gelb", "Schwarz", "Weiss",
                                     "Rotgef", "Blaugef", "Gruengef", "Gelbgef", "Schwarzgef", "Weissgef",
                                     "Nach Oben", "Nach Unten",
                                     "Info"};

    public static Color[] farben =  {Color.red, Color.blue, Color.green, Color.yellow, Color.black, Color.white};
    public static Color[] ffarben =  {Color.red, Color.blue, Color.green, Color.yellow, Color.black, Color.white};

    Grafikeindim figur;
    public Grafikeindim ersatz;
    public boolean anfang = true;
    public boolean verschieben = false;
    private ByteArrayOutputStream puffer = new ByteArrayOutputStream();
    public int x1, x2, y1, y2;


    public Fenster() {
        this.addMouseListener(new MausListener());
        this.addMouseMotionListener(new MausMotionListener());
        farbe = Color.black;
        ffarbe = Color.red;
    }

    public static void main (String args[]) {


        Fenster canvas = new Fenster();
        Aktionen reaktion = new Aktionen(canvas);




        Frame fenster = new Frame("Ein Grafikprogramm");
        fenster.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });


        fenster.setSize(600,600);

        // ein Panel erzeugen
        Panel panel = new Panel();
        panel.setLayout(new FlowLayout(FlowLayout.LEFT));

        // das Menü
        MenuBar mb = new MenuBar();  // die Menüpunkte werden angelegt

        Menu m1 = new Menu("Datei");
        for (int i = 0; i <= 2; i++) {
            canvas.Menueeintrag(m1, canvas.befehle[i], reaktion);
        }
        m1.addSeparator();
        canvas.Menueeintrag(m1, canvas.befehle[3], reaktion);

        Menu m2 = new Menu("Bearbeiten");
        for (int i = 4; i <= 5; i++) {
            canvas.Menueeintrag(m2, canvas.befehle[i], reaktion);
        }
        m2.addSeparator();
        canvas.Menueeintrag(m2, canvas.befehle[6], reaktion);

        Menu m3 = new Menu("Form");
        for (int i = 7; i <= 12; i++) {
            canvas.Menueeintrag(m3, canvas.befehle[i], reaktion);
        }

        Menu m4 = new Menu("Farben");
        Menu submenu1 = new Menu("Malfarbe");
        for (int i = 13; i <= 18; i++) {
            canvas.Menueeintrag(submenu1, canvas.befehle[i], reaktion);
        }
        Menu submenu2 = new Menu("Fuellfarbe");
        for (int i = 19; i <= 24; i++) {
            canvas.Menueeintrag(submenu2, canvas.befehle[i], reaktion);
        }


        Menu m5 = new Menu("Anordnung");
        for (int i = 25; i<=26; i++) {
            canvas.Menueeintrag(m5, canvas.befehle[i], reaktion);
        }

        Menu m6 = new Menu("Hilfe");
        canvas.Menueeintrag(m6, canvas.befehle[27], reaktion);

        mb.add(m1);
        mb.add(m2);
        mb.add(m3);
        mb.add(m4);
        m4.add(submenu1);
        m4.add(submenu2);
        mb.add(m4);
        mb.add(m5);
        mb.add(m6);


        fenster.setMenuBar(mb);



        //der Listener
        canvas.addMouseListener(new Aktionen(canvas));


        // ein Panel erzeugen
        for (int i = 7; i <= 12; i++) {
            canvas.Buttoneintrag(panel, canvas.befehle[i], reaktion);
        }



        fenster.setLayout(new BorderLayout());
        fenster.add("South", panel);
        fenster.add("Center", canvas);
        fenster.show();


    }


    public void paint(Graphics g) {
        try{
            Enumeration i = elemente.elements();
            while (i.hasMoreElements()) {
                ((Grafikeindim)i.nextElement()).Zeichne(g);
            }
        }
        catch (Exception err) {}
        try{
            ersatz.Zeichne(g);
            /* die Ersatz Figur wird gezeichnet,
               damit man Veränerungen sihet */

        }
        catch (Exception err) {
        }
    }


    public void SetzeFuellfarbe(Color fuellfarbe) {
        ffarbe = fuellfarbe;
        if (figur instanceof Voll) {
            ((Voll)figur).SetzeFuellfarbe(ffarbe);
        }
    }



    public void SetzeFarbe(Color malfarbe) {  // die Farbe wird gesetzt
        farbe = malfarbe;
        figur.SetzeFarbe(farbe);
    }



    public void Neu() {
        deselect();
        elemente = new Vector();
        deselect();
        repaint();
    }

    public void Speichern() {  /* in eine Datei wird geschrieben,
                                  da es sich nicht nur um TExt handelt
                                  wird ObjectOutputStream genutzt,
                                  damit man die Rohdaten speichert
                                  siehe:
                                  http://java.sun.com/j2se/1.4/docs/api/java/io/ObjectOutputStream.html
                               */
        Frame speicher = new Frame();
        FileDialog speicherdialog = new FileDialog(speicher, "Datei speichern", FileDialog.SAVE);
        speicherdialog.show();
        if (speicherdialog.getFile() != null) {
            try {
                FileOutputStream out = new FileOutputStream(speicherdialog.getDirectory()+speicherdialog.getFile());
                SchreibeBild(out);
            }
            catch(FileNotFoundException err) {
            }
            catch (IOException err) {
            }
        }
    }

    public void SchreibeBild(OutputStream os) {
        try {
            ObjectOutputStream ous = new ObjectOutputStream(os);
            ous.writeObject(elemente);
        }
        catch (Exception err) {
        }
    }

    public void Oeffnen() {
        Frame oeffnen = new Frame();
        FileDialog oeffnendialog = new FileDialog(oeffnen, "Datei oeffnen", FileDialog.LOAD);
        oeffnendialog.show();
        if (oeffnendialog.getFile() != null) {

            try {
                FileInputStream in = new FileInputStream(oeffnendialog.getDirectory()+oeffnendialog.getFile());
                LeseBild(in);
            }
            catch (Exception err) {
            }
        }
    }

    public void LeseBild(InputStream is) {
        try {
            ObjectInputStream ois = new ObjectInputStream(is);
            elemente = (Vector)ois.readObject();
            deselect();
            repaint();
        }
        catch (Exception err) {
        }
    }


    public void deselect() {  /* ein markiertes Objekt soll aus dem
                                 markierten Bereich heraus.
                              */

        Enumeration i = elemente.elements();
        while (i.hasMoreElements() == true) {
            ((Grafikeindim)i.nextElement()).ausgewaehlt = false;
        }
        figur = null;
        ersatz = null;
    }




    public void select(Point p) {                   //auswahl eines Punktes
        deselect();
        Grafikeindim ersatz;
        for (int i = elemente.size() -1; i >= 0; i--) {  /* es wird der Vektor
                                                            von hinten durchschaut, ob
                                                            das Objekt enthalten ist
                                                         */

               ersatz = (Grafikeindim)elemente.elementAt(i);
               if (ersatz.contains(p) == true) {
                   figur = ersatz;
                   ersatz.ausgewaehlt = true;
                   break;                               /* wenn der Punkt
                                                           gefunden wurde
                                                           wird die for-Schleife
                                                           beendet.
                                                        */

               }

        }
           repaint();
    }


    public void SchreibeRueckgaengig() {
        puffer = new ByteArrayOutputStream();
        SchreibeBild(puffer);
    }


    public void Rueckgaengig() {
        ByteArrayInputStream  pufferin = new ByteArrayInputStream(puffer.toByteArray());
        LeseBild(pufferin);
    }


    public void Loeschen() {
        if (figur != null) {
            elemente.remove(figur);
            figur = null;
            repaint();
        }


    }


    public void Vorne() {  /* Objekt nach hinten in den Vector packen */
        if (figur != null) {
       elemente.remove(figur);
       elemente.add(figur);
       repaint();
       deselect();

        }
    }

    public void Hinten() { /* Objekt nach voorne in den Vektor packeb */
        if (figur != null) {
            elemente.remove(figur);
            elemente.add(0, figur);
            repaint();
            deselect();
        }

    }

    public void Info() {

        getGraphics().setColor(new Color(0,0,0));
        getGraphics().setFont(new Font(null, 0, 12));
        getGraphics().drawString("Dieses Programm ist von Xenia (-:", 10,10);

    }






    // erleichtert die Arbeit
    public void Menueeintrag(Menu m, String eintrag, Aktionen wo) { // ein Menü wird angelegt

        MenuItem item = new MenuItem(eintrag);
        item.setActionCommand(eintrag);
        item.addActionListener(wo);
        m.add(item);

    }

    public void Buttoneintrag(Panel p, String eintrag, Aktionen wo) {  //definiert die Buttons

        Button button = new Button(eintrag);
        button.setActionCommand(eintrag);
        button.addActionListener(wo);
        p.add(button);

    }




    /* ............................. */
    // hier kommt die Maus (wo ist der Elefant?)...
    /* ............................. */


    class MausListener extends MouseAdapter {

        public void mouseReleased(MouseEvent e) {
        anfang = true;
        verschieben = false;
        }
        public void mouseClicked(MouseEvent e) {
            select(e.getPoint());
            try {
                if ((figur == null) && objektauswahl.getName().equals("Punkt")) {
                    SchreibeRueckgaengig();
                    try {
                        figur = new Punkt();
                        figur.SetzeFarbe(farbe);
                        figur.SetzePos(e.getX(),e.getY());
                        figur.Zeichne(getGraphics());
                        elemente.add(figur);
                    }
                    catch (Exception err) {}
               }
            }
            catch (Exception err) {
           }


       }

    }


    class MausMotionListener extends MouseMotionAdapter {

        public void mouseDragged(MouseEvent e) {
            if (figur != null) {  /* es gibt schon eine Figur, deren Anfang übernommen wird */
                if (anfang == true) {
                    x1 = figur.x1;
                    y1 = figur.y1;
                    anfang = false;
                }
                else {
                    if (verschieben == true) {      /* Objekt verschieben */
                        figur.SetzePosrel(e.getX(), e.getY());
                        figur.SetzeFarbe(farbe);
                        if (figur instanceof Voll)
                            ((Voll)figur).SetzeFuellfarbe(ffarbe);
                        figur.Zeichne(getGraphics());


            }
                    else {                     /* Skalieren */
                        figur.SetzePositionen(x1,y1,e.getX(),e.getY());
                        figur.SetzeFarbe(farbe);
                        if (figur instanceof Voll)
                            ((Voll)figur).SetzeFuellfarbe(ffarbe);
                        figur.Zeichne(getGraphics());

                    }
                }
            }
            else {
                if (anfang == true) {
                    x1 = e.getX();
                    y1 = e.getY();
                    try {
                        SchreibeRueckgaengig();
                        ersatz = (Grafikeindim)objektauswahl.newInstance();
                        ersatz.SetzePositionen(x1, y1, e.getX(), e.getY());
                        if (ersatz instanceof Grafikzweidim)
                            ((Grafikzweidim)ersatz).SetzePositionen(x1, y1, e.getX(), e.getY());
                        ersatz.SetzeFarbe(farbe);
                        if (ersatz instanceof Voll)
                            ((Voll)ersatz).SetzeFuellfarbe(ffarbe);
                        elemente.add(ersatz);
                    }
                    catch (Exception ex) {
                }
                    anfang = false;
                }
                else {
                    if (ersatz instanceof Grafikzweidim) {
                        ((Grafikzweidim)ersatz).SetzePositionen(x1, y1, e.getX(), e.getY());
                    }
                }
            }
            repaint();
        }
    }

}

