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

  let gSelectWrap;

  /**
   * 検索型セレクトボックス
   */
  $.fn.vSelect = function( opts ) {
    if (opts === undefined) opts = {};


    /**
     * 置換HTML
     */
    let repHtml = "";
    repHtml += '<div class="vSelectWrap">';
    repHtml += ' <div class="vDummy">';
    repHtml += '  <input type="text" readonly>';
    repHtml += ' </div><!-- END div.vDummy -->';
    repHtml += ' <div class="vPopup">';
    repHtml += '  <div class="vSearch">';
    repHtml += '   <input type="text" placeholder="検索">';
    repHtml += '  </div><!-- END div.vSearch -->';
    repHtml += '  <div class="vNoResult">';
    repHtml += '   <div class="vHeadline"></div>';
    repHtml += '   <div class="vPlus"></div>';
    repHtml += '  </div><!-- END div.vNoResult -->';
    repHtml += '  <div class="vHeadline">検索結果</div>';
    repHtml += '  <ul class="vSelect"></ul>';
    repHtml += '  <div class="vNoMatch"></div>';
    repHtml += ' </div><!-- END div.vPopup -->';
    repHtml += '</div><!-- END div.vSelectWrap -->';


    /**
     * 関数
     */
    let func = (function(){
      return{
        /**
         * ポップアップ開閉処理
         */
        popupVisible: function(vSelectWrap) {
          if (gSelectWrap && gSelectWrap[0]) $(gSelectWrap).removeClass('visible');
          gSelectWrap = vSelectWrap;
          $(vSelectWrap).addClass('visible');
          const vPopup = vSelectWrap.children('div.vPopup');
          vPopup.children('div.vSearch').children('input').val('').focus();
          vPopup.children('div.vNoResult').addClass('hidden');
          vPopup.children('ul.vSelect').children('li').removeClass('hidden');
          vPopup.children('div.vNoMatch').addClass('hidden');
          func.searchExec(vSelectWrap);
        },
        popupHidden: function(vSelectWrap) {
          gSelectWrap = null;
          $(vSelectWrap).removeClass('visible');
        },

        /**
         * 検索フォーム変更時
         */
        searchExec: function(vSelectWrap, thisIdx) {
          return(function() {
            const vPopup = vSelectWrap.children('div.vPopup');
            const vSearchInput = vPopup.children('div.vSearch').children('input');
            vPopup.children('div.vNoResult').addClass('hidden');
            vPopup.children('ul.vSelect').children('li').removeClass('hidden');
            vPopup.children('div.vNoMatch').addClass('hidden');
            if (!vSearchInput.val()) return;
            let isMatch = false;
            vPopup.children('ul.vSelect').children('li').each(function(idx, elem) {
              if (elem.innerText.indexOf(vSearchInput.val()) !== -1) {
                if (elem.innerText == vSearchInput.val()) isMatch = true;
                vPopup.children('div.vNoMatch').addClass('hidden');
              } else {
                $(elem).addClass('hidden');
              };
            });
            // 追加して選択する
            if (!isMatch && 'addSelectFunc' in opts && (typeof(opts['addSelectFunc']) == "function" || typeof(opts['addSelectFunc'][thisIdx]) != "undefined")) {
              vPopup.children('div.vNoResult').removeClass('hidden').children('div.vPlus').text(vSearchInput.val());
            };
            // マッチなし
            if (vPopup.children('ul.vSelect').children('li').not('.hidden').length === 0) vPopup.children('div.vNoMatch').removeClass('hidden');
          });
        }
      }
    })();



    /**
     * 他クリックで閉じる
     */
    $(document).on('click', function(e) {
      if ($(e.target).closest('div.vSelectWrap')[0] !== undefined) return;
      if (!gSelectWrap) return;
      $(gSelectWrap).removeClass('visible');
      gSelectWrap = null;
    });



    /**
     * ひとつずつ処理
     */
    $(this).each( (thisIdx, thisElem) => {
      if ($(thisElem).next('div.vSelectWrap')[0]) {
        $(thisElem).next('div.vSelectWrap').remove();
      };

      /**
       * オプション
       */
      let noMatchTxt = "一致しません";
      if ('noMatchTxt' in opts !== false) {
        if (typeof(opts['noMatchTxt']) == "string") noMatchTxt = opts['noMatchTxt'];
        else if (typeof(opts['noMatchTxt'][thisIdx]) != "undefined") noMatchTxt = opts['noMatchTxt'][thisIdx];
      };
      let maxHeight = "300px";
      if ('maxHeight' in opts !== false) {
        if (typeof(opts['maxHeight']) == "string") maxHeight = opts['maxHeight'];
        else if (typeof(opts['maxHeight'][thisIdx]) != "undefined") maxHeight = opts['maxHeight'][thisIdx];
      };
      let addSelectFunc = undefined;
      if ('addSelectFunc' in opts !== false) {
        if (typeof(opts['addSelectFunc']) == "function") addSelectFunc = opts['addSelectFunc'];
        else if (typeof(opts['addSelectFunc'][thisIdx]) != "undefined") addSelectFunc = opts['addSelectFunc'][thisIdx];
      };
      let addSelectTxt = "追加して選択する";
      if ('addSelectTxt' in opts !== false) {
        if (typeof(opts['addSelectTxt']) == "string") addSelectTxt = opts['addSelectTxt'];
        else if (typeof(opts['addSelectTxt'][thisIdx]) != "undefined") addSelectTxt = opts['addSelectTxt'][thisIdx];
      };
      let selectedCallback = undefined;
      if ('selectedCallback' in opts !== false) {
        if (typeof(opts['selectedCallback']) == "function") selectedCallback = opts['selectedCallback'];
        else if (typeof(opts['selectedCallback'][thisIdx]) != "undefined") selectedCallback = opts['selectedCallback'][thisIdx];
      };


      /**
       * ラッパー
       */
      let vSelectWrap = $(repHtml);
      vSelectWrap.css({
        'display': 'inline',
        'margin': $(thisElem).css('margin'),
        'width': $(thisElem).css('width'),
        'font-size': $(thisElem).css('font-size')
      });

      /**
       * 疑似SELECT
       */
      vSelectWrap.children('div.vDummy').children('input').css({
        'border': $(thisElem).css('border'),
        'font-size': $(thisElem).css('font-size'),
        'outline': $(thisElem).css('outline')
      }).val( $('option:selected', thisElem).text() ).click(function() {
        let parent = $(this).closest('div.vSelectWrap');
        if (parent.hasClass('visible')) func.popupHidden(parent);
        else func.popupVisible(parent);
      });

      /**
       * 追加して選択する
       */
      if (addSelectFunc === undefined) {
        vSelectWrap.children('div.vPopup').children('div.vNoResult').css('display', 'hidden');
      } else {
        vSelectWrap.children('div.vPopup').children('div.vNoResult').children('div.vHeadline').text(addSelectTxt);
      };

      /**
       * 検索フォーム
       */
      vSelectWrap.children('div.vPopup').children('div.vSearch').children('input').css({
        'font-size': $(thisElem).css('font-size')
      }).change(func.searchExec(vSelectWrap, thisIdx)).keyup(func.searchExec(vSelectWrap, thisIdx));

      /**
       * 追加して選択する
       */
      if (addSelectFunc !== undefined) {
        vSelectWrap.children('div.vPopup').children('div.vNoResult').children('div.vPlus').click(function() {
          if (!addSelectFunc( $(this).html(), thisElem[thisIdx] )) return;
          let vSelectWrap = $(this).closest('div.vSelectWrap');
          vSelectWrap.children('div.vDummy').children('input').val( $(this).text() ).trigger('click');
          vSelectWrap.children('div.vPopup').children('ul.vSelect').append('<li data-value="' + $(this).text() + '">' + $(this).text() + '</li>');
        });
      };

      /**
       * 仮想SELECT
       */
      const vSelect = vSelectWrap.children('div.vPopup').children('ul.vSelect').css({
        'max-height': maxHeight,
        'font-size': $(thisElem).css('font-size')
      });
      $('option', thisElem).each(function() {
        vSelect.append('<li data-value="' + $(this).val() + '">' + $(this).text() + '</li>');
      });
      // click
      $(vSelect).on('click', 'li', function(e) {
        $(thisElem).val( $(this).attr('data-value') ).trigger('change');
        $(this).closest('div.vSelectWrap').children('div.vDummy').children('input').val( $(this).text() ).trigger('click');
      });
      // callback
      if (selectedCallback) {
        $(vSelect).on('click', 'li', selectedCallback());
      };

      /**
       * マッチなし
       */
      vSelectWrap.children('div.vPopup').children('div.vNoMatch').html(noMatchTxt);

      // 置換
      $(thisElem).after(vSelectWrap).css('display', 'none');
    });

  };
})(jQuery);