#include <Bildschirm.h>
#include <Datei.h>
#include <DateiSystem.h>
#include <Fenster.h>
#include <GraphicsApi.h>
#include <HttpRequest.h>
#include <JSON.h>
#include <main.h>
#include <Network.h>
#include <RenderThread.h>
#include <Schrift.h>
#include <Textur.h>

#include "CustomDX11API.h"
#include "Globals.h"
#include "Initialisierung.h"

void createModels(Bildschirm* zScreen);

/* Test rendering of specific block types
int KSGStart Framework::Start(Framework::Startparam p)
{
    Network::Start(20);
    initVariables();
    setDebugDX(1);

    Datei d;
    d.setDatei("data/schriften");
    auto list = d.getDateiListe();
    for (Text* fontFile : *list)
    {
        LTDSDatei dat;
        dat.setPfad(
            new Text(Text("data/schriften/").operator+(fontFile->getText())));
        dat.leseDaten();
        Text* name = fontFile->getTeilText(0, fontFile->getLength() - 5);
        fontRegister->put(*name, RCPointer<Schrift>::of(dat.ladeSchrift()));
        name->release();
    }
    list->release();

    WFenster window;
    ::window = &window;
    WNDCLASS wc = Framework::F_Normal(p.hinst);
    wc.lpszClassName = "Factory Craft";
    window.erstellen(WS_POPUPWINDOW, wc);
    Monitor m = Framework::getMonitor(0);
    window.setBounds(Punkt(m.x, m.y), Punkt(m.breite, m.height));
    window.setAnzeigeModus(SW_SHOWNORMAL);
    window.setVSchließAktion([&window](void* p, void* f) {
        StopNachrichtenSchleife(window.getFensterHandle());
    });
    window.setMausAktion(_ret1ME);
    window.setTastaturAktion(_ret1TE);
    Bildschirm3D screen(
        dynamic_cast<WFenster*>(window.getThis()), new CustomDX11API());
    screen.setHandleUserInputsOnTick(1);
    window.setBildschirm(dynamic_cast<Bildschirm*>(screen.getThis()));
    screen.setFillFarbe(0);

    uiFactory = Framework::defaultUI(fontRegister->get("normal"), &screen);

    createModels(&screen);

    // loading textures
    Datei texturF;
    texturF.setDatei("data/textures");
    RCArray<Text>* files = texturF.getDateiListe();
    if (files)
    {
        int count = 0;
        for (Text* fileName : *files)
        {
            LTDBDatei dat;
            dat.setDatei(new Text(Text("data/textures/") + *fileName));
            dat.leseDaten(0);
            count += dat.getBildAnzahl();
        }
        for (Text* fileName : *files)
        {
            LTDBDatei dat;
            dat.setDatei(new Text(Text("data/textures/") + *fileName));
            dat.leseDaten(0);
            for (Text* name : *dat.zBildListe())
            {
                Bild* b = dat.laden(0, new Text(*name));
                screen.zGraphicsApi()
                    ->createOrGetTextur(*fileName + "/" + *name, b)
                    ->release();
            }
        }
        files->release();
    }

    BlockType* type = new BlockType(
        26, 1, ModelInfo("cube", "fluids.ltdb/water.png", 0, 6), 10, 1); // block type to render
    Block* b = type->createBlock(Vec3<float>(0, 0, 0));
    unsigned char light[] = {255, 255, 255, 255, 255, 255};
    b->setLightData(TOP, light);
    b->setLightData(NORTH, light);
    b->setLightData(EAST, light);
    b->setLightData(SOUTH, light);
    b->setLightData(WEST, light);
    b->setLightData(BOTTOM, light);
    Chunk *c = new Chunk(Punkt(0, 0));
    c->setBlock(b);
    Welt3D* w = new Welt3D();
    w->addCollection(c);
    Kam3D* kam = new Kam3D();
    kam->setStyle(
        Kam3D::Style::Movable | Kam3D::Style::Rotatable | Kam3D::Style::Tick);
    kam->setPosition(Vec3<float>(10, 0, 0));
    kam->setAusrichtung(Vec3<float>(0, 0, 0));
    kam->setWelt(w);
    screen.addKamera(kam);

    RenderTh rTh;
    rTh.setMaxFps(60);
    rTh.setQuiet(1);
    rTh.setBildschirm(dynamic_cast<Bildschirm*>(screen.getThis()));

    rTh.beginn();
    StartNachrichtenSchleife();
    rTh.beenden();
    releaseVariables();
    Network::Exit();
    return 0;
}
*/

int KSGStart Framework::Start(Framework::Startparam p)
{
    Network::Start(20);
    initVariables();
    setDebugDX(1);

    Datei d;
    d.setDatei("data/schriften");
    auto list = d.getDateiListe();
    for (Text* fontFile : *list)
    {
        LTDSDatei dat;
        dat.setPfad(
            new Text(Text("data/schriften/").operator+(fontFile->getText())));
        dat.leseDaten();
        Text* name = fontFile->getTeilText(0, fontFile->getLength() - 5);
        fontRegister->put(*name, RCPointer<Schrift>::of(dat.ladeSchrift()));
        name->release();
    }
    list->release();

    WFenster window;
    ::window = &window;
    WNDCLASS wc = Framework::F_Normal(p.hinst);
    wc.lpszClassName = "Factory Craft";
    window.erstellen(WS_POPUPWINDOW, wc);
    Monitor m = Framework::getMonitor(0);
    window.setBounds(Punkt(m.x, m.y), Punkt(m.breite, m.height));
    window.setAnzeigeModus(SW_SHOWNORMAL);
    window.setVSchließAktion([&window](void* p, void* f) {
        StopNachrichtenSchleife(window.getFensterHandle());
    });
    window.setMausAktion(_ret1ME);
    window.setTastaturAktion(_ret1TE);
    Bildschirm3D screen(
        dynamic_cast<WFenster*>(window.getThis()), new CustomDX11API());
    screen.setHandleUserInputsOnTick(1);
    window.setBildschirm(dynamic_cast<Bildschirm*>(screen.getThis()));
    screen.setFillFarbe(0);
    screen.setTestRend(0);

    uiFactory = Framework::defaultUI(fontRegister->get("normal"), &screen);
    uiFactory.createKnopf = createKnopf;
    uiFactory.createTextFeld = createTextFeld;
    uiFactory.createKontrollKnopf = createKontrollKnopf;
    uiFactory.createObjTabelle = createObjTabelle;
    initMenus();

    RenderTh rTh;
    rTh.setMaxFps(-1);
    rTh.setQuiet(1);
    rTh.setBildschirm(dynamic_cast<Bildschirm*>(screen.getThis()));

    rTh.setTickFunktion([](void* p, void* o, double time) {
        if (World::INSTANCE)
        {
            World::INSTANCE->onTick(time);
        }
    });

    rTh.beginn();
    StartNachrichtenSchleife();
    rTh.beenden();

    releaseVariables();
    Network::Exit();
    return 0;
}