var SetCache = require('./_SetCache'),

arraySome = require('./_arraySome'),
cacheHas = require('./_cacheHas');

/** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1,

COMPARE_UNORDERED_FLAG = 2;

/**

* A specialized version of `baseIsEqualDeep` for arrays with support for
* partial deep comparisons.
*
* @private
* @param {Array} array The array to compare.
* @param {Array} other The other array to compare.
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
* @param {Function} customizer The function to customize comparisons.
* @param {Function} equalFunc The function to determine equivalents of values.
* @param {Object} stack Tracks traversed `array` and `other` objects.
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
*/

function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {

var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
    arrLength = array.length,
    othLength = other.length;

if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
  return false;
}
// Assume cyclic values are equal.
var stacked = stack.get(array);
if (stacked && stack.get(other)) {
  return stacked == other;
}
var index = -1,
    result = true,
    seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;

stack.set(array, other);
stack.set(other, array);

// Ignore non-index properties.
while (++index < arrLength) {
  var arrValue = array[index],
      othValue = other[index];

  if (customizer) {
    var compared = isPartial
      ? customizer(othValue, arrValue, index, other, array, stack)
      : customizer(arrValue, othValue, index, array, other, stack);
  }
  if (compared !== undefined) {
    if (compared) {
      continue;
    }
    result = false;
    break;
  }
  // Recursively compare arrays (susceptible to call stack limits).
  if (seen) {
    if (!arraySome(other, function(othValue, othIndex) {
          if (!cacheHas(seen, othIndex) &&
              (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
            return seen.push(othIndex);
          }
        })) {
      result = false;
      break;
    }
  } else if (!(
        arrValue === othValue ||
          equalFunc(arrValue, othValue, bitmask, customizer, stack)
      )) {
    result = false;
    break;
  }
}
stack['delete'](array);
stack['delete'](other);
return result;

}

module.exports = equalArrays;