public TriggerColliderData(Collider2D newCollider, Paths newPath, Bounds newBounds)
 {
     collider      = newCollider;
     center        = collider.bounds.center;
     particleMagic = newCollider.GetComponent <ParticleMagic>();
     element       = particleMagic.GetElement();
     path          = newPath;
     bounds        = newBounds;
 }
    public override void Activate()
    {
        if (isActive)
        {
            Deactivate();
            shouldActivate = 10;
            return;
        }
        if (shouldActivate > 0)
        {
            shouldActivate = 0;
        }
        isActive = true;
        if (currentMagic != null)
        {
            currentMagic.Deactivate();
        }
        print("emissionRate: " + emissionRate);
        magicParent = new GameObject(myElement.ToString() + " Magic Parent");
        magicParent.transform.position = transform.position;
        GameObject magic = Instantiate(MagicList.elementMagicList[myElement], magicParent.transform) as GameObject;

        magic.name   = myElement.ToString() + " Magic PS";
        currentMagic = magic.GetComponent <ParticleMagic>();
        currentMagic.SetElement(myElement);
        ClipperTest ct = magic.GetComponent <ClipperTest>();

        if (ct == null)
        {
            magic.AddComponent <ClipperTest>();
        }
        magicCollider = magic.GetComponent <Collider2D>();
        if (currentMagic != null)
        {
            Debug.Log("Activating the " + myElement.ToString() + " Magic");
            if (autoActivate)
            {
                Debug.Log("There ain't no shape, so we just shooting the magic");
                currentMagic.Activate();
            }
            else
            {
                Debug.Log("Waiting for the Form MC to activate the magic");
            }
        }
        else
        {
            Debug.LogError("YO, you forgot to put the ParticleMagic on " + myElement.ToString());
        }
    }
 // Start is called before the first frame update
 void Start()
 {
     if (ActivateOnCollision == null)
     {
         ActivateOnCollision = new LinkableData <ActivationFunction>(PrintCollision);
     }
     if (ActivateOnTrigger == null)
     {
         ActivateOnTrigger = new LinkableData <ActivationFunction>(PrintTriggerCollision);
     }
     solution        = new Paths();
     ps              = GetComponent <ParticleSystem>();
     myMagic         = GetComponent <ParticleMagic>();
     myCollider      = GetComponent <PolygonCollider2D>();
     collisionPoints = new List <ParticleCollisionData>();
     if (myCollider == null)
     {
         myCollider = gameObject.AddComponent <PolygonCollider2D>();
     }
     psCollisionEvents = new List <ParticleCollisionEvent>();
 }
    void OnTriggerStay2D(Collider2D other)
    {
        ParticleMagic pm = other.gameObject.GetComponent <ParticleMagic>();

        if (pm != null && myCollider.isTrigger)
        {
            nonSolidMagicCollision          = true;
            nonSolidMagicCollisionResetTime = .1f;
            ActivateOnTrigger.Value()();
            particleTriggerCollisionJob.gameObjectID = other.gameObject.GetInstanceID();
        }
        // RaycastHit2D[] myContacts = new RaycastHit2D[30];
        // int count = other.Cast( (transform.position - other.transform.position).normalized, myContacts, 0 );
        // print("On trigger 2D enter contact count " + count );
        // float markerLength = .2f;
        // for( int i = 0; i < count; i++ )
        // {
        //     Debug.DrawLine( myContacts[i].point - Vector2.up * markerLength/2, myContacts[i].point + Vector2.up * markerLength/2, Color.blue );
        //     Debug.DrawLine( myContacts[i].point - Vector2.right * markerLength/2, myContacts[i].point + Vector2.right * markerLength/2, Color.blue );
        // }
    }
        void PushBackCollision(ParticleSystemJobData particles, int particleIndex, float percent)
        {
            ParticleMagic pm       = particleTriggerColliders[gameObjectID].particleMagic;
            Vector3       velocity = pm.initialVelocity * pm.direction;

            var velocitiesX = particles.velocities.x;
            var velocitiesY = particles.velocities.y;
            var velocitiesZ = particles.velocities.z;

            // Set the x,y,and z velocities for the push back
            if (Mathf.Abs(velocitiesX[particleIndex]) < Mathf.Abs(velocity.x) || Mathf.Sign(velocitiesX[particleIndex]) != Mathf.Sign(velocity.x))
            {
                velocitiesX[particleIndex] += velocity.x * deltaTime * percent;
            }
            if (Mathf.Abs(velocitiesY[particleIndex]) < Mathf.Abs(velocity.y) || Mathf.Sign(velocitiesY[particleIndex]) != Mathf.Sign(velocity.y))
            {
                velocitiesY[particleIndex] += velocity.y * deltaTime * percent;
            }
            if (Mathf.Abs(velocitiesZ[particleIndex]) < Mathf.Abs(velocity.z) || Mathf.Sign(velocitiesZ[particleIndex]) != Mathf.Sign(velocity.z))
            {
                velocitiesZ[particleIndex] += velocity.z * deltaTime * percent;
            }
        }
    void OnParticleCollision(GameObject other)
    {
        ParticlePhysicsExtensions.GetCollisionEvents(ps, other, psCollisionEvents);
        ParticleMagic pm = other.gameObject.GetComponent <ParticleMagic>();

        if (pm != null)
        {
            solidMagicCollision          = true;
            solidMagicCollisionResetTime = .1f;
            ActivateOnCollision.Value()();

            //     // List<Vector3> collisionPoints = new List<Vector3>( psCollisionEvents.Count );
            for (int i = 0; i < psCollisionEvents.Count; i++)
            {
                ParticleCollisionData pcd = new ParticleCollisionData();
                pcd.pointOfCollision = psCollisionEvents[i].intersection;
                pcd.velocity         = psCollisionEvents[i].velocity;
                if (myCollider.isTrigger)
                {
                    ClipperTest ct = other.gameObject.GetComponent <ClipperTest>();
                    pcd.elementCollision = myMagic.GetElement();
                    ct.AddCollisionPoints(pcd);
                    // print("ADDING TO OTHER CT");
                }
                else
                {
                    pcd.elementCollision = pm.GetElement();
                    collisionPoints.Add(pcd);
                }
                float markerLength = .2f;
                Debug.DrawLine(psCollisionEvents[i].intersection - Vector3.up * markerLength / 2, psCollisionEvents[i].intersection + Vector3.up * markerLength / 2, Color.blue);
                Debug.DrawLine(psCollisionEvents[i].intersection - Vector3.right * markerLength / 2, psCollisionEvents[i].intersection + Vector3.right * markerLength / 2, Color.blue);
                // print("ParticleCollision object " + psCollisionEvents[i].intersection );
            }
        }
    }
    public override void Activate()
    {
        isActive = true;
        if (movableMagic.Value() != null)
        {
            // print( "We got the current magic: " + formableMagic.Value().gameObject.name );
            Debug.Log("Activating movement");

            ParticleMagic pm = movableMagic.Value().GetComponent <ParticleMagic>() as ParticleMagic;
            if (pm != null)
            {
                pm.SetMovement(myMovement);
            }

            magicControllerTracker = movableMagic.Value().GetComponent <MagicControllerTracker>();
            if (magicControllerTracker == null)
            {
                magicControllerTracker = movableMagic.Value().gameObject.AddComponent <MagicControllerTracker>();
            }
            magicControllerTracker.SetCurrentMovementController(this);

            switch (myMovement)
            {
            case MovementType.Push:
            {
                if (pm != null)
                {
                    Debug.Log("Pouring/pushing Movement");
                    relativePositionOffset = movableMagic.Value().transform.position - transform.position;
                    if (dragMagic && movableMagic.Value().GetComponent <ParticleMagic>() != null)
                    {
                        parentMagicControllerTracker = movableMagic.Value().transform.parent.gameObject.GetComponent <MagicControllerTracker>();
                        if (parentMagicControllerTracker == null)
                        {
                            parentMagicControllerTracker = movableMagic.Value().transform.parent.gameObject.AddComponent <MagicControllerTracker>();
                        }
                        parentMagicControllerTracker.SetCurrentMovementController(this);
                    }
                }
                else
                {
                    Debug.Log("Pushing Movement");
                    if ((movableRb = movableMagic.Value().GetComponent <Rigidbody2D>()) == null)
                    {
                        movableRb = movableMagic.Value().AddComponent <Rigidbody2D>();
                    }
                    movableRb.gravityScale = 0;
                    direction.SetDefaultValue(transform.right);
                    movableRb.AddForce((Vector2)(initialVelocity.Value() * direction.Value().normalized), ForceMode2D.Impulse);
                }
                break;
            }

            case MovementType.Control:
            {
                Debug.Log("Controling Movement");
                if ((movableRb = movableMagic.Value().GetComponent <Rigidbody2D>()) == null)
                {
                    movableRb = movableMagic.Value().AddComponent <Rigidbody2D>();
                }
                movableRb.gravityScale = 0;
                break;
            }

            case MovementType.Path:
            {
                Debug.Log("Using Path Movement");
                if ((movableRb = movableMagic.Value().GetComponent <Rigidbody2D>()) == null)
                {
                    movableRb = movableMagic.Value().AddComponent <Rigidbody2D>();
                }
                movableRb.gravityScale = 0;
                break;
            }

            // case MovementType.Pour:
            // {
            //     relativePositionOffset = movableMagic.Value().transform.position - transform.position;
            //     if( dragMagic && movableMagic.Value().GetComponent<ParticleMagic>() != null )
            //     {
            //         parentMagicControllerTracker = movableMagic.Value().transform.parent.gameObject.GetComponent<MagicControllerTracker>();
            //         if( parentMagicControllerTracker == null )
            //         {
            //             parentMagicControllerTracker = movableMagic.Value().transform.parent.gameObject.AddComponent<MagicControllerTracker>();
            //         }
            //         parentMagicControllerTracker.SetCurrentMovementController( this );
            //     }
            //     Debug.Log("Pouring Movement");
            //     break;
            // }
            // TODO: add ability to compress when stopped
            // Currently it's just changing the shape of the form
            case MovementType.Stop:
            {
                // relativePositionOffset = movableMagic.Value().transform.position - transform.position;
                Debug.Log("Stopping Movement");
                goto case MovementType.Push;
                break;
            }

            default:
            {
                Debug.LogWarning("Movement Type not implemented");
                break;
            }
            }
        }
        else
        {
            Debug.Log("YOOOOO, there aint no element to move the object");
        }
    }