package gui.simulator;

import gui.simulator.facilities.RestRoom;
import gui.simulator.facilities.SimulatorStage;
import gui.simulator.facilities.SnackBar;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedHashMap;

public class Sidebar implements Serializable  {
	private int sideBarWidth;
	private int sideBarHeight;
	private Terrain terrain;
	private LinkedHashMap<String, DrawEngine> drawableStages = new LinkedHashMap<String, DrawEngine>();
	private LinkedHashMap<String, DrawEngine> drawableFacilities = new LinkedHashMap<String, DrawEngine>();
	private LinkedHashMap<String, DrawEngine> drawablePaths = new LinkedHashMap<String, DrawEngine>();
	public enum SideBarTab{STAGES, FACILITIES, PATHS}
	private SideBarTab currentTab = SideBarTab.STAGES;
	private int tabWidth, tab1X, tab2X, tab3X;
	
	/*
	 * Constructor for initializing all variables
	 * @param: int sideBarWidth -> width of sidebar
	 * @param int screenHeight -> Height of screen, so sidebar will be same height 
	 */
	public Sidebar(int sideBarWidth, int screenHeight, Terrain terrain){
		this.sideBarWidth = sideBarWidth;
		this.sideBarHeight = screenHeight;
		this.terrain = terrain;
		this.tabWidth = sideBarWidth/3;
		this.tab1X = 0;
		this.tab2X = sideBarWidth/3;
		this.tab3X = 2*sideBarWidth/3;
		loadDrawableObjects();
	}
	
