
#include <iostream>
#include <Fenster.h>
#include <Bildschirm.h>
#include <RenderThread.h>
#include <KSGScript.h>
#include <MausEreignis.h>
#include <TastaturEreignis.h>
#include <Schrift.h>
#include <DateiSystem.h>
#include <time.h>
#include <Textfeld.h>
#include <Datei.h>
#include <M2Datei.h>
#include <Model2D.h>
#include <Bild.h>
#include <Textur2D.h>

namespace Framework
{
    void initFramework();
    void releaseFramework();
}

using namespace Framework;
using namespace KSGScript;

class Obj : public Zeichnung
{
private:
    Model2D mdl;
    Model2D mdlA;
    Model2D mdlB;
    Punkt maus;
    Punkt mausAlt;
    Vertex hp;
    Vertex speed;
    Textur2D txt;
    float rot;

public:
    Obj()
    {
        M2Datei d;
        d.setPfad( "ship.m2" );
        d.leseDaten();
        Model2DData *m = d.ladeModel( "ship" );
        mdl.setModel( m );
        mdl.setStyle( Model2D::Style::Mesh | Model2D::Style::Textur | Model2D::Style::Sichtbar );
        mdl.setFarbe( 0xFFFFFFFF );
        mdl.setPosition( 150, 150 );
        mdlA.setStyle( Model2D::Style::Mesh | Model2D::Style::Textur );
        mdlA.setFarbe( 0xFFFFFFFF );
        mdlA.setPosition( 50, 50 );
        mdlB.setStyle( Model2D::Style::Mesh | Model2D::Style::Textur );
        mdlB.setFarbe( 0xFFFFFFFF );
        mdlB.setPosition( 250, 50 );
        hp = Vertex( 0, 0 );
        mausAlt = Punkt( 0, 0 );
        maus = Punkt( 0, 0 );
        LTDBDatei td;
        td.setDatei( new Text( "ship.ltdb" ) );
        td.leseDaten( 0 );
        Bild *b = td.laden( 0, new Text( "a.png" ) );
        txt.setTexturZ( b );
        mdl.setTextur( txt.getThis(), "ship" );
    }
    ~Obj()
    {}
    void doMausEreignis( MausEreignis &me ) override
    {
        lockZeichnung();
        maus.x = me.mx;
        maus.y = me.my;
        if( me.id == ME_RLinks )
        {
            mausAlt.x = me.mx;
            mausAlt.y = me.my;
        }
        hp = Vertex( 0, 0 );
        speed = Vertex( 0, 0 );
        if( mdl.zModel()->calcHitPoint( mausAlt - Vertex( 150, 150 ), maus - mausAlt, "ship", hp, speed, rot ) )
        {
            if( me.id == ME_RRechts )
            {
                Polygon2D a;
                Polygon2D b;
                Punkt pa;
                Punkt pb;
                mdl.zModel()->split( mausAlt - Vertex( 150, 150 ), maus - mausAlt, "ship", a, b, pa, pb, []()
                {
                    return rand() / (double)RAND_MAX;
                } );
                Array< Polygon2D > *aa = new Array< Polygon2D >();
                aa->add( a );
                Model2DData *ad = new Model2DData();
                ad->erstelleModell( aa );
                Array< Polygon2D > *ba = new Array< Polygon2D >();
                ba->add( b );
                Model2DData *bd = new Model2DData();
                bd->erstelleModell( ba );
                mdlA.setModel( ad );
                mdlB.setModel( bd );
                mdlA.setTextur( txt.getThis() );
                mdlB.setTextur( txt.getThis() );
                mdlA.addStyle( Model2D::Style::Sichtbar );
                mdlB.addStyle( Model2D::Style::Sichtbar );
            }
        }
        unlockZeichnung();
    }
    bool tick( double t ) override
    {
        return 1;
    }
    void render( Bild &bild ) override
    {
        lockZeichnung();
        mdl.render( bild );
        mdlA.render( bild );
        mdlB.render( bild );
        bild.fillCircle( maus.x, maus.y, 1, 0xFFFF0000 );
        bild.drawLinie( mausAlt, maus, 0xFF00FF00 );
        bild.fillCircle( hp.x + 150, hp.y + 150, 1, 0xFF0000FF );
        bild.drawLinie( Punkt( 150, 150 ), speed + Punkt( 150, 150 ), 0xFF00FF00 );
        for( int i = 1; i < 10; i++ )
        {
            Vertex pos = hp + ( maus - mausAlt ) * i + Vertex( 150, 150 );
            Vertex pos2 = hp + ( maus - mausAlt ) * ( i - 1 ) + Vertex( 150, 150 );
            bild.drawLinie( pos, pos2, 0xFFFF0000 );
            bild.fillCircle( pos.x, pos.y, 1, 0xFF00FFFF );
        }
        unlockZeichnung();
    }
};

