Skip to content
Snippets Groups Projects
ScrollDetails.cs 12.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System.Collections;
    using System.Collections.Generic;
    
    using UnityEngine;
    
    using TMPro;
    
    using UnityEngine.Networking;
    
    using Newtonsoft.Json;
    
    using static CommunicationEvents;
    
    using System.Linq;
    using static SOMDocManager;
    
    
    public class ScrollDetails : MonoBehaviour
    {
    
    Richard Marcus's avatar
    Richard Marcus committed
        public WorldCursor cursor;
    
        public GameObject parameterDisplayPrefab;
    
        public Scroll ActiveScroll;
    
        public GameObject mmtAnswerPopUp;
    
    Richard Marcus's avatar
    Richard Marcus committed
        public static List<GameObject> ParameterDisplays;
    
        private static List<Scroll.ScrollAssignment> LatestCompletions;
    
        private static List<Fact> LatestRenderedHints;
    
        public bool dynamicScrollDescriptionsActive = true;
        public bool automaticHintGenerationActive = true;
    
    
        // Start is called before the first frame update
        void Start()
        {
    
            cursor ??= GameObject.FindObjectOfType<WorldCursor>();
            
            mmtAnswerPopUp.GetComponent<PopupBehavior>().hidePopUp();
        }
    
    Richard Marcus's avatar
    Richard Marcus committed
    
    
        private void OnEnable()
        {
    
            ScrollFactHintEvent.AddListener(animateHint);
    
            NewAssignmentEvent.AddListener(newAssignmentTrigger);
    
            RemoveFactEvent.AddListener(removeFactFromAssignment);
    
        private void OnDisable()
        {
            ScrollFactHintEvent.RemoveListener(animateHint);
            NewAssignmentEvent.RemoveListener(newAssignmentTrigger);
            RemoveFactEvent.RemoveListener(removeFactFromAssignment);
    
    BenniHome's avatar
    BenniHome committed
        public void setScroll(Scroll s)
        {
    
            Transform originalScroll = gameObject.transform.GetChild(1).transform;
            Transform originalScrollView = originalScroll.GetChild(1);
            Transform originalViewport = originalScrollView.GetChild(0);
    
            this.ActiveScroll = s;
    
            originalScroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = s.description;
    
    
            //Clear all current ScrollFacts
    
            originalViewport.GetChild(0).gameObject.DestroyAllChildren();
    
    Richard Marcus's avatar
    Richard Marcus committed
            ParameterDisplays = new List<GameObject>();
            for (int i = 0; i < s.requiredFacts.Count; i++)
    
    BenniHome's avatar
    BenniHome committed
            {
    
                var originalObj = Instantiate(parameterDisplayPrefab, Vector3.zero, Quaternion.identity, transform);
                var originalScrollFact = originalObj.transform.GetChild(0).GetComponent<RenderedScrollFact>();
                originalScrollFact.ID = i;
                originalScrollFact.Label = s.requiredFacts[i].label;
    
                originalScrollFact.factUri = s.requiredFacts[i].@ref.uri;
    
    
                originalObj.transform.SetParent(originalViewport.GetChild(0));
    
                ParameterDisplays.Add(originalObj);
    
    
            //set active scroll for ErrorMessagePopup
            PopupBehavior popup = mmtAnswerPopUp.GetComponent<PopupBehavior>();
            popup.setScroll(this.ActiveScroll);
            popup.setParameterDisplays(ParameterDisplays);
    
        public void magicButtonTrigger()
        {
    
            StartCoroutine(magicButton());
    
    
            IEnumerator magicButton()
    
    BenniHome's avatar
    BenniHome committed
            {
    
                //Non blocking wait till sendView() is finished
                yield return sendView("/scroll/apply");
                if (currentMmtAnswer == null)
                {
                    Debug.Log("DAS HAT NICHT GEKLAPPT");
                    PushoutFactFailEvent.Invoke(null, null);
                }
                else
                {
                    Debug.Log(currentMmtAnswer);
                    Scroll.ScrollApplicationInfo pushout = JsonConvert.DeserializeObject<Scroll.ScrollApplicationInfo>(currentMmtAnswer);
                    if (pushout.acquiredFacts.Count == 0)
                        PushoutFactFailEvent.Invoke(null, pushout);
                    readPushout(pushout.acquiredFacts);
                }
    
    John Schihada's avatar
    John Schihada committed
    
    
        public void newAssignmentTrigger()
    
            if (this.automaticHintGenerationActive || this.dynamicScrollDescriptionsActive)
                StartCoroutine(newAssignment());
    
            IEnumerator newAssignment()
    
                //Non blocking wait till sendView() is finished
                yield return sendView("/scroll/dynamic");
    
                if (currentMmtAnswer == null)
                {
                    Debug.Log("DAS HAT NICHT GEKLAPPT");
                }
                else
                {
                    // Todo delte maybe
                    Debug.Log("Current mmt answer:  " + currentMmtAnswer);
                    Scroll.ScrollDynamicInfo scrollDynamicInfo = JsonConvert.DeserializeObject<Scroll.ScrollDynamicInfo>(currentMmtAnswer);
                    processScrollDynamicInfo(scrollDynamicInfo);
                }
    
    BenniHome's avatar
    BenniHome committed
        {
    
            string body = prepareScrollAssignments();
    
            System.DateTime startTime = System.DateTime.UtcNow;
    
    BenniHome's avatar
    BenniHome committed
    
    
            using UnityWebRequest www = UnityWebRequest.Put(ServerAdress + endpoint, body);
    
    BenniHome's avatar
    BenniHome committed
            www.method = UnityWebRequest.kHttpVerbPOST;
    
            www.SetRequestHeader("Content-Type", "application/json");
    
            yield return www.SendWebRequest();
    
            System.DateTime twoTime = System.DateTime.UtcNow;
    
    BenniHome's avatar
    BenniHome committed
    
    
            if (www.result == UnityWebRequest.Result.ConnectionError
    
             || www.result == UnityWebRequest.Result.ProtocolError)
    
    BenniHome's avatar
    BenniHome committed
            {
                Debug.Log(www.error);
    
    Benjamin Bösl's avatar
    Benjamin Bösl committed
            }
    
                string answer = www.downloadHandler.text;
    
            System.DateTime endTime = System.DateTime.UtcNow;
    
    
            string diffInSeconds = (endTime - startTime).TotalMilliseconds.ToString();
    
            string diff = (twoTime - startTime).TotalMilliseconds.ToString();
    
    Benjamin Bösl's avatar
    Benjamin Bösl committed
        }
    
        private string prepareScrollAssignments()
        {
    
            List<Scroll.ScrollAssignment> assignmentList = new();
    
    
            for (int i = 0; i < ParameterDisplays.Count; i++)
            {
    
                Fact tempFact = ParameterDisplays[i].GetComponentInChildren<DropHandling>().currentFact;
    
                    assignmentList.Add(new Scroll.ScrollAssignment(ActiveScroll.requiredFacts[i].@ref.uri, tempFact.Id));
    
            return JsonConvert.SerializeObject(new Scroll.FilledScroll(ActiveScroll.@ref, assignmentList));
    
        private void readPushout(List<MMTDeclaration> pushoutFacts)
    
            mmtAnswerPopUp.GetComponent<PopupBehavior>().hidePopUp(); //close error Window
    
    
            bool samestep = false;
            for (int i = 0; i < pushoutFacts.Count; i++, samestep = true)
    
            {
                Fact newFact = ParsingDictionary.parseFactDictionary[pushoutFacts[i].getType()].Invoke(pushoutFacts[i]);
    
                if (newFact != null)
    
                    PushoutFactEvent.Invoke(FactManager.AddFactIfNotFound(newFact, out _, samestep, null, ActiveScroll.label), FactObject.FactMaterials.Solution);
    
                    Debug.Log("Parsing on pushout-fact returned null -> One of the dependent facts does not exist");
    
        public void processScrollDynamicInfo(Scroll.ScrollDynamicInfo scrollDynamicInfo)
        {
            LatestCompletions = scrollDynamicInfo.completions.Count > 0 
                ? scrollDynamicInfo.completions[0] 
                : new List<Scroll.ScrollAssignment>();
    
            List<string> hintUris = LatestCompletions.Select(completion => completion.fact.uri).ToList();
    
            //Update Scroll, process data for later hints and update Uri-List for which hints are available
            hintUris = processRenderedScroll(scrollDynamicInfo.rendered, hintUris);
    
            if (automaticHintGenerationActive)
    
                //Show that Hint is available for ScrollParameter
                HintAvailableEvent.Invoke(hintUris);
    
        public List<string> processRenderedScroll(Scroll rendered, List<string> hintUris)
    
        {
            Transform scroll = gameObject.transform.GetChild(1).transform;
    
    
            if (this.dynamicScrollDescriptionsActive)
                //Update scroll-description
                scroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = rendered.description;
    
            LatestRenderedHints = new List<Fact>();
    
            for (int i = 0; i < rendered.requiredFacts.Count; i++)
            {
    
                GameObject obj = ParameterDisplays.Find(x => x.transform.GetChild(0).GetComponent<RenderedScrollFact>().factUri.Equals(rendered.requiredFacts[i].@ref.uri));
    
    
                if (this.dynamicScrollDescriptionsActive)
                {
                    //Update ScrollParameter label
                    obj.transform.GetChild(0).GetComponent<RenderedScrollFact>().Label = rendered.requiredFacts[i].label;
                }
    
    
                //Check Hint Informations
                //If ScrollFact is assigned -> No Hint
    
                if (obj.transform.GetChild(0).GetComponent<DropHandling>().currentFact == null)
                {
    
                    //  Debug.Log(" print out " + rendered.requiredFacts[i].getType());
    
                    Fact currentFact = ParsingDictionary.parseFactDictionary[rendered.requiredFacts[i].getType()].Invoke(rendered.requiredFacts[i]);
    
                    //If currentFact could be parsed: this fact maybe not yet exists in the global fact-list but there must be a fact
                    // of the same type and the same dependent facts in the fact-list, otherwise currentFact could not have been parsed
    
    
                    //If the fact could not be parsed -> Therefore not all dependent Facts exist -> No Hint
                    //AND if fact has no dependent facts -> No Hint
    
                    if (currentFact != null && currentFact.HasDependentFacts)
    
                    {
                        //Hint available for abstract-problem uri
    
                        LatestRenderedHints.Add(currentFact);
                    }
                }
    
        public void animateHint(GameObject scrollParameter, string scrollParameterUri)
        {
            Scroll.ScrollAssignment suitableCompletion = LatestCompletions.Find(x => x.fact.uri.Equals(scrollParameterUri));
    
            if (suitableCompletion != null)
            {
    
                if (StageStatic.stage.factState.ContainsKey(suitableCompletion.assignment.uri))
    
                    fact = FactOrganizer.AllFacts[suitableCompletion.assignment.uri];
    
    John Schihada's avatar
    John Schihada committed
                    scrollParameter.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
    
                    //Animate Fact in FactPanel
    
                    AnimateExistingFactEvent.Invoke(fact, FactObject.FactMaterials.Hint);
    
            else if (LatestRenderedHints.Exists(x => x.Id.Equals(scrollParameterUri)))
    
                fact = LatestRenderedHints.Find(x => x.Id.Equals(scrollParameterUri));
                var factId = fact.Id;
    
    
                //If there is an equal existing fact -> Animate that fact AND ScrollParameter
    
                if (StageStatic.stage.factState.ContainsKey(factId))
    
                    Fact existingFact = FactOrganizer.AllFacts[factId];
    
    
                    //Animate ScrollParameter
    
    John Schihada's avatar
    John Schihada committed
                    scrollParameter.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
    
                    //Animate Fact in FactPanel
    
                    AnimateExistingFactEvent.Invoke(existingFact, FactObject.FactMaterials.Hint);
    
                }
                //If not -> Generate a Fact-Representation with such dependent facts
                else
                {
                    //Animate ScrollParameter
    
    John Schihada's avatar
    John Schihada committed
                    scrollParameter.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
    
                    //Generate new FactRepresentation and animate it
                    AnimateNonExistingFactEvent.Invoke(fact);
                }
            }
    
        //this is called whenever a Fact is Deleted in the world, to make sure it is removed from the scroll
        public void removeFactFromAssignment(Fact fact)
    
            Transform originalScroll = gameObject.transform.GetChild(1).transform;
            Transform originalScrollView = originalScroll.GetChild(1);
            Transform originalViewport = originalScrollView.GetChild(0);
    
            for (int i = 0; i < originalViewport.GetChild(0).childCount; i++)
            {
                RenderedScrollFact scrollFact = originalViewport.GetChild(0).transform.GetChild(i).GetChild(0).gameObject.GetComponent<RenderedScrollFact>();
                if (scrollFact.Label == fact.Label)
                {
                    DropHandling dropHandling = originalViewport.GetChild(0).transform.GetChild(i).GetChild(0).gameObject.GetComponent<DropHandling>();
                    dropHandling.OnPointerClick(null);
                }
            }