﻿/**
 * Copyright 2016 Bad Mishka LLC
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace BadMishka
{
    public static class ArrayExtensions
    {


        /// <summary>
        /// Swaps the values for the left and right indices in the specified list.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list">The list.</param>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Swap<T>(IList<T> list, int left, int right)
        {
            var reference = list[left];
            list[left] = list[right];
            list[right] = reference;
        }


        public static T[] Clear<T>(this T[] array)
        {
            Array.Clear(array, 0, array.Length);
            return array;
        }

        public static bool EqualTo<T>(this IEnumerable<T> left, IEnumerable<T> right)
        {
            if (left == null && right != null)
                return false;

            if (left != null && right == null)
                return false;

            var leftEnumerator = left.GetEnumerator();
            var rightEnumerator = right.GetEnumerator();

            while(true)
            {
                var lNext = leftEnumerator.MoveNext();
                var rNext = rightEnumerator.MoveNext();

                if (lNext == false && rNext == false)
                    return true;

                if (lNext != rNext)
                    return false;

                var lValue = leftEnumerator.Current;
                var rValue = rightEnumerator.Current;

                var lEquatable = lValue as IEquatable<T>;
                if (lEquatable != null && !lEquatable.Equals(rValue))
                    return false;

                var lComparable = lValue as IComparable<T>;
                if (lComparable != null && lComparable.CompareTo(rValue) != 0)
                    return false;

                if (!lValue.Equals(rValue))
                    return false;
            }
        }
    }
}
