package projectzombie.menu;

import java.io.File;
import java.util.ArrayList;
import java.util.Random;

import bdf.types.BdfArray;
import bdf.types.BdfNamedList;
import bdf.types.BdfObject;
import bdf.types.BdfReader;
import gl_engine.matrix.Matrix4;
import gl_engine.vec.Vec2d;
import projectzombie.Main;
import projectzombie.init.Models;
import projectzombie.input.types.InputGUI;
import projectzombie.menu.gui.GUI;
import projectzombie.menu.gui.GUIAlignment;
import projectzombie.menu.gui.GUIBackToMenu;
import projectzombie.menu.gui.GUIButtonBasic;
import projectzombie.menu.gui.GUIContainerSlider;
import projectzombie.menu.gui.GUILabel;
import projectzombie.menu.gui.GUISavesCard;
import projectzombie.model.ModelGui;
import projectzombie.util.FileHelpers;
import projectzombie.worker.WorkerTasks;
import projectzombie.world.World;

public class MenuSaves extends Menu
{
	private static final Random rand = new Random();
	
	private ArrayList<SaveCard> saves;
	private int saves_remove = -1;
	
	private Menu parent;
	private GUIContainerSlider slider;
	private GUI gui;
	
	private class SaveCard
	{
		String text, filename;
		
		public SaveCard(String text, String filename)
		{
			this.text = text;
			this.filename = filename;
		}
	}
	
	public MenuSaves(Menu parent)
	{
		this.parent = parent;
		
		doGameloop = parent.doGameloop;
		doGameRender = parent.doGameRender;
		showIngameGUI = parent.showIngameGUI;
		
		gui = new GUIBackToMenu(parent);
		saves = new ArrayList<SaveCard>();
		
		input = new InputGUI(gui);
		keepMouse = false;
		
		GUIButtonBasic buttonBack = new GUIButtonBasic("Back", button -> {
			Main.menu = parent;
		});
		
		GUIButtonBasic buttonCreate = new GUIButtonBasic("Create", button -> {
			createWorld();
		});
		
		slider = new GUIContainerSlider(new Vec2d(
				-Models.UI_SELECTION_BOX_WIDE.getWidth() * 127 / 256.0,
				-Models.UI_SELECTION_BOX_WIDE.getHeight() * 63 / 128.0), new Vec2d(
				Models.UI_SELECTION_BOX_WIDE.getWidth() * 254 / 256.0, 
				Models.UI_SELECTION_BOX_WIDE.getHeight() * 126 / 128.0), 10);
		
		reloadDatabase(Main.bdf_saves);
		
		buttonBack.setAlign(GUIAlignment.RIGHT);
		buttonCreate.setAlign(GUIAlignment.LEFT);
		
		buttonBack.setPos(new Vec2d(-0.5, -8));
		buttonCreate.setPos(new Vec2d(0.5, -8));
		
		GUILabel labelSaves = new GUILabel();
		labelSaves.setText("Saves");
		labelSaves.setSize(new Vec2d(1, 1));
		labelSaves.setPos(new Vec2d(0, 6.8));
		gui.add(labelSaves);
		
		gui.add(buttonBack);
		gui.add(buttonCreate);
		gui.add(slider);
	}
	
	private void createWorld() {
		Main.menu = new MenuWorldNew(this);
	}
	
	private void loadSave(int index)
	{
		BdfObject bdf = Main.bdf_saves.getObject();
		BdfNamedList nl = bdf.getNamedList();
		BdfArray array = nl.get("saves").getArray();
		
		BdfObject save_bdf = array.remove(index);
		array.add(save_bdf);
		
		WorkerTasks.saveToFile("./saves.bdf.gz", Main.bdf_saves);
		
		Main.world = new World(saves.get(index).filename);
		Main.menu = new MenuLoadingWorld();
	}
	
	private void deleteSave(int index)
	{
		SaveCard save = saves.get(index);
		Main.menu = new MenuWorldDelete(this, save.text, save.filename);
	}
	
	public void reloadDatabase(BdfReader reader)
	{
		saves.clear();
		BdfNamedList nl = reader.getObject().getNamedList();
		BdfArray array = nl.get("saves").getArray();
		
		for(BdfObject save_bdf : array)
		{
			BdfNamedList save_nl = save_bdf.getNamedList();
			
			SaveCard save = new SaveCard(
					save_nl.get("name").getString(),
					save_nl.get("path").getString());
			
			saves.add(save);
		}
		
		generateSaveCards();
	}
	
	private void generateSaveCards()
	{
		double slider_length = Models.UI_LABEL.getHeight() * 18.0 * saves.size() / 16.0;
		double selection_length = Models.UI_SELECTION_BOX_WIDE.getHeight() * 248 / 256.0;
		
		slider.clear();
		slider.setLength(slider_length > selection_length ? slider_length - selection_length : 0);
		
		for(int i=0;i<saves.size();i++)
		{
			int[] index = {saves.size() - i - 1};
			SaveCard save = saves.get(index[0]);
			
			GUISavesCard savesCard = new GUISavesCard(save.text, new Vec2d(
					-Models.UI_LABEL.getWidth() / 2.0,
					-Models.UI_LABEL.getHeight() +
					Models.UI_SELECTION_BOX_WIDE.getHeight() * 60.0 / 128.0 -
					Models.UI_LABEL.getHeight() * 18.0 * i / 16.0))
			{
				@Override
				public void onDeletePressed() {
					super.onDeletePressed();
					
					deleteSave(index[0]);
				}
				
				@Override
				public void onPlayPressed() {
					super.onPlayPressed();
					
					loadSave(index[0]);
				}
			};
			
			slider.add(savesCard);
		}
	}

	@Override
	public void render()
	{
		ModelGui selection_box = Models.UI_SELECTION_BOX_WIDE;
		selection_box.setModel(Matrix4.translate(
				-selection_box.getWidth() / 2,
				-selection_box.getHeight() / 2, 0));
		selection_box.render();
		
		gui.render();
	}
	
	@Override
	public void update()
	{
		parent.update();
		super.update();
	}

}
