# Python script to create volunteer schedule
# To run with F5 in Notepad++ cmd /K "$(FULL_CURRENT_PATH)"

import csv

DEBUG = False
MYPATH = 'e:/dave/for_papa'
HEADER = ''
NUM_SLOTS = 6
EmptySlotText = "Empty Slot"

# Input files
volunteerList = "volunteer_list.csv"
positionsNeeded = "positions.csv"
# Output file
outFile = "schedule.csv"

# Layout
#
# First create a dictionary with each slot as a label
# Each dictionary value should be a list of strings as long as the number of
#  people needed in that slot. Init each string to ""
# 
# Now load in a 2d list with each person a list of:
#  name,slotsLeft,eachPosition of the 6 init to "open" or "closed"
#  As the slots are filled, replace "open" with the dictionary key of the slot
#
# First pass, loop through volunteers and try to place in a preferance
# Second pass, fill non-preferances

myVolunteers = [] # Volunteer matrix
myPositions = [] # List of position names
mySchedule = {} # Schedule so far with keys of name + slot

# Read in the list of positions needed and create the base schedule		
with open("{}/{}".format(MYPATH, positionsNeeded)) as f:
	positions = csv.reader(f)
	firstLine = True
	for row in positions:
		if DEBUG:
			print("current row is:", row)
		if firstLine:
			firstLine = False
			HEADER = '{},"{}","{}","{}","{}","{}","{}"'.format(row[0],
				row[1],row[2],row[3],row[4],row[5],row[6])
			continue
		posName = row[0].strip().lower()
		myPositions.append(posName)
		for i, num in enumerate(row[1:int(NUM_SLOTS)+1]):
			key = "{}{}".format(posName, i+1)
			value = []
			if num == 0:
				mySchedule[key] = None
				continue
			for j in range(1, int(num)+1):
				value.append(EmptySlotText)
			mySchedule[key] = value
# Now we should have a dictionary of the entire schedule
if DEBUG:
	print("\nMy empty schedule is:")
	print(mySchedule)
			
# Read in the list of volunteers
with open("{}/{}".format(MYPATH, volunteerList)) as f:
	volunteers = csv.reader(f)
	firstLine = True
	for row in volunteers:
		# Drop the header row
		if firstLine:
			firstLine = False
			continue
		# Drop rows without names assuming they are empty
		if row[0] == None or row[0] == "":
			continue
		# Create a new volunteer row describing which slots they would work
		#  and any position preferances
		myRow = []
		myRow.append(row[0]) # get name and
		myRow.append(int(row[1])) # the number of slots they would like
		# row[2] and [3] are email and phone which we don't need now
		# the next 6 cells are the avalibility for that time slot
		for x in row[4:10]:
			if (x == 'yes') or (x == 'YES') or (x == 'Yes'):
				myRow.append(True)
			elif (x == 'no') or (x == 'NO') or (x == 'No'):
				myRow.append(False)
			elif isinstance(x, str):
				curPref = x.strip().lower()
				myRow.append(curPref)
			else:
				myRow.append(False)
		myVolunteers.append(myRow)
if DEBUG:
	print("\nMy volunteers are:")
	print(myVolunteers)

# Assign people to positions
# First look if a person's preferance is open
for volIndex, curVolunteer in enumerate(myVolunteers):
	# Check if this person already has all the work they want
	if myVolunteers[volIndex][1] < 1:
		continue
	curName = curVolunteer[0]
	for x in range(2, NUM_SLOTS+2):
		alreadyAssigned = False
		if myVolunteers[volIndex][1] < 1:
			continue
		if isinstance(myVolunteers[volIndex][x], str):
			volPref = myVolunteers[volIndex][x]
			tempKey = volPref + str(x-1)
			# If there is still a blank fill this persons preferance
			for myIndex, curString in enumerate(mySchedule[tempKey]):
				if (myVolunteers[volIndex][1] < 1) or (alreadyAssigned == True):
					continue
				if EmptySlotText == curString:
					# Assign the job slot
					mySchedule[tempKey][myIndex] = curName
					# Mark it off of the volunteer matrix
					myVolunteers[volIndex][x] = False
					alreadyAssigned = True
					# Decriment the number of slots desired
					myVolunteers[volIndex][1] = myVolunteers[volIndex][1] - 1
# All fillable preferances should be filled				
if DEBUG:
	print("\nNow my schedule is")
	print(mySchedule)					

# Then look to fill general slots
for volIndex, curVolunteer in enumerate(myVolunteers):
	curName = curVolunteer[0]
	if DEBUG:
		print(myVolunteers[volIndex][1])
	if myVolunteers[volIndex][1] > 0:
		for curPosition in myPositions:
			for i,x in enumerate(curVolunteer[2:8]):
				if myVolunteers[volIndex][1] > 0:
					if x: # True if the person is OK with this slot
						curNameList = mySchedule[curPosition + str(i+1)]
						if myVolunteers[volIndex][1] < 1 or curName in curNameList:
							continue # no slots left or already in this slot
						else:
							if EmptySlotText in curNameList and myVolunteers[volIndex][1] > 0:
								curNameList[curNameList.index(EmptySlotText)] = curName
								myVolunteers[volIndex][1] = myVolunteers[volIndex][1] - 1
								if DEBUG:
									print(myVolunteers[volIndex][0] + " is now at " +
										str(myVolunteers[volIndex][1]) + " slots")
								myVolunteers[volIndex][i+2] = False
						
if DEBUG:
	print("\nNow my schedule is")
	print(mySchedule)
	print("\n")

# Now make the CSV file output
with open("{}/{}".format(MYPATH, outFile), 'w') as myFile:
	myFile.write("{}\n".format(HEADER))
	for curPosition in myPositions:
		curLine = curPosition
		for i in range(1,7):
			curNameList = mySchedule[curPosition + str(i)]
			curLine = curLine + ',"' + "\n".join(curNameList) + '"'
		if DEBUG:
			print(curLine)
		myFile.write("{}\n".format(curLine))

print("\nReached the end, so should be a good run")
