/**
 * Skript pro kontrolu protnuti obalovych objektu kosticek ve scene s paprskem.
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/**
 * Author:			Karel Zavrel
 * 
 * Thesis:			An interactive application for development of creativity
 * Application:		Little Builder
 */
public class BricksSelectionScript : MonoBehaviour {
		/**
		 * promenne:
		 * 	- paprsek
		 * 	- podminka, zda je povolena funkce vyberu kosticek
		 * 	- instance Octree
		 * 	- panel pro spravu vybrane kosticky
		 * 	- vybrana kosticka
		 * 	- panel pro zpravy uzivateli
		 * 	- textove pole pro zpravy uzivateli
		 * 	- obalovy objekt vybrane kosticky
		 * 	- material
		 * 	- bod na displeji
		 * 	- tlacitko pro zapnuti ci vypnuti funkce vyberu kosticky
		 * 	- barvy tlacitka: vychozi barva, nova barva ukazujici na zapnuti funkce vyberu kosticky
		 */
		private Ray ray;
		private bool isSelectionPermitted = false;
		private MyOctree myOctree;
		private GameObject selectionPanel, brickForMaterialChange, editorLogLabelPanel;
		private Text editorLogLabelText;
		private Bounds selectedBounds;
		private Material material;
		private Vector3 screenPoint;
		private Button permitSelectionButton;
		private Color inicialColor = new Color (255.0f, 255.0f, 255.0f, 255.0f), newColor = new Color (128.0f, 128.0f, 128.0f, 255.0f);
	/**
	 * funkce uzita pro nacteni stejnych objektu napric nekolika skripty
	 * 	-	provede se jeste pred funkci Start
	 */
	void Awake(){
		editorLogLabelPanel = GameObject.Find ("EditorLogLabelPanel");
		editorLogLabelText = GameObject.Find ("EditorLogLabelText").GetComponent<Text> ();
	}
	/**
	 * funkce pro inicializaci promennych
	 */
	void Start () {
		myOctree = MyOctree.getInstance ();
		selectionPanel = GameObject.Find ("SelectionPanel");
		selectionPanel.SetActive (false);
		permitSelectionButton = GameObject.Find ("PermitSelectionButton").GetComponent<Button> ();
	}
	/**
	 * funkce volana kazdy frame
	 * 	- pokud je povolena funkce vyberu kosticky, tak provadi kontrolu na protnuti s paprskem
	 */
	void Update () {
		if (isSelectionPermitted) {
			if (!InnerStoringScript.getMovePanelClicked()) {
				checkCollisions ();
			}
		}
	}
	/**
	 * funkce pro kontrolu kolizi s paprskem
	 */
	private void checkCollisions(){
		if (Input.GetMouseButtonDown (0) || (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began)) {
			ray = Camera.main.ScreenPointToRay (Input.mousePosition);
			if (myOctree.checkCollisions (ray)) {
				selectionPanel.SetActive (true);
				// ze jmena kosticky odriznu (Clone)
				setLogLabel ("Vybrána kostička: "
					+ InnerStoringScript.getSelectedBrick().name.Substring(0, InnerStoringScript.getSelectedBrick().name.Length - 7)
					+ ".");
			} else {
				if (selectionPanel.activeSelf) {
					selectionPanel.SetActive (false);
					InnerStoringScript.setSelectedBrick (null);
					InnerStoringScript.setSelectedBrickBounds (new Bounds ());
				}
			}
		}
	}
	/**
	 * funkce pro zmenu hodnoty isSelectionPermitted a zmenu barvy daneho tlacitka
	 * 	-	zda muzeme vybirat objekty
	 */
	public void changeIsSelectionPermitted(){
		isSelectionPermitted = !isSelectionPermitted;
		if (isSelectionPermitted) {
			permitSelectionButton.image.color = new Color (0.5f, 0.5f, 0.5f, 1.0f);
		} else {
			permitSelectionButton.image.color = new Color (1.0f, 1.0f, 1.0f, 1.0f);
		}
	}
	/**
	 * funkce pro odstraneni vybrane kosticky
	 */
	public void removeSelectedBrick(){
		if (myOctree.removeBrickFromOctree (InnerStoringScript.getSelectedBrick (), InnerStoringScript.getSelectedBrickBounds ())) {
			InnerStoringScript.removeBrickFromList (InnerStoringScript.getSelectedBrick ());
			InnerStoringScript.removeBoundsFromList (InnerStoringScript.getSelectedBrickBounds ());
			Destroy (InnerStoringScript.getSelectedBrick ());
			InnerStoringScript.setSelectedBrick (null);
			InnerStoringScript.setSelectedBrickBounds (new Bounds ());
			selectionPanel.SetActive (false);
			setLogLabel ("Kostička byla odstraněna z modelu.");
		}
	}
	/**
	 * funkce pro nastaveni promenne movePanelClicked
	 */
	public void setMovePanelClicked(bool clicked){
		InnerStoringScript.setMovePanelClicked (clicked);
	}
	/**
	 * funkce pro zmenu materialu
	 * 	- pokud je vybrana kosticka, je zmenen jeji material
	 * 	- jinak je zmenen material, ktery je nastavovan vsem nove vkladanym kostickam do sceny
	 */
	private void changeMaterial(Button button){
		brickForMaterialChange = InnerStoringScript.getSelectedBrick ();
		string buttonName = button.name;
		string materialName = buttonName.Substring (0, buttonName.Length - 6);
		if (brickForMaterialChange != null) {
			changeBrickColor (materialName);
		} else {
			InnerStoringScript.setUsedMaterial (Resources.Load ("Models/Materials/" + materialName) as Material);
			setLogLabel ("Barva nově vkládaných kostiček změněna na " + InnerStoringScript.getUsedMaterial ().name + ".");
		}
	}
	/**
	 * funkce volana pri stisku nektere barvy, aby nebyla provedena kontrola na protnuti s novym paprskem a uvolneni stavajici vybrane kosticky
	 */
	public void changeMaterialPointerDown(Button button){
		InnerStoringScript.setMovePanelClicked (true);
		changeMaterial (button);
	}
	/**
	 * funkce volana pri uvolneni nektere barvy
	 */
	public void changeMaterialPointerUp(){
		InnerStoringScript.setMovePanelClicked (false);
	}
	/**
	 * funkce pro zmenu materialu
	 * 	- zmeni material vsem potomkum dane kosticky, nemeni prvni nadrazeny prvek
	 */
	private void changeBrickColor(string materialName){
		Transform[] allChildren = brickForMaterialChange.GetComponentsInChildren<Transform>();
		for (int i = 1; i < allChildren.Length; i++) {
			allChildren [i].gameObject.GetComponent<MeshRenderer> ().material = Resources.Load ("Models/Materials/" + materialName) as Material;
		}
	}
	/**
	 * 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);
	}
}