private async void DecompileCode(UndertaleCode code)
        {
            LoaderDialog dialog = new LoaderDialog("Decompiling", "Decompiling, please wait... This can take a while on complex scripts");

            dialog.Owner = Window.GetWindow(this);

            FlowDocument document = new FlowDocument();

            document.PagePadding = new Thickness(0);
            document.FontFamily  = new FontFamily("Lucida Console");
            Paragraph par = new Paragraph();

            UndertaleCode gettextCode = null;

            if (gettext == null)
            {
                gettextCode = (Application.Current.MainWindow as MainWindow).Data.Code.ByName("gml_Script_textdata_en");
            }

            string gettextJsonPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName((Application.Current.MainWindow as MainWindow).FilePath), "lang/lang_en.json");

            var  dataa = (Application.Current.MainWindow as MainWindow).Data;
            Task t     = Task.Run(() =>
            {
                string decompiled = null;
                Exception e       = null;
                try
                {
                    decompiled = Decompiler.Decompile(code, dataa).Replace("\r\n", "\n");
                }
                catch (Exception ex)
                {
                    e = ex;
                }

                if (gettextCode != null)
                {
                    UpdateGettext(gettextCode);
                }

                if (gettextJSON == null && File.Exists(gettextJsonPath))
                {
                    UpdateGettextJSON(File.ReadAllText(gettextJsonPath));
                }

                Dispatcher.Invoke(() =>
                {
                    if (e != null)
                    {
                        Brush exceptionBrush = new SolidColorBrush(Color.FromRgb(255, 0, 0));
                        par.Inlines.Add(new Run("EXCEPTION!\n")
                        {
                            Foreground = exceptionBrush, FontWeight = FontWeights.Bold
                        });
                        par.Inlines.Add(new Run(e.ToString())
                        {
                            Foreground = exceptionBrush
                        });
                    }
                    else if (decompiled != null)
                    {
                        string[] lines = decompiled.Split('\n');
                        if (lines.Length > 5000)
                        {
                            par.Inlines.Add(new Run(decompiled));
                        }
                        else
                        {
                            Brush keywordBrush = new SolidColorBrush(Color.FromRgb(0, 0, 150));
                            Brush stringBrush  = new SolidColorBrush(Color.FromRgb(0, 0, 200));
                            Brush commentBrush = new SolidColorBrush(Color.FromRgb(0, 150, 0));
                            Brush funcBrush    = new SolidColorBrush(Color.FromRgb(100, 100, 0));
                            Brush assetBrush   = new SolidColorBrush(Color.FromRgb(0, 150, 100));

                            Dictionary <string, UndertaleFunction> funcs = new Dictionary <string, UndertaleFunction>();
                            foreach (var x in (Application.Current.MainWindow as MainWindow).Data.Functions)
                            {
                                funcs.Add(x.Name.Content, x);
                            }

                            foreach (var line in lines)
                            {
                                char[] special = { '.', ',', ')', '(', '[', ']', '>', '<', ':', ';', '=', '"' };
                                Func <char, bool> IsSpecial = (c) => Char.IsWhiteSpace(c) || special.Contains(c);
                                List <string> split         = new List <string>();
                                string tok         = "";
                                bool readingString = false;
                                for (int i = 0; i < line.Length; i++)
                                {
                                    if (tok == "//")
                                    {
                                        tok += line.Substring(i);
                                        break;
                                    }
                                    if (!readingString && tok.Length > 0 && (
                                            (Char.IsWhiteSpace(line[i]) != Char.IsWhiteSpace(tok[tok.Length - 1])) ||
                                            (special.Contains(line[i]) != special.Contains(tok[tok.Length - 1])) ||
                                            (special.Contains(line[i]) && special.Contains(tok[tok.Length - 1])) ||
                                            line[i] == '"'
                                            ))
                                    {
                                        split.Add(tok);
                                        tok = "";
                                    }
                                    tok += line[i];
                                    if (line[i] == '"')
                                    {
                                        if (readingString)
                                        {
                                            split.Add(tok);
                                            tok = "";
                                        }
                                        readingString = !readingString;
                                    }
                                }
                                if (tok != "")
                                {
                                    split.Add(tok);
                                }

                                Dictionary <string, object> usedObjects = new Dictionary <string, object>();
                                for (int i = 0; i < split.Count; i++)
                                {
                                    string token = split[i];
                                    if (token == "if" || token == "else" || token == "return" || token == "break" || token == "continue" || token == "while" || token == "with" || token == "switch" || token == "case" || token == "default")
                                    {
                                        par.Inlines.Add(new Run(token)
                                        {
                                            Foreground = keywordBrush, FontWeight = FontWeights.Bold
                                        });
                                    }
                                    else if (token == "self" || token == "global" || token == "local" || token == "other" || token == "noone" || token == "true" || token == "false")
                                    {
                                        par.Inlines.Add(new Run(token)
                                        {
                                            Foreground = keywordBrush
                                        });
                                    }
                                    else if (token.StartsWith("\""))
                                    {
                                        par.Inlines.Add(new Run(token)
                                        {
                                            Foreground = stringBrush
                                        });
                                    }
                                    else if (token.StartsWith("//"))
                                    {
                                        par.Inlines.Add(new Run(token)
                                        {
                                            Foreground = commentBrush
                                        });
                                    }
                                    else if (token.StartsWith("@") && split[i - 1][0] == '"' && split[i - 1][split[i - 1].Length - 1] == '"')
                                    {
                                        par.Inlines.LastInline.Cursor     = Cursors.Hand;
                                        par.Inlines.LastInline.MouseDown += (sender, ev) =>
                                        {
                                            MainWindow mw = Application.Current.MainWindow as MainWindow;
                                            mw.ChangeSelection(mw.Data.Strings[Int32.Parse(token.Substring(1))]);
                                        };
                                    }
                                    else if (dataa.ByName(token) != null)
                                    {
                                        par.Inlines.Add(new Run(token)
                                        {
                                            Foreground = assetBrush, Cursor = Cursors.Hand
                                        });
                                        par.Inlines.LastInline.MouseDown += (sender, ev) => (Application.Current.MainWindow as MainWindow).ChangeSelection(dataa.ByName(token));
                                        if (token == "scr_gettext" && gettext != null)
                                        {
                                            if (split[i + 1] == "(" && split[i + 2].StartsWith("\"") && split[i + 3].StartsWith("@") && split[i + 4] == ")")
                                            {
                                                string id = split[i + 2].Substring(1, split[i + 2].Length - 2);
                                                if (!usedObjects.ContainsKey(id))
                                                {
                                                    usedObjects.Add(id, (Application.Current.MainWindow as MainWindow).Data.Strings[gettext[id]]);
                                                }
                                            }
                                        }
                                        if (token == "scr_84_get_lang_string" && gettextJSON != null)
                                        {
                                            if (split[i + 1] == "(" && split[i + 2].StartsWith("\"") && split[i + 3].StartsWith("@") && split[i + 4] == ")")
                                            {
                                                string id = split[i + 2].Substring(1, split[i + 2].Length - 2);
                                                if (!usedObjects.ContainsKey(id))
                                                {
                                                    usedObjects.Add(id, gettextJSON[id]);
                                                }
                                            }
                                        }
                                    }
                                    else if (funcs.ContainsKey(token))
                                    {
                                        par.Inlines.Add(new Run(token)
                                        {
                                            Foreground = funcBrush, Cursor = Cursors.Hand
                                        });
                                        par.Inlines.LastInline.MouseDown += (sender, ev) => (Application.Current.MainWindow as MainWindow).ChangeSelection(funcs[token]);
                                    }
                                    else if (Char.IsDigit(token[0]))
                                    {
                                        par.Inlines.Add(new Run(token)
                                        {
                                            Cursor = Cursors.Hand
                                        });
                                        par.Inlines.LastInline.MouseDown += (sender, ev) =>
                                        {
                                            // TODO: Add type resolving to the decompiler so that this is handled mostly automatically

                                            UndertaleData data = (Application.Current.MainWindow as MainWindow).Data;
                                            int id             = Int32.Parse(token);
                                            List <UndertaleObject> possibleObjects = new List <UndertaleObject>();
                                            if (id < data.Sprites.Count)
                                            {
                                                possibleObjects.Add(data.Sprites[id]);
                                            }
                                            if (id < data.Rooms.Count)
                                            {
                                                possibleObjects.Add(data.Rooms[id]);
                                            }
                                            if (id < data.GameObjects.Count)
                                            {
                                                possibleObjects.Add(data.GameObjects[id]);
                                            }
                                            if (id < data.Backgrounds.Count)
                                            {
                                                possibleObjects.Add(data.Backgrounds[id]);
                                            }
                                            if (id < data.Scripts.Count)
                                            {
                                                possibleObjects.Add(data.Scripts[id]);
                                            }
                                            if (id < data.Paths.Count)
                                            {
                                                possibleObjects.Add(data.Paths[id]);
                                            }
                                            if (id < data.Fonts.Count)
                                            {
                                                possibleObjects.Add(data.Fonts[id]);
                                            }
                                            if (id < data.Sounds.Count)
                                            {
                                                possibleObjects.Add(data.Sounds[id]);
                                            }
                                            if (id < data.Shaders.Count)
                                            {
                                                possibleObjects.Add(data.Shaders[id]);
                                            }
                                            // if (id < data.Extensions.Count)
                                            //    possibleObjects.Add(data.Extensions[id]);
                                            if (id < data.Timelines.Count)
                                            {
                                                possibleObjects.Add(data.Timelines[id]);
                                            }

                                            ContextMenu contextMenu = new ContextMenu();
                                            foreach (UndertaleObject obj in possibleObjects)
                                            {
                                                MenuItem item = new MenuItem();
                                                item.Header   = obj.ToString().Replace("_", "__");
                                                item.Click   += (sender2, ev2) => (Application.Current.MainWindow as MainWindow).ChangeSelection(obj);
                                                contextMenu.Items.Add(item);
                                            }
                                            if (id > 0x00050000)
                                            {
                                                contextMenu.Items.Add(new MenuItem()
                                                {
                                                    Header = "#" + id.ToString("X6") + " (color)", IsEnabled = false
                                                });
                                            }
                                            contextMenu.Items.Add(new MenuItem()
                                            {
                                                Header = id + " (number)", IsEnabled = false
                                            });
                                            (sender as Run).ContextMenu = contextMenu;
                                            contextMenu.IsOpen          = true;
                                            ev.Handled = true;
                                        };
                                    }
                                    else
                                    {
                                        par.Inlines.Add(new Run(token));
                                    }

                                    if (token == "." && (Char.IsLetter(split[i + 1][0]) || split[i + 1][0] == '_'))
                                    {
                                        int id;
                                        if (Int32.TryParse(split[i - 1], out id))
                                        {
                                            var gos = (Application.Current.MainWindow as MainWindow).Data.GameObjects;
                                            if (!usedObjects.ContainsKey(split[i - 1]) && id >= 0 && id < gos.Count)
                                            {
                                                usedObjects.Add(split[i - 1], gos[id]);
                                            }
                                        }
                                    }
                                }
                                foreach (var gt in usedObjects)
                                {
                                    par.Inlines.Add(new Run(" // ")
                                    {
                                        Foreground = commentBrush
                                    });
                                    par.Inlines.Add(new Run(gt.Key)
                                    {
                                        Foreground = commentBrush
                                    });
                                    par.Inlines.Add(new Run(" = ")
                                    {
                                        Foreground = commentBrush
                                    });
                                    par.Inlines.Add(new Run(gt.Value is string? "\"" + (string)gt.Value + "\"" : gt.Value.ToString())
                                    {
                                        Foreground = commentBrush, Cursor = Cursors.Hand
                                    });
                                    if (gt.Value is UndertaleObject)
                                    {
                                        par.Inlines.LastInline.MouseDown += (sender, ev) => (Application.Current.MainWindow as MainWindow).ChangeSelection(gt.Value);
                                    }
                                }
                                par.Inlines.Add(new Run("\n"));
                            }
                        }
                    }

                    document.Blocks.Add(par);
                    DecompiledView.Document = document;
                    CurrentDecompiled       = code;
                    dialog.Hide();
                });
            });

            dialog.ShowDialog();
            await t;
        }