package org.drools.games.wumpus.server;

import org.drools.games.wumpus.Init;
import org.drools.games.wumpus.Score;
import org.drools.games.wumpus.Cell;
import org.drools.games.wumpus.Pit;
import org.drools.games.wumpus.Wumpus;
import org.drools.games.wumpus.Gold;
import org.drools.games.wumpus.Hero;

import org.drools.games.wumpus.Reset;
import org.drools.games.wumpus.PitDeath;
import org.drools.games.wumpus.GoldWin;
import org.drools.games.wumpus.WumpusDeath;

import org.drools.games.wumpus.Play;
import org.drools.games.wumpus.SensorArray;

import org.drools.games.wumpus.view.GameView
import org.drools.games.wumpus.view.GameUI

import java.util.ArrayList
import org.kie.internal.logger.KnowledgeRuntimeLogger
import org.kie.internal.logger.KnowledgeRuntimeLoggerFactory
import org.kie.internal.runtime.StatefulKnowledgeSession

global org.drools.games.wumpus.WumpusWorldConfiguration wumpusWorldConfiguration;

global java.util.Random randomInteger;

dialect "mvel"

rule "Start Game Init Process" agenda-group "Init"  when
then
   insert( new Init() );
end

rule "Insert Score" agenda-group "Init" when
    Init()
    not Score()
then
    insert( new Score() );
end

rule "Create GUI"  agenda-group "Init" when
    not GameUI()
then
    insert( new GameUI(wumpusWorldConfiguration) );
end

rule "Init Game View"   agenda-group "Init" when
    Play()
    $ui : GameUI()
    not GameView()
then
    GameView $gv = new GameView();
    $gv.init(50, 50, 3, 20, 5, 5);
    $gv.setKsession( (StatefulKnowledgeSession) kcontext.knowledgeRuntime );
    $gv.setKbase( ((StatefulKnowledgeSession) kcontext.knowledgeRuntime).getKieBase() );

//    new java.io.File("log").mkdir();
//    KnowledgeRuntimeLogger klogger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger((StatefulKnowledgeSession) kcontext.knowledgeRuntime, "log/wumpus", 500);
//    $gv.setKlogger( klogger );

    $ui.gameView = $gv;
    insert( $gv );
end

	
rule "Create Cells" agenda-group "Init" when
    Init()
	$i : Integer() from [0, 1, 2, 3, 4]
	$j : Integer() from [0, 1, 2, 3, 4]
	$c : Cell() from new Cell($i, $j)
then
    insert( $c );
end

rule "Show First Cell" agenda-group "Init" when
    Init()
    $c : Cell( row == 0, col == 0, hidden == true )
then
    modify( $c ) { hidden = false };
end    

rule "Create Pitt"  agenda-group "Init" when
    Init()
    $c : Cell( row != 0, col != 0 )
    Number( this > 0 && <= 20 ) from randomInteger.nextInt( 100 )
then
    Pit pit = new Pit( $c.row, $c.col );
    insert( pit );
end    

rule "Create Wumpus"  agenda-group "Init" when
    Init()
    not Wumpus()// here to break sharing, to force new random numbers, also retriggers on retraction
    $row : Integer() from randomInteger.nextInt( 4 )
    $col : Integer() from randomInteger.nextInt( 4 )
then
    Wumpus wumpus = new Wumpus($row, $col);
    insert( wumpus );    
end

rule "Invalid Wumpus" agenda-group "Init" when
    Init()
    $w : Wumpus( row == 0, col == 0 )    
then
    retract( $w ); // retraction triggers the "not" CE
end    

rule "Create Gold" agenda-group "Init" when
    Init()
    not Gold() // here to break sharing, to force new random numbers, also retriggers on retraction
    $row : Integer() from randomInteger.nextInt( 4 )
    $col : Integer() from randomInteger.nextInt( 4 )
then
    Gold gold = new Gold($row, $col);
    insert( gold );
end

rule "Invalid Gold" agenda-group "Init" when
    Init()
    $g : Gold( row == 0, col == 0 )  
    not Hero( gold == true ) // gold can be in row first square, if hero is carrying it
then
    retract( $g ); // retraction triggers the "not" CE
end   

rule "Create Hero" agenda-group "Init"  when
    Init()
    exists Wumpus( row != 0 || col != 0 ) // create the Hero after the Wumpus has been created in a safe location
    exists Gold( row != 0 || col != 0 ) // create the Hero after the Gold has been placed in a good location
then
    insert( new Hero( 0, 0 ) );
end

rule "Trigger Play" agenda-group "Init" when
    $i : Init()
then
    retract( $i );
    insert( new Play() );
    insert( new SensorArray() );    
end