using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.UI; using System.Linq; using static SOMDocManager; using static Scroll; public class PopupBehavior : MonoBehaviour { [SerializeField] GameObject canvas; [SerializeField] Button CloseButton; [SerializeField] TMP_Text message; public string MessageText { get => message.text; set => message.text = value; } public Scroll ActiveScroll { private get; set; } public List<RenderedScrollFact> ParameterDisplays { private get; set; } public string ServerErrorMessage = "unknown server error"; public string NonTotalMessage = "Scroll application not complete"; public string UnknownErrorMessage = "Unkown error - did you apply all facts?"; public string InvalidAssignmentMessage = "Invalid Assignment"; private string errorMessage; #region UnityMethods void Awake() { CommunicationEvents.ScrollApplicationCheckingErrorEvent.AddListener(OnFailedScrollInput); CloseButton.onClick.RemoveAllListeners(); CloseButton.onClick.AddListener(HidePopUp); HidePopUp(); } #endregion UnityMethods public void ShowTimedPopUp() { canvas.SetActive(true); StartCoroutine(_BlossomAndDie()); IEnumerator _BlossomAndDie() { yield return new WaitForSeconds(GlobalBehaviour.HintAnimationDuration); HidePopUp(); } } public void HidePopUp() => canvas.SetActive(false); /// <summary> /// this method creates a helpful error message and shows the popup. For it to work properly, the setScroll and setParameterDisplays must have been set. /// </summary> /// <param name="startfact"></param> /// <param name="errorInfo"></param> public void OnFailedScrollInput(ScrollApplicationCheckingError[] errorInfo) { MessageText = generateHelpfulMessageAndAnimateScrollParam(errorInfo); ShowTimedPopUp(); } private string generateHelpfulMessageAndAnimateScrollParam(ScrollApplicationCheckingError[] errorInfo) { if (errorInfo == null) return ServerErrorMessage; int invAssCount = 0; errorMessage = ""; for (int i = 0; i < errorInfo.Length; i++) { ScrollApplicationCheckingError error = errorInfo[i]; //check which error ocurred and set Message to a helpful error message. if (error.kind == "nonTotal") { errorMessage += NonTotalMessage; errorMessage += '\n'; } else if (error.kind == "invalidAssignment") { invAssCount++; MMTDeclaration fact = parseFactFromError(error); //animate all invalidly assigned facts if (ParameterDisplays != null && fact != null) { foreach (RenderedScrollFact scrollfact in ParameterDisplays) if (scrollfact.ScrollFactURI == fact.@ref.uri) scrollfact.HighlightAs(FactWrapper.FactMaterials.Hint); } else { Debug.Log("PopupBehavior: Error: scroll or parameterDisplays not set."); } } else if (error.kind == "unknown") { errorMessage += UnknownErrorMessage; errorMessage += '\n'; } } //invalid assignment message if (invAssCount > 0) { errorMessage += invAssCount.ToString() + " " + InvalidAssignmentMessage; if (invAssCount > 1) //plural for invalid assignments { errorMessage += 's'; } errorMessage += '\n'; } return errorMessage; } //this should be changed, the Fact Object should be parsed by JSON. This is a workaround because the MMT servers JSON serialization contains a bug private MMTDeclaration parseFactFromError(ScrollApplicationCheckingError error) { if (error == null || error.msg == null) return null; string message = error.msg; //cut start of string int indexFact = message.IndexOf('['); string factUri = message.Substring(indexFact + 1); // cut end of string int indexFactEnd = factUri.IndexOf(']'); string rest = factUri.Substring(indexFactEnd); factUri = factUri.Substring(0, indexFactEnd); //get fact Label from the rest of the string int factNameLength = rest.IndexOf('?') - 2; string factLabel = rest.Substring(2, factNameLength); //add ?factName to URI factUri += "?" + factLabel; //find the required fact in the active scroll thats invalidly assigned return ActiveScroll?.requiredFacts .Find(decl => decl.@ref.uri == (error.fact as OMS).uri); } }