function distributeCards()
	--the asshole receives the cards first, then the vice asshole,
	--then the vice president and then the president

	local order={}
	local i=0
	--see if the players are still in a neutral position or not
	if players[1].rank=="neutral" then
		for i=1,4 do
			order[i]=i
		end
	else --find the order described up there
		for i=1,4 do
			if players[i].rank=="asshole" then
				order[1]=i
			elseif players[i].rank=="vice asshole" then
				order[2]=i
			elseif players[i].rank=="vice president" then
				order[3]=i
			elseif players[i].rank=="president" then
				order[4]=i
			end
		end
	end
	
	--now we have the order of distribution, it is important as the
	--asshole and vice asshole have one more card
	
	--distribution axactly as in reality
	for i=1,118+4 do 
		local cardNum=math.floor((i-1)/4)+1
		local playerNum=math.mod(i-1, 4)+1
		if cardNum<=118 then
			players[order[playerNum]].hand[cardNum]=mainDeck[i]
			mainDeck[i]=nil--removes the card from the deck
		else
			--TODO: see if it's ok & useful to do that
			players[order[playerNum]].hand[cardNum]=nil --ensures that the right number is returned by the counting function
		end
	end
end


function orderCards(tableOfCards)
	local len=tableLength(tableOfCards)
	orderedTableOfCards={} --will get the cards in the right order
	local numberOfCardsOrdered=0
	local i=0
	
	while numberOfCardsOrdered<len do
		local indice=0
		local power=1000 --random big number
		for i=1,len do
			if tableOfCards[i]~=nil then
				if tableOfCards[i].power<power then
					indice=i
					power=tableOfCards[i].power
				end
			end
		end
		
		table.insert(orderedTableOfCards, tableOfCards[indice])
		tableOfCards[indice]=nil
		
		
		numberOfCardsOrdered=numberOfCardsOrdered+1
	end
	
	return orderedTableOfCards
end

function positionAllCards()
	local i=0
	for i=1,4 do
		positionCards(players[i])
	end
end	

function hideCardsOfPlayerNum(playerNum, hidden)
	if hidden==nil then
		hidden=true
	end
	local i=0
	for i=1, handSize(playerNum) do
		players[playerNum].hand[i].visible= not hidden
	end
end

function positionCardsOfPlayerNum(num)
	return positionCards(players[num])
end

