(function(context,$) {

    "use strict";

    context.JK = context.JK || {};
    context.JK.InstrumentSelectorDeferred = null;
    context.JK.InstrumentSelector = (function(app, parentSelector) {

      var logger = context.JK.logger;
      var rest = new context.JK.Rest();
      var _instruments = [];  // will be list of structs: [ {label:xxx, value:yyy}, {...}, ... ]
      var _instrumentsSorted = [];
      var _rsvp = false;
      var _noICheck = false;
      if (typeof(_parentSelector)=="undefined") {_parentSelector=null}
      var _parentSelector = parentSelector;
      var deferredInstruments = null;
      var self = this;

      function reset() {
        $('input[type="checkbox"]', _parentSelector).attr('checked', '');
        if (_rsvp) {
          $('select.rsvp_count option', _parentSelector).eq(0).prop('selected', true);
          $('select.rsvp_level option', _parentSelector).eq(0).prop('selected', true);
        }
        else {
          $('select option', _parentSelector).eq(0).prop('selected', true);
        }
      }

      function instrumentsLoaded(response) {
        $.each(response, function (index) {
          _instruments.push({
            id: 'instrument-' + _rsvp + '-' + index,
            value: this.id,
            label: this.description
          });
        });

        _instrumentsSorted = _instruments.slice().sort(sortAlpha)
      }

      function sortAlpha(a, b) {
        if (a.value == b.value)
          return 0;
        if (a.value < b.value)
          return -1;
        else
          return 1;
      }

      function render(parentSelector, userInstruments) {
        userInstruments = typeof userInstruments !== 'undefined' ? userInstruments : [];

        _parentSelector = parentSelector;
        $(parentSelector).empty();
        var template = null;
        if (_rsvp) {
          template = $('#template-instrument-rsvp-option').html();
        }
        else {
          template = $('#template-instrument-option').html();
        }

        var userInstrumentList = [];
        $.each(userInstruments, function(index) {
          userInstrumentList.push({
            id: 'instrument-false-' + this.instrument_id.replace(' ', '-'),
            value: this.instrument_id,
            label: this.description,
            level: this.level
          });
        });

        $.each(userInstrumentList, function (index, value) {
          var instrumentOptionHtml = $(context.JK.fillTemplate(template, value));
          $(_parentSelector).append(instrumentOptionHtml);
          context.JK.dropdown(instrumentOptionHtml.find('select'));
        });

        // do not auto-pick anything for the user currently
        //setSelectedInstruments(userInstrumentList);

        $.each(_instruments, function(index, instrument) {
          var isRendered = false;
          $.each(userInstrumentList, function(index, userInstrument) {
            if (instrument.value == userInstrument.value) {
              isRendered = true;
            }
          })
          if (!isRendered) {
            var instrumentOptionHtml = $(context.JK.fillTemplate(template, instrument));
            $(_parentSelector).append(instrumentOptionHtml);
            context.JK.dropdown(instrumentOptionHtml.find('select'));
          }
        });

      }

      function renderDropdown($select, notSelectedString) {
        if(!notSelectedString) {
          notSelectedString = 'Any Instrument'
        }
        $select.empty();
        $select.append('<option value="">' + notSelectedString + '</option>');
        var template = $('#template-instrument-option-simple').html();
        $.each(_instrumentsSorted, function(index, value) {
          // value will be a dictionary entry from _genres:
          // { value: xxx, label: yyy }
          var instrumentOptionHtml = context.JK.fillTemplate(template, value);
          $select.append(instrumentOptionHtml);
        });
        context.JK.dropdown($select);
      }


      function getSelectedInstruments() {
        var selectedInstruments = [];
        var $selectedVal = $('input[type="checkbox"]:checked', _parentSelector);
        $.each($selectedVal, function (index, value) {
          var id = $(value).attr('session-instrument-id');
          var name = $('label[for="' + $(value).attr('id') + '"]', _parentSelector).text().trim();
          if (_rsvp) {
            var count = $('select[session-instrument-id="' + id + '"].rsvp-count', _parentSelector).val();
            var rsvp_level = $('select[session-instrument-id="' + id + '"].rsvp-level', _parentSelector).val();
            selectedInstruments.push({id: id, name: name, count: count, level: rsvp_level});
          }
          else {
            var level = $('select[session-instrument-id="' + id + '"]', _parentSelector).val();
            selectedInstruments.push({id: id, name: name, level: level});
          }
        });

        return selectedInstruments;
      }

      function setSelectedInstruments(instrumentList) {
        if (!instrumentList) {
          return;
        }        
        $.each(instrumentList, function (index, value) {          
          var $item = $('input[type="checkbox"][session-instrument-id="' + value.id + '"]')
            .attr('checked', 'checked')
          if(!_noICheck) {
            $item.iCheck({
              checkboxClass: 'icheckbox_minimal',
              radioClass: 'iradio_minimal',
              inheritClass: true
            })
          }
          if (_rsvp) {
            $('select[session-instrument-id="' + value.id + '"].rsvp-count', _parentSelector).val(value.count);
            $('select[session-instrument-id="' + value.id + '"].rsvp-level', _parentSelector).val(value.level);
          }
          else {
            $('select[session-instrument-id="' + value.id + '"]').val(value.level);
          }
        });
      }

      function initialize(rsvp, noICheck) {
        _rsvp = rsvp;
        _noICheck = noICheck;
        // XXX; _instruments should be populated in a template, rather than round-trip to server
        if(!context.JK.InstrumentSelectorDeferred) {
          // this dance is to make sure there is only one server request instead of InstrumentSelector instances *
          context.JK.InstrumentSelectorDeferred = rest.getInstruments()
        }

        context.JK.InstrumentSelectorDeferred
          .done(function(response) {instrumentsLoaded(response)})
          .fail(app.ajaxError)

        return this;
      }

      this.initialize = initialize;
      this.getSelectedInstruments = getSelectedInstruments;
      this.setSelectedInstruments = setSelectedInstruments;
      this.render = function() {
        var _args = arguments;
        context.JK.InstrumentSelectorDeferred.done(function(){render.apply(self, _args)})
      }
      this.renderDropdown = function() {
        var _args = arguments;
        context.JK.InstrumentSelectorDeferred.done(function(){renderDropdown.apply(self, _args)})
      }
    });

})(window,jQuery);