# FlockingSimulator2.py
# Run as FlockingSimulator2.py Data_filename Obstacle_filename

# This program is the core simulation engine for the project. It creates a flock of birds with randomly assigned
# initial locations and velocities, and then use the function 'FlockStep' from the file FlockingUpdateRules2.py
# to update the movement of the flock for some number of timesteps. The results (i.e. locations of all birds in the  
# flock at each times step are written to data files for later analysis). A number of random obstacles may also be 
# generated for the birds to negotiate.

# The data is stored in the file filename
# The user is allowed to specify a number of parameters:

# (1) gridsize = the size of the grid to run simulation on, a rectangle gridsize x gridsize
# (2) num_steps = the number of timesteps to simulate for
# (3) timestep = the size of each timestep 
# (4) N = total number of birds in the flock
# (5) MA = birds maximum acceleration
# (6) MV = birds maximum velocity
# (7) sightrange = the birds sightrange
# (8) dmin = the minimum distance an object can be from a bird, before the bird treats it as an obstacle to avoid
# (9) Num_Obstacles = the number of randomly generated obstacles


# determine filename
import sys
filename = sys.argv[1]
Obstacle_file = sys.argv[2]

# import modules
from Scientific.Geometry import *
from numpy import *
from numpy.random import *
from FlockingClassDefinitions import *
from FlockingUpdateRules2 import *


# define parameters
gridsize = 100          #(integer)
num_steps = 10000       #(integer)
timestep = 0.1          #(float)
N = 20                  #(integer)
MA = 0.125               #(float)
MV = 0.5                #(float)
sightrange = 10.0       #(float)
dmin = 3.0              #(float)
Num_Obstacles = 0       #(integer)


# Step (I) Randomly determine Obstacle Locations for cross shaped obstacles (may overlap)
Obstacles = []
if Num_Obstacles > 0:
    for n in xrange(Num_Obstacles):
        o = Vector( uniform(20.0,1.0*gridsize - 20.0) , uniform(20.0,1.0*gridsize - 20.0), 0.0 )
        oprime1 = Vector( o[0]+1, o[1], 0.0)    
        oprime2 = Vector( o[0]-1, o[1], 0.0)    
        oprime3 = Vector( o[0], o[1]+1, 0.0)    
        oprime4 = Vector( o[0], o[1]-1, 0.0)
        Obstacles.append(o)
        Obstacles.append(oprime1)
        Obstacles.append(oprime2)
        Obstacles.append(oprime3)
        Obstacles.append(oprime4) 

    file = open(Obstacle_file, 'w')
    for o in Obstacles:
        file.write(`o[0]` + ' ')
        file.write(`o[1]` + ' ')
        file.write('\n')

    file.close()

if Num_Obstacles == 0:
   file = open(Obstacle_file, 'w')
   file.close()
   

# Step (II) - Generate the Flock
ListOfBirds = []

# Create Birds with randomly assigned positions and velocities on the grid
for n in xrange(N):

    label = 'b' + `n`

    p_current = uniform(0.0,gridsize*1.0,(1,2))
    p_current = Vector(p_current[0][0],p_current[0][1],0.0)
    
    v_current = uniform(0.0,MV/2**0.5,(1,2))
    v_current = Vector(v_current[0][0],v_current[0][1],0.0)

    p_last = p_current - v_current*timestep

    bird = Bird(label,MV,MA,sightrange,p_current,p_last,v_current,[])
    ListOfBirds.append(bird)

# Create the flock (its called dummyflock)
dummyflock = Flock('dummyflock',ListOfBirds,Vector(0.0,0.0,0.0),Vector(0.0,0.0,0.0),Vector(0.0,0.0,0.0))

# loop over birds and assign their neighbors
for n in xrange(N):
    FindNeighbors(n,dummyflock)


# Step (III) - run the simulation and write data to file

# open the file to write to 
#file = open('BirdData3','w')
file = open(filename,'w')

# write the initial data

# x data on one line
for n in xrange(N):
    file.write(`dummyflock.ListOfBirds[n].p_current[0]` + ' ')
file.write('\n')

# y data on another
for n in xrange(N):
    file.write(`dummyflock.ListOfBirds[n].p_current[1]` + ' ')
file.write('\n')

# run the simulation and write data at each time step
for step in xrange(num_steps):
    FlockStep(dummyflock,timestep,dmin,gridsize,Obstacles)  

    # x data on one line 
    for n in xrange(N):
        file.write(`dummyflock.ListOfBirds[n].p_current[0]` + ' ')
    file.write('\n')

    # y data on the next
    for n in xrange(N):
        file.write(`dummyflock.ListOfBirds[n].p_current[1]` + ' ')
    file.write('\n')

file.close()

    
    
    
    

