package org.drools.examples.wumpus

import org.drools.examples.wumpus.Arrow
import org.drools.examples.wumpus.Move
import org.drools.examples.wumpus.Direction
import org.drools.examples.wumpus.MoveCommand
import org.drools.examples.wumpus.ShootCommand
import org.drools.examples.wumpus.Cell

dialect "mvel"

/*
declare Hero
	@propSpecific
end	
*/

rule "Direction.UP, Move.TURN_LEFT"  when
    $h  : Hero( direction == Direction.UP)
    $mc : MoveCommand( move == Move.TURN_LEFT )   
then
	retract ( $mc ); 
    modify( $h ) { direction = Direction.LEFT };  
end

rule "Direction.LEFT, MOVE.TURN_LEFT"  when
    $h  : Hero( direction == Direction.LEFT)
    $mc : MoveCommand( move == Move.TURN_LEFT )   
then
	retract ( $mc );
    modify( $h ) { direction = Direction.DOWN };   
end

rule "Direction DOWN,  MOVE.TURN_LEFT"  when
    $h  : Hero( direction == Direction.DOWN)
    $mc : MoveCommand( move == Move.TURN_LEFT )   
then
	retract ( $mc );
    modify( $h ) { direction = Direction.RIGHT };   
end

rule "Direction.RIGHT, MOVE.TURN_LEFT"  when
    $h  : Hero( direction == Direction.RIGHT )
    $mc : MoveCommand( move == Move.TURN_LEFT )   
then
	retract ( $mc );  
    modify( $h ) { direction = Direction.UP }; 
end

rule "Direction.UP, Move.TURN_RIGHT"  when
    $h  : Hero( direction == Direction.UP)
    $mc : MoveCommand( move == Move.TURN_RIGHT )   
then
	retract ( $mc );  
    modify( $h ) { direction = Direction.RIGHT }; 
end

rule "Direction.RIGHT, MOVE.TURN_RIGHT"  when
    $h  : Hero( direction == Direction.RIGHT)
    $mc : MoveCommand( move == Move.TURN_RIGHT )   
then
	retract ( $mc );  
    modify( $h ) { direction = Direction.DOWN }; 
end

rule "Direction DOWN,  MOVE.TURN_RIGHT"  when
    $h  : Hero( direction == Direction.DOWN)
    $mc : MoveCommand( move == Move.TURN_RIGHT )   
then
	retract ( $mc );
    modify( $h ) { direction = Direction.LEFT };   
end

rule "Direction.LEFT, MOVE.TURN_RIGHT"  when
    $h  : Hero( direction == Direction.LEFT )
    $mc : MoveCommand( move == Move.TURN_RIGHT )   
then
	retract ( $mc );
    modify( $h ) { direction = Direction.UP };   
end


rule "Move Up"  when
    ($mc : MoveCommand( move == Move.MOVE_FORWARD ) and   
     $h  : Hero(direction == Direction.UP)) or
    ($mc : MoveCommand( move == Move.MOVE_BACKWARD ) and  
     $h  : Hero(direction == Direction.DOWN)) 
     $c  : Cell(row == $h.row + 1, col == $h.col )
then
	retract ( $mc );  
    modify( $h ) { row = $h.row + 1 };
    $c.setHidden( false ); 
end

rule "Move Down"  when
    ($mc : MoveCommand( move == Move.MOVE_FORWARD ) and   
     $h  : Hero(direction == Direction.DOWN)) or
    ($mc : MoveCommand( move == Move.MOVE_BACKWARD ) and  
     $h  : Hero(direction == Direction.UP)) 
     $c  : Cell(row == $h.row - 1, col == $h.col )
then
	retract ( $mc );  
    modify( $h ) { row = $h.row - 1 };
    $c.setHidden( false ); 	
end

rule "Move Left"  when
    (($mc : MoveCommand( move == Move.MOVE_FORWARD ) and   
     $h  : Hero(direction == Direction.LEFT)) or
    ($mc : MoveCommand( move == Move.MOVE_BACKWARD ) and  
     $h  : Hero(direction == Direction.RIGHT)))
     and 
     $c  : Cell(row == $h.row, col == $h.col - 1 )
then
	retract ( $mc );  
    modify( $h ) { col = $h.col - 1 };
    $c.setHidden( false ); 
end

rule "Move Right"  when
    ($mc : MoveCommand( move == Move.MOVE_FORWARD ) and   
     $h  : Hero(direction == Direction.RIGHT)) or
    ($mc : MoveCommand( move == Move.MOVE_BACKWARD ) and  
     $h  : Hero(direction == Direction.LEFT)) 
     $c  : Cell(row == $h.row, col == $h.col + 1 )
then
	retract ( $mc );  
    modify( $h ) { col = $h.col + 1 };
    $c.setHidden( false ); 
end

rule "Invalid Move, Feel Bump" salience -100 when
    $mc : MoveCommand()   
then
    retract( $mc );
    insert( new FeelBump() )
end

rule "New Move, Remove old Bump" salience 100 when
    exists MoveCommand() 
    $fp : FeelBump()
then
    retract( $fp )
end


rule "Shoot Arrow"  when
    $sc : ShootCommand();
    $h  : Hero()
then
    retract ( $sc );
    insert( new Arrow($h.row, $h.col, $h.direction) );
end 

rule "Move Arrow Up"  when
     $a :  Arrow( direction == Direction.UP)    
then
    modify( $a ) { row = $a.row + 1 };
end   

rule "Move Arrow Down"  when
     $a :  Arrow( direction == Direction.DOWN)    
then
    modify( $a ) { row = $a.row - 1 };
end   

rule "Move Arrow Left"  when
     $a :  Arrow( direction == Direction.LEFT)    
then
    modify( $a ) { col = $a.col - 1 };
end    

rule "Move Arrow Right"  when
     $a :  Arrow( direction == Direction.RIGHT)
then
    modify( $a ) { col = $a.col + 1 };
end  

rule "Remove Arrow"  when
     $a : Arrow() 
     not Cell(row == $a.row, col == $a.col )            
then
    retract ( $a );
end  