package games.colonier.ld44.renderer;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
import games.colonier.ld44.chemistry.Atom;
import games.colonier.ld44.chemistry.Connection;

import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class AtomsRenderer {

    Set <Connection> visitedConnections = new HashSet<> ();

    public void renderAtoms (
            ShapeRenderer shapeRenderer,
            List <Atom> atoms,
            boolean renderOutline,
            Rectangle targetRect,
            float radius
    ) {

        visitedConnections.clear ();

        float scale = 1f;
        float offX = 0.0f;
        float offY = 0.0f;
        float transX = 0.0f;
        float transY = 0.0f;

        if (targetRect != null) {

            float minX = (float) atoms.stream ().mapToDouble (a -> a.drawPosition.x).min ().getAsDouble ();
            float maxX = (float) atoms.stream ().mapToDouble (a -> a.drawPosition.x).max ().getAsDouble ();
            float minY = (float) atoms.stream ().mapToDouble (a -> a.drawPosition.y).min ().getAsDouble ();
            float maxY = (float) atoms.stream ().mapToDouble (a -> a.drawPosition.y).max ().getAsDouble ();

            float width = Math.abs (maxX - minX) + 2f * (radius);
            float height = Math.abs (maxY - minY) + 2f * (radius);

            if (width < targetRect.width && height < targetRect.height) {

                offX = (targetRect.width - width) / 2f;
                offY = (targetRect.height - height) / 2f;

            } else if (width > targetRect.width && height <= targetRect.height) {

                scale = targetRect.width / width;
                offX = 0f;
                offY = (targetRect.height - height * scale) / 2f;

            } else if (width <= targetRect.width && height > targetRect.height) {

                scale = targetRect.height / height;
                offX = (targetRect.width - width * scale) / 2f;
                offY = 0f;

            } else {

                float wDiff = width / targetRect.width;
                float hDiff = height / targetRect.height;

                if (wDiff > hDiff) {

                    scale = targetRect.width / width;
                    offX = 0f;
                    offY = (targetRect.height - height * scale) / 2f;

                } else {

                    scale = targetRect.height / height;
                    offX = (targetRect.width - width * scale) / 2f;
                    offY = 0f;

                }

            }

            transX = -minX;
            transY = -minY;

            offX += targetRect.x + radius;
            offY += targetRect.y + radius;

        }

        shapeRenderer.begin (ShapeRenderer.ShapeType.Line);

        for (Atom a1 : atoms) {
            for (Atom a2 : a1.connectedTo) {
                Connection c = new Connection (a1.id, a2.id);
                if (visitedConnections.add (c) && atoms.contains (a2)) {
                    shapeRenderer.setColor (Color.BLACK);
                    shapeRenderer.line (
                            (a1.drawPosition.x + transX) * scale + offX,
                            (a1.drawPosition.y + transY) * scale + offY,
                            (a2.drawPosition.x + transX) * scale + offX,
                            (a2.drawPosition.y + transY) * scale + offY
                    );
                }
            }
        }

        shapeRenderer.end ();

        shapeRenderer.begin (ShapeRenderer.ShapeType.Filled);

        for (Atom a : atoms) {

            if (renderOutline) {

                shapeRenderer.setColor (Color.BLACK);
                shapeRenderer.circle (
                        (a.drawPosition.x + transX) * scale + offX,
                        (a.drawPosition.y + transY) * scale + offY,
                        radius
                );

            }

            shapeRenderer.setColor (a.type.color);
            shapeRenderer.circle (
                    (a.drawPosition.x + transX) * scale + offX,
                    (a.drawPosition.y + transY) * scale + offY,
                    radius + (renderOutline ? -2f : 0f)
            );

        }

        shapeRenderer.end ();

    }

}
