;
/*************************************************************
 *
 * Copyright (c) 2023 ysrock Co., Ltd.	<info@ysrock.co.jp>
 * Copyright (c) 2023 Yasuo Sugano	<sugano@ysrock.co.jp>
 *
 * Version	: 1.0.3
 * Update	  : 2023.04.11
 *
 ************************************************************/
'use strict';
(function($){
  $(document).ready(function(){



    /**
     * 検索型セレクトボックス
     */
    $.fn.vSelect = function( opts ) {
      if (opts === undefined) opts = {};
      if ('noMathTxt' in opts === false || !opts.noMatchTxt) opts.noMathTxt = "一致しません";
      if ('addTxt' in opts === false || !opts.addTxt) opts.addTxt = "登録して選択する";
      if ('maxHeight' in opts === false || !opts.maxHeight) opts.maxHeight = "300px";
      if ('selectedCallback' in opts === false) {
        opts.selectedCallback = function() {
          console.log([ 'selectedCallback', this ]);
        };
      };

      const THIS = this;
      const originalWidth = THIS.width();
      const originalMargin = THIS.css('margin');
      const originalPadding = THIS.css('padding');
      const originalFontSize = THIS.css('font-size');
      const originalLineHeight = THIS.css('line-height');
      let openAry = [];

      // HTML
      let insHtml = makeHtml( opts );
      // 要素化
      let insElem = $(insHtml);
      insElem.css('width', THIS.width() );


      /**
       * 置き換えINPUT
       */
      $('div.replace > input', insElem).css({
        border: THIS.css('border')
      }).click(function() {
        let vWrap = $(this).closest('div.v-wrap');
        if (vWrap.hasClass('visible')) {
          vWrap.removeClass('visible');
          openAry.pop();
        } else {
          vWrap.addClass('visible');
          openAry.push(vWrap);
          $('div.candidate > div.search > input', vWrap).val('').focus();
          $('div.candidate > div.result > ul.select > li', vWrap).removeClass('hidden');
          searchFunc(vWrap)();
        };
      });


      /**
       * 検索INPUT
       */
      let searchFunc = function(vWrap) {
        return(function(){
          const candidateElement = typeof(vWrap) == "undefined" ? $(this).closest('div.candidate') : $(vWrap).children('div.candidate');
          const addFormElement = candidateElement.children('div.addForm');
          const ulElement = candidateElement.children('div.result').children('ul.select');
          const noMatchElement = candidateElement.children('div.result').children('div.no-result');
          const searchTxt = $(this).prop('tagName') == "INPUT" ? $(this).val() : "";
          // 登録して選択する
          addFormElement.addClass('hidden');
          // 候補
          ulElement.children('li').removeClass('hidden');
          // 一致しない
          noMatchElement.addClass('hidden');

          if (!searchTxt) return;
          let isMatch = false;
          ulElement.children('li').each(function(idx, elem) {
            if (elem.innerText.indexOf(searchTxt) !== -1) {
              if (elem.innerText == searchTxt) isMatch = true;
              noMatchElement.addClass('hidden');
            } else {
              $(elem).addClass('hidden');
            };
          });

          if (!isMatch && 'addCallback' in opts) addFormElement.removeClass('hidden').children('div.plus').text(searchTxt);
          if (ulElement.children('li').not('.hidden').length === 0) noMatchElement.removeClass('hidden');
        });
      };
      $('div.candidate > div.search > input', insElem)
      .change(searchFunc())
      .keyup(searchFunc());


      /**
       * 登録して選択する
       */
      $('div.candidate > div.addForm > div.plus', insElem).click(function(e) {
        if ('addCallback' in opts === false) return;
        if (!opts.addCallback()) return;
        let elem = $('<li data-value="' + $(this).text() + '">' + $(this).text() + '</li>');
        $('div.candidate > div.result > ul.select', insElem).append( elem );
        $('div.replace > input', insElem).val( $(this).text() ).trigger('click');
      });


      /**
       * 検索候補を追加
       */
      $('option', THIS).each(function( idx, obj ) {
        let elem = $('<li data-value="' + obj.value + '">' + obj.innerText + '</li>');
        $('div.candidate > div.result > ul.select', insElem).append( elem );
      });
      $(insElem).on('click', 'div.candidate > div.result > ul.select > li', function(e) {
        $('div.replace > input', insElem).val( $(this).text() ).trigger('click');
        opts.selectedCallback();
      });


      // 表示する
      insElem.css({
        width: originalWidth,
        margin: originalMargin,
        padding: originalPadding
      }).children('div.replace').children('input').css({
        'font-size': originalFontSize,
        'line-height': originalLineHeight
      }).val($('option:selected', THIS).text());
      insElem.children('div.candidate').css({
        width: originalWidth,
        'max-height': opts.maxHeight
      });
      if (THIS.next('div.v-wrap')[0]) THIS.next('div.v-wrap').remove();
      THIS.css('display', 'none').after( insElem );


      /**
       * HTML
       */
      function makeHtml( opts ) {
        let html = "";
        html += "<div class=\"v-wrap\">";
        html += " <div class=\"replace\"><input type=\"text\" readonly></div>";
        html += " <div class=\"candidate\">";
        html += "  <div class=\"search\"><input type=\"text\" placeholder=\"検索\"></div>";
        html += "  <div class=\"addForm\">";
        html += "   <div class=\"headline\">" + opts.addTxt + "</div>";
        html += "   <div class=\"plus\"></div>";
        html += "  </div><!-- END div.addForm -->";
        html += "  <div class=\"result\">";
        html += "   <div class=\"headline\">検索結果</div>";
        html += "   <ul class=\"select\"></ul>";
        html += "   <div class=\"no-result\">" + opts.noMathTxt + "</div>";
        html += "  </div><!-- END div.result -->";
        html += " </div><!-- END div.candidate -->";
        html += "</div><!-- END div.v-wrap -->";
        return html;
      };

      /**
       * 他クリックで閉じる
       */
      $(document).on('click', function(e) {
        if ($(e.target).closest('div.v-wrap')[0] !== undefined) return;
        $(openAry[ openAry.length-1 ]).removeClass('visible');
        openAry.pop()
      });
    };

  });
})(jQuery);