package rpgEngine.Logic.Camera;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.List;

import rpgEngine.Data.Abstract.Game;
import rpgEngine.Data.Abstract.Item;
import rpgEngine.Data.Abstract.NPC.NPC;
import rpgEngine.Data.Abstract.NPC.ScriptItem;
import rpgEngine.Data.Abstract.Party.HumanPlayer;
import rpgEngine.Data.Abstract.World.CharacterAvatar;
import rpgEngine.Data.Abstract.World.Map;
import rpgEngine.Data.Abstract.World.MapCell;
import rpgEngine.Data.Abstract.World.Terrain;
import rpgEngine.Data.Raw.Graphics.CharacterSet;
import rpgEngine.Data.Raw.Graphics.ChipSet;
import rpgEngine.Resources.FontPool;
import rpgEngine.Resources.HeroPool;
import rpgEngine.Resources.ImagePool;
import rpgEngine.Resources.ItemPool;
import rpgEngine.UI.GamePanel;


public class GameCamera extends GenericCamera {
	private GamePanel panel;
	
	public GameCamera(GamePanel p) {
		super();
		
		panel = p;
	}

	@Override
	public BufferedImage getImage() {
		BufferedImage img = null;
		Graphics2D g = null;
		Integer width = 800;
		Integer height = 600;
		
		Game game = null;
		Map map = null;
		HumanPlayer player = null;
		NPC npc = null;
		Terrain terrainObject = null;
		Terrain terrain = null;
		List<MapCell> mapRow = null;
		MapCell cell = null;
		ChipSet chipset = null;
		ChipSet objectChipset = null;
		CharacterAvatar character = null;
		CharacterSet charset = null;
		Integer mapX = 0;
		Integer mapY = 0;
		Integer playerX = 0;
		Integer playerY = 0;
		Integer[] xRange = new Integer[2];
		Integer[] yRange = new Integer[2];
		Integer x = null;
		Integer y = null;
		
		ScriptItem scriptItem = null;
		Integer itemID = -1;
		Item item = null;
		String text = "";
		
		Boolean varValue = false;
		Boolean varReq = false;
		Integer varID = -1;
		
		
		//Draw Defaults
		img = new BufferedImage(800,600,BufferedImage.TYPE_INT_RGB);		
		g = img.createGraphics();
		
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, width, height);
		
		
		//Get and validate Game Info
		game = panel.getParentMainFrame().getGame();
		
		if(game == null) {
			return img;
		}
		
		map = game.getActiveMap();
		
		if(map == null) {
			return img;
		}
		
		player = game.getParty().get(0);
		 
		if(player == null) {
			return img;
		}
		
		mapX = map.getWidth() - 1;
		mapY = map.getHeight() - 1;
		cell = map.findCharacter(player);
		playerX = cell.getX();
		playerY = cell.getY();
		
		
		//Draw Game Screen at 32x32 tiles (display 25 tiles by 19 tiles)
		xRange[0] = playerX - 13;
		xRange[1] = playerX + 13;
		yRange[0] = playerY - 10;
		yRange[1] = playerY + 10;
		
		if(xRange[0] < 0) {
			xRange[1] = xRange[1] - (xRange[0]);
			xRange[0] = 0;
		}
		
		if(yRange[0] < 0) {
			yRange[1] = yRange[1] - (yRange[0]);
			yRange[0] = 0;
		}
		
		if(xRange[1] >= mapX) {
			xRange[0] = xRange[0] - (xRange[1] - mapX);
			xRange[1] = mapX;
		}
		
		if(yRange[1] >= mapY) {
			yRange[0] = yRange[0] - (yRange[1] - mapY);
			yRange[1] = mapY;
		}
		
		
		//Draw Terrain
		x = 0;
		y = 0;
		for(Integer j = yRange[0]; j <= yRange[1]; j++) {
			mapRow = map.getRows().get(j);
			
			for(Integer i = xRange[0]; i <= xRange[1]; i++) {
				cell = mapRow.get(i);
				
				terrain = cell.getTerrain();
				terrainObject = cell.getTerrainObject();
				
				chipset = terrain.getChipset();
				g.drawImage(chipset.getImage(),x,y,32,32,null);
				
				if(terrainObject != null) {
					objectChipset = terrainObject.getChipset();
					g.drawImage(objectChipset.getImage(),x,y,32,32,null);
				}
							
				x = x + 32;
			}
			
			x = 0;
			y = y + 32;
		}
		
		
		//Draw Characters
		x = 0;
		y = 0;
		for(Integer j = yRange[0]; j <= yRange[1]; j++) {
			mapRow = map.getRows().get(j);
			
			for(Integer i = xRange[0]; i <= xRange[1]; i++) {
				cell = mapRow.get(i);
				
				character = cell.getCharacter();
				
				//if no human character, try NPC
				if(character == null) {
					character = cell.getNPC();
					
					//test to see if npc is showable
					if(character != null) {
						npc = (NPC) character;
						
						if(npc.getHasOnlyShowCriteria()) {
							varID = npc.getOnlyShowVariable();
							varReq = npc.getOnlyShowVariableValue();
							varValue = game.getVariable(varID);
							
							if(varValue != varReq) {
								character = null;
							}
						}
					}
				}
				
				if(character != null) {
					charset = character.getCharacterSet();
					g.drawImage(charset.getImage(character.getCharacterPosition()),x-8,y-32,48,64,null);
				}
				
				x = x + 32;
			}
			
			x = 0;
			y = y + 32;
		}
		
		
		//If Script Active Draw Script
		if(game.getActiveScript() != null) {
			scriptItem = game.getActiveScript().current();
			
			if(scriptItem != null) {
				text = "";
				
				if(scriptItem.getType() == ScriptItem.TYPE_TEXT) {
					text = scriptItem.getArgument1();
				}
				else if(scriptItem.getType() == ScriptItem.TYPE_GIVE_ITEM) {
					itemID = Integer.valueOf(scriptItem.getArgument1());
					item = ItemPool.getInstance().getPoolItem(itemID);
					
					text = "Received " + item.getName() + "!";
				}
				else if(scriptItem.getType() == ScriptItem.TYPE_GIVE_GOLD) {
					text = "Received " + scriptItem.getArgument1() + " gold!";
				}
				else if(scriptItem.getType() == ScriptItem.TYPE_GIVE_EXPERIENCE) {
					text = "Received " + scriptItem.getArgument1() + " experience!";
				}
				else if(scriptItem.getType() == ScriptItem.TYPE_GIVE_CHARACTER_WITH_EXP) {
					varID = Integer.valueOf(scriptItem.getArgument1());
					
					text = HeroPool.getInstance().getPoolItem(varID).getName() + " joined your party";
				}
				if(text.equals("") == false) {
					g.drawImage(ImagePool.getInstance().getPoolItem(ImagePool.ID_DIALOG_GAME_EVENT), 0, 400, 800, 200, null);
					
					g.setColor(Color.WHITE);
					g.setFont(FontPool.getInstance().getPoolItem(FontPool.FONT_MINECRAFT).deriveFont(Font.PLAIN,26));
					
					if(text.length() <= 50) {
						g.drawString(text, 30, 450);
					}
					else if (text.length() <= 100) {
						g.drawString(text.substring(0, 49), 30, 450);
						g.drawString(text.substring(49), 30, 500);
					}
					else {
						g.drawString(text.substring(0, 49), 30, 450);
						g.drawString(text.substring(49, 99), 30, 500);
						g.drawString(text.substring(99), 30, 550);
					}
				}
			}
		}
			
		return img;
	}
}