function positionCards(player)
	local i=0
	if player.position=="bottom" then --player 1
		x=GAMEPREF["playerBottomCardsX"]
		y=GAMEPREF["playerBottomCardsY"]-CARDSPREF["height"]
		gravityx=GAMEPREF["playerBottomCardsGravityX"]
		nbCardsInHand=tableLength(player.hand)
		if nbCardsInHand*CARDSPREF["width"]<=(gravityx-x)*2 then
			x=gravityx-math.floor((nbCardsInHand*CARDSPREF["width"])/2)
		end
		
		--starting from x, shift the cards to the right 
		for i=1,nbCardsInHand do
			--enableDebug()
			debug("player.hand["..i.."].position.x = "..player.hand[i].position.x)
			--disableDebug()
			player.hand[i].position.x=x+(i-1)*CARDSPREF["width"]
			player.hand[i].position.y=y
			player.hand[i].orientation="verticalmain"
			player.hand[i].visible=true
			player.hand[i].greyed=false
			player.hand[i].selected=false
		end
	else
		nbCardsDrawable=math.floor(GAMEPREF["maxHandSize"]/CARDSPREF["smallwidth"])
		nbCardsInHand=tableLength(player.hand)
		
		if player.position=="left" then
			debug("nbCardsDrawable = "..nbCardsDrawable, "nbCardsInHand = "..nbCardsInHand)
			x=GAMEPREF["playerLeftCardsX"]
			y=GAMEPREF["playerLeftCardsY"]
			
			if nbCardsInHand<=nbCardsDrawable then
				y=y+math.floor((GAMEPREF["maxHandSize"]-(nbCardsInHand*CARDSPREF["smallwidth"]))/2)
				for i=1,nbCardsInHand do
					player.hand[i].position.x=x
					player.hand[i].position.y=y+(i-1)*CARDSPREF["smallwidth"]
				end
			else
				
				--we are going to draw 2 lines of cards, the 1st being always longer
				nbCardsIn1stLine=math.floor(nbCardsInHand/2)+1		
				y=y+math.floor((GAMEPREF["maxHandSize"]-(nbCardsIn1stLine*CARDSPREF["smallwidth"]))/2)		
				for i=1,nbCardsInHand do
					if i<=nbCardsIn1stLine then
						player.hand[i].position.x=x
						player.hand[i].position.y=y+(i-1)*CARDSPREF["smallwidth"]
					else
						player.hand[i].position.x=x+15 --was: x+math.floor(CARDSPREF["smallheight"]/2)
						player.hand[i].position.y=y+(i-1-nbCardsIn1stLine)*CARDSPREF["smallwidth"]+math.floor(CARDSPREF["smallwidth"]/2)
					end
				end
			end
			for i=1,nbCardsInHand do
				player.hand[i].orientation="horizontal"
				player.hand[i].visible=false
				player.hand[i].greyed=false
				player.hand[i].selected=false
			end
			
		elseif player.position=="top" then
			x=GAMEPREF["playerTopCardsX"]
			y=GAMEPREF["playerTopCardsY"]-CARDSPREF["smallheight"]
			gravityx=GAMEPREF["playerTopCardsGravityX"]
			nbCardsInHand=tableLength(player.hand)
			if nbCardsInHand*CARDSPREF["smallwidth"]<=(gravityx-x)*2 then
				x=gravityx-math.floor((nbCardsInHand*CARDSPREF["smallwidth"])/2)
			end
			
			--starting from x, shift the cards to the right 
			for i=1,nbCardsInHand do
				player.hand[i].position.x=x+(i-1)*CARDSPREF["smallwidth"]
				player.hand[i].position.y=y
				player.hand[i].orientation="verticalsub"
				player.hand[i].visible=false
				player.hand[i].greyed=false
				player.hand[i].selected=false
			end
			
			
		else  --if player.position=="right" then
			x=GAMEPREF["playerRightCardsX"]-CARDSPREF["smallheight"]
			y=GAMEPREF["playerRightCardsY"]
			
			if nbCardsInHand<=nbCardsDrawable then
				y=y+math.floor((GAMEPREF["maxHandSize"]-(nbCardsInHand*CARDSPREF["smallwidth"]))/2)
				for i=1,nbCardsInHand do
					player.hand[i].position.x=x
					player.hand[i].position.y=y+(i-1)*CARDSPREF["smallwidth"]
				end
			else
				
				--we are going to draw 2 lines of cards, the 1st being always longer
				nbCardsIn1stLine=math.floor(nbCardsInHand/2)+1
				y=y+math.floor((GAMEPREF["maxHandSize"]-(nbCardsIn1stLine*CARDSPREF["smallwidth"]))/2)
				debug("nbCardsIn1stLine = "..nbCardsIn1stLine, "nbCardsInHand = "..nbCardsInHand)		
				for i=1,nbCardsInHand do
					if i<=nbCardsIn1stLine then
						player.hand[i].position.x=x
						player.hand[i].position.y=y+(i-1)*CARDSPREF["smallwidth"]
					else
						player.hand[i].position.x=x-15 --x-math.floor(CARDSPREF["smallheight"]/2)
						player.hand[i].position.y=y+(i-1-nbCardsIn1stLine)*CARDSPREF["smallwidth"]+math.floor(CARDSPREF["smallwidth"]/2)
					end
				end	
			end
			for i=1,nbCardsInHand do
				player.hand[i].orientation="horizontal"
				player.hand[i].visible=false
				player.hand[i].greyed=false
				player.hand[i].selected=false
			end
			
		end
	end
	
end

function shuffleMainDeck()
	mainDeck=shuffle(mainDeck)
end

