<commit_before>﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using PrepareLanding.Extensions;
using PrepareLanding.Filters;
using RimWorld.Planet;
using UnityEngine;
using Verse;

namespace PrepareLanding
{
    public class WorldTileFilter
    {
        private readonly Dictionary<string, ITileFilter> _allFilters;

        private readonly List<int> _allValidTileIds = new List<int>();

        private readonly List<int> _matchingTileIds = new List<int>();
        private readonly List<ITileFilter> _sortedFilters = new List<ITileFilter>();
        private readonly PrepareLandingUserData _userData;
        public ReadOnlyCollection<int> AllTilesWithRiver;
        public ReadOnlyCollection<int> AllTilesWithRoad;

        public ReadOnlyCollection<int> AllMatchingTiles => _matchingTileIds.AsReadOnly();


        public WorldTileFilter(PrepareLandingUserData userData)
        {
            _userData = userData;
            _userData.PropertyChanged += OnDataPropertyChanged;

            PrepareLanding.Instance.OnWorldGenerated += WorldGenerated;

            FilterInfoLogger.PropertyChanged += FilterInfoChanged;

            _allFilters = new Dictionary<string, ITileFilter>
            {
                /* terrain */
                {
                    nameof(_userData.ChosenBiome),
                    new TileFilterBiomes(_userData, nameof(_userData.ChosenBiome), FilterHeaviness.Light)
                },
                {
                    nameof(_userData.ChosenHilliness),
                    new TileFilterHilliness(_userData, nameof(_userData.ChosenHilliness), FilterHeaviness.Light)
                },
                {
                    nameof(_userData.SelectedRoadDefs),
                    new TileFilterRoads(_userData, nameof(_userData.SelectedRoadDefs), FilterHeaviness.Light)
                },
                {
                    nameof(_userData.SelectedRiverDefs),
                    new TileFilterRivers(_userData, nameof(_userData.SelectedRiverDefs), FilterHeaviness.Light)
                },
                {
                    nameof(_userData.CurrentMovementTime),
                    new TileFilterCurrentMovementTimes(_userData, nameof(_userData.CurrentMovementTime),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.WinterMovementTime),
                    new TileFilterWinterMovementTimes(_userData, nameof(_userData.WinterMovementTime),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.SummerMovementTime),
                    new TileFilterSummerMovementTimes(_userData, nameof(_userData.SummerMovementTime),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.SelectedStoneDefs),
                    new TileFilterStones(_userData, nameof(_userData.SelectedStoneDefs), FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.ChosenCoastalTileState),
                    new TileFilterCoastalTiles(_userData, nameof(_userData.ChosenCoastalTileState),
                        FilterHeaviness.Light)
                },
                {
                    nameof(_userData.Elevation),
                    new TileFilterElevations(_userData, nameof(_userData.Elevation), FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.TimeZone),
                    new TileFilterTimeZones(_userData, nameof(_userData.TimeZone), FilterHeaviness.Medium)
                }, //TODO: check heaviness
                /* temperature */
                {
                    nameof(_userData.AverageTemperature),
                    new TileFilterAverageTemperatures(_userData, nameof(_userData.AverageTemperature),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.WinterTemperature),
                    new TileFilterWinterTemperatures(_userData, nameof(_userData.WinterTemperature),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.SummerTemperature),
                    new TileFilterSummerTemperatures(_userData, nameof(_userData.SummerTemperature),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.GrowingPeriod),
                    new TileFilterGrowingPeriods(_userData, nameof(_userData.GrowingPeriod), FilterHeaviness.Heavy)
                }, // TODO check heaviness
                {
                    nameof(_userData.RainFall),
                    new TileFilterRainFalls(_userData, nameof(_userData.RainFall), FilterHeaviness.Medium)
                }, //TODO check heaviness
                {
                    nameof(_userData.ChosenAnimalsCanGrazeNowState),
                    new TileFilterAnimalsCanGrazeNow(_userData, nameof(_userData.ChosenAnimalsCanGrazeNowState),
                        FilterHeaviness.Heavy)
                } //TODO check heaviness
            };

            var lightFilters = _allFilters.Values.Where(filter => filter.Heaviness == FilterHeaviness.Light).ToList();
            var mediumFilters = _allFilters.Values.Where(filter => filter.Heaviness == FilterHeaviness.Medium).ToList();
            var heavyFilters = _allFilters.Values.Where(filter => filter.Heaviness == FilterHeaviness.Heavy).ToList();

            _sortedFilters.AddRange(lightFilters);
            _sortedFilters.AddRange(mediumFilters);
            _sortedFilters.AddRange(heavyFilters);
        }

