package colro;

import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.media.opengl.GL;

import com.sun.opengl.util.texture.Texture;

import devUtil.TextureLoader;
import devUtil.Vector3;

import object.ImageHeightMap;
import object.Model;
import world.Camera;

public class Landscape extends ImageHeightMap {
	
	private double xPos;
	private double yPos;
	private double zPos;
	
	private boolean [][] color;
	
	private Texture grass;
	private ArrayList<Flower> flowers;
	private ArrayList<Vector3> locations;
	
	public Landscape(BufferedImage heightMap) {
		
		super(heightMap);
		
		color = new boolean[heightMap.getWidth()][heightMap.getHeight()];
		
		for(int x = 0; x < color.length; x++)
			for(int z = 0; z < color.length; z++)
				
				color[x][z] = false;
		
		grass = TextureLoader.getTexture("/visual/Textures/Grass.jpg");
		flowers = new ArrayList<Flower>();
		
		locations = new ArrayList<Vector3>();
		
		for(int i = 0; i < 50; i++)
			locations.add(new Vector3(Math.random() * color.length, 0, Math.random() * color[0].length));
	}
	
	public void setPosition(double xPos, double yPos, double zPos) {
		this.xPos = xPos;
		this.yPos = yPos;
		this.zPos = zPos;
	}
	
	public void colorIn(Camera camera, double xSize, double zSize, int xSquares, double zSquares) {
		
		double xPosition = camera.getXPosition() + xSize / 2;
		double zPosition = camera.getZPosition() + zSize / 2;
		
		double squareSizeX = xSize / xSquares;
		double squareSizeZ = zSize / zSquares;
		
		int xPos = (int) ((double) (xPosition) / squareSizeX);
		int zPos = (int) ((double) (zPosition) / squareSizeZ);
		
		for(int x = 0; x < color.length; x++)
			for(int z = 0; z < color[x].length; z++)
				
				if(new Vector3(xPos - x, 0, zPos - z).getMagnitude() < 10) {
					
					if(!color[x][z]) {
						
						if(camera.getYPosition() < 1500) {
							
							for(int i = 0; i < locations.size(); i++)
								
								if((int) locations.get(i).getX() == x && (int) locations.get(i).getZ() == z) {
									
									Flower flower = new Flower(new Vector3(
											camera.getXPosition(),
											camera.getYPosition(),
											camera.getZPosition()));
									
									flowers.add(flower);
									
									break;
								}
						}
					}
					
					color[x][z] = true;
				}
		
		for(int i = 0; i < flowers.size(); i++)
			flowers.get(i).update();
	}
	
	public void render(GL gl, double width, double length, double height) {
		
		width /= map.length;
		length /= map[0].length;
		height /= highestPoint - lowestPoint;
		
		for(int x = 0; x < map.length - 2; x++)
			for(int z = 0; z < map.length - 2; z++) {
				
				if(color[x][z]) {
					grass.enable();
					grass.bind();
				}
				
				gl.glBegin(GL.GL_QUADS);
				
				setColor(gl, x, z);
				
				gl.glTexCoord2d(0, 0);
				
				gl.glVertex3d(
						(x * width) - ((width * map.length) / 2) + xPos,
						map[x][z] * height + yPos,
						(z * length) - ((length * map[0].length) / 2) + zPos
						);
				
				gl.glTexCoord2d(1, 0);
				
				gl.glVertex3d(
						(x * width) - ((width * map.length) / 2) + xPos,
						map[x][z + 1] * height + yPos,
						((z + 1) * length) - ((length * map[0].length) / 2) + zPos
						);
				
				gl.glTexCoord2d(1, 1);
				
				gl.glVertex3d(
						((x + 1) * width) - ((width * map.length) / 2) + xPos,
						map[x + 1][z + 1] * height + yPos,
						((z + 1) * length) - ((length * map[0].length) / 2) + zPos
						);
				
				gl.glTexCoord2d(0, 1);
				
				gl.glVertex3d(
						((x + 1) * width) - ((width * map.length) / 2) + xPos,
						map[x + 1][z] * height + yPos,
						(z * length) - ((length * map[0].length) / 2) + zPos
						);
				
				gl.glEnd();
				
				if(color[x][z])
					grass.disable();
			}
		
		for(int i = 0; i < flowers.size(); i++)
			flowers.get(i).render(gl);
	}
	
	public void setColor(GL gl, int x, int z) {
		
		double height = (map[x][z] + map[x + 1][z] + map[x][z + 1] + map[x + 1][z + 1]) / 4;
		
		if(!color[x][z])
			
			gl.glColor3f(
					(float) ((height - lowestPoint) * (1 / (highestPoint - lowestPoint))),
					(float) ((height - lowestPoint) * (1 / (highestPoint - lowestPoint))),
					(float) ((height - lowestPoint) * (1 / (highestPoint - lowestPoint)))
					);
		
		else
			
			gl.glColor3f(
					0,
					(float) ((height - lowestPoint) * (1 / (highestPoint - lowestPoint))),
					1 - (float) ((height - lowestPoint) * (1 / (highestPoint - lowestPoint)))
					);
	}
}

class Flower {
	
	Model flower;
	
	Vector3 position;
	Vector3 color;
	
	float size;
	
	public Flower(Vector3 position) {
		
		flower = new Model();
		
		flower.setMode(true, false);
		flower.parseObjectFile(ClassLoader.getSystemResourceAsStream(
						"visual/models/Flowers.obj"));
		
		this.position = position;
		
		flower.setPosition(
				(float) position.getX(),
				(float) (position.getY() - 25),
				(float) position.getZ());
		
		flower.setSize(100, 0, 100);
		
		flower.setColor((float) Math.random(), (float) Math.random(), (float) Math.random());
	}
	
	public void update() {
		
		if(size < 50)
			size += .1;
		
		flower.setSize(100, size, 100);
		
		flower.setPosition(
				(float) position.getX(),
				(float) (position.getY() - (75 - size)),
				(float) position.getZ());
	}
	
	public void render(GL gl) {
		flower.render(gl);
	}
}