// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.modules.debug;

import java.util.Random;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageSystems;
import com.hypixel.hytale.server.core.modules.splitvelocity.SplitVelocity;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.core.modules.splitvelocity.VelocityConfig;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.protocol.packets.player.ClearDebugShapes;
import java.util.Iterator;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.protocol.packets.player.DisplayDebug;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.math.matrix.Matrix4d;
import com.hypixel.hytale.protocol.DebugShape;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.universe.world.World;

public class DebugUtils
{
    public static boolean DISPLAY_FORCES;
    
    public static void add(@Nonnull final World world, @Nonnull final DebugShape shape, @Nonnull final Matrix4d matrix, @Nonnull final Vector3f color, final float time, final boolean fade) {
        final DisplayDebug packet = new DisplayDebug(shape, matrix.asFloatData(), new com.hypixel.hytale.protocol.Vector3f(color.x, color.y, color.z), time, fade, null);
        for (final PlayerRef playerRef : world.getPlayerRefs()) {
            playerRef.getPacketHandler().write(packet);
        }
    }
    
    public static void addFrustum(@Nonnull final World world, @Nonnull final Matrix4d matrix, @Nonnull final Matrix4d frustumProjection, @Nonnull final Vector3f color, final float time, final boolean fade) {
        final DisplayDebug packet = new DisplayDebug(DebugShape.Frustum, matrix.asFloatData(), new com.hypixel.hytale.protocol.Vector3f(color.x, color.y, color.z), time, fade, frustumProjection.asFloatData());
        for (final PlayerRef playerRef : world.getPlayerRefs()) {
            playerRef.getPacketHandler().write(packet);
        }
    }
    
    public static void clear(@Nonnull final World world) {
        final ClearDebugShapes packet = new ClearDebugShapes();
        for (final PlayerRef playerRef : world.getPlayerRefs()) {
            playerRef.getPacketHandler().write(packet);
        }
    }
    
    public static void addArrow(@Nonnull final World world, @Nonnull final Matrix4d baseMatrix, @Nonnull final Vector3f color, final double length, final float time, final boolean fade) {
        final double adjustedLength = length - 0.3;
        if (adjustedLength > 0.0) {
            final Matrix4d matrix = new Matrix4d(baseMatrix);
            matrix.translate(0.0, adjustedLength * 0.5, 0.0);
            matrix.scale(0.10000000149011612, adjustedLength, 0.10000000149011612);
            add(world, DebugShape.Cylinder, matrix, color, time, fade);
        }
        final Matrix4d matrix = new Matrix4d(baseMatrix);
        matrix.translate(0.0, adjustedLength + 0.15, 0.0);
        matrix.scale(0.30000001192092896, 0.30000001192092896, 0.30000001192092896);
        add(world, DebugShape.Cone, matrix, color, time, fade);
    }
    
    public static void addSphere(@Nonnull final World world, @Nonnull final Vector3d pos, @Nonnull final Vector3f color, final double scale, final float time) {
        final Matrix4d matrix = makeMatrix(pos, scale);
        add(world, DebugShape.Sphere, matrix, color, time, true);
    }
    
    public static void addCone(@Nonnull final World world, @Nonnull final Vector3d pos, @Nonnull final Vector3f color, final double scale, final float time) {
        final Matrix4d matrix = makeMatrix(pos, scale);
        add(world, DebugShape.Cone, matrix, color, time, true);
    }
    
    public static void addCube(@Nonnull final World world, @Nonnull final Vector3d pos, @Nonnull final Vector3f color, final double scale, final float time) {
        final Matrix4d matrix = makeMatrix(pos, scale);
        add(world, DebugShape.Cube, matrix, color, time, true);
    }
    
    public static void addCylinder(@Nonnull final World world, @Nonnull final Vector3d pos, @Nonnull final Vector3f color, final double scale, final float time) {
        final Matrix4d matrix = makeMatrix(pos, scale);
        add(world, DebugShape.Cylinder, matrix, color, time, true);
    }
    
    public static void addArrow(@Nonnull final World world, @Nonnull final Vector3d position, @Nonnull final Vector3d direction, @Nonnull final Vector3f color, final float time, final boolean fade) {
        final Vector3d directionClone = direction.clone();
        final Matrix4d tmp = new Matrix4d();
        final Matrix4d matrix = new Matrix4d();
        matrix.identity();
        matrix.translate(position);
        final double angleY = Math.atan2(directionClone.z, directionClone.x);
        matrix.rotateAxis(angleY + 1.5707963267948966, 0.0, 1.0, 0.0, tmp);
        final double angleX = Math.atan2(Math.sqrt(directionClone.x * directionClone.x + directionClone.z * directionClone.z), directionClone.y);
        matrix.rotateAxis(angleX, 1.0, 0.0, 0.0, tmp);
        addArrow(world, matrix, color, directionClone.length(), time, fade);
    }
    
    public static void addForce(@Nonnull final World world, @Nonnull final Vector3d position, @Nonnull final Vector3d force, @Nullable final VelocityConfig velocityConfig) {
        if (!DebugUtils.DISPLAY_FORCES) {
            return;
        }
        final Vector3d forceClone = force.clone();
        if (velocityConfig == null || SplitVelocity.SHOULD_MODIFY_VELOCITY) {
            final Vector3d vector3d = forceClone;
            vector3d.x /= DamageSystems.HackKnockbackValues.PLAYER_KNOCKBACK_SCALE;
            final Vector3d vector3d2 = forceClone;
            vector3d2.z /= DamageSystems.HackKnockbackValues.PLAYER_KNOCKBACK_SCALE;
        }
        final Matrix4d tmp = new Matrix4d();
        final Matrix4d matrix = new Matrix4d();
        matrix.identity();
        matrix.translate(position);
        final double angleY = Math.atan2(forceClone.z, forceClone.x);
        matrix.rotateAxis(angleY + 1.5707963267948966, 0.0, 1.0, 0.0, tmp);
        final double angleX = Math.atan2(Math.sqrt(forceClone.x * forceClone.x + forceClone.z * forceClone.z), forceClone.y);
        matrix.rotateAxis(angleX, 1.0, 0.0, 0.0, tmp);
        final Random random = new Random();
        final Vector3f color = new Vector3f(random.nextFloat(), random.nextFloat(), random.nextFloat());
        addArrow(world, matrix, color, forceClone.length(), 10.0f, true);
    }
    
    @Nonnull
    private static Matrix4d makeMatrix(@Nonnull final Vector3d pos, final double scale) {
        final Matrix4d matrix = new Matrix4d();
        matrix.identity();
        matrix.translate(pos);
        matrix.scale(scale, scale, scale);
        return matrix;
    }
    
    static {
        DebugUtils.DISPLAY_FORCES = false;
    }
}
