#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "particles.h"

void part_init(part_t *particles, int capacity)
{
   particles->count = 0;
   particles->capacity = 0;

   particles->owner_rank = NULL;
   particles->mass = NULL;
   vec_init(&particles->force, 0);
   vec_init(&particles->velocity, 0);
   vec_init(&particles->location, 0);

   if(capacity) {
      part_reserve(particles, capacity);
   }
}

void part_reserve(part_t *particles, int capacity)
{
   assert(capacity >= particles->count);
   particles->owner_rank = realloc(particles->owner_rank, capacity * sizeof(int));
   particles->mass = realloc(particles->mass, capacity * sizeof(double));
   vec_reserve(&particles->force, capacity);
   vec_reserve(&particles->velocity, capacity);
   vec_reserve(&particles->location, capacity);
 
   particles->capacity = capacity;
}

void part_resize(part_t *particles, int count)
{
   if(count > particles->capacity) {
      part_reserve(particles, count);
   }
   particles->count = count;
}

void part_free(part_t *particles)
{
   part_resize(particles, 0);
   part_reserve(particles, 0);
}

void part_copy(part_t *dst, int dst_start, const part_t *src, int src_start, int count)
{
   if(dst->count < dst_start + count) {
      part_resize(dst, dst_start + count);
   }

   memmove(&dst->owner_rank[dst_start], &src->owner_rank[src_start], count * sizeof(int));
   memmove(&dst->mass[dst_start], &src->mass[src_start], count * sizeof(double));
   vec_copy(&dst->force, dst_start, &src->force, src_start, count);
   vec_copy(&dst->velocity, dst_start, &src->velocity, src_start, count);
   vec_copy(&dst->location, dst_start, &src->location, src_start, count);
}

