(include "player.ddh")

(def extern int CARD_ROSE)

(class_function Player void create (group)
	(group

	(= this.isUser 0)

	# player itself
	(this.mesh.load (asset "assets/character.asset" DD_PLY))
	(this.mesh.loadTexture (asset "assets/character_1.asset" DD_PLY))

	# individual cards
	(= this.cardsTotal 0)

	# font
	(this.font.setAlign DD_STRING3D_ALIGN_CENTER)
	(this.font.setColorFront 0.9 0.9 0.9)
	(this.font.setColorBack 0.3 0.3 0.3)

	# selection
	(= this.highlightCard -1)
	(= this.selectedCard -1)
	(= this.selectedCard2 0)
	(dd_matrix_identity this.selectedMatrix)
	(dd_matrix_translate this.selectedMatrix 0 2.01 2.6)
	(dd_matrix_rotate this.selectedMatrix 90 1 0 0)
	#(dd_matrix_rotate this.selectedMatrix (- (dd_math_rand 20) 10) 0 0 1)

	(= this.userLookingAtCard -1)

	)
)

(class_function Player void draw (group)
	(group

	(if this.isUser
		(this.drawUser)
		(this.drawAI)
	)

	# draw cards
	(for (def int i 0) (< i this.cardsTotal) (= i (+ i 1))
		(group

		# highlighted card
		(if (== i this.highlightCard)
			(group
			(dd_matrix_push)
			(this.cards[i].applyMatrix)
			(dd_scalef 1.15 1.15 1.15)
			(this.cards[i].drawRaw)
			(dd_translatef 0 0 0.01)
			(dd_scalef 0.1 0.1 0.1)
			(this.font.draw "confirm")
			(dd_matrix_pop)
			)
		# looking at card
		(&& (== i this.userLookingAtCard) (== this.highlightCard -1))
			(group
			(dd_matrix_push)
			(this.cards[i].applyMatrix)
			(dd_scalef 1.1 1.1 1.1)
			(this.cards[i].drawRaw)
			(dd_matrix_pop)
			)
		# else
			(this.cards[i].draw)
		)
		)
	)

	# draw selected card
	(if this.selectedCard2
		(this.selectedCard2.draw)
	)

	)
)

(class_function Player void drawUser (group)
	(group

	)
)

(class_function Player void drawLookingAtText (group)
	(group

#	(if (>= this.userLookingAtCard 0)
#		(group
#		(dd_matrix_push)
#		(dd_translatef 0 0 -5)
#		(this.cards[this.userLookingAtCard].drawText)
#		(dd_matrix_pop)
#		)
#	)

	)
)

(class_function Player void drawAI (group)
	(group

	# draw player
	(dd_matrix_push)
	(dd_multMatrixf this)
	(this.mesh.draw)
	(dd_translatef 0 2.2 0.3)
	(dd_scalef 0.5 0.5 0.5)
	(this.font.drawInt this.cardsTotal)
	(dd_matrix_pop)

	)
)

(class_function Player void clean (group)
	(group
	)
)

# add new card to the hand
(def ref dd_meshColour newCardMesh)
(def ref Card newCard)

(class_function Player void addCard (group Card card)
	(group

	# apply limit
	(if (>= this.cardsTotal 10)
		(echo "CANNOT GIVE MORE CARDS")
		(group

		(= this.cards[this.cardsTotal] card)
		(= this.cardsTotal (+ this.cardsTotal 1))

		(if this.isUser
			(this.calculateCardPositionsUser)
			(this.calculateCardPositions)
		)

		)
	)

	)
)

(class_function Player void removeCard (group int index)
	(group

	# no cards to remove
	(if (<= this.cardsTotal 0)
		(echo "NO CARDS TO REMOVE")
	# index out of bounds
	(|| (< index 0) (>= index this.cardsTotal))
		(echo "INDEX OUT OF BOUNDS TO REMOVE")
	# remove given card
		(group
			(def int temp)
			# shuffle all cards in the array down one step
			(for (def int i index) (< i (- this.cardsTotal 1)) (= i (+ i 1))
				(group
				(= temp (+ i 1))
				(= this.cards[i] this.cards[temp])
				)
			)
			(= temp (- this.cardsTotal 1))
			(= this.cards[temp] 0)

			# update new number of cards
			(= this.cardsTotal (- this.cardsTotal 1))

			# re-position cards
			(if this.isUser
				(this.calculateCardPositionsUser)
				(this.calculateCardPositions)
			)
		)
	)

	)
)

(class_function Player void calculateCardPositions (group)
	(group
	(for (def int i 0) (< i this.cardsTotal) (= i (+ i 1))
		(group
		(dd_matrix_identity this.cards[i].target)
		(dd_matrix_mult this.cards[i].target this)
		(dd_matrix_translate this.cards[i].target 0 2.5 0.2)
		(dd_matrix_translate this.cards[i].target (- (* i 0.42) (/ (* (- this.cardsTotal 1) 0.42) 2)) 0 0)
		(dd_matrix_rotate this.cards[i].target 180 0 1 0)

		(if (== this.cards[i].id CARD_ROSE)
			(dd_matrix_rotate this.cards[i].target 180 0 1 0)
		)
		)
	)
	)
)

