:- discontiguous(villageStart/1).
:- discontiguous(villageDo/2).

/**
 @descr initialize village action (nothing has been done before this)
 @form village
*/
village :-
	%get current player position
	currentPlayer(ID),
	taoist(ID,_,_,_,_,Pos),
	%get action of village of this position
	village(_,_,Action,_,Pos),
	%start village action
	villageStart(Action).

/**
 @descr continue village action (before this: village initializiation and gui interaction)
 @form village(-Args)
*/
village(Args) :-
	%get current player position and village
	currentPlayer(ID),
	taoist(ID,_,_,_,_,Pos),
	village(_,_,Action,_,Pos),
	%do the rest of village Action
	villageDo(Action,Args).	

/**
 @descr Graveyard: resurrects a choosen Player and roles the curse-dice
 @form villageStart(ressurect)
*/
villageStart(resurrect) :-
	%get a list of all dead taoists
	findall(Player,
		taoist(Player,_,_,0,_,_),
		[]),
	!.

% beginning
villageStart(resurrect) :-
	%get a list of all dead taoists
	findall(Player,
		taoist(Player,_,_,0,_,_),
		PlayerList),
	playerRessurectPlayer(PlayerList).

% continue
villageDo(resurrect,[TargetPlayer]) :-
	%testing if QiCount = 0, e.g. the TargetPlayer is dead
	taoist(TargetPlayer,_,_,0,_,Pos),
	%setting QiCount of TP to 2
	addQi(TargetPlayer,2),
	broadcastTaoistAlive(TargetPlayer),
	broadcastMove(TargetPlayer,Pos),
	currentPlayer(Player),
	%rolling the "curse-dice"
	curseDie(Player).

/**
 @descr Altar of Taoists: unhaunts a village and places a new ghost to the current players ghost-field
 @form villageStart(unhautVillage)
*/
% beginning
villageStart(unhauntVillage) :-
	%get a list of all haunted villages
	findall(Pos,
		village(_,_,_,haunted,Pos),
		TileList),
	playerUnhauntVillage(TileList).

% continue
villageDo(unhauntVillage,[TargetVillage]) :-
        %tests if TargetVillage is haunted
	village(_,_,_,haunted,TargetVillage),
	%unhaunts the TargetVillage
	freeVillage(TargetVillage),
	%current Player adds a ghost to the game
	addGhost.

/**
 @descr Marktstand des Kraeuterhaendlers: role two tao-dices and take Tao-markers with the same color.
 @form villageStart(twoTao)
*/
% beginning
% no white dice
villageStart(twoTao) :-
	%roll the dice and safe the result to buffer
	dice(2,DiceList),
	setBuffer(DiceList),
	checkWhiteDice(DiceList).
	
checkWhiteDice([0|_]):-
	%if there are _no_ white dice...
	villageDo(twoTao, [[0,0,0,0,0]]),
	!.
	
checkWhiteDice(_):-
	%if there are white dices...
	buffer(Dice),
	playerSelectVillageTaoMarker(Dice).

% continue
villageDo(twoTao, [InputDiceList]) :-
	%get saved Buffer
	buffer([WhiteDice|DiceList]),
	WhiteDice > 1,
	WhiteDiceN is WhiteDice - 1,
	%validide given Input-List
	sumlist(InputDiceList,1), %the InputDiceList must have WhiteCount Elements
	length(InputDiceList,5),
	%add the two given Vektors to the Players Tao-Marker List
	vectoradd(InputDiceList,DiceList,SumList),
	!,
	playerSelectVillageTaoMarker([WhiteDiceN|SumList]).

villageDo(twoTao, [InputDiceList]) :-
	buffer([1|DiceList]),
	sumlist(InputDiceList,1),
	length(InputDiceList,5),
	vectoradd(InputDiceList,DiceList,SumList),
	addTaoMarkers(SumList).