	/*
	 * Add your new objects to this method. This method is run when the sidebar is drawn and will automatically align and place 
	 * all inserted objects. Only thing YOU have to do is insert nice parameter values to the object instantiation.
	 */
	public void loadDrawableObjects(){
		//stages
		drawableStages.put("Stage1",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage2",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage3",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage4",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage5",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage6",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage7",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage8",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage9",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage10",new SimulatorStage(0, 62, 0.26, 1));
		drawableStages.put("Stage11",new SimulatorStage(0, 62, 0.26, 1));
		
		//facilities
		drawableFacilities.put("Toilet",new RestRoom(60, 275, 1 , 1));
		drawableFacilities.put("Ingang",new AccessPoint(terrain, 0, 425, 0.5, 1));
		drawableFacilities.put("Uitgang",new ExitPoint(terrain, 0, 525, 0.5, 1));
		drawableFacilities.put("Snackbar",new SnackBar(0, 620, 0.5, 1));
		
		//paths
		//drawablePaths.add("My awesome path name", new AwesomePath());

	}
	
	public void draw(Graphics2D g2){
		//setclip
        g2.setClip(new Rectangle2D.Double(0,0, sideBarWidth, sideBarHeight));
        
        //header + tabs
        g2.setColor(Color.GRAY);
        //g2.fill3DRect(x, y, width, height, raised);
        g2.fill3DRect(0, 0, sideBarWidth, 30, true);
        g2.fill3DRect(tab1X, 30, tabWidth, 30, true);
        g2.fill3DRect(tab2X, 30, tabWidth, 30, true);
        g2.fill3DRect(tab3X, 30, tabWidth, 30, true);       
        g2.setColor(Color.WHITE);
        g2.setFont(new Font("Serif", Font.BOLD, 20));
        //g2.drawString(str, x, y);
        g2.drawString("Drag and drop", 30, 25);  
        g2.setFont(new Font("Serif", Font.BOLD, 16));
        g2.drawString("Stages", tab1X+10, 50);
        g2.drawString("Facilities", tab2X+3, 50);
        g2.drawString("Paths", tab3X+15, 50);
        switch (currentTab) {
		case STAGES:
			g2.drawLine(tab1X+10, 55, tab1X+55, 55);
			break;
		case FACILITIES:
			g2.drawLine(tab2X+3, 55, tab2X+63, 55);
			break;
		case PATHS:
			g2.drawLine(tab3X+15, 55, tab3X+50, 55);
			break;
		default:
			break;
		}
        
        //draw objects
        g2.setColor(Color.BLACK);
        int objectPlacementX = 0;
        int objectPlacementY = 61;
		switch (currentTab) {
		case STAGES:
			for(HashMap.Entry<String, DrawEngine> object : drawableStages.entrySet()){
				object.getValue().draw(g2);
				g2.drawString(object.getKey(), objectPlacementX, objectPlacementY + 95);
				g2.drawRect(objectPlacementX, objectPlacementY, sideBarWidth/2, 100);
				objectPlacementY += 100;
				//switch to column2 if colum1 is filled
				if(objectPlacementY > sideBarHeight)
					objectPlacementY += sideBarWidth/2;
	            //System.out.println(object.getKey() +" :: "+ object.getValue());
			}
			break;
		case FACILITIES:
			//toilet
			DrawEngine restroom = new RestRoom(60,275, 1 , 10);
			restroom.draw(g2);
	        g2.drawString("Toilettage", 65, 400);
	        //accespoint
	        DrawEngine accesPoint = new AccessPoint(terrain, 0,425, 0.5, 10);
	        accesPoint.draw(g2);
	        g2.drawString("Ingang", 70, 500);
	        //exitpoint
	        DrawEngine exitPoint = new ExitPoint(terrain, 0,525, 0.5, 10);
	        exitPoint.draw(g2);
	        g2.drawString("Uitgang", 70, 600);
	        //snackbar
	        DrawEngine snackBar = new SnackBar(0, 620, 0.5, 10);
	        snackBar.draw(g2);
	        g2.drawString("Snackbar", 70, 825);
			break;
		case PATHS:
			
			break;
		default:
			break;
		}
		
		//draw seperation line between sidebar and field
        g2.setColor(Color.BLACK);
        g2.setStroke(new BasicStroke(5));
        g2.drawLine(199, 0, 199, sideBarHeight);
    }
	
	/*
	 * Make new facility and place it on the mousepointer, dependent on where the user clicked in the sidebar
	 * @param: MouseEvent e -> Used to get mouselocation
	 */
    protected void getFacility(MouseEvent e){
    	Point2D clickPoint = terrain.getClickPoint(e.getPoint());
    	DrawEngine dragObject = null;
    	if(e.getX() < sideBarWidth)
		{
    		//check for click on tabs
    		if(e.getY() > 30 && e.getY() < 60){
    			if(e.getX() > tab1X && e.getX() < tab2X){
    				currentTab = SideBarTab.STAGES;
    			}else if(e.getX() > tab2X && e.getX() < tab3X){
    				currentTab = SideBarTab.FACILITIES;
    			}else if(e.getX() > tab3X && e.getX() < sideBarWidth){
    				currentTab = SideBarTab.PATHS;
    			}
    		}
    		//check for object selection
    		switch (currentTab) {
    		case STAGES:
    			
    			break;
    		case FACILITIES:
    			
    			break;
    		case PATHS:
    			
    			break;
    		default:
    			break;
    		}
			if(e.getY() > 100 && e.getY() < 260){
				dragObject = new SimulatorStage((int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
				terrain.setDragObject(dragObject);
			}else if(e.getY() >= 260 && e.getY() < 425){
				dragObject = new RestRoom((int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
				terrain.setDragObject(dragObject);
			}else if(e.getY() >= 430 && e.getY() < 510){
				dragObject = new AccessPoint(terrain, (int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
				terrain.setDragObject(dragObject);
			}
			else if(e.getY() >= 510 && e.getY() < 610){
				dragObject = new ExitPoint(terrain, (int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
				terrain.setDragObject(dragObject);
			}
			else if(e.getY() > 610 && e.getY() < terrain.getFestivalHeight()){
				dragObject = new SnackBar((int)clickPoint.getX(),(int)clickPoint.getY(), 0.5, 10);
				terrain.setDragObject(dragObject);
			}
			if(dragObject != null)
				terrain.addEntity(dragObject);
		}
    }
	
	public int getSideBarWidth(){
		return sideBarWidth;
	}
}