(class_function Player void calculateCardPositionsUser (group)
	(group
	(for (def int i 0) (< i this.cardsTotal) (= i (+ i 1))
		(group
		(dd_matrix_identity this.cards[i].target)
		(dd_matrix_mult this.cards[i].target this)
		(dd_matrix_translate this.cards[i].target 0 3.7 0)
		(dd_matrix_rotate this.cards[i].target (- (* -30 i) (* (/ (- this.cardsTotal 1) 2.0) -30)) 0 1 0)
		(dd_matrix_rotate this.cards[i].target -43 1 0 0)
		(dd_matrix_translate this.cards[i].target 0 0 -1.2)
		(dd_matrix_rotate this.cards[i].target 25 1 0 0)
		)
	)
	)
)

(class_function Player void highlightLookingCard (group)
	(group

	# player has cards
	(if (<= this.cardsTotal 0)
		(group
		(echo "cannot select card, no cards left")
		)
	# card is highlighted, either select it or remove highlight
	(>= this.highlightCard 0)
		(group

		# looking at highlighted card - select it
		(if (== this.highlightCard this.userLookingAtCard)
			(group

			(= this.selectedCard2 this.cards[this.highlightCard])
			(dd_matrix_identity this.selectedCard2.target)
			(dd_matrix_mult this.selectedCard2.target this.actual)
			(dd_matrix_mult this.selectedCard2.target this.selectedMatrix)

			# remove card from array
			(for (def int i (+ this.highlightCard 1)) (< i this.cardsTotal) (= i (+ i 1))
				(group
				(def int prevIndex (- i 1))
				(= this.cards[prevIndex] this.cards[i])
				)
			)

			(= this.cardsTotal (- this.cardsTotal 1))
			(if this.isUser
				(this.calculateCardPositionsUser)
				(this.calculateCardPositions)
			)

			)
		# looking elsewhere - de-highlight card
			(group
			(= this.highlightCard -1)
			)
		)
		)
	(&& (>= this.userLookingAtCard 0) (< this.userLookingAtCard this.cardsTotal))
		(group
		(= this.highlightCard this.userLookingAtCard)
		)
	)

	)
)

(class_function Player void planCard (group int index)
	(group

	(if (<= this.cardsTotal 0)
		(group
		(echo "cannot select card, no cards left")
		)
	(&& (< index 0) (>= index this.cardsTotal))
		(group
		(echo "cannot select card, out of bounds")
		)
	# else
		(group
		(= this.selectedCard2 this.cards[index])
		(dd_matrix_identity this.selectedCard2.target)
		(dd_matrix_mult this.selectedCard2.target this.actual)
		(dd_matrix_mult this.selectedCard2.target this.selectedMatrix)

		# remove card from array
		(for (def int i (+ index 1)) (< i this.cardsTotal) (= i (+ i 1))
			(group
			(def int prevIndex (- i 1))
			(= this.cards[prevIndex] this.cards[i])
			)
		)

		(= this.cardsTotal (- this.cardsTotal 1))
		(if this.isUser
			(this.calculateCardPositionsUser)
			(this.calculateCardPositions)
		)

		) # selected card
	)

	)
)

(class_function Player void selectCard (group)
	(group

	(if (<= this.cardsTotal 0)
		(group
		(echo "cannot select card, no cards left")
		)
	(&& (< this.userLookingAtCard 0) (>= this.userLookingAtCard this.cardsTotal))
		(group
		(echo "cannot select card, out of bounds")
		)
	# else
		(group

		# get index, either by card being looked at, or random for AI
		(def int index)
		(if this.isUser
			(group
			(= index this.highlightCard)
			(= this.highlightCard -1)
			)
			(group
			(= index (dd_math_rand this.cardsTotal))
			)
		)
		(= this.selectedCard (dd_math_rand this.cardsTotal))
		(= this.selectedCard2 this.cards[index])
		(dd_matrix_identity this.selectedCard2.target)
		(dd_matrix_mult this.selectedCard2.target this.actual)
		(dd_matrix_mult this.selectedCard2.target this.selectedMatrix)

		# remove card from array
		(for (def int i (+ index 1)) (< i this.cardsTotal) (= i (+ i 1))
			(group
			(def int prevIndex (- i 1))
			(= this.cards[prevIndex] this.cards[i])
			)
		)

		(= this.cardsTotal (- this.cardsTotal 1))
		(if this.isUser
			(this.calculateCardPositionsUser)
			(this.calculateCardPositions)
		)

		) # selected card
	)

	)
)

(class_function Player void deselectCard (group)
	(group
	(= this.selectedCard -1)
	(= this.selectedCard2 0)
	)
)

(class_function Player void lookAtCard (group float rotX float rotY)
	(group

	(def int lookingAtCard -1)

	# looking at the hand's layer (Y-axis)
	(if (&& (< rotY -40) (> rotY -60))
		(group

		# looking at the hand - figure out which card
		(if (&& (> rotX (* (/ (- this.cardsTotal 0.0) 2.0) -30)) (< rotX (* (/ (- this.cardsTotal 0) 2.0) 30)))
			(group
			(= lookingAtCard (/ (+ (/ (* this.cardsTotal 30) 2.0) rotX) 30))
			)
		)

		)
	) # looking at hand's layer

	(= this.userLookingAtCard lookingAtCard)

	)
) # look at card