KSGScriptEditor *obj;

void FClose( void *p, void *zF )
{
    StopNachrichtenSchleife( ( (WFenster*)zF )->getFensterHandle() );
}

int kamera2DTest();
int rotationTest();

int main()
{
    //return rotationTest();
    return kamera2DTest();
    
    Datei d;
    Datei d2;
    d.setDatei( "data_old.map" );
    d2.setDatei( "data.map" );
    d2.open( Datei::Style::schreiben );
    d.open( Datei::Style::lesen );
    int ressourceAnz = 0;
    d.lese( (char*)&ressourceAnz, 4 );
    d2.schreibe( (char*)&ressourceAnz, 4 );
    for( int i = 0; i < ressourceAnz; i++ )
    {
        int j = 0;
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        char len = 0;
        d.lese( &len, 1 );
        d2.schreibe( (char*)&len, 1 );
        Text txt;
        txt.fillText( '0', len + 1 );
        d.lese( txt, len );
        d2.schreibe( (char*)txt, len );
    }
    d.lese( (char*)&ressourceAnz, 4 );
    d2.schreibe( (char*)&ressourceAnz, 4 );
    d.lese( (char*)&ressourceAnz, 4 );
    d2.schreibe( (char*)&ressourceAnz, 4 );
    d.lese( (char*)&ressourceAnz, 4 );
    d2.schreibe( (char*)&ressourceAnz, 4 );
    for( int i = 0; i < ressourceAnz; i++ )
    {
        int j = 0;
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        double f = 0;
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        char t = 0;
        d.lese( &t, 1 );
        d2.schreibe( (char*)&t, 1 );
    }
    for( int i = 0; i < 9; i++ )
    {
        int j = 0;
        double f = 0;
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        d.lese( (char*)&f, 8 );
        f = 5;
        d2.schreibe( (char*)&f, 8 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        double antriebsEffizienz = 100;
        d.lese( (char*)&antriebsEffizienz, 8 );
        d2.schreibe( (char*)&antriebsEffizienz, 8 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
    }
    for( int i = 0; i < 3; i++ )
    {
        int j = 0;
        double f = 0;
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
        d.lese( (char*)&f, 8 );
        d2.schreibe( (char*)&f, 8 );
        double antriebsEffizienz = 0;
        d.lese( (char*)&antriebsEffizienz, 8 );
        d2.schreibe( (char*)&antriebsEffizienz, 8 );
        d.lese( (char*)&j, 4 );
        d2.schreibe( (char*)&j, 4 );
    }
    d.close();
    d2.close();
    getchar();
    return 0;
    

#ifdef _DEBUG
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
    initFramework();
    WFenster *f = new WFenster();
    WNDCLASS fc = F_Normal( 0 );
    fc.lpszClassName = "Test";
    f->erstellen( WS_OVERLAPPEDWINDOW, fc );
    f->setSize( 900, 900 );
    f->setPosition( Punkt( 100, 100 ) );
    f->setVSchließAktion( FClose );
    f->setMausAktion( _ret1ME );
    f->setTastaturAktion( _ret1TE );
    f->setAnzeigeModus( 1 );
    Bildschirm *b = new Bildschirm3D( f->getThis() );
    b->setBackBufferSize( 300, 300 );
    f->setBildschirm( b->getThis() );
    b->setTestRend( 0 );

    Obj o;
    b->addMember( &o );

    b->update();
    RenderTh *r = new RenderTh();
    r->setBildschirm( b->getThis() );
    r->setMaxFps( 60 );
    r->beginn();
    StartNachrichtenSchleife();
    r->beenden();
    r->release();
    f->setBildschirm( 0 );
    b->release();
    f->release();
    releaseFramework();
    return 0;
}