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

package com.hypixel.hytale.server.core.modules.physics.util;

import com.hypixel.hytale.math.vector.Vector3d;
import javax.annotation.Nonnull;
import com.hypixel.hytale.logger.HytaleLogger;

public abstract class ForceProviderStandard implements ForceProvider
{
    @Nonnull
    public static HytaleLogger LOGGER;
    @Nonnull
    protected Vector3d dragForce;
    
    public ForceProviderStandard() {
        this.dragForce = new Vector3d();
    }
    
    public abstract double getMass(final double p0);
    
    public abstract double getVolume();
    
    public abstract double getDensity();
    
    public abstract double getProjectedArea(final PhysicsBodyState p0, final double p1);
    
    public abstract double getFrictionCoefficient();
    
    public abstract ForceProviderStandardState getForceProviderStandardState();
    
    @Override
    public void update(@Nonnull final PhysicsBodyState bodyState, @Nonnull final ForceAccumulator accumulator, final boolean onGround) {
        final ForceProviderStandardState standardState = this.getForceProviderStandardState();
        final Vector3d extForce = standardState.externalForce;
        final double extForceY = extForce.y;
        accumulator.force.add(extForce);
        final double speed = accumulator.speed;
        final double dragForceDivSpeed = standardState.dragCoefficient * this.getProjectedArea(bodyState, speed) * speed;
        this.dragForce.assign(bodyState.velocity).scale(-dragForceDivSpeed);
        this.clipForce(this.dragForce, accumulator.resistanceForceLimit);
        accumulator.force.add(this.dragForce);
        final double gravityForce = -standardState.gravity * this.getMass(this.getVolume());
        if (onGround) {
            double frictionForce = (gravityForce + extForceY) * this.getFrictionCoefficient();
            if (speed > 0.0 && frictionForce > 0.0) {
                frictionForce /= speed;
                final Vector3d force = accumulator.force;
                force.x -= bodyState.velocity.x * frictionForce;
                final Vector3d force2 = accumulator.force;
                force2.z -= bodyState.velocity.z * frictionForce;
            }
        }
        else {
            final Vector3d force3 = accumulator.force;
            force3.y += gravityForce;
        }
        if (standardState.displacedMass != 0.0) {
            final Vector3d force4 = accumulator.force;
            force4.y += standardState.displacedMass * standardState.gravity;
        }
    }
    
    public void clipForce(@Nonnull final Vector3d value, @Nonnull final Vector3d threshold) {
        if (threshold.x < 0.0) {
            if (value.x < threshold.x) {
                value.x = threshold.x;
            }
        }
        else if (value.x > threshold.x) {
            value.x = threshold.x;
        }
        if (threshold.y < 0.0) {
            if (value.y < threshold.y) {
                value.y = threshold.y;
            }
        }
        else if (value.y > threshold.y) {
            value.y = threshold.y;
        }
        if (threshold.z < 0.0) {
            if (value.z < threshold.z) {
                value.z = threshold.z;
            }
        }
        else if (value.z > threshold.z) {
            value.z = threshold.z;
        }
    }
    
    static {
        ForceProviderStandard.LOGGER = HytaleLogger.forEnclosingClass();
    }
}
