package org.drools.games.adventures

import org.drools.games.adventures.Room;
import org.drools.games.adventures.Thing;

import org.drools.games.adventures.Request;
import org.drools.games.adventures.Response;
import org.drools.games.adventures.SessionCharacter

import org.drools.games.adventures.MoveCommand
import org.drools.games.adventures.Command
import org.drools.games.adventures.PickupCommand
import org.drools.games.adventures.DropCommand
import org.drools.games.adventures.LookCommand
import org.drools.games.adventures.SetSessionCharacterCommand

global org.drools.games.adventures.Counter counter

dialect "mvel"


rule lookCmd agenda-group "commands" lock-on-active auto-focus  when
    lc : LookCommand(  c : character )
    ?look( c, r, things, exits; )
then    
    str = "You are in the " + r + "\n";
    str +="You can see " + things + "\n";
    str +="Available exits are  " + exits + "\n";
    str +="\n";
            
    res = new Response( str );
    res.localId = lc.requestId;
    insert( res );    
end

rule setUserSessionCharacter agenda-group "commands" lock-on-active auto-focus  when
    $c : SetSessionCharacterCommand()    
    $sc : SessionCharacter( session == $c.session, character !=  $c.character )
then
    modify( $sc ) { character = $c.character }; 
    insert( new CharacterSelectedEvent( $c.character ) );   
    
    res = new Response( "You have selected the character " + $c.character + "\n" );
    res.localId = $c.requestId;
    insert( res );     
end

rule validMove agenda-group "commands" lock-on-active auto-focus  when
    mc : MoveCommand( c : character, r : room )    
    l  : Location( thing == c, ltarget : target )
    exists ?connect( r, ltarget; ) 
then
    exit = new ExitEvent( c, (Room) l.target )
    enter = new EnterEvent( c, r );
        
    modify( l ) { target = r };
            
    insert( exit );
    insert( enter );    
    
    res = new Response( "You have entered the " + l.target + "\n" );
    res.localId = mc.requestId;
    insert( res );    
end

rule validPickup agenda-group "commands" lock-on-active auto-focus  when
    pc : PickupCommand( c : character, t : thing)    
    
    cl  : Location( thing == c )
    tl : Location( thing == t, target == cl.target ) 
then
    insert( new Holding(  c, t ) );
    modify( tl ) { target =  c };
    insert( new PickupEvent( c, t ) );
    
    res = new Response( "You have picked up the " + t + "\n" );
    res.localId = pc.requestId;
    insert( res );  
end

rule validDrop agenda-group "commands" lock-on-active auto-focus  when
    dc : DropCommand( c : character, t : thing)    
    
    cl  : Location( thing == c )    
    tl  : Location( thing == t ) 
    h : Holding( c, t;)
then
    modify( tl ) { target = cl.target };
    retract ( h );
    insert( new DropEvent( c, t ) );    
    
    res = new Response( "You have droped the " + t + "\n" );
    res.localId = dc.requestId;
    insert( res );      
end

rule validGive agenda-group "commands" lock-on-active auto-focus  when
    gc : GiveCommand( $giver : giver, $thing : thing )    
    
    // They are in the same room
    giverl  : Location( thing == gc.giver )
              Location( thing == gc.receiver, target == giverl.target )

    // The giver must be holding the thing                   
    h : Holding( $giver, $thing;)
then
    modify( h ) { character = gc.receiver };
    insert( new GiveEvent( gc.giver, gc.thing, gc.receiver ) );    
    
    res = new Response( "You have given the " + gc.thing + " to " + gc.receiver + "\n" );
    res.localId = gc.requestId;
    insert( res );      
end    

rule invalidCommand  agenda-group "commands" lock-on-active auto-focus  when
    $cmd : Command()
    not Response( localId == $cmd.requestId )
then
    res = new Response( "Invalid Command: " + $cmd );
    res.localId = $cmd.requestId;
    insert( res ); 
end               

rule retractCommand agenda-group "commands" lock-on-active auto-focus salience -100 when
    c : Command()
then
    retract( c );
end
