;
/*************************************************************
 *
 * Copyright (c) 2023 ysrock Co., Ltd.	<info@ysrock.co.jp>
 * Copyright (c) 2023 Yasuo Sugano	<sugano@ysrock.co.jp>
 *
 * Version	: 1.1.1
 * Update	  : 2023.04.11
 *
 ************************************************************/
'use strict';
(function($){
  /**
   * 検索型セレクトボックス
   */
  $.fn.vSelect = function( opts ) {
    if (opts === undefined) opts = {};
    if ('noMatchTxt' in opts === false || !opts.noMatchTxt) opts.noMatchTxt = "一致しません";
    if ('maxHeight' in opts === false || !opts.maxHeight) opts.maxHeight = "300px";
    if ('addSelectTxt' in opts === false || !opts.addSelectTxt) opts.addSelectTxt = "追加して選択する";


    const THIS = this;


    /**
     * 入力値で検索する
     */
    const searchFunc = function(wrap) {
      return(function(){
        const searchTxt = searchElement.children('input').val();

        // 初期化：登録して選択する
        addSelectElement.addClass('hidden');
        // 初期化：検索結果
        virtualElement.children('li').removeClass('hidden');
        // 初期化：マッチなし
        noMatchElement.addClass('hidden');
        // 未入力時
        if (!searchTxt) return;

        let isMatch = false;
        // マッチするものだけ表示
        virtualElement.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 && 'addSelectFunc' in opts) addSelectElement.removeClass('hidden').children('div.plus').text(searchTxt);
        // マッチなし
        if (virtualElement.children('li').not('.hidden').length === 0) noMatchElement.removeClass('hidden');
      });
    };


    /**
     * ポップアップの開閉
     */
    globalOpenElem = null;
    const popupOpenFunc = function(wrap) {
      if (globalOpenElem) $(globalOpenElem).removeClass('visible');
      globalOpenElem = wrap;
      wrap.addClass('visible');
      $('div.popup > div.search > input', wrap).val('').focus();
      searchFunc(wrap)();
    };
    const popupCloseFunc = function(wrap) {
      globalOpenElem = null;
      wrap.removeClass('visible');
    };

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





    /**
     * 疑似SELECT
     */
    const dummyElement = $('<div class="dummy"><input type="text" readonly></div>');
    dummyElement.children('input').css({
      'border': THIS.css('border'),
      'padding': $('option', THIS).css('padding'),
      'background-color': THIS.css('background-color'),
      'font-size': THIS.css('font-size'),
      'color': THIS.css('color'),
      'line-height': THIS.css('line-height'),
      'outline': THIS.css('outline')
    }).click(function(){
      let wrap = $(this).closest('div.vSelectWrap');
      if (wrap.hasClass('visible')) popupCloseFunc(wrap);
      else popupOpenFunc(wrap);
    }).val($('option:selected', THIS).text());


    /**
     * ポップアップ
     */
    const popupElement = $('<div class="popup"></div>');


    /**
     * 検索フォーム
     */
    const searchElement = $('<div class="search"><input type="text" placeholder="検索"></div>');
    searchElement.children('input').change(searchFunc()).keyup(searchFunc());
    popupElement.append(searchElement);


    /**
     * 追加して選択する
     */
    const addSelectElement = $('<div class="addSelect"></div>');
    if ('addSelectFunc' in opts) {
      addSelectElement.append('<div class="headline">' + opts.addSelectTxt + '</div>');
      addSelectElement.append('<div class="plus"></div>');
      addSelectElement.children('div.plus').click(function(e) {
        if (!opts.addSelectFunc( $(this).html(), $(this).closest('div.vSelectWrap').children('select') )) return;
        $(this).closest('div.vSelectWrap').children('div.dummy').children('input').val( $(this).text() ).trigger('click');
        $(this).closest('div.popup').children('ul.select').append('<li data-value="' + $(this).text() + '">' + $(this).text() + '</li>');
      });
      popupElement.append(addSelectElement);
    };


    /**
     * 検索結果
     */
    const resultHeadline = $('<div class="headline">検索結果</div>');
    popupElement.append(resultHeadline);


    /**
     * 仮想SELECT
     */
    const virtualElement = $('<ul class="select"></ul>');
    virtualElement.css({
      'max-height': opts.maxHeight,
      'font-size': THIS.css('font-size')
    });
    $('option', THIS).each(function() {
      virtualElement.append('<li data-value="' + $(this).val() + '">' + $(this).text() + '</li>');
    });
    $(virtualElement).on('click', 'li', function(e) {
      $(this).closest('div.vSelectWrap').children('div.dummy').children('input').val( $(this).text() ).trigger('click');
    });
    if ('selectedCallback' in opts) {
      $(virtualElement).on('click', 'li', opts['selectedCallback']());
    };
    popupElement.append(virtualElement);


    /**
     * マッチなし
     */
    const noMatchElement = $('<div class="noMatch"></div>');
    noMatchElement.text(opts.noMatchTxt);
    popupElement.append(noMatchElement);


    /**
     * selectとvSelectを入れ替える
     */
    if (THIS.next('div.vSelectWrap')[0]) THIS.next('div.vSelectWrap').remove();
    const replaceElement = $('<div class="vSelectWrap"></div>');
    replaceElement.css('width', THIS.css('width'));
    replaceElement.css('margin', THIS.css('margin'));
    replaceElement.append( dummyElement );
    replaceElement.append( popupElement );
    THIS.after(replaceElement).css('display', 'none');

    


  };
})(jQuery);