
class DiagnosisSignal:
	NORMAL = 1
	BROKEN = 0

class PowerSource:
	NOT_AVAIL = 0
	LEFT_ENGINE = 1
	RIGHT_ENGINE = 2
	APU = 3 

# input[0]: diagnosis signal of left engine
# input[1]: diagnosis signal of right engine
# input[2]: diagnosis signal of APU 
# input[3-8]: diagnosis signals of switches 01-06

def left_trsfun(input):
	if (input[0]==DiagnosisSignal.NORMAL 
	and input[3]==DiagnosisSignal.NORMAL):
		return PowerSource.LEFT_ENGINE
	if (input[1]==DiagnosisSignal.NORMAL 
	and input[4]==DiagnosisSignal.NORMAL 
	and input[6]==DiagnosisSignal.NORMAL 
	and input[6]==DiagnosisSignal.NORMAL 
	and input[7]==DiagnosisSignal.NORMAL 
	and input[8]==DiagnosisSignal.NORMAL):
		return PowerSource.RIGHT_ENGINE
	if (input[2]==DiagnosisSignal.NORMAL
	and input[4]==DiagnosisSignal.NORMAL
	and input[5]==DiagnosisSignal.NORMAL):
		return PowerSource.APU
	return PowerSource.NOT_AVAIL

def right_trsfun(input):
	if (input[1]==DiagnosisSignal.NORMAL
	and input[7]==DiagnosisSignal.NORMAL):
		return PowerSource.RIGHT_ENGINE
	if (input[0]==DiagnosisSignal.NORMAL 
	and input[3]==DiagnosisSignal.NORMAL
	and input[4]==DiagnosisSignal.NORMAL
	and input[6]==DiagnosisSignal.NORMAL
	and input[8]==DiagnosisSignal.NORMAL):
		return PowerSource.LEFT_ENGINE
	if (input[2]==DiagnosisSignal.NORMAL
	and input[5]==DiagnosisSignal.NORMAL
	and input[6]==DiagnosisSignal.NORMAL
	and input[8]==DiagnosisSignal.NORMAL):
		return PowerSource.APU
	return PowerSource.NOT_AVAIL

class FIFOSignal:
	EMPTY = 0
	FULL = 1

class Action:
	# Compute and output PowerSource Selection 0-3
	BLOCKED = 4

# input[0]: diagnosis signal of left engine
# input[1]: diagnosis signal of right engine
# input[2]: diagnosis signal of APU 
# input[3-8]: diagnosis signals of switches 01-06
# input[9]: whether the subsequent FIFO is full or not

def left_df(input):
	if input[9] == FIFOSignal.EMPTY:
		return left_trsfun(input[0:9])	
	else:
		return Action.BLOCKED

def right_df(input):
	if input[9] == FIFOSignal.EMPTY:
		return right_trsfun(input[0:9])	
	else:
		return Action.BLOCKED

def left_fsm(input):
	if (input[0]==PowerSource.NOT_AVAIL or input[0]==input[1]):
		return input[1]
	else: 
		return PowerSource.NOT_AVAIL

def right_fsm(input):
	return left_fsm(input)

def left_fsm_df(input):
	if input[2]==1 and input[3]==0:
		return left_fsm(input[0:2])
	else:
		return Action.BLOCKED

def right_fsm_df(input):
	if input[2]==1 and input[3]==0:
		return right_fsm(input[0:2])
	else:
		return Action.BLOCKED

# input[0]: left load
#	0: no power
#	1: LE
#	2: RE
#	3: APU
# input[1]: right load
#	0: no power
#	1: LE
#	2: RE
#	3: APU

# output[0]: control signal for left engine
# output[1]: control signal for right egine
# output[2]: control signal for APU
# output[3-8]: control signal for switches 1-6

def control_trsfun(input, output_bit):
	output = 0
	if input[0]==PowerSource.NOT_AVAIL and input[1]==PowerSource.NOT_AVAIL:
		output = (0, 0, 0, 0, 0, 0, 0, 0, 0)
	elif input[0]==PowerSource.LEFT_ENGINE and input[1]==PowerSource.NOT_AVAIL:
		output = (1, 0, 0, 1, 0, 0, 0, 0, 0)
	elif input[0]==PowerSource.NOT_AVAIL and input[1]==PowerSource.RIGHT_ENGINE:
		output = (0, 1, 0, 0, 0, 0, 0, 1, 0)
	elif input[0]==PowerSource.LEFT_ENGINE and input[1]==PowerSource.RIGHT_ENGINE:
		output = (1, 1, 0, 1, 0, 0, 0, 1, 0)
	elif input[0]==PowerSource.APU and input[1]==PowerSource.APU:
		output = (0, 0, 1, 0, 1, 1, 1, 0, 1)
	elif input[0]==PowerSource.LEFT_ENGINE and input[1]==PowerSource.LEFT_ENGINE:
		output = (1, 0, 0, 1, 1, 0, 1, 0, 1)
	elif input[0]==PowerSource.RIGHT_ENGINE and input[1]==PowerSource.RIGHT_ENGINE:
		output = (0, 1, 0, 0, 1, 0, 1, 1, 1)
	elif input[0]==PowerSource.APU and input[1]==PowerSource.NOT_AVAIL:
		output = (0, 0, 1, 0, 1, 1, 0, 0, 0)
	elif input[0]==PowerSource.NOT_AVAIL and input[1]==PowerSource.APU:
		output = (0, 0, 1, 0, 0, 1, 1, 0, 1)
	elif input[0]==PowerSource.LEFT_ENGINE and input[1]==PowerSource.APU:
		output = (0, 0, 1, 1, 0, 1, 1, 0, 1)
	elif input[0]==PowerSource.APU and input[1]==PowerSource.RIGHT_ENGINE:
		output = (0, 1, 1, 0, 1, 1, 0, 1, 0)
	else:
		output = (0, 0, 0, 0, 0, 0, 0, 0, 0)

	return output[output_bit]

class ControlAction:
	BLOCKED = 2

def control_df(input, output_bit):
	if input[2]==FIFOSignal.FULL and input[3]==FIFOSignal.FULL:
		return control_trsfun(input, output_bit)
	else:
		return ControlAction.BLOCKED


