package ludumdare.game;

import java.util.HashMap;
import java.util.PriorityQueue;
import java.util.Random;

import org.crusty.math.Vec2double;
import org.crusty.math.Vec2int;

public class ScreenManager {

	static HashMap<Vec2int, Screen> screens = new HashMap<Vec2int, Screen>();
	static Screen rootScreen;
	static Screen currentScreen = null;
	static Vec2int currentSpaceScreen = new Vec2int(0, 0);
	static Random r = new Random();
	static int border = 50;
	
	public ScreenManager() {
		
		PriorityQueue<Entity> entities = new PriorityQueue<Entity>(10, new DepthComparator());
		rootScreen = new Screen(entities, null);
	}
	
	public static void setRoot(PriorityQueue<Entity> ents, String[] messages) {
		PriorityQueue<Entity> entities = new PriorityQueue<Entity>(10, new DepthComparator()); //getRoot().entitiesInScreen;
		entities.addAll(ents);
		rootScreen = new Screen(entities, messages);
	}
	
	public static Screen getFirstScreen(Vec2int v, Vec2double playerLoc) { // , Vec2double playerLoc
		Screen s = screens.get(v);
		if (s == null) {
			System.out.println("Generating new Screen!");
//			s = generateScreen(v);
			PriorityQueue<Entity> pq = new PriorityQueue<Entity>(10, new DepthComparator());
			pq.add(Game.player);
			pq.add(new SpaceStation(SpriteManager.getSprite("stationalpha.png")));
			String[] messages = { "(" + v.x + ", " + v.y + ") SpaceSystem: " + r.nextInt(1000) };
			s = new Screen(pq, messages);
			s.setupBackgroundStars();
			screens.put(v, s);
		}
		Game.player.pos.x = playerLoc.x;
		Game.player.pos.y = playerLoc.y;
		return s;
	}
	
	public static Screen getScreen(Vec2int v, Vec2double playerLoc) { // , Vec2double playerLoc
		Screen s = screens.get(v);
		if (s == null) {
			System.out.println("Generating new Screen!");
			s = generateScreen(v);
		}
		Game.player.pos.x = playerLoc.x;
		Game.player.pos.y = playerLoc.y;
		return s;
	}
	
	private static Screen generateScreen(Vec2int v) {
		PriorityQueue<Entity> pq = new PriorityQueue<Entity>(10, new DepthComparator());
		pq.add(Game.player);
		
		// Planets
		int numOfPlanets = r.nextInt(3);
		for (int i = 0; i < numOfPlanets; i++) {
			String s = "";
			if (r.nextInt(4) == 0) {
				s = "planet1.png";
			} else {
				s = "planet2.png";
			}
			Planet spaceBody = new Planet(SpriteManager.getSprite(s), 
					new Vec2double(border + r.nextInt(500 - border*2 - SpriteManager.getSprite(s).image.getWidth()), 
									border + r.nextInt(500 - border*2 - SpriteManager.getSprite(s).image.getHeight())),
									r.nextInt(50) + 20);
			spaceBody.generateRandomData();
			pq.add(spaceBody);
		}
		
		int rad = r.nextInt(50) + 20;
		if (r.nextBoolean()) {
			rad += r.nextInt(50);
		}
		// Stars
		if (r.nextBoolean()) {
			String s = "";
			if (r.nextInt(4) == 0) {
				s = "bluestar.png";
			} else {
				s = "bigstar.png";
			}
			Star star = new Star(SpriteManager.getSprite(s),
					new Vec2double(border + r.nextInt(500 - border*2 - SpriteManager.getSprite(s).image.getWidth()), 
									border + r.nextInt(500 - border*2 - SpriteManager.getSprite(s).image.getHeight())),
									rad);
			star.generateRandomData();
			pq.add(star);
		}
		
		// Black Hole
		if (r.nextInt(5) == 0) {
			BlackHole bh = new BlackHole(SpriteManager.getSprite("blackhole.png"),
					new Vec2double(border + r.nextInt(500 - border*2 - SpriteManager.getSprite("blackhole.png").image.getWidth()), 
									border + r.nextInt(500 - border*2 - SpriteManager.getSprite("blackhole.png").image.getHeight())),
									r.nextInt(50) + 20);
			bh.generateRandomData();
			pq.add(bh);
		}
		
		// Quick Hack to make sure no planets touch
		Object[] arr = pq.toArray();
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr.length; j++) {
				if (i == j)
					continue;
				if (arr[i] instanceof Player)
					continue;
				if (arr[j] instanceof Player)
					continue;
				if (((SpaceBody) arr[i]).pos.sub(((SpaceBody) arr[j]).pos).length() <
						(((SpaceBody) arr[i]).diameter/2) + (((SpaceBody) arr[j]).diameter/2)) {
					// Delete one
					pq.remove(arr[i]);
					System.out.println("Deleted too close Space Body.");
				}
			}
		}
		
		String[] messages = { "(" + v.x + ", " + v.y + ") SpaceSystem: " + r.nextInt(1000) };
		Screen screen = new Screen(pq, messages);
		screen.setupBackgroundStars();
		screens.put(v, screen);
		return screen;
	}
	
	public static Screen getRoot() {
		return rootScreen;
	}
	
//	public static void spaceNotify() {
//		if (currentScreen.pos < currentScreen.messages.length - 1) {
//			currentScreen.pos++;
//		} else {
//			currentScreen.pos = 0;
//		}
//		MessageManager.changeAndIncMessage(currentScreen.messages[currentScreen.pos]);
//	}
	
	public static void notifyIncrement() {
		if (currentScreen.pos < currentScreen.messages.length - 1) {
			currentScreen.pos++;
		} else {
			System.out.println("Screen switch");
			currentScreen = currentScreen.nextScreen;
//			Game.updateScreen();
			Game.notifyUpdate();
			// Switch screen
		}
		MessageManager.changeAndIncMessage(currentScreen.messages[currentScreen.pos]);
		//else
		// NEXT SCREEN
		//MessageManager.curMessage = messages[pos];
	}
	
	public static void goToScreen(Vec2int s) {
		System.out.println("Screen switch: " + s.toString());
		currentScreen = getScreen(s, new Vec2double(240, 237));
		currentSpaceScreen.x = s.x;
		currentSpaceScreen.y = s.y;
		MessageManager.changeAndIncMessage(currentScreen.messages[currentScreen.pos]);
		Game.notifyUpdate();
	}
	
	public static void notifyBorderCross(Vec2double pos) {
		System.out.println("Screen switch");
		Vec2int nextScreen = currentSpaceScreen;
		if (pos.x > 500) {
			nextScreen.x++;
			currentScreen = getScreen(nextScreen, new Vec2double(0, pos.y));
		} else if (pos.x < 0) {
			nextScreen.x--;
			currentScreen = getScreen(nextScreen, new Vec2double(500, pos.y));
		} else if (pos.y > 500) {
			nextScreen.y++;
			currentScreen = getScreen(nextScreen, new Vec2double(pos.x, 0));
		} else if (pos.y < 0) {
			nextScreen.y--;
			currentScreen = getScreen(nextScreen, new Vec2double(pos.x, 500));
		}
		MessageManager.changeAndIncMessage(currentScreen.messages[currentScreen.pos]);
		Game.notifyUpdate();
	}
	
}
