/**
 * Skript pro spravnou funkcnost hlavniho menu aplikace.
 */
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections;
using System.Collections.Generic;
using System.IO;
/**
 * Author:			Karel Zavrel
 * 
 * Thesis:			An interactive application for development of creativity
 * Application:		Little Builder
 */
public class SwitchingPanelsByTabs : MonoBehaviour {
	/**
	 * promenne:
	 * 	- jednotlive panely menu: hlavni nabidka, nastaveni, staveni noveho modelu, nacteni existujiciho modelu, panel pro zpravy uzivateli, panel pro potvrzeni prepsani souboru, galerie modelu
	 * 	- hlavni ovladaci tlacitka ovladajici zobrazeni prislusnych panelu: hlavni nabidka, galerie, nastaveni
	 * 	- barvy pro predchozi 3 tlacitka: pocatecni barva, nova barva
	 * 	- vstupni pole pro zadani nazvu nove vytvareneho modelu
	 * 	- vstupni pole pro zadani prezdivky uzivatele
	 * 	- rozbalovaci nabidka, kam se vypisi vsechny nalezene soubory s modely
	 * 	- textove pole pro vzkaz uzivateli
	 * 	- instance tridy ModelSaveLoadScript pro ukladani a nacitani modelu do a ze souboru
	 * 	- seznam jmen vsech souboru s modely
	 */
	private GameObject mainPanel, settingsPanel, newModelPanel, openModelPanel, logLabelPanel, logButtonPanel, galleryPanel;
	private Button mainMenuButton, galleryButton, settingsButton;
	private Color initialColor, newColor;
	private InputField newModelNameInputField, usernameInputField;
	private Dropdown openModelDropdown;
	private Text logLabelText;
	private ModelSaveLoadScript modelSaveLoadScriptInstance = ModelSaveLoadScript.getInstance();
	private List<string> names = new List<string>();
	/**
	 * promenne pro mraky a figurinu:
	 * 	- podminka, zda se mraky pohybuji doprava
	 * 	- objekt mraky
	 * 	- nejzazsi pozice, kam az se mraky posunou, prava a leva
	 * 	- pole materialu, kterych mohou nabyvat jednotlive casti figuriny
	 * 	- nazvy materialu pro jejich nacteni
	 * 	- kamery: hlavni kamera, kamera pro ulozeni detailniho pohledu na avatara
	 * 	- platno pro GUI
	 */
	private bool cloudsToRight = true;
	private GameObject clouds;
	private Vector3 rightCloudsPos, leftCloudsPos;
	private Material[] materialsMatrix = new Material[9];
	private string[] materialNames = new string[]{"BrownColor", "BeigeColor", "Trunk", "Body_1", "BlueColor", "MountainMat_1", "jeans", "MountainMat_2", "Sleeve"};
	private Camera mainCam, avatarCam;
	private Canvas mainCanvas;
	/**
	 * funkce volana jednou za zivotnost skriptu
	 * 	- pro nacteni materialu na figuriny
	 */
	void Awake(){
		fillMaterialsMatrix();
	}
	/**
	 * funkce naplni pole materialu pro figurinu dle pole nazvu jednotlivych materialu
	 */
	private void fillMaterialsMatrix(){
		for (int i = 0; i < materialNames.Length; i++) {
			materialsMatrix [i] = Resources.Load ("Models/Materials/" + materialNames[i]) as Material;
		}
	}
	/**
	 * funkce pro inicializaci promennych
	 */
	void Start () {
		/**
		 * nacte data z konfiguracni tridy
		 */
		ConfigFile.loadData();
		/**
		 * nastaveni cesty pro ukladani
		 */
		setPathToModelsDirectory ();
		/**
		 * jednotlive panely
		 */
		mainPanel = GameObject.Find ("MainPanel");
		settingsPanel = GameObject.Find ("SettingsPanel");
		newModelPanel = GameObject.Find ("NewModelPanel");
		openModelPanel = GameObject.Find ("OpenModelPanel");
		logLabelPanel = GameObject.Find ("LogLabelPanel");
		logButtonPanel = GameObject.Find ("LogButtonPanel");
		galleryPanel = GameObject.Find ("GalleryPanel");
		/**
		 * zalozky panelu
		 */
		mainMenuButton = GameObject.Find ("MainMenuButton").GetComponent<Button> ();
		galleryButton = GameObject.Find ("GalleryButton").GetComponent<Button> ();
		settingsButton = GameObject.Find ("SettingsButton").GetComponent<Button> ();
		/**
		 * input field jmena noveho modelu
		 */
		newModelNameInputField = GameObject.Find ("NewModelNameInputField").GetComponent<InputField> ();
		usernameInputField = GameObject.Find ("UsernameInputField").GetComponent<InputField> ();
		openModelDropdown = GameObject.Find ("OpenModelDropdown").GetComponent<Dropdown> ();
		logLabelText = GameObject.Find ("LogLabelText").GetComponent<Text> ();
		/**
		 * definovani dvou barev, ktere jsou pouzivany pro zmenu zalozek
		 */
		initialColor = mainMenuButton.image.color;
		newColor = new Color (0.5f, 0.5f, 0.5f, 1.0f);
		/**
		 * nastaveni panelu na false
		 */
		settingsPanel.SetActive (false);
		newModelPanel.SetActive (false);
		openModelPanel.SetActive (false);
		logButtonPanel.SetActive (false);
		logLabelPanel.SetActive (false);
		galleryPanel.SetActive (false);
		/**
		 * nastaveni barev tlacitek
		 */
		galleryButton.image.color = newColor;
		settingsButton.image.color = newColor;
		/**
		 * mraky
		 */
		clouds = GameObject.Find ("Clouds");
		leftCloudsPos = new Vector3 (-50.0f, 30.0f, 72.5f);
		rightCloudsPos = new Vector3 (200.0f, 30.0f, 72.5f);
		/**
		 * figurina
		 */
		GameObject.Find ("Hair").GetComponent<MeshRenderer> ().material = materialsMatrix [ConfigFile.getHeadIndex ()];
		GameObject.Find ("Body").GetComponent<MeshRenderer> ().material = materialsMatrix [ConfigFile.getBodyIndex ()];
		GameObject.Find ("Bottom").GetComponent<MeshRenderer> ().material = materialsMatrix [ConfigFile.getLegsIndex ()];
		GameObject.Find ("LeftLeg").GetComponent<MeshRenderer> ().material = materialsMatrix [ConfigFile.getLegsIndex ()];
		GameObject.Find ("RightLeg").GetComponent<MeshRenderer> ().material = materialsMatrix [ConfigFile.getLegsIndex ()];
		/**
		 * kamery a canvas
		 */
		mainCam = GameObject.Find ("Main Camera").GetComponent<Camera> ();
		avatarCam = GameObject.Find ("AvatarCamera").GetComponent<Camera> ();
		mainCanvas = GameObject.Find ("MainMenuCanvas").GetComponent<Canvas> ();
		avatarCam.enabled = false;
	}
	/**
	 * funkce volana jednou pro kazdy frame
	 * 	- zajistuje pohyb mraku ve scene
	 */
	void Update () {
		moveClouds();
	}
	/**
	 * funkce pro pohyb mraku
	 */
	private void moveClouds(){
		if (cloudsToRight) {
			clouds.transform.position = Vector3.Lerp (clouds.transform.position, rightCloudsPos, 0.2f * Time.deltaTime);
			if (clouds.transform.position.x > 189.0f) {
				cloudsToRight = false;
			}
		} else {
			clouds.transform.position = Vector3.Lerp (clouds.transform.position, leftCloudsPos, 0.2f * Time.deltaTime);
			if (clouds.transform.position.x < -39.0f) {
				cloudsToRight = true;
			}
		}
	}
	/**
	 * funkce pro nastaveni cesty pro ulozeni modelu
	 */
	private void setPathToModelsDirectory(){
		if (!Directory.Exists (Application.persistentDataPath + "/TxtModels")) {
			Directory.CreateDirectory (Application.persistentDataPath + "/TxtModels");
		}
		modelSaveLoadScriptInstance.setPathToSaveFiles (Application.persistentDataPath + "/TxtModels/");
	}
	/**
	 * funkce pro prepnuti na panel nastaveni
	 */
	public void clickOnSettingsTab(){
		settingsPanel.SetActive(true);
		mainPanel.SetActive (false);
		galleryPanel.SetActive (false);
		newModelPanel.SetActive (false);
		openModelPanel.SetActive (false);

		mainMenuButton.image.color = newColor;
		galleryButton.image.color = newColor;
		settingsButton.image.color = initialColor;

		fillUsernameInputfield ();
	}
	/**
	 * funkce pro nastaveni obsahu usernameInputField
	 * 	- pokud jiz byla prezdivka nastavena, tak ji vyplni
	 */
	private void fillUsernameInputfield(){
		string name = ConfigFile.getAvatarsName();
		if (name != "Avatar") {
			usernameInputField.text = name;
		}
	}
	/**
	 * funkce pro prepnuri na hlavni panel
	 */
	public void clickOnMainMenuTab(){
		settingsPanel.SetActive(false);
		mainPanel.SetActive (true);
		galleryPanel.SetActive (false);
		newModelPanel.SetActive (false);
		openModelPanel.SetActive (false);

		mainMenuButton.image.color = initialColor;
		galleryButton.image.color = newColor;
		settingsButton.image.color = newColor;
	}
	/**
	 * funkce pro prepnuri na galerii
	 */
	public void clickOnGalleryTab(){
		settingsPanel.SetActive(false);
		mainPanel.SetActive (false);
		galleryPanel.SetActive (true);
		newModelPanel.SetActive (false);
		openModelPanel.SetActive (false);

		mainMenuButton.image.color = newColor;
		galleryButton.image.color = initialColor;
		settingsButton.image.color = newColor;
	}
	/**
	 * funkce pro prepnuti na panel noveho modelu
	 */
	public void clickOnNewModelButton(){
		mainPanel.SetActive (false);
		newModelPanel.SetActive (true);

		mainMenuButton.image.color = newColor;
	}
	/**
	 * funkce pro prepnuti na panel pro otevreni modelu
	 */
	public void clickOnOpenModelButton(){
		mainPanel.SetActive (false);
		openModelPanel.SetActive (true);

		mainMenuButton.image.color = newColor;
		fillDropdown ();
	}
	/**
	 * funkce pro naplneni dropdown vyctu dostupnych txt souboru s modelem
	 */
	private void fillDropdown(){
		openModelDropdown.ClearOptions ();
		FileInfo[] fi = modelSaveLoadScriptInstance.getAllFilesNames ();
		names = new List<string> ();
		if (fi != null) {
			for (int i = 0; i < fi.Length; i++) {
				if (fi [i].Name.Substring (fi [i].Name.Length - 4) == ".txt") {
					names.Add (fi [i].Name);
				}
			}
			if (names.Count == 0) {
				names.Add ("Nejsou zde žádné soubory s modelem.");
				setLogLabel ("Adresář neobsahuje žádný textový soubor!", false);
			}
		} else {
			names.Add ("Nejsou zde žádné soubory s modelem.");
			setLogLabel ("Adresář neexistuje!", false);
		}
		openModelDropdown.AddOptions (names);
	}
	/**
	 * funkce pro nacteni nove sceny pro novy model
	 */
	public void clickOnSaveButton(){
		string nameOfFile = newModelNameInputField.text;
		if (newModelNameInputField.text == "") {
			nameOfFile = "NewModel_" + Random.Range (1, 100).ToString () + ".txt";
		} else {
			nameOfFile = nameOfFile + ".txt";
		}
		modelSaveLoadScriptInstance.setFileName (nameOfFile);
		if (modelSaveLoadScriptInstance.fileExists ()) {
			setLogLabel ("Soubor již existuje. Přejete si soubor přepsat novým?", true);
		} else {
			InnerStoringScript.setIsLoading (false);
			setStaticVariables ();
			SceneManager.LoadScene ("EditorScene");
		}
	}
	/**
	 * funkce pro nacteni sceny s existujicim modelem
	 */
	public void clickOnLoadModelButton(){
		string filesName = names [openModelDropdown.value];
		modelSaveLoadScriptInstance.setFileName (filesName);
		if (modelSaveLoadScriptInstance.fileExists ()) {
			InnerStoringScript.setIsLoading (true);
			setStaticVariables ();
			SceneManager.LoadScene ("EditorScene");
		} else {
			setLogLabel ("Daný soubor se nepodařilo otevřít. Soubor neexistuje nebo je porušený!", false);
		}
	}
	/**
	 * funkce pro nacteni sceny s modelem z galerie
	 */
	public void clickOnGalleryLoadButton(Button button){
		string filesName = button.name;
		filesName = filesName + ".txt";
		modelSaveLoadScriptInstance.setFileName (filesName);
		InnerStoringScript.setIsLoading (true);
		InnerStoringScript.setIsLoadingFromGallery (true);
		setStaticVariables ();
		SceneManager.LoadScene ("EditorScene");
	}
	/**
	 * funkce pro zobrazeni logLabelPanel
	 */
	private void setLogLabel(string message, bool buttonVisible){
		logLabelPanel.SetActive (true);
		logLabelText.text = message;
		if (buttonVisible) {
			logButtonPanel.SetActive (true);
		}
		StartCoroutine (hideLogLabelPanel ());
	}
	/**
	 * funkce, ktera po 5 vterinach schova logLabelPanel
	 */
	private IEnumerator hideLogLabelPanel(){
		yield return new WaitForSecondsRealtime (5);
		logLabelText.text = "";
		logButtonPanel.SetActive (false);
		logLabelPanel.SetActive (false);
	}
	/**
	 * funkce pro stisknuti Ano / Ne tlacitka
	 * 	-	0 - ano
	 * 	-	1 - ne
	 */
	public void clickOnLogButton(int choice){
		if (choice == 0) {
			InnerStoringScript.setIsLoading (false);
			setStaticVariables ();
			SceneManager.LoadScene ("EditorScene");
		} else if (choice == 1) {
			logLabelText.text = "";
			logButtonPanel.SetActive (false);
			logLabelPanel.SetActive (false);
		}
	}
	/**
	 * funkce pro vypnuti aplikace
	 */
	public void closeApplication(){
		Application.Quit ();
	}
	/**
	 * funkce pro nastaveni InnerStoringScript promennych
	 */
	private void setStaticVariables(){
		InnerStoringScript.setIsRotationPermitted (true);
		InnerStoringScript.setIsScalePermitted (true);
		InnerStoringScript.setMovePanelClicked (false);
	}
	/**
	 * 
	 */
	public void saveSettings(){
		string name = usernameInputField.text;
		if (name != "") {
			ConfigFile.setAvatarsName (name);
		} else {
			ConfigFile.setAvatarsName ("Avatar");
		}
		ConfigFile.saveData ();
		avatarCam.enabled = true;
		mainCam.enabled = false;
		mainCanvas.enabled = false;
		saveAvatarsImage ();
		clickOnMainMenuTab ();
	}
	/**
	 * funkce pro nahrani vychoziho nastaveni
	 */
	public void loadInitialSettings(){
		ConfigFile.loadInitialSettings();
		clickOnMainMenuTab();
	}
	/**
	 * funkce pro zmenu materialu hlavy figuriny
	 */
	public void clickOnFigurinesHeadButton(bool rightButton){
		GameObject.Find("Hair").GetComponent<MeshRenderer>().material = materialsMatrix[(0 * 3) + ConfigFile.getIndex(rightButton, "figurines_head")];
	}
	/**
	 * funkce pro zmenu materialu tela figuriny
	 */
	public void clickOnFigurinesBodyButton(bool rightButton){
		GameObject.Find("Body").GetComponent<MeshRenderer>().material = materialsMatrix[(1 * 3) + ConfigFile.getIndex(rightButton, "figurines_body")];
	}
	/**
	 * funkce pro zmenu materialu nohou figuriny
	 */
	public void clickOnFigurinesLegsButton(bool rightButton){
		int matIndex = (2 * 3) + ConfigFile.getIndex(rightButton, "figurines_legs");
		GameObject.Find("Bottom").GetComponent<MeshRenderer>().material = materialsMatrix[matIndex];
		GameObject.Find("LeftLeg").GetComponent<MeshRenderer>().material = materialsMatrix[matIndex];
		GameObject.Find("RightLeg").GetComponent<MeshRenderer>().material = materialsMatrix[matIndex];
	}
	/**
	 * funkce pro spusteni ulozeni snimku avatara
	 */
	private void saveAvatarsImage(){
		StartCoroutine(makeAvatarImage());
	}
	/**
	 * funkce pro ulozeni detailniho snimku avatara
	 */
	private IEnumerator makeAvatarImage(){
		yield return new WaitForEndOfFrame();
		Texture2D avatarImg = new Texture2D (avatarCam.pixelWidth, avatarCam.pixelWidth, TextureFormat.RGB24, false);
		avatarImg.ReadPixels (new Rect (10, 120, Screen.width, Screen.height), 0, 0);
		avatarImg.Apply ();
		File.WriteAllBytes (Application.persistentDataPath + "/avatarImg.png", avatarImg.EncodeToPNG());
		avatarCam.enabled = false;
		mainCam.enabled = true;
		mainCanvas.enabled = true;
	}
}