package game;

import java.awt.Color;
import java.util.Random;

import java.util.ArrayList;
import java.util.List;

import base.Edge;
import game.map.Castle;
import game.map.GameMap;
import gui.components.JokerPanel.JokerTypes;


public abstract class AI extends Player {

    private AIThread aiThread;
    private Random random;
    protected boolean fastForward;

    public AI(String name, Color color) {
        super(name, color);
        this.random = new Random();
    }

    protected Random getRandom() {
        return this.random;
    }

    protected abstract void actions(Game game) throws InterruptedException;

    public void doNextTurn(Game game) {
        if(aiThread != null)
            return;

        fastForward = false;
        aiThread = new AIThread(game);
        aiThread.start();
    }

    public void fastForward() {
        if(aiThread != null)
            fastForward = true;
    }

    protected void sleep(int ms) throws InterruptedException {
        long end = System.currentTimeMillis() + ms;
        while(System.currentTimeMillis() < end && !fastForward) {
            Thread.sleep(10);
        }
    }
    
    protected void playTroopsJoker() {
    	if(getJokers()[0] == JokerTypes.ADD_TROOPS_USED)
    		return;
    	
    	this.addTroops(5);
    	this.setJoker(0, JokerTypes.ADD_TROOPS_USED);
    }
    
    
    protected void playScareJoker(Castle scared, Game game) {
    	if(getJokers()[1] == JokerTypes.SCARE_TROOPS_USED)
    		return;
    	
    	// Verscheuchen-Joker
    	if(scared == null)
    		return;

    	GameMap map = game.getMap();
    	List<Edge<Castle>> castleEdges = map.getEdges();
    	List<Castle> adjacentCastles = new ArrayList<>();
    	for(Edge<Castle> edge : castleEdges) {
    		if(edge.getNodeA().getValue().equals(scared)) {
    			if(edge.getNodeB().getValue().getOwner() != game.getCurrentPlayer() && !edge.getNodeB().getValue().equals(scared)) {
    				adjacentCastles.add(edge.getNodeB().getValue());
    			}
    		} else if(edge.getNodeB().getValue().equals(scared)) {
    			if(edge.getNodeA().getValue().getOwner() != game.getCurrentPlayer() && !edge.getNodeA().getValue().equals(scared)) {
    				adjacentCastles.add(edge.getNodeA().getValue());
    			}
    		}
    	}
    	
    	int troopsToDistribute = scared.getTroopCount() - 1;
    	System.out.println(troopsToDistribute);
    	scared.removeTroops(troopsToDistribute);
    	System.out.println(adjacentCastles.size());
    	for(Castle c : adjacentCastles) {
    		System.out.print(c.getName() + " ");
    	}
    	
    	
    	if(adjacentCastles.isEmpty()) {
        	return;
    	}
    	
    	Random random = new Random();
    	for(int i = 0; i < troopsToDistribute; i++) {
    		int castleNumber = random.nextInt(adjacentCastles.size());
    		System.out.print(castleNumber + " ");
    		adjacentCastles.get(castleNumber).addTroops(1);
    	}
    	
    	this.setJoker(1, JokerTypes.SCARE_TROOPS_USED);
    	return;
    }

    private class AIThread extends Thread {

        private Game game;

        private AIThread(Game game) {
            this.game = game;
        }

        private void finishTurn() {
            aiThread = null;
            fastForward = false;

            // Trigger next round, if not automatically
            if(game.getRound() > 1 && game.getCurrentPlayer() == AI.this)
                game.nextTurn();
        }

        @Override
        public void run() {
            try {
                actions(game);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            finishTurn();
        }
    }
}
