package gui.simulator;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.io.Serializable;
import java.util.List;

import javax.swing.ImageIcon;


public class Visitor implements Serializable {
	Point2D positie;
	double rotation;
	double speed;
	Point2D target;
	WalkingPath currentpath;
	int currentpoint;
	
	Images.ImageType image = Images.ImageType.Visitor;
	
	public Visitor(Point2D positie) {
		this.positie = positie;
		this.rotation = 0;
		double number = Math.random()*2;
		if(number < 1){
			this.speed = 1;
		} else {
			this.speed = number;
		}
		this.target = new Point2D.Double(0, 0);
	}

	void update(List<Visitor> visitors, List<DrawEngine> buildings)
	{
		
		Point2D difference = new Point2D.Double(
				target.getX() - positie.getX(),
				target.getY() - positie.getY()
				);
		
		double newRotation = Math.atan2(difference.getY(), difference.getX());
		double rotDifference = rotation - newRotation;
		while(rotDifference > Math.PI)
			rotDifference -= 2 * Math.PI;
		while(rotDifference < -Math.PI)
			rotDifference += 2 * Math.PI;
		
		if(Math.abs(rotDifference) < 0.1)
			rotation = newRotation;
		else if(rotDifference < 0)
			rotation += 0.1;
		else if(rotDifference > 0)
			rotation -= 0.1;
		
		Point2D oldPositie = positie;
		
		positie = new Point2D.Double(
				positie.getX() + speed * Math.cos(rotation),
				positie.getY() + speed * Math.sin(rotation)
				);
		

		if(hasCollision(visitors) || hasCollisionObject(buildings))
		{
			positie = oldPositie;
			rotation += 0.2;
		}
		if(currentpath != null){
			if(hasCollision(currentpath.get(currentpoint))){
				if(currentpoint < currentpath.getPath().size()-1){
					currentpoint++;
					target = currentpath.get(currentpoint);
				}
			}
		}
		
	}
	
	void paint(Graphics2D g)
	{
		AffineTransform tx = new AffineTransform();
		tx.translate(positie.getX()-8, positie.getY()-11);
		tx.rotate(rotation, 4, 6);
		
		g.drawImage(Images.getImage(image), tx ,null);
		
	}

	public boolean hasCollision(List<Visitor> visitors) {
		for(Visitor b : visitors)
		{
			if(b == this)
				continue;
			if(b.positie.distance(positie) < 11)
				return true;
		}
		return false;
	}
	public boolean hasCollisionObject(List<DrawEngine> objects){
		for(DrawEngine o:objects){
			if (o.contains(positie))
				return true;
		}
		return false;
	}
	public boolean hasCollision(Point p){
		return positie.distance(p) < 11;
	}
	public void walkRoute(WalkingPath p){
		this.currentpath = p;
		currentpoint = 0;
		target = p.get(0);
	}
}