function disposePlayersAroundTheTable()
	--simple case: everyone is neutral
	players[1].position="bottom" --he is always at the bottom
	if players[1].rank=="neutral" then
		players[2].position="left"
		players[3].position="top"
		players[4].position="right"
	else --the player 1 must be at the bottom, and the order is always president-asshole-vice asshole-vice president
		--lazy way of doing it :/
		if players[1].rank == "asshole" then
			players[playerNumByRank("vice asshole")].position="left"
			players[playerNumByRank("vice president")].position="top"
			players[playerNumByRank("president")].position="right"
		elseif players[1].rank == "vice asshole" then
			players[playerNumByRank("vice president")].position="left"
			players[playerNumByRank("president")].position="top"
			players[playerNumByRank("asshole")].position="right"
		elseif players[1].rank == "vice president" then
			players[playerNumByRank("president")].position="left"
			players[playerNumByRank("asshole")].position="top"
			players[playerNumByRank("vice asshole")].position="right"
		else --players[1].rank == "president" then
			players[playerNumByRank("asshole")].position="left"
			players[playerNumByRank("vice asshole")].position="top"
			players[playerNumByRank("vice president")].position="right"
		end
	end
end

function placeCursorOnCardNum(num) --aligns the centers of the card and of the cursor
	local cardMiddleX=players[1].hand[num].position.x+math.floor(CARDSPREF["width"]/2)
	local cardMiddleY=players[1].hand[num].position.y+math.floor(CARDSPREF["height"]/2)
	
	--fdebug("CURSOR:")
	--fdebug(ICONSPREF["ingameCursorWidth"])
	--fdebug(ICONSPREF["ingameCursorHeight"])
	--fdebug(CURSORPREF["width"])
	--fdebug(CURSORPREF["height"])
	ingameCursor.position.x=cardMiddleX-math.floor(CURSORPREF["width"]/2)
	ingameCursor.position.y=cardMiddleY-math.floor(CURSORPREF["height"]/2)
	
	if players[1].hand[num].selected then
		ingameCursor.position.y=ingameCursor.position.y-CARDSPREF["selectedShift"]
	end
	
	ingameCursor.indice=num
end

function replaceCursor()--called after changing the cursor's skin
	placeCursorOnCardNum(ingameCursor["indice"])
end

function makeCursorAvailable(available)
	if available==nil then
		available=true
	end
	ingameCursor.available=available
end

function moveCursorToThe(direction, nb)
	if nb==nil then
		nb=1
	end
	if direction=="right" then
		if ingameCursor.indice<=tableLength(players[1].hand)-nb then
			placeCursorOnCardNum(ingameCursor.indice+nb)
		elseif nb==1 then
			placeCursorOnCardNum(1)
		else
			placeCursorOnCardNum(tableLength(players[1].hand))
		end
	else --left
		if ingameCursor.indice>=1+nb then
			placeCursorOnCardNum(ingameCursor.indice-nb)
		elseif nb==1 then
			placeCursorOnCardNum(tableLength(players[1].hand))
		else
			placeCursorOnCardNum(1)
		end
	end
end

function putEveryOneInState(state)
	local i=0
	for i=1,4 do
		players[i].state=state
	end
end

function makePlayerLeader(playerNum)
	local i=0
	for i=1,4 do
		if players[i].state=="leader" then
			players[i].state="in_game"
		end
	end
	players[playerNum].state="leader"
end

function deselectAllCards(playerNum)
	if playerNum==nil then
		playerNum=1
	end	
	local i=0
	for i=1, tableLength(players[playerNum].hand) do
		players[playerNum].hand[i].selected=false
	end
end

function selectCardNum(num, select)
	if select==nil then
		select=true
	end
	players[1].hand[num].selected=select
end

function invertSelectionOfCardNum(num)
	players[1].hand[num].selected = not players[1].hand[num].selected
end

function selectAllCardsWithValue(val, select)
	if select==nil then
		select=true
	end
	local i=0
	for i=1, tableLength(players[1].hand) do
		if players[1].hand[i].value==val then
			players[1].hand[i].selected=select
		end
	end
end