        public FilterInfoLogger FilterInfoLogger { get; } = new FilterInfoLogger();

        public ReadOnlyCollection<int> AllValidTilesReadOnly => _allValidTileIds.AsReadOnly();

        public string FilterInfoText => FilterInfoLogger.Text;

        public event Action OnFilterInfoTextChanged = delegate { };

        public int TilesCount()
        {
            return _matchingTileIds.Count;
        }

        public void ClearMatchingTiles()
        {
            _matchingTileIds.Clear();
        }

        public void FilterInfoChanged(object sender, PropertyChangedEventArgs e)
        {
            OnFilterInfoTextChanged?.Invoke();
        }

        public void WorldGenerated()
        {
            LongEventHandler.QueueLongEvent(Prefilter, "[PrepareLanding] Prefiltering World Tiles", true, null);
        }

        public void Prefilter()
        {
            //TODO allow user to use non valid tiles in their search

            Log.Message($"[PrepareLanding] Prefilter: {Find.WorldGrid.tiles.Count} tiles in WorldGrid.tiles");

            // clear all valid tile ids
            _allValidTileIds.Clear();

            // get all valid tiles for a new settlement
            var tileCount = Find.World.grid.TilesCount;
            for (var i = 0; i < tileCount; i++)
            {
                if (!IsViableTile(i))
                    continue;

                _allValidTileIds.Add(i);<commit_msg>Add warning when filtered tiles are cleared.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using PrepareLanding.Extensions;
using PrepareLanding.Filters;
using RimWorld.Planet;
using UnityEngine;
using Verse;

namespace PrepareLanding
{
    public class WorldTileFilter
    {
        private readonly Dictionary<string, ITileFilter> _allFilters;

        private readonly List<int> _allValidTileIds = new List<int>();

        private readonly List<int> _matchingTileIds = new List<int>();
        private readonly List<ITileFilter> _sortedFilters = new List<ITileFilter>();
        private readonly PrepareLandingUserData _userData;
        public ReadOnlyCollection<int> AllTilesWithRiver;
        public ReadOnlyCollection<int> AllTilesWithRoad;

        public ReadOnlyCollection<int> AllMatchingTiles => _matchingTileIds.AsReadOnly();


        public WorldTileFilter(PrepareLandingUserData userData)
        {
            _userData = userData;
            _userData.PropertyChanged += OnDataPropertyChanged;

            PrepareLanding.Instance.OnWorldGenerated += WorldGenerated;

            FilterInfoLogger.PropertyChanged += FilterInfoChanged;

            _allFilters = new Dictionary<string, ITileFilter>
            {
                /* terrain */
                {
                    nameof(_userData.ChosenBiome),
                    new TileFilterBiomes(_userData, nameof(_userData.ChosenBiome), FilterHeaviness.Light)
                },
                {
                    nameof(_userData.ChosenHilliness),
                    new TileFilterHilliness(_userData, nameof(_userData.ChosenHilliness), FilterHeaviness.Light)
                },
                {
                    nameof(_userData.SelectedRoadDefs),
                    new TileFilterRoads(_userData, nameof(_userData.SelectedRoadDefs), FilterHeaviness.Light)
                },
                {
                    nameof(_userData.SelectedRiverDefs),
                    new TileFilterRivers(_userData, nameof(_userData.SelectedRiverDefs), FilterHeaviness.Light)
                },
                {
                    nameof(_userData.CurrentMovementTime),
                    new TileFilterCurrentMovementTimes(_userData, nameof(_userData.CurrentMovementTime),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.WinterMovementTime),
                    new TileFilterWinterMovementTimes(_userData, nameof(_userData.WinterMovementTime),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.SummerMovementTime),
                    new TileFilterSummerMovementTimes(_userData, nameof(_userData.SummerMovementTime),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.SelectedStoneDefs),
                    new TileFilterStones(_userData, nameof(_userData.SelectedStoneDefs), FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.ChosenCoastalTileState),
                    new TileFilterCoastalTiles(_userData, nameof(_userData.ChosenCoastalTileState),
                        FilterHeaviness.Light)
                },
                {
                    nameof(_userData.Elevation),
                    new TileFilterElevations(_userData, nameof(_userData.Elevation), FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.TimeZone),
                    new TileFilterTimeZones(_userData, nameof(_userData.TimeZone), FilterHeaviness.Medium)
                }, //TODO: check heaviness
                /* temperature */
                {
                    nameof(_userData.AverageTemperature),
                    new TileFilterAverageTemperatures(_userData, nameof(_userData.AverageTemperature),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.WinterTemperature),
                    new TileFilterWinterTemperatures(_userData, nameof(_userData.WinterTemperature),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.SummerTemperature),
                    new TileFilterSummerTemperatures(_userData, nameof(_userData.SummerTemperature),
                        FilterHeaviness.Heavy)
                },
                {
                    nameof(_userData.GrowingPeriod),
                    new TileFilterGrowingPeriods(_userData, nameof(_userData.GrowingPeriod), FilterHeaviness.Heavy)
                }, // TODO check heaviness
                {
                    nameof(_userData.RainFall),
                    new TileFilterRainFalls(_userData, nameof(_userData.RainFall), FilterHeaviness.Medium)
                }, //TODO check heaviness
                {
                    nameof(_userData.ChosenAnimalsCanGrazeNowState),
                    new TileFilterAnimalsCanGrazeNow(_userData, nameof(_userData.ChosenAnimalsCanGrazeNowState),
                        FilterHeaviness.Heavy)
                } //TODO check heaviness
            };

            var lightFilters = _allFilters.Values.Where(filter => filter.Heaviness == FilterHeaviness.Light).ToList();
            var mediumFilters = _allFilters.Values.Where(filter => filter.Heaviness == FilterHeaviness.Medium).ToList();
            var heavyFilters = _allFilters.Values.Where(filter => filter.Heaviness == FilterHeaviness.Heavy).ToList();

            _sortedFilters.AddRange(lightFilters);
            _sortedFilters.AddRange(mediumFilters);
            _sortedFilters.AddRange(heavyFilters);
        }

        public FilterInfoLogger FilterInfoLogger { get; } = new FilterInfoLogger();

        public ReadOnlyCollection<int> AllValidTilesReadOnly => _allValidTileIds.AsReadOnly();

        public string FilterInfoText => FilterInfoLogger.Text;

        public event Action OnFilterInfoTextChanged = delegate { };

        public int TilesCount()
        {
            return _matchingTileIds.Count;
        }

        public void ClearMatchingTiles()
        {
            FilterInfoLogger.AppendWarningMessage("Filtered files cleared.");
            _matchingTileIds.Clear();
        }

        public void FilterInfoChanged(object sender, PropertyChangedEventArgs e)
        {
            OnFilterInfoTextChanged?.Invoke();
        }

        public void WorldGenerated()
        {
            LongEventHandler.QueueLongEvent(Prefilter, "[PrepareLanding] Prefiltering World Tiles", true, null);
        }

        public void Prefilter()
        {
            //TODO allow user to use non valid tiles in their search

            Log.Message($"[PrepareLanding] Prefilter: {Find.WorldGrid.tiles.Count} tiles in WorldGrid.tiles");

            // clear all valid tile ids
            _allValidTileIds.Clear();

            // get all valid tiles for a new settlement
            var tileCount = Find.World.grid.TilesCount;
            for (var i = 0; i < tileCount; i++)
            {
                if (!IsViableTile(i))
                    continue;

                _allValidTileIds.Add(i);
{'fraction_non_alphanumeric': 0.07463613161343727, 'fraction_numerical': 0.00013795957784369179, 'mean_word_length': 1.8255700643149484, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, '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': '5358846', 'n_tokens_mistral': 3794, 'n_tokens_neox': 3529, 'n_words': 582}