import socket
import struct
import math
from time import sleep

global option

global SOCKET_OPT
global MCAST_GRP
global PORT
global ENDPNT_ADDR
global FPS

SOCKET_OPT = 2
MCAST_GRP = '239.192.1.1'
PORT = 5432
ENDPNT_ADDR = '127.0.0.1'
FPS = 24

def menu():
	print("###################################")
	print()
	print("[1] Unicast (1) or multicast (2)? (Default is Multicast)")
	print("[2] Set Mutlicast Address (Default is 239.192.1.1)")
	print("[3] Set Port (Default is 5432)")
	print("[4] Set endpoint Address (Default is 127.0.0.1)")
	print("[5] Set FPS (Default is 24)")
	print("[6] Print all current Settings")
	print("[7] Send Metadata (CTRL + C to end)")
	print("[0] EXIT")
	print()
	print("###################################")

	global option
	option = int(input("What would you like to do?: "))

	while option !=0:
		if option == 1:
			setSocketType()
		elif option == 2:
			setMulticast()
		elif option == 3:
			setPort()
		elif option == 4:
			setEndpointAddress()
		elif option == 5:
			setFPS()
		elif option == 6:
			printSettings()
		elif option == 7:
			sendData()
		else:
			print("invalid option")


def sendData():
	#jsonMessage = '{"metadata":{"camera":{"state":1,"device":{"model":"UMC-4","umc4SerialNumber":"K2.0000642-6001","umc4SoftwareVersion":2.2,"serialNumber":"123548","softwareVersion":2.2},"optic":{"filter":{"ndFilterDensity":1.2,"ndFilterType":"none"},"lens":{"device":{"model":"lensName","serialNumber":"S234TFhg","motorRawEncoderLimitsFocus":{"min":50,"max":50},"motorRawEncoderLimitsIris":{"min":50,"max":50},"motorRawEncoderLimitsFL":{"min":50,"max":50}},"state":{"focusDistanceMetric":50,"focusDistanceImperial":50,"iris":50,"focalLength":50,"lensRawEncoderValueFocus":50,"lensRawEncoderValueIris":50,"lensRawEncoderValueFL":50,"motorRawEncoderValueFocus":50,"motorRawEncoderValueIris":50,"motorRawEncoderValueFL":50}}},"sensor":{"shutterAngle":172.8,"exposureTime":15254,"exposureIndex":800},"recording":{"media":{"capacity":500},"projectRate":{"timebase":25,"dropframe":false},"acquisitionTimestamp":214748364,"clip":{"clipInfo":{"clipNumber":15},"slateInfo":{"cameraIndex":"AA"}}},"processing":{"whitebalance":{"cct":5600,"tint":15}},"positional":{"orientation":{"tilt":0,"roll":0}}}}}'
	jsonMessagePt1 = '{"metadata":{"camera":{"state":1,"device":{"model":"UMC-4","umc4SerialNumber":"K2.0000642-6001","umc4SoftwareVersion":"2.2","serialNumber":"123548","softwareVersion":"2.2"},"optic":{"filter":{"ndFilterDensity":1.2,"ndFilterType":0},"lens":{"device":{"model":"lensName","serialNumber":"S234TFhg","motorRawEncoderLimitsFocus":{"min":50,"max":50},"motorRawEncoderLimitsIris":{"min":50,"max":50},"motorRawEncoderLimitsFL":{"min":50,"max":50}},"state":{"focusUnit":"metric","focusDistanceMetric":'
	jsonMessagePt2 = ',"focusDistanceImperial":50,"iris":'
	jsonMessagePt3 = ',"focalLength":'
	jsonMessagePt4 = ',"lensRawEncoderValueFocus":50,"lensRawEncoderValueIris":50,"lensRawEncoderValueFL":50,"motorRawEncoderValueFocus":50,"motorRawEncoderValueIris":50,"motorRawEncoderValueFL":50}}},"sensor":{"shutterAngle":172.8,"exposureTime":15254,"exposureIndex":800},"recording":{"media":{"capacity":500},"projectRate":{"timebase":25,"dropframe":false},"acquisitionTimestamp":214748364,"clip":{"clipInfo":{"clipNumber":15},"slateInfo":{"cameraIndex":"AA"}}},"processing":{"whitebalance":{"cct":5600,"tint":15}},"positional":{"orientation":{"tilt":0,"roll":0}}}}}'

	HOURS = 00
	MINUTES = 00
	SECONDS = 00
	FRAMES = 00
	
	INDEX = 1
	MasterTC = str(HOURS) + ":" + str(MINUTES) + ":" + str(SECONDS) + ":" + str(FRAMES)
	CameraIndex = 'A'
	LensName = 'MetadataEncoder'
	LensDistanceUnit = "Meter"
	FocusDistance = 20
	LensFocalLength = 25.0
	LensIris = " T2  + 2/10"
	LensLinearIris = 5000
	RawEncoderFocus = 0
	RawEncoderFocal = 0
	RawEncoderIris = 0
	EncoderLimFocusMotorMin = 0
	EncoderLimFocusMotorMax  = 0
	EncoderLimFocalMotorMin = 0
	EncoderLimFocalMotorMax = 0
	EncoderLimIrisMotorMin = 0
	EncoderLimIrisMotorMax = 0
	Tilt = -0.7
	Roll = 0.5
	TAB = "\t"
	NEWLINE = "\n"

	if SOCKET_OPT == 2:

		sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
		sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
		sock.connect((ENDPNT_ADDR, PORT))

		x = 1
		y = 1
		while True:

			if x<250:
				LensLinearIris += x/10
				FocusDistance += x/100
				LensFocalLength += x/1000

				if y < FPS:
					FRAMES = y
				else:
					FRAMES = y%FPS

				if y%FPS == 0:
					SECONDS += 1

				if SECONDS%60 == 0 and SECONDS != 0:
					SECONDS = 0
					MINUTES += 1

				if MINUTES%60 == 0 and MINUTES !=0:
					MINUTES = 0
					HOURS += 1

				MasterTC = str(HOURS) + ":" + str(MINUTES) + ":" + str(SECONDS) + ":" + str(FRAMES)
				message = jsonMessagePt1 + str(FocusDistance) + jsonMessagePt2 + str(LensLinearIris) + jsonMessagePt3 + str(LensFocalLength) + jsonMessagePt4;
				byt = message.encode()

				sock.sendto(byt, (MCAST_GRP, PORT))
				#print(LensLinearIris)
				print(LensFocalLength)
				sleep(1.0/FPS)

			else:
				x = 1
				LensLinearIris = 5000
				FocusDistance = 20
				LensFocalLength = 25.0

			x+=1
			y+=1

	elif SOCKET_OPT == 1:

		sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

		x = 1
		y = 1
		while True:

			if x<250:
				LensLinearIris += x/10
				FocusDistance += x/100
				LensFocalLength += x/1000

				if y < FPS:
					FRAMES = y
				else:
					FRAMES = y%FPS

				if y%FPS == 0:
					SECONDS += 1

				if SECONDS%60 == 0 and SECONDS != 0:
					SECONDS = 0
					MINUTES += 1

				if MINUTES%60 == 0 and MINUTES !=0:
					MINUTES = 0
					HOURS += 1

				MasterTC = str(HOURS) + ":" + str(MINUTES) + ":" + str(SECONDS) + ":" + str(FRAMES)
				message = jsonMessagePt1 + str(FocusDistance) + jsonMessagePt2 + str(LensLinearIris) + jsonMessagePt3 + str(LensFocalLength) + jsonMessagePt4;
				byt = message.encode()

				sock.sendto(byt, (ENDPNT_ADDR, PORT))
				#print(LensLinearIris)
				print(LensFocalLength)
				sleep(1.0/FPS)

			else:
				x = 1
				LensLinearIris = 5000
				FocusDistance = 20
				LensFocalLength = 25.0

			x+=1
			y+=1
		

