package org.crusty.wurrums.levels;

import org.crusty.wurrums.entities.Gun;
import org.crusty.wurrums.entities.Worm;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;

import org.crusty.engine.CrustyEngine;
import org.crusty.engine.Screen;
import org.crusty.engine.entity.Entity;
import org.crusty.engine.sprite.Sprite;
import org.crusty.engine.sprite.SpriteManager;
import org.crusty.perlin.PerlinNoise;

public class EditLevel extends Screen {
	
	BufferedImage perlinNoise;
	Color colour = new Color(255, 255, 155, 255);
	
	public EditLevel(CrustyEngine engine) {
		super(engine);
		
		Random r = new Random();
		
		// Starting Perlin positions
		int startX = r.nextInt(100000000);
		int startY = r.nextInt(100000000);
		
		// Generate Perlin Noise
		int width = this.getEngine().getWidth(), height = this.getEngine().getHeight();
		double[] perlinNoiseArray = new double[width*height];
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				perlinNoiseArray[y*width + x] = PerlinNoise.perlinNoise2D(x + startX, y + startY, 0.015, 0.65, 1, 1); // 0.2 freq
			}
		}
		
		perlinNoise = PerlinNoise.doubleArrayToWormsImage(perlinNoiseArray, width, height, colour);
//		Graphics2D g = (Graphics2D) perlinNoise.getGraphics();
//		g.setColor(colour);
//		g.drawRect(0, 0, width - 1, height - 1);
		
		// Add texture to perlinNoise
		Sprite texture = SpriteManager.getSprite("img/backgrounds/back3.png");
		
		AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1);
		Graphics2D g = (Graphics2D) perlinNoise.getGraphics();
		Composite old = g.getComposite();
		g.setComposite(ac);
		// Tile texture
		for (int y = 0; y <= perlinNoise.getHeight(); y += texture.getHeight()) {
			for (int x = 0; x <= perlinNoise.getWidth(); x += texture.getWidth()) {
				g.drawImage(texture.images[0], x, y, null);
			}
		}
		g.setComposite(old);
		
		SpriteManager.addSprite(perlinNoise, "perlinNoise1");
//		BouncyFader bouncyPerlinNoise = new BouncyFader(SpriteManager.getSprite("perlinNoise1"));
		Entity perlinNoiseEntity = new Entity(new Sprite[] { SpriteManager.getSprite("perlinNoise1") }, 0, 0);
		perlinNoiseEntity.pos.x = 0;
		perlinNoiseEntity.pos.y = 0;
		
		double wormx, wormy;
		
		// Determine if black
		int red, green, blue;
		boolean landBelow;
		do {
			wormx = 100 + r.nextInt(perlinNoise.getWidth() - 200);
			wormy = 100 + r.nextInt(perlinNoise.getHeight() - 300);
			int c = perlinNoise.getRGB((int) wormx, (int) wormy);
			red   = (c & 0x00ff0000) >> 16;
			green = (c & 0x0000ff00) >> 8;
			blue  =  c & 0x000000ff;
			landBelow = false;
			for (int i = (int) wormy; i < perlinNoise.getHeight(); i++) {
				int c2 = perlinNoise.getRGB((int) wormx, (int) i);
				int red2   = (c2 & 0x00ff0000) >> 16;
				int green2 = (c2 & 0x0000ff00) >> 8;
				int blue2  =  c2 & 0x000000ff;
				if (!(red2 == 0 && green2 == 0 && blue2 == 0)) {
					landBelow = true;
					System.out.println("Land at: " + wormx + ", " + i);
					break;
				}
			}
		} while (!(red == 0 && green == 0 && blue == 0) && !landBelow);
		
		// Make hole for worm
		
		Composite oldComp = g.getComposite();
		g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, 1));
		g.setColor(Color.BLACK);
		int rad = 30;
		g.fillOval((int) wormx - rad, (int) wormy - rad, rad*2, rad*2);
		g.setComposite(oldComp);
		
//		g.setColor(Color.BLACK);
//		int rad = 30;
//		g.fillOval((int) wormx - rad, (int) wormy - rad, rad*2, rad*2);
		
		Worm worm = new Worm(null, wormx, wormy, 
				new Sprite[] { 	SpriteManager.getSprite("WormWalkingLeft"),
								SpriteManager.getSprite("WormWalkingRight"),
								SpriteManager.getSprite("WormDeadLeft"),
								SpriteManager.getSprite("WormDeadRight"),
								SpriteManager.getSprite("WormFlyingLeft"),
								SpriteManager.getSprite("WormFlyingRight")
							},
								10, 18);
		
		Gun assaultRifle = new Gun(new Sprite[] { SpriteManager.getSprite("img/guns/assaultrifle.bmp") }, 13, 4, null);
		assaultRifle.setWorm(worm);
		worm.setGun(assaultRifle);
		
		addEntity(worm);
		addEntity(perlinNoiseEntity);
		addEntity(assaultRifle);
	}

	@Override
	public void draw(Graphics2D g) {
		// Clear
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, CrustyEngine.width, CrustyEngine.height);
		
		super.draw(g);
		
//		g.setColor(Color.WHITE);
//		g.drawString("Level 1", 100, 100);
	}

	@Override
	public void logic(long dt) {
		super.logic(dt);
		
		if (CrustyEngine.keys[KeyEvent.VK_P]) {
			// Save image
			File file = new File("level.png");
			try {
				ImageIO.write(perlinNoise, "png", file);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
		
	}
	
	public void mouseMoved(MouseEvent e) {
		super.mouseMoved(e);
		if (CrustyEngine.keys[KeyEvent.VK_K]) { // e.getButton() == MouseEvent.BUTTON3
			Graphics2D g = (Graphics2D) perlinNoise.getGraphics();
			g.setColor(colour);
			int rad = 20;
			g.fillOval(e.getX() - rad, e.getY() - rad, rad*2, rad*2);
			
			// Add texture to perlinNoise
			Sprite texture = SpriteManager.getSprite("img/backgrounds/back3.png");
			
			AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1);
//			Graphics2D g = (Graphics2D) perlinNoise.getGraphics();
			Composite old = g.getComposite();
			g.setComposite(ac);
			// Tile texture
			for (int y = 0; y <= perlinNoise.getHeight(); y += texture.getHeight()) {
				for (int x = 0; x <= perlinNoise.getWidth(); x += texture.getWidth()) {
					g.drawImage(texture.images[0], x, y, null);
				}
			}
			g.setComposite(old);
			
		} else if (CrustyEngine.keys[KeyEvent.VK_L]) { // e.getButton() == MouseEvent.BUTTON1
			Graphics2D g = (Graphics2D) perlinNoise.getGraphics();
			Composite old = g.getComposite();
			
			// Make hole
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, 1));
			g.setColor(Color.BLACK);
			int rad = 20;
			g.fillOval((int) e.getX() - rad, (int) e.getY() - rad, rad*2, rad*2);
			
			g.setComposite(old);
			
//			Graphics2D g = (Graphics2D) perlinNoise.getGraphics();
//			g.setColor(colour);
//			if (CrustyEngine.keys[KeyEvent.VK_L]) {
//				g.drawLine(e.getX() - 20, e.getY(), e.getX() + 20, e.getY());
//			} else {
//				int rad = 50;
//				g.fillOval(e.getX() - rad, e.getY() - rad, rad*2, rad*2);
//			}
		}
	}
	
	public void mousePressed(MouseEvent e) {
		super.mousePressed(e);

	}

}
