/// <summary>
        /// create property gameobject on the ui from the script's variables
        /// </summary>
        /// <param name="extract"></param>
        /// <param name="script"></param>
        /// <returns></returns>
        private Tuple <ScriptProperty, Action <string> >[] CreateScriptProperties(ScriptProperty[] extract, Script script)
        {
            if (extract == null)
            {
                extract = ScriptUtility.ExtractProperties(script);
            }

            var properties = new Tuple <ScriptProperty, Action <string> > [extract.Length];

            for (var i = 0; i < properties.Length; ++i)
            {
                var             index    = i;
                var             prop     = extract[index];
                Action <string> callback = null;

                switch (prop.type)
                {
                case PropertyType.Boolean:
                    callback = s => {
                        prop.value     = s;
                        extract[index] = prop;
                        ScriptUtility.ApplyProperties(script, extract);
                    };
                    break;

                case PropertyType.Number:
                    callback = s => {
                        var num = default(double);
                        if (double.TryParse(s, out num))
                        {
                            prop.value     = s.ToString();
                            extract[index] = prop;
                            ScriptUtility.ApplyProperties(script, extract);
                        }
                    };
                    break;

                case PropertyType.String:
                    callback = s => {
                        prop.value     = s;
                        extract[index] = prop;
                        ScriptUtility.ApplyProperties(script, extract);
                    };
                    break;
                }

                properties[i] = new Tuple <ScriptProperty, Action <string> > (prop, callback);
            }

            return(properties);
        }
        public void ApplyScript()
        {
            var isScriptValid = false;

            try {
                var table    = script.script.Globals;
                var dynValue = new List <DynValue> ();

                foreach (var key in table.Keys)
                {
                    var value    = table.Get(key);
                    var dataType = value.Type;
                    if (dataType == DataType.String || dataType == DataType.Boolean || dataType == DataType.Number)
                    {
                        dynValue.Add(key);
                    }
                }

                foreach (var thing in dynValue)
                {
                    table.Remove(thing);
                }

                script.script.DoString(input.text);
                errorMessage.SetActive(false);
                isScriptValid = true;
            } catch {
                Debug.LogWarning("Error on script!  Will not apply");
                errorMessage.SetActive(true);
                errorMessage.GetComponent <Animator> ().Play("Error Msg Shake");
                isScriptValid = false;
            }

            if (isScriptValid)
            {
                var candidate = script.CreateCopy();
                candidate.code       = input.text;
                candidate.properties = ScriptUtility.ExtractProperties(script.script);
                entity.Script        = candidate;
                eventTable.Invoke <IEntityContainer> ("OnScriptApply", entity);
            }
        }
        private void PrepareScriptTemplates()
        {
            var scripts = scriptDatabase.Scripts;

            var options = new List <Dropdown.OptionData> ();

            for (var i = 0; i < scripts.Length; ++i)
            {
                options.Add(new Dropdown.OptionData {
                    text = scripts[i].name
                });
            }

            dropdownMenu.ClearOptions();
            dropdownMenu.AddOptions(options);

            dropdownMenu.onValueChanged.AddListener(i => {
                var overwrite   = scriptDatabase.Scripts[i];
                var script      = entity.Script;
                var isValidated = true;
                try {
                    script.script.DoString(overwrite.script);
                } catch {
                    Debug.LogWarning("Error on code!");
                    isValidated = false;
                }

                // If the code passes the Moonsharp text, finalize the script values
                if (isValidated)
                {
                    script.code       = overwrite.script;
                    script.properties = ScriptUtility.ExtractProperties(script.script);
                    entity.Script     = script;

                    eventTable?.Invoke <Tuple <ScriptProperty, Action <string> >[]> ("OnPropertiesInspect", CreateScriptProperties(script.properties, script.script));
                    eventTable?.Invoke <IEntityContainer, LuaScript> ("OnScriptEditorOpen", entity, entity.Script);
                }
            });
        }