#include <iostream>
#include <cstdio>
using namespace std;
static const int width = 512, height = 512;
static const int pixels_per_unit = 20;
    pos[0] += vels[0] * pixels_per_unit * dt;
    pos[1] += vels[1] * pixels_per_unit * dt;
    
    
    forces[0] = -1 * diff_x / dist;
    forces[1] = -1 * diff_y / dist;
    
    forces[0] *= pixels_per_unit * dt;
    forces[1] *= pixels_per_unit * dt;
    
    vels[0] *= 1 - (0.005*dt);
    vels[1] *= 1 - (0.005*dt);
    
    vels[0] += forces[0];
    vels[1] += forces[1];
}
    
    
    
    const int radius = 50;
    const float elastic_constant = 0.91f;
    if(sum<int>(dist<radius) > 0) {
        vels[0](dist<radius) = -elastic_constant * vels[0](dist<radius);
        vels[1](dist<radius) = -elastic_constant * vels[1](dist<radius);
        
        diff_x /= dist;
        diff_y /= dist;
        
        pos[0](dist<radius) = width/2 + diff_x(dist<radius) * radius;
        pos[1](dist<radius) = height/2 +  diff_y(dist<radius) * radius;
    }
}
int main(int argc, char *argv[])
{
    try {
        const static int total_particles = 1000;
        static const int reset = 500;
        af::Window myWindow(width, height, 
"Gravity Simulation using ArrayFire");
         int frame_count = 0;
        
        
        pos[1] = 
af::randu(total_particles) * height;
        while(!myWindow.
close()) {
             ids = (pos[0].
as(
u32) * height) + pos[1].as(
u32);
            image(ids) += 255;
            frame_count++;
            
            if(frame_count % reset == 0) {
                pos[1] = 
af::randu(total_particles) * height;
            }
            
            collisions(pos, vels);
            
            simulate(pos, vels, forces, dt);
        }
        fprintf(stderr, 
"%s\n", e.
what());
        throw;
    }
    return 0;
}