package hangman;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;

import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

/**
 * This is a sample file to launch a process.
 */
public class Hangman {

	public static final void main(String[] args) {
//		try {
//			// load up the knowledge base
//			KnowledgeBase kbase = readKnowledgeBase();
//			StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
//			KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "Hangman");
//			
//			//Insert classes into a session to allow the management of those
//			RandomWord rW = new RandomWord();
//			ksession.insert( rW );
//			ksession.insert( new GuessedWord() );
//	        ksession.insert( new GameRules(4) );
//			
//			// start a new process instance
//			ksession.startProcess("Hangman");
//			logger.close();
//		} catch (Throwable t) {
//			t.printStackTrace();
//		}
		
		//Add Rules and Flow to Knowledge Builder 
        final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add( ResourceFactory.newClassPathResource( "hangman.drl",
        		Hangman.class ),//Ponía ShppongExample.class
                              ResourceType.DRL );
        kbuilder.add( ResourceFactory.newClassPathResource( "hangman.rf",
        		Hangman.class ),
                              ResourceType.DRF );

        //Create Knowledge Base and add Knowledge from KBuilder
        final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
        
        // Create a stateful session
        final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
        
        //Generate a log file of the session
        KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "log/hang");

        //Insert classes into a session to allow the management of those
        RandomWord rW = new RandomWord();
		ksession.insert( rW );
		ksession.insert( new GuessedWord(rW) );
		ksession.insert( new Solution() );
        ksession.insert( new GameRules(4) );
        
        //Start the the process
        ksession.startProcess( "Hangman" );
        
        //Fire all rules
        ksession.fireAllRules();
        
        //Close the logger
        logger.close();

        ksession.dispose();
		
		
	}

	private static KnowledgeBase readKnowledgeBase() throws Exception {
		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		kbuilder.add(ResourceFactory.newClassPathResource("hangman.rf"), ResourceType.DRF);
		KnowledgeBuilderErrors errors = kbuilder.getErrors();
		if (errors.size() > 0) {
			for (KnowledgeBuilderError error: errors) {
				System.err.println(error);
			}
			throw new IllegalArgumentException("Could not parse knowledge.");
		}
		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
		return kbase;
	}
	
	public static class RandomWord {
        private String randomWord;

        public RandomWord() {
            int index = new Random().nextInt( 9 );
            Map<Integer,String> m = new HashMap<Integer, String>();
            m.put(0,"MULTIMEDIA");
            m.put(1,"INFORMATION");
            m.put(2,"RETRIEVAL");
            m.put(3,"DROOLS");
            m.put(4,"MORTGAGE");
            m.put(5,"INSURANCE");
            m.put(6,"TUPPERWARE");
            m.put(7,"HANGMAN");
            m.put(8,"MOVIES");
            m.put(9,"CAR");
            this.randomWord = m.get(index);
        }

        public String getrandomWord() {
            return this.randomWord;
        }
        
    }
	
	public static class GuessedWord {
        private RandomWord randomWord;
        private String guessedWord = "";
        private String letters = "";

        public GuessedWord(RandomWord rW){
        	randomWord = rW;
        	this.guessedWord = "";
        	int count = this.randomWord.getrandomWord().length();
        	while(count != 0){
        		this.guessedWord = this.guessedWord + "_ ";
        		count = count -1;
        	}
        }
        
        public boolean solution(String solution){
        	solution = solution.toUpperCase();
        	if(solution.compareTo(randomWord.getrandomWord()) == 0){
        		return true;
        	}
        	else{
        		return false;
        	}
        }
        
        public void sayOneLetter(String c){
        	c = c.toUpperCase();
        	StringBuffer buffer = new StringBuffer(this.randomWord.getrandomWord());
        	StringBuffer buffer2 = new StringBuffer(this.guessedWord);
        	this.letters = this.letters + c + " ";
        	int index = 0;
        	while((index = buffer.indexOf(c, index)) != -1){
        		buffer2 = buffer2.replace(index*2, index*2+2, c+" ");
        		index = index + 1;
        	}
        	this.guessedWord = buffer2.toString();
        }

        public String getGuessedWord() {
            return this.guessedWord;
        }
        
        public String getLetters() {
            return this.letters;
        }
        
        public String getrandomWord() {
            return this.randomWord.getrandomWord();
        }
    }
	
	public static class GameRules {
        private int allowedGuesses;
//        private int allowedSolves;
        private int value;
        private boolean exit = false;
        public String decision;

        public GameRules(int allowedGuesses) {
            this.allowedGuesses = allowedGuesses;
//            this.allowedSolves = 2;
            this.value = 2;
        }
        
        public int getAllowedGuesses() {
            return this.allowedGuesses;
        }
        
        public void setAllowedGuesses(int in) {
            this.allowedGuesses = in;
        }
        
        public int getAllowedSolves() {
//            return this.allowedSolves;
        	return this.value;
        }
        
        public void setAllowedSolves(int in) {
//            this.allowedSolves = in;
        	this.value = in;
        }
        
        public String getDecision() {
            return this.decision;
        }
        
        public void setDecision(String in) {
            this.decision = in;
        }

		public void setExit(boolean exit) {
			this.exit = exit;
		}

		public boolean isExit() {
			return exit;
		}
	}
	
	public static class Solution {
        private String solution;
        
        public Solution() {
            this.solution = "";
        }
        
        public String getSolution() {
            return this.solution;
        }
        
        public void setSolution(String in) {
            this.solution = in;
        }
	}
}