public void ClearRecords()
 {
     AssetFilterRecords.Clear();
     PartRecords.Clear();
     PhaseRecords.Clear();
     UserRecords.Clear();
     ScoreRecords.Clear();
     TroopRecords.Clear();
     BarrackRecords.Clear();
     TowerRecords.Clear();
     HeroRecords.Clear();
     SkillRecords.Clear();
     CutsceneRecords.Clear();
     SceneRecords.Clear();
     SpeakRecords.Clear();
 }
    void Load(String jsonUnarrangedData, String userId, Action onDataLoaded)
    {
        var unarrangedData = JsonConvert
                             .DeserializeObject <Dictionary <string, Dictionary <string, List <object> > > >(jsonUnarrangedData);

        /* Quando o userId é nulo, isso indica que apenas os dados iniciais são
         * carregados, independentemente do usuário */

        ClearRecords();

        foreach (var table in unarrangedData)
        {
            string tableName = table.Key;
            IEnumerable <string> primaryKeys = table.Value["primaryKeys"].Select(i => ToString());
            List <JObject>       records     = table.Value["records"].Cast <JObject>().ToList();

            foreach (var record in records)
            {
                AssetFilter filter = AssetFilterRecords
                                     .SingleOrDefault(i => i.NamTable == tableName);

                switch (tableName)
                {
                case "assetfilter":
                    AssetFilter assetFilter = record.ToObject <AssetFilter>();
                    // assetFilter.TxtAssetPath = $"Assets/{assetFilter.TxtAssetPath}";
                    AssetFilterRecords.Add(assetFilter);
                    break;

                case "score":     // only current user scores are retrieved
                    Score score = record.ToObject <Score>();
                    ScoreRecords.Add(score);
                    break;

                case "part":
                    Part part = record.ToObject <Part>();
                    PartRecords.Add(part);
                    break;

                case "phase":
                    Phase phase = record.ToObject <Phase>();
                    phase.Part = PartRecords
                                 .SingleOrDefault(i => i.CodPart == phase.CodPart);
                    phase.UserScore = ScoreRecords
                                      .SingleOrDefault(i => i.NumPhase == phase.NumPhase);
                    PhaseRecords.Add(phase);
                    phase.TilemapsGrid = dataUtil
                                         .LoadAsset <Grid>($"Grid_{filter.TxtAssetFilter}_{phase.NumPhase}",
                                                           new[] { filter.TxtAssetPath });
                    break;

                case "gameuser":     // only current user data is retrieved
                    GameUser user = record.ToObject <GameUser>();
                    user.CurrentPhase = PhaseRecords
                                        .SingleOrDefault(i => i.NumPhase == user.NumCurrentPhase);
                    UserRecords.Add(user);
                    break;

                case "troop":
                    Troop troop = record.ToObject <Troop>();
                    troop.GameObject = dataUtil
                                       .LoadAsset <GameObject>($"{filter.TxtAssetFilter}_{troop.TxtAssetIdentifier}",
                                                               new[] { filter.TxtAssetPath });
                    TroopRecords.Add(troop);
                    break;

                case "barrack":
                    Barrack barrack = record.ToObject <Barrack>();
                    barrack.Part = PartRecords
                                   .SingleOrDefault(i => i.CodPart == barrack.CodPart);
                    barrack.Troop = TroopRecords
                                    .SingleOrDefault(i => i.CodTroop == barrack.CodTroop);
                    barrack.GameObject = dataUtil
                                         .LoadAsset <GameObject>($"{filter.TxtAssetFilter}_{barrack.Troop.TxtAssetIdentifier}",
                                                                 new[] { filter.TxtAssetPath });
                    BarrackRecords.Add(barrack);
                    break;

                case "tower":
                    Tower tower = record.ToObject <Tower>();
                    tower.GameObject = dataUtil
                                       .LoadAsset <GameObject>($"{filter.TxtAssetFilter}_{(tower.IsEnemy ? "enemy" : "player")}",
                                                               new[] { filter.TxtAssetPath });
                    TowerRecords.Add(tower);
                    break;

                case "skill":
                    Skill skill = record.ToObject <Skill>();
                    skill.Action = dataUtil
                                   .LoadAsset <SkillAction>($"{filter.TxtAssetFilter}_{skill.TxtAssetIdentifier}",
                                                            new[] { filter.TxtAssetPath });
                    SkillRecords.Add(skill);
                    break;

                case "hero":
                    Hero hero = record.ToObject <Hero>();
                    hero.Part = PartRecords
                                .SingleOrDefault(i => i.CodPart == hero.CodPart);
                    hero.Skills = SkillRecords
                                  .Where(i => i.CodHero == hero.CodHero)
                                  .ToList();
                    hero.GameObject = dataUtil
                                      .LoadAsset <GameObject>($"{filter.TxtAssetFilter}_{hero.TxtAssetIdentifier}",
                                                              new[] { filter.TxtAssetPath });
                    HeroRecords.Add(hero);
                    break;

                case "speak":
                    Speak speak = record.ToObject <Speak>();
                    SpeakRecords.Add(speak);
                    break;

                case "scene":
                    Scene scene = record.ToObject <Scene>();
                    scene.Texts = SpeakRecords
                                  .Where(i => i.CodCutscene == scene.CodCutscene && i.CodScene == scene.CodScene)
                                  .ToList();
                    scene.Sprite = dataUtil
                                   .LoadAsset <Sprite>(new[] { $"{filter.TxtAssetPath}/{scene.TxtImagePath}" });
                    SceneRecords.Add(scene);
                    break;

                case "cutscene":
                    Cutscene cutscene = record.ToObject <Cutscene>();
                    cutscene.Scenes = SceneRecords
                                      .Where(i => i.CodCutscene == cutscene.CodCutscene)
                                      .ToList();
                    CutsceneRecords.Add(cutscene);
                    break;

                default:
                    break;
                }
            }
        }

        if (userId != null && userId.Length != 0 && UserRecords.Count == 1)
        {
            loadedUser = UserRecords.SingleOrDefault();
            SaveUserData(loadedUser); // remove later
        }

        if (!(onDataLoaded is null))
        {
            onDataLoaded();
        }
    }