#pragma once

#include <Knopf.h>
#include <Array.h>
#include <Punkt.h>
#include <Bild.h>
#include <Model2D.h>
#include <DateiDialog.h>

using namespace Framework;

namespace Model2DEditor
{
    class VertexData
    {
    private:
        Vec2< float > vertex;
        Punkt textur;
        bool selected;
        bool sichtbar;
        int ref;

    public:
        // Konstruktor
        VertexData( Vec2< float > v, Punkt t );
        // nicht constant
        void nachLinks( float num );
        void nachOben( float num );
        void saveTextur( Punkt tPos );
        void select( Punkt p1, Punkt p2 );
        void deSelect();
        void setAuswahl( bool ausw );
        void setSichtbar( bool s );
        // constant
        bool istSichtbar() const;
        bool istAusgewählt() const;
        Vec2< float > getPos() const;
        Punkt getTPos() const;
        // Reference Counting
        VertexData *getThis();
        VertexData *release();
    };

    class PolygonData
    {
    private:
        RCArray< VertexData > *vd;
        bool sichtbar;
        int ref;

    public:
        // Konstruktor
        PolygonData( Polygon2D &pg );
        // Destruktor
        ~PolygonData();
        // nicht constant
        void addVertex( Vec2< float >v, Punkt t );
        void removeVertex( int num );
        void nachLinks( float num );
        void nachOben( float num );
        void saveTextur( Punkt tPos );
        void select( Punkt p1, Punkt p2 );
        void deSelect();
        void setSichtbar( bool s );
        // constant
        bool istSichtbar() const;
        VertexData *zVertex( int num ) const;
        int getVertexAnzahl() const;
        void getM2( Polygon2D &pd, bool textur ) const;
        // Reference Counting
        PolygonData *getThis();
        PolygonData *release();
    };

    class Data
    {
    private:
        RCArray< PolygonData > *pd;
        Bild *textur;
        Punkt tPos;
        bool rTextur;
        int sp;
        int ref;

    public:
        // Konstruktor
        Data( Model2DData *mdl );
        // Destruktor
        ~Data();
        // nicht constant
        void addPolygon();
        void removePolygon( int num );
        void selectPolygon( int num );
        void nachLinks( float num );
        void nachOben( float num );
        void tNachLinks( int num );
        void tNachOben( int num );
        void setRTextur( bool rt );
        void saveTextur();
        void setTextur( Bild *t );
        void select( Punkt p1, Punkt p2 );
        void deSelect();
        // constant
        PolygonData *zPolygon( int num ) const;
        int getPolygonAnzahl() const;
        int getSelectedPolygon() const;
        Model2DData *getM2() const;
        Bild *zTextur() const;
        Punkt getTPos() const;
        // Reference Counting
        Data *getThis();
        Data *release();
    };

    class EditorListe : public Zeichnung
    {
    private:
        LRahmen *ram;
        VScrollBar *scroll;
        Data *data;
        Array< bool > ausgeklappt;
        Schrift *schrift;
        int ref;

    public:
        // Konstruktor
        EditorListe( Schrift *zSchrift );
        // Destruktor
        ~EditorListe();
        // nicht constant
        void setDataZ( Data *d );
        void doMausEreignis( MausEreignis &me ) override;
        bool tick( double zeit ) override;
        void render( Bild &zRObj ) override;
        // Reference Counting
        EditorListe *getThis();
        EditorListe *release();
    };
    
    class Editor2D : public Zeichnung
    {
    private:
        Punkt pos;
        Punkt offs;
        Data *data;
        LRahmen *ram;
        LRahmen *select;
        Schrift *schrift;
        Punkt mausPos;
        Vertex addV;
        bool mausIn;
        float größe;
        int ref;

    public:
        // Konstruktor
        Editor2D( Schrift *zSchrift );
        // Destruktor
        ~Editor2D();
        // nicht constant
        void setDataZ( Data *d );
        void doMausEreignis( MausEreignis &me ) override;
        void doTastaturEreignis( TastaturEreignis &te ) override;
        bool tick( double zeit ) override;
        void render( Bild &zRObj ) override;
        // Reference Counting
        Editor2D *getThis();
        Editor2D *release();
    };

    class GUI : public Zeichnung
    {
    private:
        Knopf *speichern;
        Knopf *abbrechen;
        Editor2D *editor;
        EditorListe *liste;
        KontrollKnopf *textur;
        Knopf *texturLaden;
        Knopf *texturVerknüpfen;
        DateiDialogTh *importDialog;
        Data *data;
        bool sichtbar;
        unsigned char alpha;
        int aktion;
        int ref;

    public:
        // Konstruktor
        GUI( Schrift *zSchrifto );
        // Destruktor
        ~GUI();
        // nicht constant
        void setSichtbar( bool s );
        void setModel( Model2DData *data );
        void doMausEreignis( MausEreignis &me ) override;
        void doTastaturEreignis( TastaturEreignis &te ) override;
        bool tick( double zeit ) override;
        void render( Bild &zRObj ) override;
        int getAktion();
        // const
        Model2DData *getM2Data() const;
        // Reference Counting
        GUI *getThis();
        GUI *release();
    };
}