public void RefreshLevels()
    {
        // TODO: List rect will f**k up on second invoke.

        // Expand the list height
        // Formula: (Height + Spacing)* (How many entries) + Extra padding
        listRectTransform.ChangeSizeDelta(y: (56 - 6) * CytoidApplication.Levels.Count + 1000);

        // Add level entries into the list
        for (var index = 0; index < CytoidApplication.Levels.Count; index++)
        {
            var level = CytoidApplication.Levels[index];

            var entryObject = Instantiate(entryPrefab, listRectTransform.transform);
            entryObject.AddComponent <LevelEntry>().Level = level;
            entryObject.GetComponent <Text>().text        = level.title;

            var dynamicScrollPoint = entryObject.GetComponent <DynamicScrollPoint>();
            listScrollFocusController.focusPoints.Add(dynamicScrollPoint);
            if (index == 0)
            {
                listScrollFocusController.first = dynamicScrollPoint;
            }
            if (CytoidApplication.CurrentLevel == level)
            {
                WillScrollTo = dynamicScrollPoint; // Automatically scroll to
            }
        }

        // Reset list position
        listRectTransform.position = new Vector2(0, 0);

        ForceLayoutInitialization.Instance.Invalidate();
    }
    public IEnumerator DetectNotInstalledLevels()
    {
        if (Application.platform == RuntimePlatform.IPhonePlayer)
        {
            if (Directory.Exists(CytoidApplication.DataPath + "/Inbox/"))
            {
                foreach (var file in Directory.GetFiles(CytoidApplication.DataPath + "/Inbox/", "*.cytoidlevel"))
                {
                    var toPath = CytoidApplication.DataPath + "/" + Path.GetFileName(file);
                    if (File.Exists(toPath))
                    {
                        File.Delete(toPath);
                    }

                    File.Move(file, toPath);
                }
            }
        }

        string[] levelFiles;
        try
        {
            levelFiles =
                Directory.GetFiles(CytoidApplication.DataPath, "*.cytoidlevel");
        }
        catch (Exception)
        {
            // Ignored
            yield break;
        }

        if (levelFiles.Length > 0)
        {
            blackout.SetActive(true);
            StartCoroutine(CytoidApplication.Instance.InstallLevels(levelFiles));
            StartCoroutine(BlackoutTextAnim());
            while (CytoidApplication.Instance.LevelsInstalling)
            {
                yield return(null);
            }
            if (false) // TODO: See RefreshLevels()
            {
                RefreshLevels();
                blackout.SetActive(false);
                // Scroll to first
                WillScrollTo = listScrollFocusController.first as DynamicScrollPoint;
            }
            else
            {
                SceneManager.LoadScene(gameObject.scene.name);
            }
        }
    }
    public void RefreshLevels()
    {
        // TODO: List rect will f**k up on second invoke.

        // Expand the list height
        // Formula: (Height + Spacing)* (How many entries) + Extra padding
        listRectTransform.ChangeSizeDelta(y: ((56 - 6) * CytoidApplication.Levels.Count) + 1000);

        // Add level entries into the list
        for (var index = 0; index < CytoidApplication.Levels.Count; index++)
        {
            var level = CytoidApplication.Levels[index];

            var entryObject = Instantiate(entryPrefab, listRectTransform.transform);
            entryObject.AddComponent <LevelEntry>().Level = level;
            var text = entryObject.GetComponent <Text>();
            if (!string.IsNullOrEmpty(level.title_localized))
            {
                text.supportRichText  = true;
                text.verticalOverflow = VerticalWrapMode.Overflow;
                text.lineSpacing      = 0.4f;
                text.text             = level.title + "\n<size=12>" + level.title_localized + "</size>";
            }
            else
            {
                text.text = level.title;
            }

            var entry = entryObject.AddComponent <LevelEntryComponent>();
            entry.Id = level.id;

            var dynamicScrollPoint = entryObject.GetComponent <DynamicScrollPoint>();
            listScrollFocusController.focusPoints.Add(dynamicScrollPoint);
            if (index == 0)
            {
                listScrollFocusController.first = dynamicScrollPoint;
            }
            if (CytoidApplication.CurrentLevel == level)
            {
                WillScrollTo = dynamicScrollPoint; // Automatically scroll to
            }
        }

        // Reset list position
        listRectTransform.position = new Vector2(0, 0);

        ForceLayoutInitialization.Instance.Invalidate();
    }
    private void Update()
    {
        if (WillScrollTo != null)
        {
            WillScrollTo.Focus();
            listScrollFocusController.scrollMover.scrollController.CenterOn(WillScrollTo.Rect);
            WillScrollTo = null;

            ForceLayoutInitialization.Instance.Invalidate();
        }

        // Android
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Application.Quit();
        }
    }