def setSocketType():
	print()
	print("###################################")
	global SOCKET_OPT
	SOCKET_OPT = int(input("Input 1 for Unicast and 2 for Multicast: "))
	if SOCKET_OPT == 1:
		print("Socket set to Unicast")
		print("###################################")
		print()
		menu()
	elif SOCKET_OPT == 2:
		print("Socket set to Multicast")
		print("###################################")
		print()
		menu()
	else:
		print("invalid option")
		menu()


def setMulticast():
	print()
	print("###################################")
	global MCAST_GRP 
	MCAST_GRP = str(input("Input Multicast Address: "))
	print("Multicast Address set to: ", MCAST_GRP)
	print("###################################")
	print()
	menu()

def setFPS():
	print()
	print("###################################")
	global FPS
	FPS = int(input("Input FPS: "))
	print("FPS set to: ", FPS)
	print("###################################")
	print()
	menu()

def setEndpointAddress():
	print()
	print("###################################")
	global ENDPNT_ADDR
	ENDPNT_ADDR = str(input("Input Endpoint Address: "))
	print("Endpoint Address set to: ", ENDPNT_ADDR)
	print("###################################")
	print()
	menu()

def setPort():
	print()
	print("###################################")
	global PORT
	PORT = int(input("Input Port: "))
	print("Port set to: ", PORT)
	print("###################################")
	print()
	menu()

def printSettings():
	print()
	print("###################################")
	print("Multicast Address: ", MCAST_GRP)
	print("Endpoint Address: ", ENDPNT_ADDR)
	print("Port: ", PORT)
	print("FPS: ", FPS)
	print("###################################")
	print()
	menu()

menu()