import java.net.*;
import java.util.*;
import java.io.*;
import java.lang.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;



public class Followers extends BaseGame {
	
	public static final short OBSTACLE_SIZE = 10; //to be multiplied by type
	public static final double SPAWN_RATE = .2; //for creating obstacles
	public static final double OBSTACLE_SPEED = 1;
	public static final byte HIT_DAMAGE = 100; //to be multiplied by type
    public static final short DAMAGE_K = 500;
	
    public static final short PLAYER_MOVE_DISTANCE = 20;
	
	public Followers(String nicName, int multicastPort, String multicastAddress){
		super(nicName, multicastPort, multicastAddress);
	}
	
	public void updateGame(){
		
		
		System.out.println("In the main loop!");
		/*move player based on keystrokes*/
		//moveObstacles();
		//processCollisions();
		//createObstacle();
		
		Graphics2D g = (Graphics2D)bufferStrategy.getDrawGraphics();

		g.setColor(Color.BLACK);
		g.fillRect(0, 0, bounds.width, bounds.height);

		GameElement player = getMyGameElements().get(-128);
		HashMap<InetAddress, GameElement> others = getOtherPlayers();
			
		if (others == null){
			player.setIsIt(true);
		}
		
		for(InetAddress i: others.keySet()){
			if((player.getDistance(others.get(i)) == 0) && (others.get(i).getIsIt())){
				player.setIsIt(true);
			}
		}
	
		
		if(player.getIsIt())
			g.setColor(Color.RED);
		else
			g.setColor(Color.WHITE);	
		player.drawSelf(g);
		//still has to draw other players

		g.dispose();

                // this whole time you have been editing the hidden "back buffer"                              
		// show() replaces the front (visible) buffer with the "back buffer"                           
		bufferStrategy.show();
		Toolkit.getDefaultToolkit().sync();

	//	killSelf();
	}

/*
	public short calcDamage(InetAddress i, Integer j){
	    //doesn't allow for multiple swarms, but let's try it
		short ans = 0;
		GameElement player = getMyGameElements().get(-128);
		
			HashMap<InetAddress, GameElement> others = getOtherPlayers();
			System.out.println(others);
			System.out.println(player);
			System.out.println(player.getHealth());
			
			for(InetAddress l: others.keySet()){
		    	ans += player.getDistance(others.get(i)) - DAMAGE_K;
        	}
        	if(ans < 0)  //if it's in a close enough swarm, increase health but at a slower rate
            	ans /= DAMAGE_K;
			System.out.println("Damage: " + ans);
			System.out.println("Health: " + player.getHealth());
        	player.applyDamage(ans);
			System.out.println("Health2: " + player.getHealth());
		
		return ans;
	}

	
	public void moveObstacles(){
		for(Integer i : getMyGameElements().keySet()){
			GameElement e = getMyGameElements().get(i);
			if(e.getType()>1){
				if((((int)(e.getX()) + (int)(e.getXspeed())) > (int) MAX_X) || ((int)(e.getY()) + (int)(e.getYspeed())) > (int) MAX_Y){
				    e.setHealth((byte)-128);
				}
				else{        
				    e.setX((short)((int)(e.getX()) + (int)(e.getXspeed())));
				    e.setY((short)((int)(e.getY()) + (int)(e.getYspeed())));
				}
				
			}
		}
	}
	
	public GameElement createObstacle(){
		Random gen = new Random();
		if(gen.nextDouble() < SPAWN_RATE*super.world.keySet().size()){
			GameElement obs = new GameElement();
			obs.setType((byte) (gen.nextInt(2) + 2));
			double num = gen.nextDouble();
			if(num < .25){
				obs.setX((short)0);
				obs.setY((short)(gen.nextDouble() * MAX_Y));
				obs.setXspeed((short)(gen.nextInt(10) * OBSTACLE_SPEED));
				obs.setYspeed((short)((gen.nextInt(20)-10) * OBSTACLE_SPEED));
			}
			else if(num < .5){
				obs.setX(MAX_X);
				obs.setY((short)(gen.nextDouble() * MAX_Y));
				obs.setXspeed((short)(gen.nextInt(10) * OBSTACLE_SPEED * -1));
				obs.setYspeed((short)((gen.nextInt(20)-10) * OBSTACLE_SPEED));
			}
			else if(num < .75){
				obs.setX((short)(gen.nextDouble() * MAX_X));
				obs.setY((short)0);
				obs.setXspeed((short)((gen.nextInt(20)-10) * OBSTACLE_SPEED));
				obs.setYspeed((short)(gen.nextInt(10) * OBSTACLE_SPEED));
			}
			else{
				obs.setX((short)(gen.nextDouble() * MAX_X));
				obs.setY(MAX_Y);
				obs.setXspeed((short)((gen.nextInt(20)-10) * OBSTACLE_SPEED));
				obs.setYspeed((short)(gen.nextInt(10) * OBSTACLE_SPEED * -1));
			}
			
			//taken from createGameElement()
			int i = 0;
		    for(; i < 256; i++){
			    if(localIDs[i] == false){
				    break;
			    }
		    }
		    localIDs[i] = true;
		    world.get(comm.getInetAddress()).put(i-128, obs);
			return obs;
		}
		return null;
	}
	
	public void processCollisions(){
	    GameElement player = getMyGameElements().get(-128);
	    HashMap<InetAddress, HashMap<Integer, GameElement>> obstacles = getAllObstacles();
	    for(InetAddress i: obstacles.keySet()){
			for(Integer j: obstacles.get(i).keySet()){
			    if(player.getDistance(obstacles.get(i).get(j)) < (double) OBSTACLE_SIZE * obstacles.get(i).get(j).getType())
			        player.applyDamage((short) (HIT_DAMAGE * obstacles.get(i).get(j).getType()));
	        }
	    }
	    //maybe make obstacles break apart when they collide with other obstacles?
	}
	*/		       
	
}
