import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

import net.mw3.etewt3.handlers.MWPlayer;
import net.mw3.etewt3.handlers.MemoryHack;
import net.mw3.etewt3.handlers.PaintListener;
import net.mw3.etewt3.script.ScriptEngine;
import net.mw3.etewt3.utils.Constants;
import net.mw3.etewt3.utils.Filter;
import net.mw3.etewt3.utils.Vector;

import com.sun.jna.Memory;

/**
 * @author Mark
 * 
 */
public class ESP extends ScriptEngine implements PaintListener {
	@Override
	public int loop() {
		return 5;
	}

	@Override
	public boolean onStart() {
		return true;
	}

	@Override
	public void onRepaint(Graphics g) {
		MWPlayer[] players = getAll(new Filter<MWPlayer>() {

			@Override
			public boolean accept(MWPlayer player) {
				if (!allForOne()
						&& player.getTeam() != getLocalPlayer().getTeam()
						&& player.isValid() || allForOne() && player.isValid()
						&& player.index != localIndex()) {
					return true;
				}
				return false;
			}

		});
		for (MWPlayer player : players) {
			int[] tester = worldToScreen(player);
			Font big = new Font("SansSerif", Font.BOLD, 12);
			g.setFont(big);
			int dist = (int)player.getDistance();
			if(dist > 20)
				g.setColor(Color.RED);
			else
				g.setColor(Color.GREEN);
			g.drawString(player.getPlayername()+" "+(int)player.getDistance(), tester[0], tester[1]);
		}
	}

	public int[] worldToScreen(MWPlayer target) {
		int[] screen = new int[]{9000,0};
		Memory sizeBuffer = MemoryHack.readMemory(Constants.REFDEF + 0x8, 8);
		int screenWidth = sizeBuffer.getInt(0), screenHeight = sizeBuffer
				.getInt(4);
		Memory fovBuffer = MemoryHack.readMemory(Constants.REFDEF + 0x10, 8);
		float fovX = fovBuffer.getFloat(0), fovY = fovBuffer.getFloat(4);

		Memory viewAxisBuffer = MemoryHack.readMemory(Constants.REFDEF + 0x24,
				36);
		float[][] viewAxis = new float[3][3];
		int index = 0;
		for (int i = 0; i < 3; i++) {
			viewAxis[i][0] = viewAxisBuffer.getFloat(index++ * 4);
			viewAxis[i][1] = viewAxisBuffer.getFloat(index++ * 4);
			viewAxis[i][2] = viewAxisBuffer.getFloat(index++ * 4);
		}

		float[] vector = Vector.vectorSubtract(target.getRawLocation(), getLocalPlayer()
				.getRawLocation());
		float[] transform = new float[3];
		transform[0] = Vector.dotProduct(vector, viewAxis[1]);
		transform[1] = Vector.dotProduct(vector, viewAxis[2]);
		transform[2] = Vector.dotProduct(vector, viewAxis[0]);
		if (transform[2] < 0.1)
			return screen;
		screen[0] = (int) ((screenWidth / 2) * (1 - (transform[0] / fovX / transform[2])));
		screen[1] = (int) ((screenHeight / 2) * (1 - (transform[1] / fovY / transform[2])));
		return screen;
	}

}
