﻿namespace _05.ImplementationOfHashSet
{
    using System.Collections;
    using System.Collections.Generic;

    using _04.ImplementationOfHashTable;

    public class MyHashSet<T> : IEnumerable<T>
    {
        private MyHashTable<int, T> elements;

        public MyHashSet()
        {
            this.elements = new MyHashTable<int, T>();
        }

        public int Count
        {
            get
            {
                return this.elements.Count;
            }
        }

        public void Add(T element)
        {
            this.elements.Add(element.GetHashCode(), element);
        }

        public void Remove(T element)
        {
            this.elements.Remove(element.GetHashCode());
        }

        public void Clear()
        {
            this.elements.Clear();
        }

        public T Find(T element)
        {
            T elementToReturn;

            if (this.elements.Find(element.GetHashCode(), out elementToReturn))
            {
                return elementToReturn;
            }

            return default(T);
        }

        public MyHashSet<T> IntersectsWith(MyHashSet<T> other)
        {
            var result = new MyHashSet<T>();

            foreach (var myNode in this)
            {
                foreach (var otherNode in other)
                {
                    if (myNode.Equals(otherNode))
                    {
                        result.Add(myNode);
                    }
                }
            }

            return result;
        }

        public MyHashSet<T> Union(MyHashSet<T> other)
        {
            var result = new MyHashSet<T>();

            foreach (var myNode in this)
            {
                result.Add(myNode);
            }

            foreach (var otherNode in other)
            {
                result.Add(otherNode);
            }

            return result;
        }

        public IEnumerator<T> GetEnumerator()
        {
            foreach (var pair in this.elements)
            {
                yield return pair.Value;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public override string ToString()
        {
            return string.Join(", ", this);
        }
    }
}