using UnityEngine;
using System.Collections.Generic;

public class LevelManager
{
    private static LevelManager instance = null;

    private LevelManager()
    {
        Reset();
    }

    public static LevelManager Instance
    {
        get
        {
            if (instance == null)
                instance = new LevelManager();

            return instance;
        }
    }

    public void RegisterSwitch(Switch s)
    {
        s.Triggered += OnSwitchTriggered;
        _switches.Add(s.id, s);
        _observers.Add(s.id, new List<IObserver>());
    }

    public void RegisterTeleporter(Teleporter t)
    {
        _teleporters.Add(t.id, t);

        List<Teleporter> _nowLinked = new List<Teleporter>();

        if (_unlinkedTeleporters.Count > 0)
        {
            foreach (Teleporter tel in _unlinkedTeleporters)
                if (tel.targetId == t.id)
                {
                    tel.LinkTo(t);
                    _nowLinked.Add(tel);
                }

            foreach (Teleporter tel in _nowLinked)
                _unlinkedTeleporters.Remove(tel);
        }

        if (t.targetId == 0)
            return;

        if (_teleporters.ContainsKey(t.targetId))
            t.LinkTo(_teleporters[t.targetId]);
        else
            _unlinkedTeleporters.Add(t);
    }

    public void ListenForSwitch(IObserver observer, int switchId)
    {
        if (_observers.ContainsKey(switchId))
            _observers[switchId].Add(observer);
        else
        {
            _observers.Add(switchId, new List<IObserver>());
            _observers[switchId].Add(observer);
        }
    }

    public void RelinkTeleporter(Teleporter t)
    {
        t.LinkTo(_teleporters[t.targetId]);
    }

    private void OnSwitchTriggered(object sender, bool newState)
    {
        Switch s = (Switch)sender;

        if (!_observers.ContainsKey(s.id))
            return;

        foreach (IObserver observer in _observers[s.id])
            observer.Notify(sender);
    }

    public void Reset()
    {
        _switches = new Dictionary<int, Switch>();
        _teleporters = new Dictionary<int, Teleporter>();
        _observers = new Dictionary<int, List<IObserver>>();

        _unlinkedTeleporters = new List<Teleporter>();
    }

    private Dictionary<int, Switch> _switches;
    private Dictionary<int, Teleporter> _teleporters;
    private Dictionary<int, List<IObserver>> _observers;

    private List<Teleporter> _unlinkedTeleporters;
}
