package io.vivarium.visualizer;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import io.vivarium.core.Creature;
import io.vivarium.core.Direction;
import io.vivarium.core.EntityType;
import io.vivarium.core.World;
import io.vivarium.core.WorldBlueprint;

public class Vivarium extends ApplicationAdapter
{
    private static final int SIZE = 30;
    private static final int BLOCK_SIZE = 32;
    // Simulation information
    private WorldBlueprint _blueprint;
    private World _world;
    private int tick = 0;

    // Low Level Graphics information
    private SpriteBatch _batch;
    private Texture _img;
    private Sprite _colored;

    @Override
    public void create()
    {
        _blueprint = WorldBlueprint.makeDefault();
        _blueprint.setSize(SIZE);
        _world = new World(_blueprint);

        _batch = new SpriteBatch();
        _img = new Texture("sprites.png");
        _colored = new Sprite(_img);
    }

    @Override
    public void render()
    {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        _colored.setColor((float) Math.random(), (float) Math.random(), (float) Math.random(), 1f);
        _colored.setPosition(100, 00);
        _batch.begin();
        // batch.draw(img, 0, 0);

        _batch.setColor(Color.WHITE);
        drawTerrain();
        drawFood();
        drawCreatures();

        tick++;
        if (tick > 0)
        {
            for (int i = 0; i < 1; i++)
            {
                _world.tick();
            }
            tick = 0;
        }
        // colored.draw(batch);
        _batch.end();
    }

    private void drawSprite(VivariumSprite sprite, int xPos, int yPos, float angle)
    {
        float x = xPos * BLOCK_SIZE;
        float y = getHeight() - yPos * BLOCK_SIZE - BLOCK_SIZE;
        float originX = BLOCK_SIZE / 2;
        float originY = BLOCK_SIZE / 2;
        float width = BLOCK_SIZE;
        float height = BLOCK_SIZE;
        float scale = 1;
        float rotation = angle; // In degrees
        int srcX = sprite.x * BLOCK_SIZE;
        int srcY = sprite.y * BLOCK_SIZE;
        int srcW = BLOCK_SIZE;
        int srcH = BLOCK_SIZE;
        boolean flipX = false;
        boolean flipY = false;
        _batch.draw(_img, x, y, originX, originY, width, height, scale, scale, rotation, srcX, srcY, srcW, srcH, flipX,
                flipY);
    }

    private void drawTerrain()
    {
        for (int c = 0; c < _world.getWorldWidth(); c++)
        {
            for (int r = 0; r < _world.getWorldHeight(); r++)
            {
                if (_world.getEntityType(r, c) == EntityType.WALL)
                {
                    drawSprite(VivariumSprite.WALL, c, r, 0);
                }
            }
        }
    }

    private void drawFood()
    {
        for (int c = 0; c < _world.getWorldWidth(); c++)
        {
            for (int r = 0; r < _world.getWorldHeight(); r++)
            {
                if (_world.getEntityType(r, c) == EntityType.FOOD)
                {
                    drawSprite(VivariumSprite.FOOD, c, r, 0);
                }
            }
        }
    }

    private void drawCreatures()
    {
        for (int c = 0; c < _world.getWorldWidth(); c++)
        {
            for (int r = 0; r < _world.getWorldHeight(); r++)
            {
                if (_world.getEntityType(r, c) == EntityType.CREATURE)
                {
                    Creature creature = _world.getCreature(r, c);
                    setColorOnGenderAndPregnancy(creature);
                    float rotation = (float) (Direction.getRadiansFromNorth(creature.getFacing()) * 180 / (Math.PI));
                    drawSprite(VivariumSprite.CREATURE_2, c, r, rotation);
                }
            }
        }
    }

    public void setColorOnGenderAndPregnancy(Creature creature)
    {
        if (creature.getIsFemale())
        {
            if (creature.getGestation() > 0)
            {
                _batch.setColor(new Color(0.4f, 0, 0.4f, 1));
            }
            else
            {
                _batch.setColor(new Color(0, 0.8f, 0.8f, 1));
            }
        }
        else
        {
            _batch.setColor(new Color(0.8f, 0, 0, 1));
        }
    }

    public void setColorOnAgeAndFood(Creature creature)
    {
        float food = ((float) creature.getFood()) / creature.getBlueprint().getMaximumFood();
        float age = ((float) creature.getAge()) / creature.getBlueprint().getMaximumAge();
        _batch.setColor(new Color(1, food, age, 1));
    }

    public static int getHeight()
    {
        return SIZE * BLOCK_SIZE;
    }

    public static int getWidth()
    {
        return SIZE * BLOCK_SIZE;
    }
}

@@ -224,53 +224,8 @@
 re;%0A
-import com.badlogic.gdx.graphics.g2d.Sprite;%0A
 impo
@@ -585,16 +585,17 @@
 E = 32;%0A
+%0A
     // S
@@ -807,37 +807,8 @@
 img;
-%0A    private Sprite _colored;
 %0A%0A  
@@ -1059,45 +1059,8 @@
 %22);%0A
-        _colored = new Sprite(_img);%0A
     
@@ -1212,193 +1212,20 @@
    _
-colored.setColor((float) Math.random(), (float) Math.random(), (float) Math.random(), 1f);%0A        _colored.setPosition(100, 00);%0A        _batch.begin();%0A        // batch.draw(img, 0, 0
+batch.begin(
 );%0A%0A
@@ -1327,24 +1327,47 @@
 eatures();%0A%0A
+        _batch.end();%0A%0A
         tick
@@ -1537,62 +1537,8 @@
   %7D%0A
-        // colored.draw(batch);%0A        _batch.end();%0A
     

Clean up