(function ($) {

$(document).ready(function() {

  // Function to update labels of text fields
  Materialize.updateTextFields = function() {
    var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
    $(input_selector).each(function(index, element) {
      if ($(element).val().length > 0 || element.autofocus ||$(this).attr('placeholder') !== undefined || $(element)[0].validity.badInput === true) {
        $(this).siblings('label').addClass('active');
      }
      else {
        $(this).siblings('label').removeClass('active');
      }
    });
  };

  // Text based inputs
  var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';

  // Add active if form auto complete
  $(document).on('change', input_selector, function () {
    if($(this).val().length !== 0 || $(this).attr('placeholder') !== undefined) {
      $(this).siblings('label').addClass('active');
    }
    validate_field($(this));
  });

  // Add active if input element has been pre-populated on document ready
  $(document).ready(function() {
    Materialize.updateTextFields();
  });

  // HTML DOM FORM RESET handling
  $(document).on('reset', function(e) {
    var formReset = $(e.target);
    if (formReset.is('form')) {
      formReset.find(input_selector).removeClass('valid').removeClass('invalid');
      formReset.find(input_selector).each(function () {
        if ($(this).attr('value') === '') {
          $(this).siblings('label').removeClass('active');
        }
      });

      // Reset select
      formReset.find('select.initialized').each(function () {
        var reset_text = formReset.find('option[selected]').text();
        formReset.siblings('input.select-dropdown').val(reset_text);
      });
    }
  });

  // Add active when element has focus
  $(document).on('focus', input_selector, function () {
    $(this).siblings('label, .prefix').addClass('active');
  });

  $(document).on('blur', input_selector, function () {
    var $inputElement = $(this);
    var selector = ".prefix";

    if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') === undefined) {
      selector += ", label";
    }

    $inputElement.siblings(selector).removeClass('active');

    validate_field($inputElement);
  });

  window.validate_field = function(object) {
    var hasLength = object.attr('length') !== undefined;
    var lenAttr = parseInt(object.attr('length'));
    var len = object.val().length;

    if (object.val().length === 0 && object[0].validity.badInput === false) {
      if (object.hasClass('validate')) {
        object.removeClass('valid');
        object.removeClass('invalid');
      }
    }
    else {
      if (object.hasClass('validate')) {
        // Check for character counter attributes
        if ((object.is(':valid') && hasLength && (len <= lenAttr)) || (object.is(':valid') && !hasLength)) {
          object.removeClass('invalid');
          object.addClass('valid');
        }
        else {
          object.removeClass('valid');
          object.addClass('invalid');
        }
      }
    }
  };

  // Radio and Checkbox focus class
  var radio_checkbox = 'input[type=radio], input[type=checkbox]';
  $(document).on('keyup.radio', radio_checkbox, function(e) {
    // TAB, check if tabbing to radio or checkbox.
    if (e.which === 9) {
      $(this).addClass('tabbed');
      var $this = $(this);
      $this.one('blur', function(e) {

        $(this).removeClass('tabbed');
      });
      return;
    }
  });

  // Textarea Auto Resize
  var hiddenDiv = $('.hiddendiv').first();
  if (!hiddenDiv.length) {
    hiddenDiv = $('<div class="hiddendiv common"></div>');
    $('body').append(hiddenDiv);
  }
  var text_area_selector = '.materialize-textarea';

  function textareaAutoResize($textarea) {
    // Set font properties of hiddenDiv

    var fontFamily = $textarea.css('font-family');
    var fontSize = $textarea.css('font-size');
    var lineHeight = $textarea.css('line-height');

    if (fontSize) { hiddenDiv.css('font-size', fontSize); }
    if (fontFamily) { hiddenDiv.css('font-family', fontFamily); }
    if (lineHeight) { hiddenDiv.css('line-height', lineHeight); }

    if ($textarea.attr('wrap') === "off") {
      hiddenDiv.css('overflow-wrap', "normal")
               .css('white-space', "pre");
    }

    hiddenDiv.text($textarea.val() + '\n');
    var content = hiddenDiv.html().replace(/\n/g, '<br>');
    hiddenDiv.html(content);

    // When textarea is hidden, width goes crazy.
    // Approximate with half of window size

    if ($textarea.is(':visible')) {
      hiddenDiv.css('width', $textarea.width());
    }
    else {
      hiddenDiv.css('width', $(window).width()/2);
    }

    $textarea.css('height', hiddenDiv.height());
  }

  $(text_area_selector).each(function () {
    var $textarea = $(this);
    if ($textarea.val().length) {
      textareaAutoResize($textarea);
    }
  });

  $('body').on('keyup keydown autoresize', text_area_selector, function () {
    textareaAutoResize($(this));
  });

  // File Input Path
  $(document).on('change', '.file-field input[type="file"]', function () {
    var file_field = $(this).closest('.file-field');
    var path_input = file_field.find('input.file-path');
    var files      = $(this)[0].files;
    var file_names = [];
    for (var i = 0; i < files.length; i++) {
      file_names.push(files[i].name);
    }
    path_input.val(file_names.join(", "));
    path_input.trigger('change');
  });

  /****************
  *  Range Input  *
  ****************/

  var range_type = 'input[type=range]';
  var range_mousedown = false;
  var left;

  $(range_type).each(function () {
    var thumb = $('<span class="thumb"><span class="value"></span></span>');
    $(this).after(thumb);
  });

  var range_wrapper = '.range-field';
  $(document).on('change', range_type, function(e) {
    var thumb = $(this).siblings('.thumb');
    thumb.find('.value').html($(this).val());
  });

  $(document).on('input mousedown touchstart', range_type, function(e) {
    var thumb = $(this).siblings('.thumb');
    var width = $(this).outerWidth();

    // If thumb indicator does not exist yet, create it
    if (thumb.length <= 0) {
      thumb = $('<span class="thumb"><span class="value"></span></span>');
      $(this).after(thumb);
    }

    // Set indicator value
    thumb.find('.value').html($(this).val());

    range_mousedown = true;
    $(this).addClass('active');

    if (!thumb.hasClass('active')) {
      thumb.velocity({ height: "30px", width: "30px", top: "-20px", marginLeft: "-15px"}, { duration: 300, easing: 'easeOutExpo' });
    }

    if (e.type !== 'input') {
      if(e.pageX === undefined || e.pageX === null){//mobile
         left = e.originalEvent.touches[0].pageX - $(this).offset().left;
      }
      else{ // desktop
         left = e.pageX - $(this).offset().left;
      }
      if (left < 0) {
        left = 0;
      }
      else if (left > width) {
        left = width;
      }
      thumb.addClass('active').css('left', left);
    }

    thumb.find('.value').html($(this).val());
  });

  $(document).on('mouseup touchend', range_wrapper, function() {
    range_mousedown = false;
    $(this).removeClass('active');
  });

  $(document).on('mousemove touchmove', range_wrapper, function(e) {
    var thumb = $(this).children('.thumb');
    var left;
    if (range_mousedown) {
      if (!thumb.hasClass('active')) {
        thumb.velocity({ height: '30px', width: '30px', top: '-20px', marginLeft: '-15px'}, { duration: 300, easing: 'easeOutExpo' });
      }
      if (e.pageX === undefined || e.pageX === null) { //mobile
        left = e.originalEvent.touches[0].pageX - $(this).offset().left;
      }
      else{ // desktop
        left = e.pageX - $(this).offset().left;
      }
      var width = $(this).outerWidth();

      if (left < 0) {
        left = 0;
      }
      else if (left > width) {
        left = width;
      }
      thumb.addClass('active').css('left', left);
      thumb.find('.value').html(thumb.siblings(range_type).val());
    }
  });

  $(document).on('mouseout touchleave', range_wrapper, function() {
    if (!range_mousedown) {

      var thumb = $(this).children('.thumb');

      if (thumb.hasClass('active')) {
        thumb.velocity({ height: '0', width: '0', top: '10px', marginLeft: '-6px'}, { duration: 100 });
      }
      thumb.removeClass('active');
    }
  });

  /**************************
   * Auto complete plugin  *
   *************************/
  $.fn.autocomplete = function (options) {
    // Defaults
    var defaults = {
      data: {}
    };

    options = $.extend(defaults, options);

    return this.each(function() {
      var $input = $(this);
      var data = options.data,
          $inputDiv = $input.closest('.input-field'); // Div to append on

      // Check if data isn't empty
      if (!$.isEmptyObject(data)) {
        // Create autocomplete element
        var $autocomplete = $('<ul class="autocomplete-content dropdown-content"></ul>');

        // Append autocomplete element
        if ($inputDiv.length) {
          $inputDiv.append($autocomplete); // Set ul in body
        } else {
          $input.after($autocomplete);
        }

        var highlight = function(string, $el) {
          var img = $el.find('img');
          var matchStart = $el.text().toLowerCase().indexOf("" + string.toLowerCase() + ""),
              matchEnd = matchStart + string.length - 1,
              beforeMatch = $el.text().slice(0, matchStart),
              matchText = $el.text().slice(matchStart, matchEnd + 1),
              afterMatch = $el.text().slice(matchEnd + 1);
          $el.html("<span>" + beforeMatch + "<span class='highlight'>" + matchText + "</span>" + afterMatch + "</span>");
          if (img.length) {
            $el.prepend(img);
          }
        };

        // Perform search
        $input.on('keyup', function (e) {
          // Capture Enter
          if (e.which === 13) {
            $autocomplete.find('li').first().click();
            return;
          }

          var val = $input.val().toLowerCase();
          $autocomplete.empty();

          // Check if the input isn't empty
          if (val !== '') {
            for(var key in data) {
              if (data.hasOwnProperty(key) &&
                  key.toLowerCase().indexOf(val) !== -1 &&
                  key.toLowerCase() !== val) {
                var autocompleteOption = $('<li></li>');
                if(!!data[key]) {
                  autocompleteOption.append('<img src="'+ data[key] +'" class="right circle"><span>'+ key +'</span>');
                } else {
                  autocompleteOption.append('<span>'+ key +'</span>');
                }
                $autocomplete.append(autocompleteOption);

                highlight(val, autocompleteOption);
              }
            }
          }
        });

        // Set input value
        $autocomplete.on('click', 'li', function () {
          $input.val($(this).text().trim());
          $input.trigger('change');
          $autocomplete.empty();
        });
      }
    });
  };

}); // End of $(document).ready

/*******************
 *  Select Plugin  *
 ******************/
$.fn.material_select = function (callback) {
  $(this).each(function(){
    var $select = $(this);

    if ($select.hasClass('browser-default')) {
      return; // Continue to next (return false breaks out of entire loop)
    }

    var multiple = $select.attr('multiple') ? true : false,
        lastID = $select.data('select-id'); // Tear down structure if Select needs to be rebuilt

    if (lastID) {
      $select.parent().find('span.caret').remove();
      $select.parent().find('input').remove();

      $select.unwrap();
      $('ul#select-options-'+lastID).remove();
    }

    // If destroying the select, remove the selelct-id and reset it to it's uninitialized state.
    if(callback === 'destroy') {
      $select.data('select-id', null).removeClass('initialized');
      return;
    }

    var uniqueID = Materialize.guid();
    $select.data('select-id', uniqueID);
    var wrapper = $('<div class="select-wrapper"></div>');
    wrapper.addClass($select.attr('class'));
    var options = $('<ul id="select-options-' + uniqueID +'" class="dropdown-content select-dropdown ' + (multiple ? 'multiple-select-dropdown' : '') + '"></ul>'),
        selectChildren = $select.children('option, optgroup'),
        valuesSelected = [],
        optionsHover = false;

    var label = $select.find('option:selected').html() || $select.find('option:first').html() || "";

    // Function that renders and appends the option taking into
    // account type and possible image icon.
    var appendOptionWithIcon = function(select, option, type) {
      // Add disabled attr if disabled
      var disabledClass = (option.is(':disabled')) ? 'disabled ' : '';
      var optgroupClass = (type === 'optgroup-option') ? 'optgroup-option ' : '';

      // add icons
      var icon_url = option.data('icon');
      var classes = option.attr('class');
      if (!!icon_url) {
        var classString = '';
        if (!!classes) classString = ' class="' + classes + '"';

        // Check for multiple type.
        if (type === 'multiple') {
          options.append($('<li class="' + disabledClass + '"><img alt="" src="' + icon_url + '"' + classString + '><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'));
        } else {
          options.append($('<li class="' + disabledClass + optgroupClass + '"><img alt="" src="' + icon_url + '"' + classString + '><span>' + option.html() + '</span></li>'));
        }
        return true;
      }

      // Check for multiple type.
      if (type === 'multiple') {
        options.append($('<li class="' + disabledClass + '"><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'));
      } else {
        options.append($('<li class="' + disabledClass + optgroupClass + '"><span>' + option.html() + '</span></li>'));
      }
    };

    /* Create dropdown structure. */
    if (selectChildren.length) {
      selectChildren.each(function() {
        if ($(this).is('option')) {
          // Direct descendant option.
          if (multiple) {
            appendOptionWithIcon($select, $(this), 'multiple');

          } else {
            appendOptionWithIcon($select, $(this));
          }
        } else if ($(this).is('optgroup')) {
          // Optgroup.
          var selectOptions = $(this).children('option');
          options.append($('<li class="optgroup"><span>' + $(this).attr('label') + '</span></li>'));

          selectOptions.each(function() {
            appendOptionWithIcon($select, $(this), 'optgroup-option');
          });
        }
      });
    }

    options.find('li:not(.optgroup)').each(function (i) {
      $(this).click(function (e) {
        // Check if option element is disabled
        if (!$(this).hasClass('disabled') && !$(this).hasClass('optgroup')) {
          var selected = true;

          if (multiple) {
            $('input[type="checkbox"]', this).prop('checked', function(i, v) { return !v; });
            selected = toggleEntryFromArray(valuesSelected, $(this).index(), $select);
            $newSelect.trigger('focus');
          } else {
            options.find('li').removeClass('active');
            $(this).toggleClass('active');
            $newSelect.val($(this).text());
          }

          activateOption(options, $(this));
          $select.find('option').eq(i).prop('selected', selected);
          // Trigger onchange() event
          $select.trigger('change');
          if (typeof callback !== 'undefined') callback();
        }

        e.stopPropagation();
      });
    });

    // Wrap Elements
    $select.wrap(wrapper);
    // Add Select Display Element
    var dropdownIcon = $('<span class="caret">&#9660;</span>');
    if ($select.is(':disabled'))
      dropdownIcon.addClass('disabled');

    // escape double quotes
    var sanitizedLabelHtml = label.replace(/"/g, '&quot;');

    var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID +'" value="'+ sanitizedLabelHtml +'"/>');
    $select.before($newSelect);
    $newSelect.before(dropdownIcon);

    $newSelect.after(options);
    // Check if section element is disabled
    if (!$select.is(':disabled')) {
      $newSelect.dropdown({'hover': false, 'closeOnClick': false});
    }

    // Copy tabindex
    if ($select.attr('tabindex')) {
      $($newSelect[0]).attr('tabindex', $select.attr('tabindex'));
    }

    $select.addClass('initialized');

    $newSelect.on({
      'focus': function (){
        if ($('ul.select-dropdown').not(options[0]).is(':visible')) {
          $('input.select-dropdown').trigger('close');
        }
        if (!options.is(':visible')) {
          $(this).trigger('open', ['focus']);
          var label = $(this).val();
          var selectedOption = options.find('li').filter(function() {
            return $(this).text().toLowerCase() === label.toLowerCase();
          })[0];
          activateOption(options, selectedOption);
        }
      },
      'click': function (e){
        e.stopPropagation();
      }
    });

    $newSelect.on('blur', function() {
      if (!multiple) {
        $(this).trigger('close');
      }
      options.find('li.selected').removeClass('selected');
    });

    options.hover(function() {
      optionsHover = true;
    }, function () {
      optionsHover = false;
    });

    $(window).on({
      'click': function () {
        multiple && (optionsHover || $newSelect.trigger('close'));
      }
    });

    // Add initial multiple selections.
    if (multiple) {
      $select.find("option:selected:not(:disabled)").each(function () {
        var index = $(this).index();

        toggleEntryFromArray(valuesSelected, index, $select);
        options.find("li").eq(index).find(":checkbox").prop("checked", true);
      });
    }

    // Make option as selected and scroll to selected position
    var activateOption = function(collection, newOption) {
      if (newOption) {
        collection.find('li.selected').removeClass('selected');
        var option = $(newOption);
        option.addClass('selected');
        options.scrollTo(option);
      }
    };

    // Allow user to search by typing
    // this array is cleared after 1 second
    var filterQuery = [],
        onKeyDown = function(e){
          // TAB - switch to another input
          if(e.which == 9){
            $newSelect.trigger('close');
            return;
          }

          // ARROW DOWN WHEN SELECT IS CLOSED - open select options
          if(e.which == 40 && !options.is(':visible')){
            $newSelect.trigger('open');
            return;
          }

          // ENTER WHEN SELECT IS CLOSED - submit form
          if(e.which == 13 && !options.is(':visible')){
            return;
          }

          e.preventDefault();

          // CASE WHEN USER TYPE LETTERS
          var letter = String.fromCharCode(e.which).toLowerCase(),
              nonLetters = [9,13,27,38,40];
          if (letter && (nonLetters.indexOf(e.which) === -1)) {
            filterQuery.push(letter);

            var string = filterQuery.join(''),
                newOption = options.find('li').filter(function() {
                  return $(this).text().toLowerCase().indexOf(string) === 0;
                })[0];

            if (newOption) {
              activateOption(options, newOption);
            }
          }

          // ENTER - select option and close when select options are opened
          if (e.which == 13) {
            var activeOption = options.find('li.selected:not(.disabled)')[0];
            if(activeOption){
              $(activeOption).trigger('click');
              if (!multiple) {
                $newSelect.trigger('close');
              }
            }
          }

          // ARROW DOWN - move to next not disabled option
          if (e.which == 40) {
            if (options.find('li.selected').length) {
              newOption = options.find('li.selected').next('li:not(.disabled)')[0];
            } else {
              newOption = options.find('li:not(.disabled)')[0];
            }
            activateOption(options, newOption);
          }

          // ESC - close options
          if (e.which == 27) {
            $newSelect.trigger('close');
          }

          // ARROW UP - move to previous not disabled option
          if (e.which == 38) {
            newOption = options.find('li.selected').prev('li:not(.disabled)')[0];
            if(newOption)
              activateOption(options, newOption);
          }

          // Automaticaly clean filter query so user can search again by starting letters
          setTimeout(function(){ filterQuery = []; }, 1000);
        };

    $newSelect.on('keydown', onKeyDown);
  });

  function toggleEntryFromArray(entriesArray, entryIndex, select) {
    var index = entriesArray.indexOf(entryIndex),
        notAdded = index === -1;

    if (notAdded) {
      entriesArray.push(entryIndex);
    } else {
      entriesArray.splice(index, 1);
    }

    select.siblings('ul.dropdown-content').find('li').eq(entryIndex).toggleClass('active');

    // use notAdded instead of true (to detect if the option is selected or not)
    select.find('option').eq(entryIndex).prop('selected', notAdded);
    setValueToInput(entriesArray, select);

    return notAdded;
  }

  function setValueToInput(entriesArray, select) {
    var value = '';

    for (var i = 0, count = entriesArray.length; i < count; i++) {
      var text = select.find('option').eq(entriesArray[i]).text();

      i === 0 ? value += text : value += ', ' + text;
    }

    if (value === '') {
      value = select.find('option:disabled').eq(0).text();
    }

    select.siblings('input.select-dropdown').val(value);
  }
};

}( jQuery ));