define([

'./select',
'../utils',
'jquery'

], function (SelectAdapter, Utils, $) {

function ArrayAdapter ($element, options) {
  var data = options.get('data') || [];

  ArrayAdapter.__super__.constructor.call(this, $element, options);

  this.addOptions(this.convertToOptions(data));
}

Utils.Extend(ArrayAdapter, SelectAdapter);

ArrayAdapter.prototype.select = function (data) {
  var $option = this.$element.find('option').filter(function (i, elm) {
    return elm.value == data.id.toString();
  });

  if ($option.length === 0) {
    $option = this.option(data);

    this.addOptions($option);
  }

  ArrayAdapter.__super__.select.call(this, data);
};

ArrayAdapter.prototype.convertToOptions = function (data) {
  var self = this;

  var $existing = this.$element.find('option');
  var existingIds = $existing.map(function () {
    return self.item($(this)).id;
  }).get();

  var $options = [];

  // Filter out all items except for the one passed in the argument
  function onlyItem (item) {
    return function () {
      return $(this).val() == item.id;
    };
  }

  for (var d = 0; d < data.length; d++) {
    var item = this._normalizeItem(data[d]);

    // Skip items which were pre-loaded, only merge the data
    if ($.inArray(item.id, existingIds) >= 0) {
      var $existingOption = $existing.filter(onlyItem(item));

      var existingData = this.item($existingOption);
      var newData = $.extend(true, {}, item, existingData);

      var $newOption = this.option(newData);

      $existingOption.replaceWith($newOption);

      continue;
    }

    var $option = this.option(item);

    if (item.children) {
      var $children = this.convertToOptions(item.children);

      Utils.appendMany($option, $children);
    }

    $options.push($option);
  }

  return $options;
};

return ArrayAdapter;

});