-- adds the cards in "tableOfCards" in the tableDeck
-- uses playerNum to calculate the positions
-- greys all cards already present
function putCardsOnTheTable(tableOfCards, playerNum)
	enableDebug()
	local tdLength=tableLength(tableDeck)
	local nbCards=tableLength(tableOfCards)
	local i=0
	--greying
	for i=1,tdLength do
		tableDeck[i].greyed=true
	end
	
	--calculate position of the cards given the position of the player
	local position=players[playerNum].position
	if position=="bottom" then
		local minCenterX=GAMEPREF["playerBottomTableMinX"]
		local maxCenterX=GAMEPREF["playerBottomTableMaxX"]
		local minCenterY=GAMEPREF["playerBottomTableMinY"]
		local maxCenterY=GAMEPREF["playerBottomTableMaxY"]
		local cardsSizeW=nbCards*CARDSPREF["width"]
		local cardsSizeH=CARDSPREF["height"]
		local tableSizeW=maxCenterX-minCenterX
		local tableSizeH=maxCenterY-minCenterY
		local x=minCenterX-math.floor(cardsSizeW/2)+random(0, tableSizeW)
		local y=minCenterY-math.floor(cardsSizeH/2)+random(0, tableSizeH)
		
		--extract cards from tableOfCards and add them to tableDeck
		for i=1,nbCards do
			tdLength=tdLength+1
			tableDeck[tdLength]=tableOfCards[i]
			tableOfCards[i]=nil
			tableDeck[tdLength].orientation="verticalmain" --normally not useful
			tableDeck[tdLength].visible=true --normally not useful
			tableDeck[tdLength].selected=false
			tableDeck[tdLength].position.x=x+(i-1)*CARDSPREF["width"]
			tableDeck[tdLength].position.y=y
		end
	elseif position=="top" then
		local minCenterX=GAMEPREF["playerTopTableMinX"]
		local maxCenterX=GAMEPREF["playerTopTableMaxX"]
		local minCenterY=GAMEPREF["playerTopTableMinY"]
		local maxCenterY=GAMEPREF["playerTopTableMaxY"]
		local cardsSizeW=nbCards*CARDSPREF["width"]
		local cardsSizeH=CARDSPREF["height"]
		local tableSizeW=maxCenterX-minCenterX
		local tableSizeH=maxCenterY-minCenterY
		local x=minCenterX-math.floor(cardsSizeW/2)+random(0, tableSizeW)
		local y=minCenterY-math.floor(cardsSizeH/2)+random(0, tableSizeH)
		
		--extract cards from tableOfCards and add them to tableDeck
		for i=1,nbCards do
			tdLength=tdLength+1
			tableDeck[tdLength]=tableOfCards[i]
			tableOfCards[i]=nil
			tableDeck[tdLength].orientation="verticalmain" --normally not useful
			tableDeck[tdLength].visible=true --normally not useful
			tableDeck[tdLength].selected=false
			tableDeck[tdLength].position.x=x+(i-1)*CARDSPREF["width"]
			tableDeck[tdLength].position.y=y
		end
	elseif position=="left" then
		local minCenterX=GAMEPREF["playerLeftTableMinX"]
		local maxCenterX=GAMEPREF["playerLeftTableMaxX"]
		local minCenterY=GAMEPREF["playerLeftTableMinY"]
		local maxCenterY=GAMEPREF["playerLeftTableMaxY"]
		local cardsSizeW=CARDSPREF["height"]
		local cardsSizeH=nbCards*CARDSPREF["width"]
		local tableSizeW=maxCenterX-minCenterX
		local tableSizeH=maxCenterY-minCenterY
		local x=minCenterX-math.floor(cardsSizeW/2)+random(0, tableSizeW)
		local y=minCenterY-math.floor(cardsSizeH/2)+random(0, tableSizeH)
		
		--extract cards from tableOfCards and add them to tableDeck
		for i=1,nbCards do
			tdLength=tdLength+1
			tableDeck[tdLength]=tableOfCards[i]
			tableOfCards[i]=nil
			tableDeck[tdLength].orientation="horizontal" --normally not useful
			tableDeck[tdLength].visible=true --normally not useful
			tableDeck[tdLength].selected=false
			tableDeck[tdLength].position.x=x
			tableDeck[tdLength].position.y=y+(i-1)*CARDSPREF["width"]
		end
	elseif position=="right" then
		local minCenterX=GAMEPREF["playerRightTableMinX"]
		local maxCenterX=GAMEPREF["playerRightTableMaxX"]
		local minCenterY=GAMEPREF["playerRightTableMinY"]
		local maxCenterY=GAMEPREF["playerRightTableMaxY"]
		local cardsSizeW=CARDSPREF["height"]
		local cardsSizeH=nbCards*CARDSPREF["width"]
		local tableSizeW=maxCenterX-minCenterX
		local tableSizeH=maxCenterY-minCenterY
		local x=minCenterX-math.floor(cardsSizeW/2)+random(0, tableSizeW)
		local y=minCenterY-math.floor(cardsSizeH/2)+random(0, tableSizeH)
		
		--extract cards from tableOfCards and add them to tableDeck
		for i=1,nbCards do
			tdLength=tdLength+1
			tableDeck[tdLength]=tableOfCards[i]
			tableOfCards[i]=nil
			tableDeck[tdLength].orientation="horizontal" --normally not useful
			tableDeck[tdLength].visible=true --normally not useful
			tableDeck[tdLength].selected=false
			tableDeck[tdLength].position.x=x
			tableDeck[tdLength].position.y=y+(i-1)*CARDSPREF["width"]
		end
	end
	disableDebug()
