/*
 * FXGL - JavaFX Game Library. The MIT License (MIT).
 * Copyright (c) AlmasB (almaslvl@gmail.com).
 * See LICENSE for details.
 */

package com.almasb.fxgl.physics.box2d.particle;

import com.almasb.fxgl.core.math.Vec2;
import com.almasb.fxgl.physics.box2d.common.Transform;

public class ParticleGroup {

    ParticleSystem m_system;
    int m_firstIndex;
    int m_lastIndex;
    int m_groupFlags;
    float m_strength;
    ParticleGroup m_prev;
    ParticleGroup m_next;

    int m_timestamp;
    float m_mass;
    float m_inertia;
    final Vec2 m_center = new Vec2();
    final Vec2 m_linearVelocity = new Vec2();
    float m_angularVelocity;
    final Transform m_transform = new Transform();

    boolean m_destroyAutomatically;
    boolean m_toBeDestroyed;
    boolean m_toBeSplit;

    Object m_userData;

    public ParticleGroup() {
        m_firstIndex = 0;
        m_lastIndex = 0;
        m_groupFlags = 0;
        m_strength = 1.0f;

        m_timestamp = -1;
        m_mass = 0;
        m_inertia = 0;
        m_angularVelocity = 0;
        m_transform.setIdentity();

        m_destroyAutomatically = true;
        m_toBeDestroyed = false;
        m_toBeSplit = false;
    }

    public ParticleGroup getNext() {
        return m_next;
    }

    public int getParticleCount() {
        return m_lastIndex - m_firstIndex;
    }

    public int getBufferIndex() {
        return m_firstIndex;
    }

    public int getGroupFlags() {
        return m_groupFlags;
    }

    public void setGroupFlags(int flags) {
        m_groupFlags = flags;
    }

    public float getMass() {
        updateStatistics();
        return m_mass;
    }

    public float getInertia() {
        updateStatistics();
        return m_inertia;
    }

    public Vec2 getCenter() {
        updateStatistics();
        return m_center;
    }

    public Vec2 getLinearVelocity() {
        updateStatistics();
        return m_linearVelocity;
    }

    public float getAngularVelocity() {
        updateStatistics();
        return m_angularVelocity;
    }

    public Transform getTransform() {
        return m_transform;
    }

    public Vec2 getPosition() {
        return m_transform.p;
    }

    public float getAngle() {
        return m_transform.q.getAngle();
    }

    public Object getUserData() {
        return m_userData;
    }

    public void setUserData(Object data) {
        m_userData = data;
    }

    public void updateStatistics() {
        if (m_timestamp != m_system.m_timestamp) {
            float m = m_system.getParticleMass();
            m_mass = 0;
            m_center.setZero();
            m_linearVelocity.setZero();
            for (int i = m_firstIndex; i < m_lastIndex; i++) {
                m_mass += m;
                Vec2 pos = m_system.m_positionBuffer.data[i];
                m_center.x += m * pos.x;
                m_center.y += m * pos.y;
                Vec2 vel = m_system.m_velocityBuffer.data[i];
                m_linearVelocity.x += m * vel.x;
                m_linearVelocity.y += m * vel.y;
            }
            if (m_mass > 0) {
                m_center.x *= 1 / m_mass;
                m_center.y *= 1 / m_mass;
                m_linearVelocity.x *= 1 / m_mass;
                m_linearVelocity.y *= 1 / m_mass;
            }
            m_inertia = 0;
            m_angularVelocity = 0;
            for (int i = m_firstIndex; i < m_lastIndex; i++) {
                Vec2 pos = m_system.m_positionBuffer.data[i];
                Vec2 vel = m_system.m_velocityBuffer.data[i];
                float px = pos.x - m_center.x;
                float py = pos.y - m_center.y;
                float vx = vel.x - m_linearVelocity.x;
                float vy = vel.y - m_linearVelocity.y;
                m_inertia += m * (px * px + py * py);
                m_angularVelocity += m * (px * vy - py * vx);
            }
            if (m_inertia > 0) {
                m_angularVelocity *= 1 / m_inertia;
            }
            m_timestamp = m_system.m_timestamp;
        }
    }
}

@@ -348,24 +348,28 @@
 m_firstIndex
+ = 0
 ;%0A    int m_
@@ -373,24 +373,28 @@
  m_lastIndex
+ = 0
 ;%0A    int m_
@@ -399,24 +399,28 @@
 m_groupFlags
+ = 0
 ;%0A    float 
@@ -429,16 +429,21 @@
 strength
+ = 1f
 ;%0A    Pa
@@ -489,24 +489,32 @@
 _next;%0A%0A    
+private 
 int m_timest
@@ -516,22 +516,35 @@
 imestamp
+ = -1
 ;%0A    
+private 
 float m_
@@ -547,22 +547,34 @@
 t m_mass
+ = 0
 ;%0A    
+private 
 float m_
@@ -576,24 +576,28 @@
 at m_inertia
+ = 0
 ;%0A    final 
@@ -693,24 +693,28 @@
 ularVelocity
+ = 0
 ;%0A    final 
@@ -789,16 +789,23 @@
 atically
+ = true
 ;%0A    bo
@@ -825,16 +825,24 @@
 estroyed
+ = false
 ;%0A    bo
@@ -858,16 +858,24 @@
 oBeSplit
+ = false
 ;%0A%0A    O
@@ -936,338 +936,31 @@
   m_
-firstIndex = 0;%0A        m_lastIndex = 0;%0A        m_groupFlags = 0;%0A        m_strength = 1.0f;%0A%0A        m_timestamp = -1;%0A        m_mass = 0;%0A        m_inertia = 0;%0A        m_angularVelocity = 0;%0A        m_transform.setIdentity();%0A%0A        m_destroyAutomatically = true;%0A        m_toBeDestroyed = false;%0A        m_toBeSplit = false
+transform.setIdentity()
 ;%0A  

clean up