package rpgEngine.Resources;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;

import rpgEngine.Data.Abstract.Enemy.EnemyParty;
import rpgEngine.Data.Abstract.NPC.NPC;
import rpgEngine.Data.Abstract.World.Door;
import rpgEngine.Data.Abstract.World.Map;
import rpgEngine.Data.Abstract.World.MapCell;
import rpgEngine.Data.Abstract.World.Terrain;

public class MapPool {
	private static MapPool instance;
	private Dictionary<Integer,Map> items;
	
	private MapPool() {
		items = new Hashtable<Integer,Map>();
		loadData();
	}
	
	
	public static MapPool getInstance() {
		if(instance == null) {
			instance = new MapPool();
		}
		
		return instance;
	}
	
	
	public Map getPoolItem(Integer i) {
		Map item = null;
		
		try 
		{
			item = items.get(i);	
		}
		catch(Exception e) 
		{
			return null;	
		}
		
		return item;
	}
	
	
	private void loadData() {	
		Integer maxErrors = 10;
		Integer errorCount = 0;
		String filename = "map00.cfg";
		String[] columns = null;
		String cell = "";
		String[] cellContents = null;
		InputStream fileStream = null;
		BufferedReader reader = null;
		String line = "";
		Map map = null;
		MapCell mapCell = null;
		List<MapCell> mapRow = null;
		Terrain terrain = null;
		Terrain terrainObject= null;
		Integer lineNum = 0;
		
		EnemyParty enemyParty = null;
		NPC npc = null;
		Door door = null;
		Integer x = 0;
		Integer y = 0;
		Integer mapID = 0;
		Integer mx = 0;
		Integer my = 0;
		Integer ID = 0;
		
		
		for(Integer i = 0; i < 1000; i++) {
			if(i < 10) {
				filename = "map" + "00" + i.toString() + ".cfg";
			}
			else if(i < 100) {
				filename = "map" + "0" + i.toString() + ".cfg";
			}
			else if(i < 1000) {
				filename = "map" + "" + i.toString() + ".cfg";
			}
			
			try {
				fileStream = this.getClass().getResourceAsStream("Config/" + filename);
			}
			catch(Exception e) {
				errorCount++;
				fileStream = null;
				
				if(errorCount >= maxErrors) {
					return;
				}
			}
		
			if(fileStream != null) {
				map = new Map();
				map.setID(i);
				
				//Open File
				try {
					reader = new BufferedReader(new InputStreamReader(fileStream));
				}
				catch(Exception e) {
					System.err.println("Error openning file" + filename);
					System.err.println(e.toString());
					return;
				}
				
				//Read File
				try {
					lineNum = 0;
					while(reader.ready()) {
						line = reader.readLine();
						
						columns = line.split(",");
						
						if(columns[0].equals("MAP")) {
							mapRow = new ArrayList<MapCell>();
							
							for(Integer j = 1; j < columns.length; j++) {
								cell = columns[j];
								cellContents = cell.split(":");
								
								terrain = TerrainPool.getInstance().getPoolItem(Integer.parseInt(cellContents[0]));
								
								if(cellContents.length > 1) {
									terrainObject = TerrainPool.getInstance().getPoolItem(Integer.parseInt(cellContents[1]));
								}
								else {
									terrainObject = null;
								}
								
								door = null;
								
								mapCell = new MapCell(terrain,terrainObject,door,j-1,lineNum);
								
								mapRow.add(mapCell);
							}
							
							map.getRows().add(mapRow);
							lineNum++;
						}
						else if(columns[0].equals("DOOR")) {
							x = Integer.parseInt(columns[1]);
							y = Integer.parseInt(columns[2]);
							mapID = Integer.parseInt(columns[3]);
							mx = Integer.parseInt(columns[4]);
							my = Integer.parseInt(columns[5]);
							
							door = new Door(mapID,mx,my);
							
							map.getRows().get(y).get(x).setDoor(door);
						}
						else if(columns[0].equals("SOUND")) {
							ID = Integer.parseInt(columns[1]);
							
							map.setBackgroundMusic(SoundPool.getInstance().getPoolItem(ID));
						}
						else if(columns[0].equals("NPC")) {
							ID = Integer.parseInt(columns[1]);
							x = Integer.parseInt(columns[2]);
							y = Integer.parseInt(columns[3]);
							
							npc = NPCPool.getInstance().getPoolItem(ID);
							map.getRows().get(y).get(x).setNPC(npc);
						}
						else if(columns[0].equals("ENEMYPARTY")) {
							cellContents = columns[1].split(":");
							
							for(Integer cc = 0; cc < cellContents.length; cc++) {
								enemyParty = EnemyPartyPool.getInstance().getPoolItem(Integer.valueOf(cellContents[cc]));
								
								map.getEnemyParties().add(enemyParty);
							}
						}
					}
				}
				catch(Exception e) {
					System.err.println("Error reading file" + filename);
					System.err.println(e.toString());
					return;
				}
				
				//Close File
				try {
					reader.close();
					fileStream.close();
				}
				catch(Exception e) {
					System.err.println("Error closing file" + filename);
					System.err.println(e.toString());
					return;
				}
				
				items.put(i,map);
			}
		}
	}
}