end

--makes a group of cards composed by those selected in the
--hand of playerNum
--if remove==true, removes them also from the hand, and repacks the hand
--default is false
--returns the group
function takeSelectedCardsFromHand(playerNum, remove)
	if remove==nil then
		remove=false
	end
	local tableOfCards={}
	local nbCardsTaken=0
	local handSize=tableLength(players[playerNum].hand)
	local i=0
	for i=1,handSize do
		if players[playerNum].hand[i].selected==true then
			nbCardsTaken=nbCardsTaken+1
			tableOfCards[nbCardsTaken]=players[playerNum].hand[i]
			if remove then
				players[playerNum].hand[i]=nil
			end
		end
	end
	if remove then
		players[playerNum].hand=repackTable(players[playerNum].hand, 16) --16: 8 same cards + 8 "2"
	end
	return tableOfCards
end

function removeSelectedCardsFromHand(playerNum)
	local handSize=tableLength(players[playerNum].hand)
	local counter=0
	for i=1,handSize do
		if players[playerNum].hand[i].selected==true then
			players[playerNum].hand[i]=nil
			counter=counter+1
		end
	end
	players[playerNum].hand=repackTable(players[playerNum].hand, 16) --16: 8 same cards + 8 "2"
	return counter
end

--TODO: better recreate everything before each game?
function cleanTableDeck() --removes cards from the table and put them back in the mainDeck
	local tdsize=tableLength(tableDeck)
	local mdsize=tableLength(mainDeck)
	--debugForced("mainDeckSize: "..mdsize)
	local i=0
	for i=1,tdsize do
		mdsize=mdsize+1
		mainDeck[mdsize]=tableDeck[i]
		tableDeck[i]=nil
	end
end

function cleanHand(playerNum)
	local hsize=tableLength(players[playerNum].hand)
	local mdsize=tableLength(mainDeck)
	--debugForced("mainDeckSize: "..mdsize)
	local i=0
	for i=1,hsize do
		mdsize=mdsize+1
		mainDeck[mdsize]=players[playerNum].hand[i]
		players[playerNum].hand[i]=nil
	end
end

function cleanHands()
	local i=0
	for i=1,4 do
		cleanHand(i)
	end
end


function makeEveryOneNeutral()
	local i=0
	for i=1,4 do
		players[i].rank="neutral"
	end
end

--assumes the hands are ordered
function getCardsToExchangeByRank(rank)
	local atable={}
	local num=playerNumByRank(rank)
	local handsz=handSize(num)
	
	if rank=="president" then
		atable[1]=players[num].hand[1]
		atable[2]=players[num].hand[2]
		players[num].hand[1]=nil
		players[num].hand[2]=nil
		players[num].hand=repackTable(players[num].hand, 2)
	elseif rank=="vice president" then
		atable[1]=players[num].hand[1]
		players[num].hand[1]=nil
		players[num].hand=repackTable(players[num].hand, 1)
	elseif rank=="vice asshole" then
		atable[1]=players[num].hand[handsz]
		players[num].hand[handsz]=nil
	elseif rank=="asshole" then
		atable[1]=players[num].hand[handsz-1]
		atable[2]=players[num].hand[handsz]
		players[num].hand[handsz-1]=nil
		players[num].hand[handsz]=nil
	else 
		return nil
	end
	return atable
end

function addCardsToHandByRank(atable, rank)
	local num=playerNumByRank(rank)
	local handsz=handSize(num)
	local nb=tableLength(atable)
	
	local i=0
	for i=1,nb do
		players[num].hand[handsz+1]=atable[i]
		handsz=handsz+1
	end
end





