/* FORMS */

;(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, i').addClass('active')
        }else {
          $(this).siblings('label, i').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, i').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, i').addClass('active')
    })

    $(document).on('blur', input_selector, function () {
      var $inputElement = $(this)
      if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') === undefined) {
        $inputElement.siblings('label, i').removeClass('active')
      }

      if ($inputElement.val().length === 0 && $inputElement[0].validity.badInput !== true && $inputElement.attr('placeholder') !== undefined) {
        $inputElement.siblings('i').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')
          }
        }
      }
    }

    // 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')

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

      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')
      }
    })
  }); // 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 ' : ''

        // 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 src="' + icon_url + '"' + classString + '><span><input type="checkbox"' + disabledClass + '/><label></label>' + option.html() + '</span></li>'))
          } else {
            options.append($('<li class="' + disabledClass + '"><img 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 + '"><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))
            })
          }
        })
      }

      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)
          }
        },
        'touchend 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
      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));

jQuery('select').siblings('input.select-dropdown').on('mousedown', function (e) {
  if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
    if (e.clientX >= e.target.clientWidth || e.clientY >= e.target.clientHeight) {
      e.preventDefault()
    }
  }
});
