<!--
 ************************************************************
 *
 * Copyright (c) 2024 ysrock Co., Ltd.	<info@ysrock.co.jp>
 * Copyright (c) 2024 Yasuo Sugano	<sugano@ysrock.co.jp>
 *
 * Version	: 1.1.1
 * Update	  : 2024.07.31
 *
 ************************************************************ -->

<!--
 ******************************
 *
 * template
 *
 ****************************** -->
<template>
 <div class="progressWrap" v-if="percentStr == null ? false : true" :style="('zIndex' in styleObj ? 'z-index:' + styleObj.zIndex : '')">
  <div class="whiteBox">
   <div class="progressBar">
    <div class="progress" :style="{ 'width': percentStr, 'background-image': 'url(' + imagePath + ')' }"></div>
   </div><!-- END div.progressBar -->
   <div class="progressStatus" v-html="statusStr"></div>
  </div><!-- END div.whiteBox -->
 </div><!-- END div.progressWrap -->
</template>




<!--
 ******************************
 *
 * script
 *
 ****************************** -->
<script scoped>
export default{
  setup (props) {
    const imagePath = '/commons/components/progress/imgs/progress_bar.png';
    const percentStr = Vue.ref(null);
    const statusStr = Vue.ref("");
    const styleObj = Vue.ref({});

    /**
     * 進捗バーを表示する
     *
     *   args (Array) 各プロセス
     *      closure (Closure)
     *        この中のexecuteを実行する
     *      status (String)
     *        表示する文言
     *      args (Array)
     *        クロージャにそのまま渡す
     */
    const execute = async (args) => await executeClosure.execute(args);
    const executeClosure = (() => {
      return {
        execute: (args) => {
          return new Promise(async (resolve, reject) => {
            await executeClosure.initialize();
            for (let i=0, len=args.length; i<len; i++) {
              percentStr.value = ((i+1) / (len+1) * 100) + "%";
              statusStr.value = 'status' in args[i] ? args[i].status : '処理中（' + (i+1) + ' / ' + (len+1) + '）';
              if ('closure' in args[i] === false) continue;
              let optObj = 'args' in args[i] ? args[i]['args'] : {};
              await args[i].closure.execute(optObj);
            };
            await executeClosure.terminate();
            resolve();
          });
        },
        initialize: () => {
          return new Promise((resolve, reject) => {
            percentStr.value = "0%";
            statusStr.value = "工程数を計算しています。";
            setTimeout(() => {
              resolve(); 
            }, 300);
          });
        },
        terminate: () => {
          return new Promise((resolve, reject) => {
            percentStr.value = "100%";
            statusStr.value = "処理が完了しました。";
            setTimeout(() => {
              percentStr.value = null;
              resolve(); 
            }, 1250);
          });
        },
      };
    })();



    /**
     * スタイルシートを適用させる
     */
    const setStyle = (args) => {
      if ('zIndex' in args) styleObj.value.zIndex = args.zIndex;
    };


    return {
      imagePath,
      percentStr,
      statusStr,
      execute,
      setStyle,
      styleObj,
    };
  }
}
</script>


<!--
 ******************************
 *
 * style
 *
 ****************************** -->
<style scoped>
div.progressWrap {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 12;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, .6);
}

div.progressWrap > div.whiteBox {
  position: fixed;
  left: 50%;
  z-index: 1;
  transform: translateX(-50%);
  background-color: #fff;
  text-align: center;
}

div.progressWrap > div.whiteBox > div.progressBar {
  width: 100%;
  border-width: 0;
  border-style: solid;
  border-color: #ccc;
  background-color: #f5f5f5;
  overflow: hidden;
}
div.progressWrap > div.whiteBox > div.progressBar > div.progress {
  height: 100%;
  background-repeat: repeat-x;
  animation-name: progress;
  animation-duration: 60s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  transition: width 1s ease-in-out;
}
@keyframes progress {
    0% { background-position-x: 0px; }
  100% { background-position-x: -2000px; }
}
@media print, screen and (min-width: 1025px){
  /* px */

  div.progressWrap > div.whiteBox {
    top: 50px;
    width: 600px;
    height: 200px;
    padding: 50px;
    border-radius: 6px;
    box-shadow: 2px 2px 9px 2px;
  }

  div.progressWrap > div.whiteBox > div.progressBar {
    height: 20px;
    border-top-width: 1px;
    border-right-width: 1px;
    border-radius: 5px;
  }
  div.progressWrap > div.whiteBox > div.progressStatus {
    margin-top: 20px;
    font-size: 14px;
  }
}
@media screen and (min-width: 641px) and (max-width: 1024px){
	/* px/8.5 */

  div.progressWrap > div.whiteBox {
    top: 5.8548vw;
    width: 70.2576vw;
    height: 23.4192vw;
    padding: 5.8548vw;
    border-radius: 0.7025vw;
    box-shadow: 0.2341vw 0.2341vw 1.0538vw 0.2341vw;
  }

  div.progressWrap > div.whiteBox > div.progressBar {
    height: 2.3419vw;
    border-top-width: 0.117vw;
    border-right-width: 0.117vw;
    border-radius: 0.5854vw;
  }
  div.progressWrap > div.whiteBox > div.progressStatus {
    margin-top: 2.3419vw;
    font-size: 1.6393vw;
  }
}
@media screen and (max-width: 640px){
	/* px/4 */

  div.progressWrap > div.whiteBox {
    top: 12.5vw;
    width: 90vw;
    height: 50vw;
    padding: 12.5vw;
    border-radius: 1.5vw;
    box-shadow: 0.5vw 0.5vw 2.25vw 0.5vw;
  }

  div.progressWrap > div.whiteBox > div.progressBar {
    height: 5vw;
    border-top-width: 0.25vw;
    border-right-width: 0.25vw;
    border-radius: 1.25vw;
  }
  div.progressWrap > div.whiteBox > div.progressStatus {
    margin-top: 5vw;
    font-size: 3.5vw;
  }
}
</style>