# Michael Van Veen
# Agent.py

k = 1.0 # Consumption coefficient
l = 1.0 # Reuptake coefficient
# Agents are the main economic agents within our market.  Each agent has resource quotas, as well as parameters that describe the behavior that the agent performs at every iteration.

# Requirements:
#	1. Store state information for two resource quantities, as well as any behaviour parameters required
#		1.1 Store state information for every iteration
# 		1.2 Provide easy accessors/mutators to these parameters
#	2. Provide a function which provides agent behavior for a given iteration (this function will be called by market class).
#		2.1 Reset resource quantities according to rate
#		2.2 Estimate survivability of agent.
#		2.3 Update consumption/reuptake rate
#		2.4 Make a buy/sell offer according to agent state

class Agent():
	def __init__(self, q1, q2, r1, r2, t1, t2, market):
		# Note: all quantities are implemented as lists.
		# Each iteration, the new values for each parameter are
		# pushed onto the list	

		# Number of iterations (also used to grab list index)
		self._count = 0 
		self._dead = -1
	
		# Resource Quantities
		self._q1 = [float(q1*0.)]	# Quantity 1
		self._q2 = [float(q2*0.)]	# Quantity 2

		# Rate
		self._r1 = [float(r1)] # (Quantity 1)
		self._r2 = [float(r2)] # (Quantity 2)

		# Survival Threshold
		self._t1 = [float(t1)]	#(Quantity 1)
		self._t2 = [float(t2)]	#(Quantity 1)

		# This is a reference to market container class
		self._market = market


	def kill(self, num):
		self._dead = num

	def grab(self, resource):
		return(resource[len(resource)-1])
		
	def getQ1(self):
		return(self.grab(self._q1))
		#return(self._q1[self._count])

	def setQ1(self, quantity):
		self._q1.append(quantity)

	def modQ1(self, quantity):
		self._q1[self._count] = quantity

	def getQ2(self):
		return(self.grab(self._q2))
		#return(self._q2[self._count])
	def modQ2(self, quantity):
		self._q2[self._count] = quantity

	def setQ2(self, quantity):
		self._q2.append(quantity)

	def getR1(self):
		#print self._r1
		#print self, " ", len(self._r1), " ", self._count
		return(self.grab(self._r1))
		#return(self._r1[self._count])

	def setR1(self, quantity):
		self._r1.append(quantity)
		
	def getR2(self):
		return(self.grab(self._r2))

	def setR1(self, quantity):
		self._r1.append(quantity)

	def setR2(self, quantity):
		self._r2.append(quantity)

	def getThresh1(self):
		return(self.grab(self._t1))

	def getThresh2(self):
		return(self.grab(self._t2))

	# Check to see if we're alive or dead
	def isAlive(self):
		return (self._dead > -1)
		#if ( (self.getQ2() - self.getThresh1() > 0.) \
		#	and (self.getQ1() - self.getThresh2() > 0.)): 
		#	return True
		#else:
		#	return False

	# Sets consumption rate within an iteration
	def setRate(self):
		self.setR1(0.*self.getR1()*1.2)
		self.setR2(0.*self.getR2()*1.2)
		
	# Sets reuptake rate within an iteration
	#def setReuptake():

	# Peform market transaction(s) within an iteration

	# Each iteration, an agent makes two transactions dependent
	# upon the amount of resource surplus it has.
	# If it has a resource deficit, it makes a buy offer for the resource.
	# Otherwise, it sells off whatever surplus it can

	#Cannot: BuyQ1 and BuyQ2

	#Can:	Sell Q1	and Sell Q2
	#	Buy  Q1 and Sell Q2
	#	Sell Q1 and Sell Q2

	def gotoMarket(self):
		remainder1 = self.getQ1() - self.getThresh1()
		remainder2 = self.getQ2() - self.getThresh1()

		#price we're willing to sell
		price1 = self.getQ1() / self.getQ2()
		price2 = self.getQ2() / self.getQ1()
		
		if (remainder1 > 0. and remainder2 < 0.):
			# Sell your quantity 1, buy quantity 2
			self._market.makeSell1(self, remainder1, price1)
			self._market.makeBuy2(self, -1.*remainder2, price2)
		elif (remainder1 < 0. and remainder2 > 0.):
			# Sell your quantity 2,  buy your quantity 1 
			self._market.makeSell2(self, remainder2, price2)
			self._market.makeBuy1(self, -1.*remainder1, price1)
		else:
			# Sell off both remainders
			self._market.makeSell1(self, remainder1, price1)
			self._market.makeSell2(self, remainder2, price2)

	# Perform one successive iteration on the agent
	def iterate(self):

		# Add reuptake to quantity 
		# Note: l is a coefficient to play with?
	

		self.setQ1(abs(l * self.getR1() + self.getQ1() - self.getThresh1())+1)
		self.setQ2(abs(l * self.getR2() + self.getQ2() - self.getThresh2()+1))

		# This little agent went to the market...
		self.gotoMarket()

		# Reset reuptake
		# self.setReuptake()
		
		# Reset consumption
		self.setRate()

		# Increment counter (used to access array indices each iteration)
		self._count += 1 

