<commit_before>// <NAME>
// June 2016
//
// The MIT License (MIT)
// Copyright (c) 2016 Personal Robots Group
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using UnityEngine;
using System;
using System.Collections.Generic;
using TouchScript.Behaviors;
using System.IO;
using System.Text.RegularExpressions;

namespace opal
{
    /// <summary>
    /// The SAR-opal-base game main controller. Orchestrates everything:
    /// sets up to receive input via ROS, initializes scenes and creates
    /// game objecgs based on that input, deals with touch events and
    /// other tablet-specific things.
    /// </summary>
    public class MainGameController : MonoBehaviour
    {

        // --------------- FLAGS ---------------
        // DEMO VERSION
        private bool demo = false;

        // STORYBOOK VERSION
        private bool story = true;
        /// <summary>
        /// The pages in story.
        /// </summary>
        public int pagesInStory = 0;

        // SOCIAL STORIES VERSION
        private bool socialStories = false;
        private List<GameObject> incorrectFeedback;
        private GameObject correctFeedback;
        /// <summary>
        /// The width of the slot.
        /// </summary>
        public float slotWidth = 1;
        /// <summary>
        /// The width of the answer slot.
        /// </summary>
        public float answerSlotWidth = 1;
        /// <summary>
        /// The scenes in order.
        /// </summary>
        public bool scenesInOrder = true;
        // --------------------------------------

        // gesture manager
        private GestureManager gestureManager = null;

        // sidekick
        private Sidekick sidekickScript = null;

        // rosbridge websocket client
        private RosbridgeWebSocketClient clientSocket = null;

        // actions for main thread, because the network messages from the
        // websocket can come in on another thread
        readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();

        // for logging stuff
        /// <summary>
        /// Occurs when log event.
        /// </summary>
        public event LogEventHandler logEvent;

        // fader for fading out the screen
        private GameObject fader = null;

        // This flag indicates whether we should scale graphics based on the
        // screen height (if true) or width (if false).
        private bool scaleToHeight = false;


        // config
        private GameConfig gameConfig;