villageDo(twoTao, _) :-
	buffer([0|DiceList]),
	addTaoMarkers(DiceList).

/**
 @descr House of Witch: sacrifice 1 Qi to instantly exorcise a chosen ghost (not Wu-Feng!) (without mentioning curses/reward)
 @form villageStart(exorcise)
*/
% beginning
villageStart(exorcise) :-
       	%get a list of all fields occupied by ghosts
       	getOccupiedFields(GhostList),
	playerSelectGhostVillage(GhostList).

% continue
villageDo(exorcise,[TargetGhostField]) :-
	%check if there is a ghost on the TargetGhostField
	ghostField(TargetGhostField,GhostID,_), 
	((   GhostID > 0,
	     GhostID =< 55 ) ;
	GhostID >= 66),
	%remove one Qi from current Taoist
        addQi(-1),
	%remove ghost from field
	retract(ghostField(TargetGhostField,_,G3)),
	assert(ghostField(TargetGhostField,0,G3)),
	removeIfHaunter(TargetGhostField,GhostID),
        broadcastDeleteGhost(TargetGhostField).

removeIfHaunter(FieldID,GhostID) :-
	ghost(GhostID,_,_,_,_,haunt,_,_),
	retract(haunter(FieldID,_)),
	broadcastDeleteHaunter(FieldID),
	!.

removeIfHaunter(_,_).	

/**
 @descr Turm des Nachtwächters: reset all haunting ghosts of one color to their startpositions
 @form villageStart(resetHaunters)
*/
% beginning
villageStart(resetHaunters) :-
       	%get a list of all ghostsfields
        findall(FieldID,
		ghostField(FieldID,_,_),
		FieldList),
	playerSelectGhostVillage(FieldList).

% continue
villageDo(resetHaunters,[TargetField]) :-  
	%check if the TargetField is actually occupied by a haunter
	%haunter(TargetField,_),
	%get color of input FieldID
	ghostField(TargetField,_,Color),
	%find all haunters on this color-fields
	findall((Field,Counter),
		(   ghostField(Field,_,Color),
		    haunter(Field,Counter)),
		HaunterList),
	% reset all haunters
	forall(member((FieldID,_),HaunterList),
	       (   retract(haunter(FieldID,_)),
		   assert(haunter(FieldID,0)),
		   broadcastGhostHaunt(FieldID,0))).
	

/**
 @descr Buddhhistischer Tempel: take a "Buddha" and place it  by the end of your next round on a choosen ghostfield next to your Taoist
 @form villageStart(takeBuddha)
*/
% beginning
villageStart(takeBuddha) :-
	currentPlayer(Player),
	taoist(Player,_,_,_,_,Pos),
	%check if there is a "Buddha" left on the temple
	%village ID 6 = Buddhistischer Tempel
	village(6,_,_,_,Pos),
	buddha(BuddhaID,Pos),
	%add a Buddha to the Players Inventory
	retract(buddha(BuddhaID,_)),
	assert(buddha(BuddhaID,Player)),
	setBuffer(buddhaTaken),
	broadcastBuddhaToPlayer(Player,BuddhaID).
	%the buddha-placement is asked at the beginning of every round



/**
@descr Gebetskreis: Place/Replace one Tao-Marker on this village
@form
*/
% beginning
villageStart(exorcismAid):-
	playerSelectVillageTaoMarker(exorcismAid).

% continue
villageDo(exorcismAid,[TaoMarkerList]):-
	%check given InputList
	sumlist(TaoMarkerList,1),
	length(TaoMarkerList,5),
	%reset prayer-List
	retract(prayer(_)),
	%add the choosen color to prayerlist
	assert(prayer(TaoMarkerList)),
	broadcastPrayer(TaoMarkerList).


