;
/*************************************************************
 *
 * Copyright (c) 2024 ysrock Co., Ltd.	<info@ysrock.co.jp>
 * Copyright (c) 2024 Yasuo Sugano	<sugano@ysrock.co.jp>
 *
 * Version	: 0.3.1
 * Update	  : 2024.01.15
 *
 ************************************************************/
'use strict';
(function($){
  
  
  /**
   * 非同期通信
   * $.fn.ysAjax();
   * $('form').ysAjax();
   *
   *  @return object $obj
   *                 object $options
   *                 callback $fail
   */
  let ysAjax = {
    construct : function( opts ){
      let result = {
        options: {}
       ,fail: null
      };

      result.options = {
        url: $(this).attr('action') ? $(this).attr('action') : ""
       ,method: $(this).attr('method') ? $(this).attr('method') : 'GET'
       ,dataType: $(this).attr('dataType') ? $(this).attr('dataType') : 'json'
       ,cache: false
      };
      if( $(this)[0] ) result.options.data = $(this).serialize();

      result.fail = function(){
        return(function(xhr, textStatus, errorThrown){
          console.log([ xhr, textStatus, errorThrown ]);
          let message = errorThrown ? errorThrown : xhr.status + " " + textStatus;
          $.fn.ysAlert( $('<div>').text( message ).html(), {
            subject: 'エラーが発生しました'
          });
        });
      };
      
      return result;
    },
  };
  $.fn.ysAjax = function( method ){
    if( ysAjax[method] ) return ysAjax[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    else if( typeof method === 'object' || !method) return ysAjax.construct.apply( this, arguments );
    else $.error('Method' + method + ' does not exist on jQuery.ysAjax');
  };
  
  
  /**
   * アラート
   * $.fn.ysAlert( string $body, ?object $opts );
   *
   *  @param  string $body
   *  @param  ?object $opts
   *                  ?string $subject
   *                  ?array  $buttons
   *                          object $button
   *                                 string $text
   *                                 ?string $cssText
   *                                 ?string $class
   *                                 ?callback $clickEvt
   *  @return element
   *
   **
   * $( element $elem ).ysAlert('destroy');
   */
  let ysAlert = {
    construct : function( body, opts ){
      if( !body ) return;
      if( opts === undefined ) opts = {};
      if('buttons' in opts === false ) opts['buttons'] = [];
      let html = ysAlert.makeHtml( body, opts );
      let elem = $(html);
      elem = ysAlert.closeButton( elem );
      elem = ysAlert.footerButtons( elem, opts['buttons'] );
      $('body').addClass('overflowY_ysAlert').append( elem );
      $('div.wrap > div.footer > button:last', elem).focus();
      return elem;
    },
    
    'makeHtml': function( body, opts ){
      let subjectTxt = 'subject' in opts ? opts['subject'] : "";
      let html = "";
      html += "<div class=\"ysAlert\">";
      html += " <div class=\"wrap\">";
      html += "  <div class=\"header\">";
      html += "   <div class=\"subject\">" + subjectTxt + "</div>";
      html += "  </div><!-- END div.header -->";
      html += "  <div class=\"body\">" + body + "</div>";
      html += "  <div class=\"footer\">";
      html += "  </div><!-- END div.footer -->";
      html += " </div><!-- END div.wrap -->";
      html += "</div><!-- END div.ysAlert -->";
      return html;
    },
    
    'closeButton': function( elements ){
      $('div.wrap > div.header', elements).append(
        $('<div></div>')
        .addClass('close')
        .click(function(){
          $(this).closest('div.ysAlert').ysAlert('destroy');
        })
      );
      return elements;
    },
    
    'footerButtons': function( elements, buttons ){
      if( buttons.length < 1 ) buttons = [{text: '閉じる'}];
      buttons.forEach(function(btnObj, btnIdx ){ 
        if('text' in btnObj === false) return true;
        let clsTxt = 'class' in btnObj ? " class=\"" + btnObj['class'] + "\"" : "";
        let html = "<button type=\"button\"" + clsTxt + ">" + btnObj['text'] + "</button>";
        let elem = $(html);
        if('cssText' in btnObj) elem[0].style.cssText = btnObj['cssText'];
        elem.click( typeof btnObj['clickEvt'] === "function"
                  ? btnObj['clickEvt']( elem )
                  : function(){ $(this).closest('div.ysAlert').ysAlert('destroy'); }
        );
        $('div.wrap > div.footer', elements).append( elem );
      });
      return elements;
    },
    
    'destroy': function(){
      $(this).remove();
      if(!$('body > div.ysAlert')[0]) $('body').removeClass('overflowY_ysAlert');
    },
  };
  $.fn.ysAlert = function( method ){
    if( ysAlert[method] ) return ysAlert[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    else return ysAlert.construct.apply( this, arguments );
  };
  
  
  /**
   * スピナー
   * $.fn.ysSpinner( $args );
   *
   *  @param  object  $args
   *                  ?callback $args['closeButton']
   *  @return element
   *
   **
   * $( element $elem ).ysSpinner('destroy');
   */
  let ysSpinner = {
    construct : function( args ){
      if(args === undefined) args = {};
      let html = ysSpinner.makeHtml( args );
      let elem = $(html);
      elem = ysSpinner.closeButton( elem, args );
      $('body').addClass('overflowY_ysSpinner').append( elem );
      return elem;
    },
    
    'makeHtml': function( args ){
      let html = "";
      html += "<div class=\"ysSpinner\">";
      if( args.closeButton !== undefined ) html += " <div class=\"close\"></div>";
      html += " <div class=\"wrap\">";
      for( let i=0; i<8; i++) html += "  <div></div>";
      html += " </div><!-- END div.wrap -->";
      html += "</div><!-- END div.ysSpinner -->";
      return html;
    },
    
    'closeButton': function( elements, args ){
      if( args.closeButton === undefined ) return elements;
      if( typeof args.closeButton == "function" ) $('div.close', elements).click( args['closeButton']() );
      else $('div.close', elements).click(function(){ $(this).closest('div.ysSpinner').ysSpinner('destroy'); });
      return elements;
    },
    
    'destroy': function(){
      $(this).remove();
      if(!$('body > div.ysSpinner')[0]) $('body').removeClass('overflowY_ysSpinner');
    },
  };
  $.fn.ysSpinner = function( method ){
    if( ysSpinner[method] ) return ysSpinner[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    else if( typeof method === 'object' || !method) return ysSpinner.construct.apply( this, arguments );
    else $.error('Method' + method + ' does not exist on jQuery.ysSpinner');
  };


  /**
   * ログインタイムアウト
   * $.fn.ysTimeout( $milliseconds );
   *
   *  @param  ints  $milliseconds
   *  @return int $timeoutId
   *
   **
   * $.fn.ysTimeout('clear');
   *
   */
  let ysTimeout = {
    construct : function( msec ){
      if (msec === undefined) msec = 5;
      this.timeoutID = setTimeout( () => {
        $.fn.ysAlert( 'セッションがタイムアウトしました', {
          buttons: [{
            text: 'ログイン画面へ',
            clickEvt: function(){
              return(function(){
                location.href = '/';
              });
            }
          }]
        });
      }, msec);
    },

    'clear': function(){
      if (typeof this.timeoutID !== "number") return;
      clearTimeout( this.timeoutID );
    }
  };
  $.fn.ysTimeout = function( method ){
    if( ysTimeout[method] ) return ysTimeout[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    else if( typeof method === 'number' || !method) return ysTimeout.construct.apply( this, arguments );
    else $.error('Method' + method + ' does not exist on jQuery.ysTimeout');
  };


  /**
   * 多次元オブジェクトからURLパラメータに変換
   *    $.fn.ysObject2URLparam( $object );
   *
   *      @param object $object
   *      @param string $URLparam
   **/
  let ysObject2URLparam = {
    construct : (obj) => {
      return ysObject2URLparam.checkType("", "", obj);
    },
    checkType: (URLparam, key, unknown) => {
      if (unknown === null) return URLparam;
      if (Array.isArray(unknown)) {
        unknown.forEach((val, idx) => URLparam = ysObject2URLparam.checkType(URLparam, key ? key + "[" + idx + "]" : idx, val));
      } else if (typeof unknown == "object") {
        Object.entries(unknown).forEach(([objKey, objVal]) => URLparam = ysObject2URLparam.checkType(URLparam, key ? key + "[" + objKey + "]" : objKey, objVal));
      } else {
        if (URLparam) URLparam += "&";
        URLparam += key + "=" + unknown;
      };
      return URLparam;
    },
  };
  $.fn.ysObject2URLparam = ( method ) => {
    if( ysObject2URLparam[method] ) return ysObject2URLparam[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    else if( typeof method === 'object') return ysObject2URLparam.construct(method);
    else if( typeof method === 'number' || !method) return ysTimeout.construct.apply( this, arguments );
    else $.error('Method' + method + ' does not exist on jQuery.ysObject2URLparam');
  };
  
  
  
})(jQuery);