        /// <summary>
        /// Called first, use to initialize stuff
        /// </summary>
        void Awake()
        {
            if (this.demo) Logger.Log("--- RUNNING IN DEMO MODE ---");
            if (this.story) Logger.Log ("--- RUNNING IN STORYBOOK MODE ---");
            if (this.socialStories) Logger.Log("--- RUNNING IN SOCIAL STORIES MODE ---");

            string path = "";

            // Scale all camera views to match the screen size of whatever
            // device we're running on.
            this.scaleToHeight = Utilities.ScaleCameraViewToScreen();

            // find the config file
            #if UNITY_ANDROID
            path = Constants.CONFIG_PATH_ANDROID + Constants.OPAL_CONFIG;
            Logger.Log("trying android path: " + path);
            #endif

            #if UNITY_EDITOR
            path = Application.dataPath + Constants.CONFIG_PATH_OSX + Constants.OPAL_CONFIG;
            Logger.Log("trying os x path: " + path);
            #endif

            #if UNITY_STANDALONE_LINUX
            path = Application.dataPath + Constants.CONFIG_PATH_LINUX + Constants.OPAL_CONFIG;
            Logger.Log("trying linux path: " + path);
            #endif

            // read config file
            if(!Utilities.ParseConfig(path, out gameConfig)) {
                Logger.LogWarning("Could not read config file! Will try default "
                    + "values of toucan=true, server IP=192.168.1.254, port=9090, "
                    + "opal_action_topic=" + Constants.ACTION_ROSTOPIC
                    + ", opal_audio_topic=" + Constants.AUDIO_ROSTOPIC
                    + ", opal_command_topic=" + Constants.CMD_ROSTOPIC
                    + ", opal_log_topic=" + Constants.LOG_ROSTOPIC
                    + ", opal_scene_topic=" + Constants.SCENE_ROSTOPIC
                    + ".");
            }
            else {
                Logger.Log("Got game config!");
            }

            // find gesture manager
            FindGestureManager();
            this.gestureManager.logEvent += new LogEventHandler(HandleLogEvent);
            this.logEvent += new LogEventHandler(HandleLogEvent);

            // share flags with everyone else
            this.gestureManager.demo = this.demo;
            this.gestureManager.story = this.story;
            this.gestureManager.socialStories = this.socialStories;

            // find our sidekick
            if (!this.story)
            {
	            GameObject sidekick = GameObject.FindGameObjectWithTag(Constants.TAG_SIDEKICK);
	            if(sidekick == null) {
	                Logger.LogError("ERROR: Could not find sidekick!");
	            } else {
	                Logger.Log("Got sidekick");
	                if(this.gameConfig.sidekick) {
	                    // add sidekick's gestures
	                    this.gestureManager.AddAndSubscribeToGestures(sidekick, false, false);

	                    // get sidekick's script
	                    this.sidekickScript = (Sidekick)sidekick.GetComponent<Sidekick>();
	                    if(this.sidekickScript == null)
                        {
	                        Logger.LogError("ERROR: Could not get sidekick script!");
	                    } else {
	                        Logger.Log("Got sidekick script");
	                        this.sidekickScript.donePlayingEvent += new DonePlayingEventHandler(HandleDonePlayingAudioEvent);
	                    }
	                }
	                else {
	                    // we don't have a sidekick in this game, set as inactive
	                    Logger.Log("Don't need sidekick... disabling");
	                    sidekick.SetActive(false);

	                    // try to disable the sidekick's highlight as well
	                    GameObject.FindGameObjectWithTag(Constants.TAG_SIDEKICK_LIGHT).SetActive(false);
	                }
                }
            }
            // TODO if this is a story make sure we have the flip buttons.

            // set up fader
            // NOTE right now we're just using one fader that fades out all but the
            // toucan - but in the unity editor there's an unused 'fader_all' that
            // can fade out everything including the toucan, just switch this tag
            // to "TAG_FADER_ALL" to use that fader instead!
            this.fader = GameObject.FindGameObjectWithTag(Constants.TAG_FADER);
            if(this.fader != null) {
                this.fader.GetComponent<Renderer>().enabled = false;
                Logger.Log("Got fader: " + this.fader.name);
            } else {
                Logger.LogError("ERROR: No fader found");
            }

            // subscribe to all log events from existing play objects
            // with collision managers
            this.SubscribeToLogEvents(new string[] { Constants.TAG_PLAY_OBJECT });

            if (this.demo)
            {
                foreach (GameObject go in GameObject.FindGameObjectsWithTag(
                    Constants.TAG_PLAY_OBJECT))
                {<commit_msg>Make sure sidekick light is off, and arrows start disabled<commit_after>// <NAME>
// June 2016
//
// The MIT License (MIT)
// Copyright (c) 2016 Personal Robots Group
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using UnityEngine;
using System;
using System.Collections.Generic;
using TouchScript.Behaviors;
using System.IO;
using System.Text.RegularExpressions;

namespace opal
{
    /// <summary>
    /// The SAR-opal-base game main controller. Orchestrates everything:
    /// sets up to receive input via ROS, initializes scenes and creates
    /// game objecgs based on that input, deals with touch events and
    /// other tablet-specific things.
    /// </summary>
    public class MainGameController : MonoBehaviour
    {

        // --------------- FLAGS ---------------
        // DEMO VERSION
        private bool demo = false;

        // STORYBOOK VERSION
        private bool story = true;
        /// <summary>
        /// The pages in story.
        /// </summary>
        public int pagesInStory = 0;

        // SOCIAL STORIES VERSION
        private bool socialStories = false;
        private List<GameObject> incorrectFeedback;
        private GameObject correctFeedback;
        /// <summary>
        /// The width of the slot.
        /// </summary>
        public float slotWidth = 1;
        /// <summary>
        /// The width of the answer slot.
        /// </summary>
        public float answerSlotWidth = 1;
        /// <summary>
        /// The scenes in order.
        /// </summary>
        public bool scenesInOrder = true;
        // --------------------------------------

        // gesture manager
        private GestureManager gestureManager = null;

        // sidekick
        private Sidekick sidekickScript = null;

        // rosbridge websocket client
        private RosbridgeWebSocketClient clientSocket = null;

        // actions for main thread, because the network messages from the
        // websocket can come in on another thread
        readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();

        // for logging stuff
        /// <summary>
        /// Occurs when log event.
        /// </summary>
        public event LogEventHandler logEvent;

        // fader for fading out the screen
        private GameObject fader = null;

        // This flag indicates whether we should scale graphics based on the
        // screen height (if true) or width (if false).
        private bool scaleToHeight = false;


        // config
        private GameConfig gameConfig;

        /// <summary>
        /// Called first, use to initialize stuff
        /// </summary>
        void Awake()
        {
            if (this.demo) Logger.Log("--- RUNNING IN DEMO MODE ---");
            if (this.story) Logger.Log ("--- RUNNING IN STORYBOOK MODE ---");
            if (this.socialStories) Logger.Log("--- RUNNING IN SOCIAL STORIES MODE ---");

            string path = "";

            // Scale all camera views to match the screen size of whatever
            // device we're running on.
            this.scaleToHeight = Utilities.ScaleCameraViewToScreen();

            // find the config file
            #if UNITY_ANDROID
            path = Constants.CONFIG_PATH_ANDROID + Constants.OPAL_CONFIG;
            Logger.Log("trying android path: " + path);
            #endif

            #if UNITY_EDITOR
            path = Application.dataPath + Constants.CONFIG_PATH_OSX + Constants.OPAL_CONFIG;
            Logger.Log("trying os x path: " + path);
            #endif

            #if UNITY_STANDALONE_LINUX
            path = Application.dataPath + Constants.CONFIG_PATH_LINUX + Constants.OPAL_CONFIG;
            Logger.Log("trying linux path: " + path);
            #endif

            // read config file
            if(!Utilities.ParseConfig(path, out gameConfig)) {
                Logger.LogWarning("Could not read config file! Will try default "
                    + "values of toucan=false, server IP=192.168.1.254, port=9090, "
                    + "opal_action_topic=" + Constants.ACTION_ROSTOPIC
                    + ", opal_audio_topic=" + Constants.AUDIO_ROSTOPIC
                    + ", opal_command_topic=" + Constants.CMD_ROSTOPIC
                    + ", opal_log_topic=" + Constants.LOG_ROSTOPIC
                    + ", opal_scene_topic=" + Constants.SCENE_ROSTOPIC
                    + ".");
            }
            else {
                Logger.Log("Got game config!");
            }

            // find gesture manager
            FindGestureManager();
            this.gestureManager.logEvent += new LogEventHandler(HandleLogEvent);
            this.logEvent += new LogEventHandler(HandleLogEvent);

            // share flags with everyone else
            this.gestureManager.demo = this.demo;
            this.gestureManager.story = this.story;
            this.gestureManager.socialStories = this.socialStories;

            // Find our sidekick.
            GameObject sidekick = GameObject.FindGameObjectWithTag(Constants.TAG_SIDEKICK);
            if (this.gameConfig.sidekick)
            {
	            if(sidekick == null) {
	                Logger.LogError("ERROR: Could not find sidekick!");
	            } else {
	                Logger.Log("Got sidekick");
	                if(this.gameConfig.sidekick) {
	                    // add sidekick's gestures
	                    this.gestureManager.AddAndSubscribeToGestures(sidekick, false, false);

	                    // get sidekick's script
	                    this.sidekickScript = (Sidekick)sidekick.GetComponent<Sidekick>();
	                    if(this.sidekickScript == null)
                        {
	                        Logger.LogError("ERROR: Could not get sidekick script!");
	                    } else {
	                        Logger.Log("Got sidekick script");
	                        this.sidekickScript.donePlayingEvent += new DonePlayingEventHandler(
                                HandleDonePlayingAudioEvent);
	                    }
	                }
                }
            }
            // No sidekick - make sure the sidekick and its highlight are disabled.
            else 
            {
                Logger.Log("Don't need sidekick... disabling");
                sidekick.SetActive(false);

                // try to disable the sidekick's highlight as well
                GameObject.FindGameObjectWithTag(
                    Constants.TAG_SIDEKICK_LIGHT).GetComponent<Renderer>().enabled = false;
            }
            // If this is a story make sure we have the flip buttons, and make sure
            // they start out hidden.
            if (this.story)
            {
                GameObject go = GameObject.FindGameObjectWithTag(Constants.TAG_BACK);
                if (go != null)
                    go.GetComponent<Renderer>().enabled = false;
                else
                    Logger.LogError("No back arrow / back button found!");
                go = GameObject.FindGameObjectWithTag(Constants.TAG_GO_NEXT);
                if (go != null)
                    go.GetComponent<Renderer>().enabled = false;
                else
                    Logger.LogError("No forward arrow / forward button found!");
            }

            // set up fader
            // NOTE right now we're just using one fader that fades out all but the
            // toucan - but in the unity editor there's an unused 'fader_all' that
            // can fade out everything including the toucan, just switch this tag
            // to "TAG_FADER_ALL" to use that fader instead!
            this.fader = GameObject.FindGameObjectWithTag(Constants.TAG_FADER);
            if(this.fader != null) {
                this.fader.GetComponent<Renderer>().enabled = false;
                Logger.Log("Got fader: " + this.fader.name);
            } else {
                Logger.LogError("ERROR: No fader found");
            }

            // subscribe to all log events from existing play objects
            // with collision managers
            this.SubscribeToLogEvents(new string[] { Constants.TAG_PLAY_OBJECT });

            if (this.demo)
            {
                foreach (GameObject go in GameObject.FindGameObjectsWithTag(
                    Constants.TAG_PLAY_OBJECT))
                {
{'fraction_non_alphanumeric': 0.09379187137114783, 'fraction_numerical': 0.0027914247431889234, 'mean_word_length': 1.7042572463768115, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '973199', 'n_tokens_mistral': 4643, 'n_tokens_neox': 4295, 'n_words': 1445}