/**
 * 
 */
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
/**
 * Author:			Karel Zavrel
 * 
 * Thesis:			An interactive application for development of creativity
 * Application:		Little Builder
 */
public class DataSaveLoadScript : MonoBehaviour {
	/**
	 * promenne:
	 * 	- instance tridy ModelSaveLoadScript - Singleton
	 * 	- instance datove struktury octree reprezentovane tridou MyOctree - Singleton
	 * 	- nadrazena kosticka celeho modelu
	 * 	- seznam radku nactenych ze souboru s modelem, kazdy radek reprezentuje prave jednu kosticku nacitaneho modelu
	 *  - panely GUI: panel pro cely editor, panel hlavniho menu, panel s informacemi slouzici jako napoveda, panel pro zpravy uzivateli, panel pro vykresleni navodu
	 * 	- textove pole pro prezdivku
	 * 	- textove pole pro zpravu uzivateli
	 * 	- obrazek pro detailni snimek avatara
	 */
	private ModelSaveLoadScript modelSaveLoadScriptInstance = ModelSaveLoadScript.getInstance();
	private MyOctree myOctree = MyOctree.getInstance();
	private GameObject rootBrick;
	private List<string> loadedList;
	private GameObject editorUIPanel, menuPanel, informationPanel, editorLogLabelPanel, printTutorialPanel;
	private Text menuAvatarNameText, editorLogLabelText;
	private RawImage menuAvatarImg;
	/**
	 * promenne nastavovane pro kazdou kosticku:
	 * 	- herni objekt dane kosticky
	 * 	- obalovy objekt dane kosticky
	 *  - cesta k prefab objektum
	 * 	- jmeno kosticky
	 * 	- pozice kosticky
	 * 	- natoceni kosticky
	 * 	- material kosticky
	 */
	private GameObject brick;
	private Bounds bricksBounds;
	private string pathToBricksPrefab, nameOfBrick;
	private Vector3 bricksPosition;
	private Quaternion bricksRotation;
	private Material bricksMaterial;
	/**
	 * promenne pro vytvoreni obaloveho objektu:
	 * 	- zavisi na natoceni kosticky ve scene, meni se pocet vystupku kosticky ve smeru osy X a Z
	 */
	private float xScale, zScale;
	/**
	 * promenne pro tisk navodu:
	 * 	- textove pole pro navod
	 * 	- textove pole pro cislo snimku navodu
	 * 	- obrazek pro nacteni renderu z hlavni kamery
	 * 	- obrazek pro nacteni renderu z kamery snimajici pudorys sceny
	 * 	- cislo snimku
	 * 	- slovnik dvoji retezec, retezec, do ktereho je ulozen cesky nazev barvy odkazovany pres klic tvoreny implicitnim nazvem materialu
	 */
	private Text tutorialText, screensNumberText;
	private RawImage mainViewRawImage, groundPlanRawImage;
	private int screensNumber = 1;
	private Dictionary<string, string> colorsOfBricks;
	/**
	 * funkce volana jednou za zivotnost celeho skriptu
	 * 	- nalezne panel pro zpravy uzivateli a prislusne textove pole
	 */
	void Awake(){
		editorLogLabelPanel = GameObject.Find ("EditorLogLabelPanel");
		editorLogLabelText = GameObject.Find ("EditorLogLabelText").GetComponent<Text> ();
	}
	/**
	 * funkce pro inicializaci promennych
	 */
	void Start () {
		/**
		 * pokud se jedna o nacteni modelu, je nutne to provest jako prvni
		 */
		if (InnerStoringScript.getIsLoading ()) {
			rootBrick = GameObject.Find ("RootBrick");
			if (rootBrick == null) {
				Debug.Log ("Nemuze najit root.");
			} else {
				InnerStoringScript.addRootBrickToListAsFirstElement (rootBrick);
			}
			if (InnerStoringScript.getIsLoadingFromGallery ()) {
				loadedList = modelSaveLoadScriptInstance.loadDataFromGallery ();
			} else {
				loadedList = modelSaveLoadScriptInstance.loadData ();
			}
			if (loadedList != null) {
				buildLoadedModel ();
				InnerStoringScript.setIsLoading (false);
				InnerStoringScript.setIsLoadingFromGallery (false);
			} else {
				InnerStoringScript.setIsLoading (false);
				InnerStoringScript.setIsLoadingFromGallery (false);
				SceneManager.LoadScene ("MainMenuScene");
			}
		}
		/**
		 * nastaveni pole barev na klic
		 */
		colorsOfBricks = setColorsDictionary ();
		/**
		 * nalezeni jednotlivych panelu
		 */
		editorUIPanel = GameObject.Find ("EditorUIPanel");
		menuPanel = GameObject.Find ("MenuPanel");
		informationPanel = GameObject.Find ("InformationPanel");
		printTutorialPanel = GameObject.Find ("PrintTutorialPanel");
		/**
		 * nalezeni casti jednotlivych panelu
		 */
		menuAvatarNameText = GameObject.Find ("MenuAvatarNameText").GetComponent<Text> ();
		screensNumberText = GameObject.Find ("ScreensNumberText").GetComponent<Text> ();
		tutorialText = GameObject.Find ("TutorialText").GetComponent<Text> ();
		menuAvatarImg = GameObject.Find ("MenuAvatarRawImage").GetComponent<RawImage> ();
		/**
		 * nastaveni log panelu do staticke tridy
		 */
		modelSaveLoadScriptInstance.setEditorLogLabelPanel (editorLogLabelPanel);
		modelSaveLoadScriptInstance.setEditorLogLabelText (editorLogLabelText);
		/**
		 * nastaveni viditelnosti panelu
		 */
		menuPanel.SetActive (false);
		informationPanel.SetActive (false);
		editorLogLabelPanel.SetActive (false);
		printTutorialPanel.SetActive (false);
	}
	/**
	 * funkce pro nastaveni pole borev na klic -- pro navod
	 */
	private Dictionary<string, string> setColorsDictionary(){
		Dictionary<string, string> d = new Dictionary<string, string>();
		d.Add ("BlackColor", "černá");
		d.Add ("GreyColor", "šedá");
		d.Add ("WhiteColor", "bílá");
		d.Add ("BeigeColor", "béžová");
		d.Add ("BrownColor", "hnědá");
		d.Add ("BordeauxColor", "vínová");
		d.Add ("RedColor", "červená");
		d.Add ("YellowColor", "žlutá");
		d.Add ("GreenColor", "zelená");
		d.Add ("BlueColor", "modrá");
		d.Add ("WhiteGlassColor", "průhledná bílá");
		d.Add ("CyanGlassColor", "průhledná tyrkysová");
		d.Add ("RedGlassColor", "průhledná červená");
		d.Add ("GreenGlassColor", "průhledná zelená");
		d.Add ("BlueGlassColor", "průhledná modrá");
		return d;
	}
	/**
	 * funkce pro ulozeni dat volana pri stisku tlacitka Ulozit model
	 */
	public void saveDataToTxtFile(){
		modelSaveLoadScriptInstance.saveData ();
		setLogLabel ("Model je uložen na adrese: " + Application.persistentDataPath + "/TxtModels");
	}
	/**
	 * funkce pro postaveni nacteneho modelu
	 */
	private void buildLoadedModel(){
		for (int i = 0; i < loadedList.Count; i++) {
			//Debug.Log ("." + loadedList [i] + ".");
			setBricksVariables (loadedList [i].Split (new char []{ '#' }, 4));
			createBrick ();
		}
		setLogLabel ("Model je kompletně načten.");
	}
	/**
	 * funkce pro vytvoreni kosticky dle nastavenych parametru
	 * 	- dle cele adresy nalezne objekt pro instanciaci
	 * 	- zvetsi velikost a nastavi material
	 * 	- otoceni kosticky
	 * 	- pridani do datove struktury Octree
	 */
	private void createBrick(){
		brick = (GameObject) Instantiate (Resources.Load (pathToBricksPrefab), bricksPosition, bricksRotation, rootBrick.transform);
		brick.transform.localScale = new Vector3 (99.99f, 99.99f, 99.99f);
		setBricksMaterial ();
		if ((brick.transform.localEulerAngles.y == 90.0f) || (brick.transform.localEulerAngles.y == -90.0f) || (brick.transform.localEulerAngles.y == 270.0f) || (brick.transform.localEulerAngles.y == -270.0f)) {
			if (nameOfBrick.Contains ("Lower")) {
				bricksBounds = new Bounds (brick.transform.position, new Vector3 (zScale * 0.799f, 0.32f, xScale * 0.799f));
			} else {
				bricksBounds = new Bounds (brick.transform.position, new Vector3 (zScale * 0.799f, 0.99f, xScale * 0.799f));
			}
		} else {
			if (nameOfBrick.Contains ("Lower")) {
			bricksBounds = new Bounds (brick.transform.position, new Vector3 (xScale * 0.799f, 0.32f, zScale * 0.799f));
			} else {
				bricksBounds = new Bounds (brick.transform.position, new Vector3 (xScale * 0.799f, 0.99f, zScale * 0.799f));
			}
		}
		if (myOctree.intersectsWithRoot (bricksBounds) && myOctree.addBrickToOctree (brick, bricksBounds)) {
			InnerStoringScript.addBoundsToList (bricksBounds);
			InnerStoringScript.addBrickToList (brick);

			setLogLabel ("Kostička byla správně přidána.");
		} else {
			Destroy (brick);
			bricksBounds = new Bounds ();

			setLogLabel ("Kostička nepřidána! Protínala se s jinou.");
		}
	}
	/**
	 * funkce pro nastaveni materialu kosticce
	 */
	private void setBricksMaterial(){
		Transform[] children = brick.GetComponentsInChildren<Transform>();
		for (int i = 1; i < children.Length; i++) {
			children [i].gameObject.GetComponent<MeshRenderer> ().material = bricksMaterial;
		}
	}
	/**
	 * funkce pro nastaveni promennych pro kosticku
	 * 	- zpetne ziskani pozice, natoce, materialu a jmena kosticky z ulozenych dat v souboru
	 */
	private void setBricksVariables(string[] parts){
		pathToBricksPrefab = getPathToBricksPrefab (parts[0]);
		bricksPosition = getVector3FromString (parts [1]);
		bricksRotation = getQuaternionFromString (parts [2]);
		bricksMaterial = Resources.Load ("Models/Materials/" + parts [3].Substring (0, parts [3].Length - 11)) as Material;
	}
	/**
	 * funkce pro ziskani kompletni cesty k danemu objektu pro instanciaci
	 */
	private string getPathToBricksPrefab(string s){
		nameOfBrick = s.Split(new char[]{'('}, 2)[0];						// z Brick_1x1(Clone) udelam Brick_1x1 a Clone) a prvni ulozim
		string[] parts = s.Split (new char[]{ '_' }, 2);					// dostanu z Brick_1x1(CLone)	... Brick a 1x1(Clone)
		string[] partsOfSecondPart = parts[1].Split(new char[]{'x'}, 2);	// dostanu z 1x1(Clone)			... 1 a 1(Clone)
		partsOfSecondPart [1] = partsOfSecondPart [1].Substring (0, partsOfSecondPart [1].IndexOf ("("));	// z 1(Clone) udela ... 1
		string directoriesName = "Models/" + parts[0] + "s_" + partsOfSecondPart[1];	// z Brick , s_ a posledniho znaku 1x1 udelam Bricks_1
		setCleats(int.Parse (partsOfSecondPart [0]), int.Parse (partsOfSecondPart [1]));
		xScale = float.Parse (partsOfSecondPart [0]);
		zScale = float.Parse (partsOfSecondPart [1]);
		return directoriesName + "/BrickPrefabs/" + s.Substring (0, s.IndexOf ("("));	// vrati kompletni cestu pro instanciovani Models/Bricks_1/BrickPrefabs/Brick_1x1
	}
	/**
	 * funkce pro nastaveni, zda jsou kosticky v nekterem smeru liche
	 */
	private void setCleats(int xAxis, int zAxis){
		if ((xAxis % 2) != 0) {
			InnerStoringScript.setOddCountOfCleatsXAxis (true);
		} else {
			InnerStoringScript.setOddCountOfCleatsXAxis (false);
		}
		if ((zAxis % 2) != 0) {
			InnerStoringScript.setOddCountOfCleatsZAxis (true);
		} else {
			InnerStoringScript.setOddCountOfCleatsZAxis (false);
		}
	}
	/**
	 * funkce pro ziskani Vector3 ze stringu
	 */
	private Vector3 getVector3FromString(string s){
		s = s.Substring (1, s.Length - 2);					// orizne zavorky ... (0.0, 0.0, 0.0) na 0.0, 0.0, 0.0
		string[] splittedS = s.Split(new char[]{','}, 3);
		for (int i = 1; i < splittedS.Length; i++) {		// ze vsech krome prvniho
			splittedS [i] = splittedS [i].Substring (1);	// z kazdeho odebere prvni znak (vezme od druheho dal)
		}
		return new Vector3 (float.Parse (splittedS [0]), float.Parse (splittedS [1]), float.Parse (splittedS [2]));
	}
	/**
	 * funkce pro ziskani Quaternion ze stringu
	 */
	private Quaternion getQuaternionFromString(string s){
		s = s.Substring (1, s.Length - 2);					// orizne zavorky ... (0.0, 0.0, 0.0, 0.0) na 0.0, 0.0, 0.0, 0.0
		string[] splittedS = s.Split(new char[]{','}, 4);
		for (int i = 1; i < splittedS.Length; i++) {		// ze vsech krome prvniho
			splittedS [i] = splittedS [i].Substring (1);	// z kazdeho odebere prvni znak (vezme od druheho dal)
		}
		return new Quaternion (float.Parse (splittedS [0]), float.Parse (splittedS [1]), float.Parse (splittedS [2]), float.Parse (splittedS [3]));
	}
	/**
	 * funkce pro zapnuti menu - stisk menu tlacitka
	 */
	public void showHideMenuAndPauseGame(){
		editorUIPanel.SetActive (!editorUIPanel.activeSelf);
		menuPanel.SetActive (!menuPanel.activeSelf);
		menuAvatarNameText.text = ConfigFile.getAvatarsName ();
		Texture2D avatarTexture = new Texture2D (280, 320);
		byte[] dataFromFile;
		if (File.Exists(Application.persistentDataPath + "/avatarImg.png")){
			dataFromFile = File.ReadAllBytes(Application.persistentDataPath + "/avatarImg.png");
			avatarTexture.LoadImage(dataFromFile);
		}
		menuAvatarImg.texture = avatarTexture;
		if (Time.timeScale == 1) {
			Time.timeScale = 0;
		} else {
			Time.timeScale = 1;
		}
	}
	/**
	 * funkce pro zapnuti napovedy
	 */
	public void showHideHelpAndPauseGame(){
		editorUIPanel.SetActive (!editorUIPanel.activeSelf);
		informationPanel.SetActive (!informationPanel.activeSelf);
		if (Time.timeScale == 1) {
			Time.timeScale = 0;
		} else {
			Time.timeScale = 1;
		}
	}
	/**
	 * ****************************************************************************************************************************************************
	 * FUNKCE CISTE JEN PRO TISK NAVODU
	 * ****************************************************************************************************************************************************
	 */
	/**
	 * funkce volana pri stisknu tlacitka Vytisknout navod
	 */
	public void printTheTutorial(){
		StartCoroutine(printTutorial());
	}
	/**
	 * funkce pro vykresleni navodu
	 * 	- nastavi viditelnosti panelu
	 * 	- zjisti vsechny kosticky v dane scene, pokud je jen nadrazena kostka modelu, vypise, ze nema smysl tisknout navod
	 * 	- jinak provede tisk navodu
	 * 		- zneviditelni vsechny kosticky
	 * 		- promitne 4, ulozi snimky z kamer do prislusnych mist panelu a cely snimek panelu ve formatu PNG na prislusnou adresu
	 * 		- kosticky zpruhledni a zobrazi dalsi 4
	 * 		- takto postupuje, dokud nejsou prosle vsechny kosticky
	 */
	private IEnumerator printTutorial(){
		string bName, bMatName;
		string textToTutorial = "Vkládané kostičky jsou: \n";
		List<GameObject> bricks = InnerStoringScript.getAllBricksInModel();
		screensNumber = 1;
		if (bricks.Count > 1) {
			setPanelVisibilityForPrinting ();
			bricks = deactivateAllBricksBeforePrinting (bricks);			
			for (int i = 0, j = 0, k = 0; i < bricks.Count; i++, j++) {
				bricks[i].SetActive (true);
				if (i != 0) {
					bName = bricks [i].name.Split(new char[]{'_'}, 2)[1];
					bName = bName.Substring (0, bName.Length - 7);
					bMatName = bricks [i].GetComponentsInChildren<Transform> () [1].gameObject.GetComponent<MeshRenderer> ().material.name;
					bMatName = bMatName.Substring (0, bMatName.Length - 11);
					textToTutorial = textToTutorial + "Kostička: " + bName + " , barva: " + colorsOfBricks[bMatName] + ".\n";
				}
				if ((j != 4) && (i != (bricks.Count - 1))) {
					continue;
				} else {
					tutorialText.text = textToTutorial;
					screensNumberText.text = screensNumber.ToString ();
					yield return StartCoroutine(getOneShot(i));
					changeMaterialOfFourBricks (bricks, 1 + (k * 4), 4);
					screensNumber++;
					k++;
					j = 0;
					textToTutorial = "Vkládané kostičky jsou: \n";
				}
			}
			bricks = changeBricksBackAfterPrinting (bricks);
			setPanelVisibilityAfterPrinting ();
		} else {
			setLogLabel ("Model neobsahuje žádnou kostičku, návod tedy není potřeba.");
			yield return 0;
		}
	}
	/**
	 * funkce pro nastaveni viditelnosti panelu pred tiskem navodu
	 */
	private void setPanelVisibilityForPrinting(){
		printTutorialPanel.SetActive(true);
		menuPanel.SetActive (false);
	}
	/**
	 * funkce pro nastaveni viditelnosti panelu po tisku navodu
	 */
	private void setPanelVisibilityAfterPrinting(){
		printTutorialPanel.SetActive(false);
		menuPanel.SetActive (true);
		setLogLabel ("Návod vytištěn a uložen v galerii zařízení.");
	}
	/**
	 * funkce nastavi vsechny kosticky na neviditelne
	 */
	private List<GameObject> deactivateAllBricksBeforePrinting(List<GameObject> bricks){
		for (int i = 1; i < bricks.Count; i++) {
			bricks[i].SetActive (false);
		}
		return bricks;
	}
	/**
	 * funkce pro ziskani snimku navodu
	 */
	private IEnumerator getOneShot(int i){
		if (i != 0) {
			StartCoroutine (getScreenShot ());
		}
		yield return null;
	}
	/**
	 * funkce pro zmenu materialu X kosticek na transparent
	 */
	private void changeMaterialOfFourBricks(List<GameObject> bricks, int startingIndex, int countOfElements){
		for (int i = startingIndex, j = 1; i < bricks.Count; i++, j++) {
			if (j <= countOfElements) {
				if (bricks [i].GetComponentsInChildren<Transform> () [1].gameObject.GetComponent<MeshRenderer> ().material.name.Contains ("Glass")) {
					changeColorOfTransparentMaterialForPrinting (bricks [i]);	// uz je transparent, staci zmeni barvu
				} else {	// neni transparent, je opaque - nutno zmenit vlastnosti materialu
					changeBrickMaterialForPrinting (bricks [i]);
				}
			} else {
				break;
			}
		}
	}
	/**
	 * funkce nalezne vsechny potomky dane cihlicky a nastavi jejich material na novy (transparent) rendering mode
	 */
	private void changeBrickMaterialForPrinting(GameObject brickToChange){
		Transform[] allChildrenOfBrickToChange = brickToChange.GetComponentsInChildren<Transform>();
		for (int i = 1; i < allChildrenOfBrickToChange.Length; i++) {
			allChildrenOfBrickToChange [i].gameObject.GetComponent<MeshRenderer> ().material = 
				changeMaterialToTransparent (allChildrenOfBrickToChange [i].gameObject.GetComponent<MeshRenderer> ().material);
		}
	}
	/**
	 * funkce projde list kosticek a kazde zmeni material zpet na puvodni
	 */
	private List<GameObject> changeBricksBackAfterPrinting(List<GameObject> bricks){
		for (int i = 1; i < bricks.Count; i++) {
			if (bricks [i].GetComponentsInChildren<Transform>()[1].gameObject.GetComponent<MeshRenderer> ().material.name.Contains ("Glass")) {
				changeColorOfTransparentMaterialBackAfterPrinting (bricks [i]);
			} else {
				changeBrickMaterialAfterPrinting (bricks [i]);
			}
		}
		return bricks;
	}
	/**
	 * funkce nalezne vsechny potomky dane cihlicky a nastavi jejich material na puvodni (opaque) rendering mode
	 */
	private void changeBrickMaterialAfterPrinting(GameObject brickToChange){
		Transform[] allChildrenOfBrickToChange = brickToChange.GetComponentsInChildren<Transform>();
		for (int i = 1; i < allChildrenOfBrickToChange.Length; i++) {
			allChildrenOfBrickToChange [i].gameObject.GetComponent<MeshRenderer> ().material = 
				changeMaterialToOpaque (allChildrenOfBrickToChange [i].gameObject.GetComponent<MeshRenderer> ().material);
		}
	}
	/**
	 * funkce pro zmenu barvy, kdyz je material od pocatku transparent pred tiskem
	 */
	private void changeColorOfTransparentMaterialForPrinting(GameObject brickForColorsMatChange){
		Transform[] childrenOfBrickForColorsMatChange = brickForColorsMatChange.GetComponentsInChildren<Transform>();
		Color c = childrenOfBrickForColorsMatChange[1].GetComponent<MeshRenderer>().material.color;
		for (int i = 1; i < childrenOfBrickForColorsMatChange.Length; i++) {
			childrenOfBrickForColorsMatChange [i].GetComponent<MeshRenderer> ().material.color = new Color (c.r, c.g, c.b, 0.25f); // 0.25f
		}
	}
	/**
	 * funkce pro zmenu barvy, kdyz je material od pocatku transparent zpet na puvodni
	 */
	private void changeColorOfTransparentMaterialBackAfterPrinting(GameObject brickForColorsMatChange){
		Transform[] childrenOfBrickForColorsMatChange = brickForColorsMatChange.GetComponentsInChildren<Transform>();
		Color c = childrenOfBrickForColorsMatChange[1].GetComponent<MeshRenderer>().material.color;
		for (int i = 1; i < childrenOfBrickForColorsMatChange.Length; i++) {
			childrenOfBrickForColorsMatChange [i].GetComponent<MeshRenderer> ().material.color = new Color (c.r, c.g, c.b, 0.49609f);
		}
	}
	/**
	 * funkce pro zmenu rendering modu na transparent
	 */
	private Material changeMaterialToTransparent(Material material){
		material.SetFloat("_Mode", 3);
		material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
		material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
		material.SetInt("_ZWrite", 0);
		material.DisableKeyword("_ALPHATEST_ON");
		material.DisableKeyword("_ALPHABLEND_ON");
		material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
		material.renderQueue = 3000;
		material.color = new Color (material.color.r, material.color.g, material.color.b, 0.2f);	// 0.2f
		return material;
	}
	/**
	 * funkce pro zmenu rendering modu na opaque
	 */
	private Material changeMaterialToOpaque(Material material){
		material.SetFloat("_Mode", 0);
		material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
		material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
		material.SetInt("_ZWrite", 1);
		material.DisableKeyword("_ALPHATEST_ON");
		material.DisableKeyword("_ALPHABLEND_ON");
		material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
		material.renderQueue = -1;
		material.color = new Color (material.color.r, material.color.g, material.color.b, 1.0f);
		return material;
	}
	/**
	 * funkce pro sejmuti screenshotu a ulozeni na adresu
	 * 	-	data/com.DefaultCompany.LittleBuilder/files/TutorialsImages/jmenoSouboru/jmenoSnimku
	 */
	private IEnumerator getScreenShot(){
		yield return new WaitForEndOfFrame();
		Texture2D texture = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false);
		texture.ReadPixels (new Rect (0, 0, Screen.width, Screen.height), 0, 0);
		texture.Apply ();
		//yield return null;
		string pathToSavePngScreenShot = createPathToSaveScreenShots ();
		File.WriteAllBytes (pathToSavePngScreenShot + "/image_" + screensNumber + ".png", texture.EncodeToPNG());
	}
	/**
	 * funkce pro slozeni adresy, kam se ulozi snimky
	 */
	private string createPathToSaveScreenShots(){
		string filesName = modelSaveLoadScriptInstance.getFileName ().Substring (0, modelSaveLoadScriptInstance.getFileName ().Length - 4);
		if (!Directory.Exists (Application.persistentDataPath + "/TutorialsImages/" + filesName)) {
			Directory.CreateDirectory (Application.persistentDataPath + "/TutorialsImages/" + filesName);
		}
		return Application.persistentDataPath + "/TutorialsImages/" + filesName;
	}
	/**
	 * ****************************************************************************************************************************************************
	 * FUNKCE CISTE JEN PRO TISK NAVODU - konec
	 * ****************************************************************************************************************************************************
	 */
	/**
	 * funkce pro navrat do hlavniho menu
	 */
	public void goToMainMenuScene(){
		Time.timeScale = 1;
		if (InnerStoringScript.getAllBricksInModel ().Count <= 1) {
			setLogLabel ("Načítám hlavní menu.");
			SceneManager.LoadScene ("MainMenuScene");
		} else {
			if (modelSaveLoadScriptInstance.saveData ()) {
				if (myOctree.cleanTree (InnerStoringScript.getAllBricksInModel (), InnerStoringScript.getAllBricksBounds ())) {
					InnerStoringScript.setAllBricksInModelOnNew ();
					InnerStoringScript.setAllBricksBoundsOnNew ();
					setLogLabel ("Model uložen! Načítám hlavní menu.");
					SceneManager.LoadScene ("MainMenuScene");
				}
			}
		}
	}
	/**
	 * funkce pro nastaveni log label panelu
	 */
	private void setLogLabel(string t){
		editorLogLabelPanel.SetActive(true);
		editorLogLabelText.text = t;
		StartCoroutine (hideLogLabelPanel ());
	}
	/**
	 * funkce, ktera po 2 vterinach schova editorLogLabelPanel
	 */
	private IEnumerator hideLogLabelPanel(){
		yield return new WaitForSecondsRealtime (2);
		editorLogLabelText.text = "";
		editorLogLabelPanel.SetActive (false);
	}
}