from RPi import GPIO
from time import sleep
import json
import requests
import random
from itertools import cycle
import time

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

segments=(6,3,0,4,11,9,10,22)
led=17
segmentOrder = (11,4,10,9,6,3,0)
segmentPeriod = 22
digitOrder = (19,26,13,5)

segmentNeighborMatrix = {}

#Top: 10 = go left a digit; 11 = go right a digit
segmentNeighborMatrix[0] = (1,5,10,11)

segmentNeighborMatrix[1] = (0,6)

segmentNeighborMatrix[2] = (1,2,6)

#bottom: 10 = go left a digit; 11 = go right a digit
segmentNeighborMatrix[3] = (2,4,10,11)

segmentNeighborMatrix[4] = (3,5,6)

segmentNeighborMatrix[5] = (0,4,6)

foodDisplayList = [1,1,1,1]

WORKER_SERVICE_BASE_URL = "http://eb-new-two.us-west-2.elasticbeanstalk.com"
#WORKER_SERVICE_BASE_URL = "http://192.168.1.9:5000"
currentAntDelay=999

#middle: 10 = go left a digit; 11 = go right a digit
segmentNeighborMatrix[6] = (1,2,4,5,10,11)

foodDisplayList = [GPIO.HIGH, GPIO.LOW, GPIO.LOW, GPIO.LOW]

internalDelayAmount = 1

def setGPIO(setTo = False):
	if setTo:
		return GPIO.HIGH
	else:
		return GPIO.LOW

def SetAntDelayAmount():
	global internalDelayAmount
	internalDelayAmount = int(requests.get(WORKER_SERVICE_BASE_URL + "/getAntMoveDelay").text)
	return(internalDelayAmount)

def getAntDelayAmount():
	global internalDelayAmount	
	ans=1
	if internalDelayAmount == 999:
		ans=random.randrange(100)
	else:
		ans=internalDelayAmount
	return ans

def InitializeAllSegments(initializeTo):
	for a in list(segmentOrder) + [segmentPeriod]:
		GPIO.setup(a,GPIO.OUT)
		GPIO.output(a,setGPIO(initializeTo))
		sleep(0.10)

def InitializeFood():
	#foodDisplayList = [GPIO.HIGH,GPIO.HIGH,GPIO.HIGH,GPIO.HIGH] 
	global foodDisplayList
	foodDisplayList = [GPIO.HIGH,GPIO.LOW,GPIO.LOW,GPIO.LOW] 
	

def InitializeAllDigitBits(initializeTo = False):
	for digit in digitOrder:
		GPIO.setup(digit, GPIO.OUT)
		GPIO.output(digit, setGPIO(initializeTo))

def SetAllDigits(setTo = False):
	for x in digitOrder:
		GPIO.output(x,setGPIO(setTo)) 

def SetAllSegments(setTo = False):
	for x in list(segmentOrder) + [segmentPeriod]:
		GPIO.output(x,setGPIO(setTo))

def SingleDigitPlay(digitNumber, segmentIndex):

	#Turn OFF all digits.
	SetAllDigits(True)

	theSegment = segmentOrder[segmentIndex]
	theDigitGPIO = digitOrder[digitNumber]

	#Turn off all segments on all digits
	SetAllSegments(False)

	#Display all four digits (3 will be blank)	
	for digit in range(4):
		if digit == digitNumber:	
			#queue up the ant segment
			GPIO.output(segmentOrder[segmentIndex], GPIO.HIGH)

		else:
			SetAllSegments(False)

		DisplayDots(digit)

		#flash the digit real quick.
		GPIO.output(digitOrder[digit], GPIO.LOW)
		sleep(0.001)
		GPIO.output(digitOrder[digit], GPIO.HIGH)
		


##############STARTING INITIALIZATION#############
# Initialize the 4 digit-bits.

InitializeAllDigitBits()
#input("1. 4 digit bits have been disabled")

InitializeAllSegments(True)
#input("2. All segments have been turned on...")

#for segment in list(segmentOrder) + [segmentPeriod]:
#	GPIO.output(segment, GPIO.LOW)

#input("3. All segments have been turned off...")



def RotateAllSegments():
	for a in segmentOrder:
		GPIO.output(a,GPIO.LOW)
		sleep(1)

def clearAllSegments():
	for a in segmentOrder:
		GPIO.output(a,GPIO.LOW)

