/*
 * Platform.java
 *
 * This class is a ObstacleSprite referencing a platform. In the physics lab, we
 * had a single class for walls and platforms. In this demo, we have separated
 * them because the JSON specification is different (we only used geometry in
 * the physics lab).
 *
 * Based on the original PhysicsDemo Lab by Don Holden, 2007
 *
 * Author:  Walker M. White
 * Version: 2/14/2025
 */
 package edu.cornell.cis3152.json;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.utils.JsonValue;
import edu.cornell.gdiac.assets.*;
import edu.cornell.gdiac.assets.*;
import edu.cornell.gdiac.math.*;
import edu.cornell.gdiac.physics2.*;

/**
 * A class representing a tiled wall
 *
 * An ObstacleSprite is a sprite (specifically a textured mesh) that is
 * connected to a obstacle. It is designed to be the same size as the
 * physics object, and it tracks the physics object, matching its position
 * and angle at all times.
 *
 * Unlike the physics lab, this object can be resized.
 */
public class Platform  extends GameObject {
    /** The platform width in box2d units */
    private float width;
    /** The platform height in box2d units */
    private float height;

    /**
     * Creates a Platform with the given physics data and geometry.
     *
     * We assume that all information -- both the geometry and the physics
     * constants -- are stored in the JSON file. The asset directory is used
     * to access the texture.
     *
     * Note that the constructor does NOT build the mesh right away. We need
     * the physics units to build the mesh. As that value is computed
     * separately from the level loading (from the window size), we handle
     * that in the method {@link #setPhysicsUnits(float)}.
     *
     * @param directory the asset manager
     * @param data      the wall geometry and physics constants
     */
    public Platform(AssetDirectory directory, JsonValue data) {
        float x = data.get("pos").getFloat(0);
        float y = data.get("pos").getFloat(1);
        width  = data.get("size").getFloat(0);
        height = data.get("size").getFloat(1);

        obstacle = new BoxObstacle(x, y, width, height);

        obstacle.setBodyType(data.get("bodytype").asString().equals("static") ? BodyDef.BodyType.StaticBody : BodyDef.BodyType.DynamicBody);
        obstacle.setDensity( data.getFloat( "density", 0 ) );
        obstacle.setFriction( data.getFloat( "friction", 0 ) );
        obstacle.setRestitution( data.getFloat( "restitution", 0 ) );
        obstacle.setUserData( this );
        obstacle.setName( data.name );

        debug = ParserUtils.parseColor( data.get("debug_color"),  Color.WHITE);

        // We have to create a polygon, even though it is a rectangle, in order
        // to tile the mesh properly (again, we will see in class)
        setTexture(directory.getEntry(data.getString("texture"), Texture.class));
    }

    /**
     * Sets the physics units for this game object.
     *
     * Setting the physics objects build the mesh for this object. This method
     * should be called whenever the window size changes to resize the meshes
     * for the new display.
     *
     * @param units The physics units for this object
     */
    public void setPhysicsUnits(float units) {
        obstacle.setPhysicsUnits(units);

        float x = obstacle.getX();
        float y = obstacle.getY();
        float tile = getSpriteSheet().getRegionWidth();
        mesh.clear();

        // Offset poly by position to remove texture seams (WHY? Come to class)
        Poly2 poly = new Poly2(units*(x-width/2.0f),units*(y-height/2.0f),units*width,units*height);
        mesh.set(poly, tile, tile);

        // Eliminating seams shifted poly off.  Shift it back.
        // This is a really advanced technique we will talk about in class
        for(int ii = 0; ii < mesh.vertexCount(); ii++) {
            float px = mesh.getPositionX( ii );
            float py = mesh.getPositionY( ii );
            mesh.setPosition( ii, px-x*units, py-y*units );
        }
    }

}
