﻿// Decompiled with JetBrains decompiler
// Type: Wb.Lpw.Game.Common.Pathfinding.ClearanceGrid
// Assembly: Wb.Lpw.Game.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 3C4BDCBA-73F8-4BAA-AC19-A98EC2D71189
// Assembly location: C:\Users\CGA Computer\Desktop\LEGO Universe Stuff\LOCO Server\Unity Web Player Extractor\Saved Files\LOCO Server.unity3d_unpacked\Wb.Lpw.Game.Common.dll

using System;
using System.Collections.Generic;
using System.Linq;
using Wb.Lpw.Shared.Common.DataTypes;

namespace Wb.Lpw.Game.Common.Pathfinding
{
  public class ClearanceGrid
  {
    private readonly Dictionary<object, List<long>> _objects = new Dictionary<object, List<long>>();
    private readonly Dictionary<long, List<object>> _positions = new Dictionary<long, List<object>>();
    public Action<int, int> OnSetDynamicObstacle;
    public Action<int, int> OnRemoveDynamicObstacle;
    private int _gridWidth;

    public ClearanceGrid(int width)
    {
      this._gridWidth = width;
    }

    public void PlaceObject(object obj, IEnumerable<IntVector2> occupiedPositions)
    {
      List<long> newPositions = Enumerable.ToList<long>(Enumerable.Distinct<long>(Enumerable.Select<IntVector2, long>(occupiedPositions, (Func<IntVector2, long>) (tpPos => this.Hash(tpPos.x, tpPos.y)))));
      List<long> prevPositions = (List<long>) null;
      if (this._objects.ContainsKey(obj))
      {
        prevPositions = this._objects[obj];
        foreach (long index in Enumerable.Where<long>((IEnumerable<long>) prevPositions, (Func<long, bool>) (pp => !newPositions.Contains(pp))))
        {
          this._positions[index].Remove(obj);
          if (this._positions[index].Count == 0)
          {
            int x;
            int y;
            this.Unhash(index, out x, out y);
            this.OnRemoveDynamicObstacle(x, y);
            this._positions.Remove(index);
          }
        }
      }
      else
        prevPositions = new List<long>();
      foreach (long index in Enumerable.Where<long>((IEnumerable<long>) newPositions, (Func<long, bool>) (np => !prevPositions.Contains(np))))
      {
        if (!this._positions.ContainsKey(index))
          this._positions[index] = new List<object>()
          {
            obj
          };
        else if (!this._positions[index].Contains(obj))
          this._positions[index].Add(obj);
        if (this._positions[index].Count == 1)
        {
          int x;
          int y;
          this.Unhash(index, out x, out y);
          this.OnSetDynamicObstacle(x, y);
        }
      }
      if (newPositions.Count > 0)
      {
        this._objects[obj] = newPositions;
      }
      else
      {
        if (!this._objects.ContainsKey(obj))
          return;
        this._objects.Remove(obj);
      }
    }

    public void RemoveObject(object obj)
    {
      if (obj == null || !this._objects.ContainsKey(obj))
        return;
      foreach (long index in this._objects[obj])
      {
        this._positions[index].Remove(obj);
        if (this._positions[index].Count == 0)
        {
          int x;
          int y;
          this.Unhash(index, out x, out y);
          this.OnRemoveDynamicObstacle(x, y);
          this._positions.Remove(index);
        }
      }
      this._objects.Remove(obj);
    }

    public IEnumerable<IntVector2> CoveredPoints(object obj)
    {
      if (obj == null)
        return (IEnumerable<IntVector2>) null;
      if (!this._objects.ContainsKey(obj))
        return (IEnumerable<IntVector2>) null;
      return Enumerable.Select<long, IntVector2>((IEnumerable<long>) this._objects[obj], (Func<long, IntVector2>) (hash =>
      {
        int x;
        int y;
        this.Unhash(hash, out x, out y);
        return new IntVector2(x, y);
      }));
    }

    public bool IsCovering(object obj, int x, int y)
    {
      if (!this._objects.ContainsKey(obj))
        return false;
      long num = this.Hash(x, y);
      return this._objects[obj].Contains(num);
    }

    private long Hash(int x, int y)
    {
      return (long) this._gridWidth * (long) y + (long) x;
    }

    private void Unhash(long hash, out int x, out int y)
    {
      y = (int) (hash / (long) this._gridWidth);
      x = (int) (hash % (long) this._gridWidth);
    }
  }
}