def PrintNumber(DigitPos1to4, numberToPrint):

	# GPIO pin numbers for lookup (immutable)
	segmentOrder = (11,4,10,9,6,3,0)
	digitOrder = (19,26,13,5)

	num = {' ':(0,0,0,0,0,0,0),
		'0':(1,1,1,1,1,1,0),
		'1':(0,1,1,0,0,0,0),
		'2':(1,1,0,1,1,0,1),
		'3':(1,1,1,1,0,0,1),
		'4':(0,1,1,0,0,1,1),
		'5':(1,0,1,1,0,1,1),
		'6':(1,0,1,1,1,1,1),
		'7':(1,1,1,0,0,0,0),
		'8':(1,1,1,1,1,1,1),
		'9':(1,1,1,1,0,1,1)}
	
	
	#enumerate returns (indexPos, lookup's value)
	for a in enumerate(num[str(numberToPrint)]): 
			if a[1] == 1:
				GPIO.output(segmentOrder[a[0]],GPIO.HIGH)
			else:
				GPIO.output(segmentOrder[a[0]],GPIO.LOW)

	GPIO.output(digitOrder[DigitPos1to4],GPIO.LOW)
	sleep(0.001)
	GPIO.output(digitOrder[DigitPos1to4],GPIO.HIGH)
	

def PrintFourDigits(theNumber):
	#theNumber must be a 4 digit string.  use ' ' for blank, 0 for zero	
	digitOrder = (19,26,13,5)
	for digit in range(4):
		PrintNumber(digit,theNumber[digit])
		GPIO.output(digitOrder[digit],GPIO.LOW)
		sleep(0.001)
		GPIO.output(digitOrder[digit],GPIO.HIGH)

def DisplayDots(theDigit):
	GPIO.output(22,foodDisplayList[theDigit])

def SignifyNewSession(theNumOfMoves, theNumCompletions):
	for x in range(5):
		for a in range(100):
			PrintFourDigits(theNumOfMoves)

		for a in range(100):
			PrintFourDigits(theNumCompletions)
			

def getNextPosition(theCurrentDigitIndex,theCurrentSegmentIndex):

	GO_LEFT_DIGIT_CODE = 10
	GO_RIGHT_DIGIT_CODE = 11
	
	returnDigit = theCurrentDigitIndex

	options = segmentNeighborMatrix[currentSegmentIndex]

	nextSegmentStep = random.choice(options)
	returnSegment = nextSegmentStep

	if nextSegmentStep == GO_LEFT_DIGIT_CODE:
		#print("Going left!")
		returnDigit -= 1
		if returnDigit == -1:
			returnDigit = len(digitOrder) - 1
		returnSegment = theCurrentSegmentIndex
		#print("new left digit: %s" % returnDigit)

		#Check if food should be eaten... (decimal)
		if currentSegmentIndex == 3: #only on bottom segment...
			if foodDisplayList[returnDigit] == GPIO.HIGH:
				foodDisplayList[returnDigit] = GPIO.LOW 
	
	if nextSegmentStep == GO_RIGHT_DIGIT_CODE:
		#print("Going right!")
		returnDigit += 1
		if returnDigit == len(digitOrder):
			returnDigit = 0
		returnSegment = theCurrentSegmentIndex

		#Check if food should be eaten... (decimal)
		if theCurrentSegmentIndex == 3: #only on bottom segment...
			if foodDisplayList[theCurrentDigitIndex] == GPIO.HIGH:
				foodDisplayList[theCurrentDigitIndex] = GPIO.LOW 
	return (returnDigit, returnSegment)

def logSession(theStartTime, theEndTime, theListOfMoves):
	theListOfMoves.insert(0,str(theEndTime))
	theListOfMoves.insert(0,str(theStartTime))

	theWholeString = ','.join(theListOfMoves)
	print(theWholeString)
	print(WORKER_SERVICE_BASE_URL + "/saveLog")
	requests.post(WORKER_SERVICE_BASE_URL + "/saveLog",data={'logData':theWholeString})
	return True	

stocks = {}
givenAnswer=input("Ready to start your program ??")

currentSegmentIndex = random.randrange(7)
currentDigitIndex = random.randrange(4)

numCompletions = 0
AntSessionsArray = []
delayAmount = 25 

while True:
	InitializeFood()
	numMoves = 0
	continueFlag = True
	startTime = time.time()
	endTime = None
	durationSeconds = 0	
	AntTracks=[]
	SetAntDelayAmount()
	while continueFlag:
		theDelayAmount = getAntDelayAmount()
		AntTracks.append('%s-%s-%s' % (currentDigitIndex, currentSegmentIndex, theDelayAmount))
		for x in range(theDelayAmount):
			SingleDigitPlay(currentDigitIndex,currentSegmentIndex)
		numMoves += 1

		if GPIO.HIGH not in foodDisplayList:
			continueFlag = False 

		currentDigitIndex, currentSegmentIndex = \
			getNextPosition(currentDigitIndex, currentSegmentIndex)
	endTime = time.time()
	numCompletions += 1
	durationSeconds = endTime - startTime

	print("GOT ALL THE FOOD! It took: %s number of moves, and %s seconds.  umber of completions: %s," % (numMoves, durationSeconds, numCompletions)) 
	logSession(startTime, endTime, AntTracks)
	SignifyNewSession(str(numMoves).rjust(4,' '), str(numCompletions).ljust(4,' '))
	
GPIO.cleanup()
g