/**
 @descr Pavillon der Himmlischen Winde: move a choosen ghost to a free/buddha ghostfield and move a choosen taoist to a choosen tile
 @form villageStart(movePlayerGhost)
*/
% beginning
villageStart(movePlayerGhost) :-
	currentPlayer(ID),
	%get a list of fields occupied by ghosts
       	getOccupiedFields(GhostList),
	%get a list of free fields
	getFreeFields(FreeList),
	%get al list of players, that aren't the current player
	findall(TaoID,
		(taoist(TaoID,_,_,_,_,_),not(TaoID = ID)), 
		PlayerList),
	%send all the data to gui event, end here and wait for continue...
	playerMoveGhostPlayer(GhostList,FreeList,PlayerList,[1,2,3,4,5,6,7,8,9]).

% continue
villageDo(movePlayerGhost,[FieldIDFrom,FieldIDTo,PlayerID,TileIDTo]) :-
	%validate the input data
	ghostField(FieldIDFrom,GhostID,_),
	% target field is empty
	ghostField(FieldIDTo,0,_),
	GhostID > 0,
	taoist(PlayerID,_,_,Qi,_,Pos),
	% the chosen player must be moved
	not(Pos = TileIDTo),
	% tho chosen ghost must be moved
	not(FieldIDFrom = FieldIDTo),
	% is the chosen player alive?
	Qi > 0,
	%is the chosen TileID valid?
	village(TileIDTo,_,_,_,_),
	%move the ghost to the choosen field
	placeGhostNow(GhostID,FieldIDTo),
	% move haunter if there is one
	moveHaunter(FieldIDFrom,FieldIDTo),
	%TODO: an dieser Stelle müssen noch der Haunter-Status, die Schriftrollen, und die "Kraft-inaktiv" Marker versetzt werden
	retract(ghostField(FieldIDFrom,GhostID,Color)),
	assert(ghostField(FieldIDFrom,0,Color)),
	broadcastDeleteGhost(FieldIDFrom),
	%move the taoist to the choosen tile
	executeMove(PlayerID,TileIDTo).

% move haunter from one field to another
moveHaunter(FieldIDFrom,FieldIDTo) :-
	ghostField(FieldIDFrom,GhostID,_),
	ghost(GhostID,_,_,_,haunt,_,_),
	retract(haunter(FieldIDFrom,Counter)),
	assert(haunter(FieldIDTo,Counter)),
	broadcastDeleteHaunter(FieldIDFrom),
	broadcastGhostHaunt(FieldIDTo,Counter),
	!.

moveHaunter(_,_).
	

/**
@desc Teehaus : get a Qi-Point and choose a Tao-Marker from stack, add a ghost.  
@form villageStart(taoQiGhost)
*/

villageStart(taoQiGhost):-
	playerSelectVillageTaoMarker(taoQiGhost).


villageDo(taoQiGhost,[TaoMarkerList]):-
	%check given InputList
	sumlist(TaoMarkerList,1),
	length(TaoMarkerList,5),
	%add a Qi and the TaoMarkers to the players Taoist
        addQi(1),
	addTaoMarkers(TaoMarkerList),
	%add a ghost to the game
	addGhost.

/**
 @descr set isHaunted = haunted
 @form hauntVillage(TileID)
 */
hauntVillage(0).
hauntVillage(7) :-
	retract(village(7,Name,Ability,_,Position)),
	assert(village(7,Name,Ability,haunted,Position)),
	retract(prayer(_)),
	assert(prayer([0,0,0,0,0])),
	broadcastVillageHaunt(7).
	
hauntVillage(TileID) :-
	retract(village(TileID,Name,Ability,_,Position)),
	assert(village(TileID,Name,Ability,haunted,Position)),
	broadcastVillageHaunt(TileID).

/**
 @descr set isHaunted = none
 @form freeVillage(TileID)
 */
freeVillage(0).
freeVillage(Position) :-
	retract(village(TileID,Name,Ability,_,Position)),
	assert(village(TileID,Name,Ability,none,Position)),
	broadcastVillageUnhaunt(TileID).	
	
		
