import * as dzsapHelpers from '../_dzsap_helpers';

const dzsapConstants = require('../../configs/_constants').constants;
window.dzsap_wavesurfer_load_attempt = 0;

export const wave_mode_canvas_try_to_get_pcm = function (selfClass, pargs) {


  var margs = {};

  var $ = jQuery;

  if (pargs) {
    margs = $.extend(margs, pargs);
  }
  var self = this;

  // console.log('this -5 ', this);

  var o = selfClass.initOptions;

  if (selfClass.src_real_mp3 === 'fake') {
    return false;
  }


  async function tryToGetPcm() {

    function tryToLoad(resolve, reject) {

      if (selfClass.cthis.attr('data-pcm')) {


      } else {
        // -- we do not have pcm so we get it

        var data = {
          action: 'dzsap_get_pcm',
          postdata: '1',
          source: selfClass.cthis.attr('data-source'),
          playerid: selfClass.identifier_pcm
        };

        if (selfClass.urlToAjaxHandler) {
          $.ajax({
            type: "POST",
            url: selfClass.urlToAjaxHandler,
            data: data,
            success: function (response) {
              if (response) {

                if (response != '0' && response.indexOf(',') > -1) {

                  response = response.replace(' data-pcm=\'', '');
                  response = response.replace('\'', '');
                  selfClass.cthis.attr('data-pcm', response);
                  selfClass.isRealPcm = true;

                  resolve({
                    resolve_type: 'success'
                  });

                } else {
                  // -- response but malformed
                  resolve({
                    resolve_type: 'error',
                    error_type: 'empty_response'
                  });
                }

                // console.log('pcm_try_to_generate - ',pcm_try_to_generate);
              } else {
                // -- no response


                // -- cue will generate
                if (selfClass.initOptions.cue === 'on') {
                  resolve({
                    resolve_type: 'error',
                    error_type: 'empty_response'
                  });
                } else {
                  selfClass.isPcmPromisingToGenerateOnMetaLoad = true; // -- we are promising generating on meta load
                  if (o.pcm_data_try_to_generate_wait_for_real_pcm === 'on') {
                    var default_pcm = [];
                    for (var i3 = 0; i3 < 200; i3++) {
                      default_pcm[i3] = Number(Math.random()).toFixed(2);
                    }
                    default_pcm = JSON.stringify(default_pcm);
                    self.scrubModeWave__transitionIn(selfClass, default_pcm);
                    selfClass.isRealPcm = false;

                    scrubModeWave__checkIfWeShouldTryToGetPcm(selfClass)
                    resolve({
                      resolve_type: 'success'
                    });
                  }
                }
              }

            },
            error: function (arg) {
              resolve({
                resolve_type: 'error'
              });
            }
          });
        } else {

        }
      }
    }

    return new Promise((resolve, reject) => {
      tryToLoad(resolve, reject);
    });
  }

  try {
    tryToGetPcm().then(r => {
      if (r.resolve_type == 'success') {

        setTimeout(function () {


          selfClass.cthis.addClass('scrubbar-loaded');
          selfClass.calculate_dims_time();
          setTimeout(function () {

            // calculate_dims();

          }, 100);
        }, 100);
      }
      if (r.resolve_type == 'error') {
        selfClass.isPcmTryingToGenerate = true;
        scrubModeWave__initGenerateWaveData(selfClass, {
          'call_from': 'pcm_data_try_to_generate .. no get call success'
        });
      }
    });
  } catch (error) {

    console.log('error - ', error);
    // Here, `error` would be an `Error` (with stack trace, etc.).
    // Whereas if you used `throw 400`, it would just be `400`.
  }


}


var dzsapWaveRender = this;

export function scrubModeWave__checkIfWeShouldTryToGetPcm(selfClass, pargs) {

  let isWeShouldGetPcm = false;
  // console.log('scrubModeWave__checkIfWeShouldTryToGetPcm()', dzsapWaveRender);


  if (selfClass.isPcmTryingToGenerate) {
    return false;
  }


  if (selfClass.isPcmPromisingToGenerateOnMetaLoad) {
    selfClass.isPcmTryingToGenerate = true;
    isWeShouldGetPcm = true;
  }

  // console.log('selfClass - ', selfClass);
  if (!(selfClass.cthis.attr('data-pcm'))) {
    // console.log('selfClass - ', selfClass);


    if (!selfClass.urlToAjaxHandler) {

      // -- if we do not have url to ajax handler then it's clear we should generate smth..

      selfClass.isPcmTryingToGenerate = true;
      isWeShouldGetPcm = true;
    }

  }

  if (isWeShouldGetPcm) {
    scrubModeWave__initGenerateWaveData(selfClass, {
      'call_from': 'pcm_data_try_to_generate .. no data-pcm'
    });
  }
}

export function view_drawCanvases(selfClass, argpcm, calledFrom) {
  var o = selfClass.initOptions;

  draw_canvas(selfClass._scrubbarbg_canvas.get(0), argpcm, "#" + o.design_wave_color_bg, {
    call_from: calledFrom + '_bg',
    selfClass,
    'skinwave_wave_mode_canvas_waves_number': parseInt(o.skinwave_wave_mode_canvas_waves_number, 10),
    'skinwave_wave_mode_canvas_waves_padding': parseInt(o.skinwave_wave_mode_canvas_waves_padding, 10)
  });
  draw_canvas(selfClass._scrubbarprog_canvas.get(0), argpcm, '#' + o.design_wave_color_progress, {
      call_from: calledFrom + '_prog',
      selfClass,
      'skinwave_wave_mode_canvas_waves_number': parseInt(o.skinwave_wave_mode_canvas_waves_number, 10),
      'skinwave_wave_mode_canvas_waves_padding': parseInt(o.skinwave_wave_mode_canvas_waves_padding, 10),
    },
    true);
}

/**
 * called after random
 * called on wavesurfer error / success
 * @param selfClass
 * @param argpcm
 */
export function scrubModeWave__transitionIn(selfClass, argpcm) {

  //console.log('generate_wave_data_animate',cthis);


  selfClass._scrubbar.find('.scrub-bg-img,.scrub-prog-img').removeClass('transitioning-in');
  selfClass._scrubbar.find('.scrub-bg-img,.scrub-prog-img').addClass('transitioning-out');
  ;

  dzsapHelpers.scrubbar_modeWave_setupCanvas({
    'prepare_for_transition_in': true
  }, selfClass);

  view_drawCanvases(selfClass, argpcm, 'canvas_generate_wave_data_animate_pcm');


  setTimeout(() => {
    dzsapHelpers.scrubbar_modeWave_clearObsoleteCanvas(selfClass);
  }, 300);

  // -- warning - not always real pcm
  selfClass.isRealPcm = true;
  selfClass.scrubbar_reveal();
}


export function scrubModeWave__initGenerateWaveData(selfClass, pargs) {


  var $ = jQuery;
  var o = selfClass.initOptions;
  var margs = {
    'call_from': 'default'
    , 'call_attempt': 0
  };
  var self = this;


  if (pargs) {
    margs = $.extend(margs, pargs);
  }

  if (selfClass.isRealPcm) {
    return false;
  }

  if (selfClass.src_real_mp3 == 'fake') {
    return false;
  }


  selfClass.isPcmTryingToGenerate = true;
  if (selfClass.isPcmTryingToGenerate) {

  } else {
    setTimeout(function () {
      margs.call_attempt++;
      if (margs.call_attempt < 10) {
        scrubModeWave__initGenerateWaveData(margs);
        console.log('%c [dzsap] trying to regenerate ', dzsapConstants.DEBUG_STYLE_1);
      }
    }, 1000)
    return false;
  }


  // console.log('scrubModeWave__initGenerateWaveData()', margs);


  // console.log('init_generate_wave_data', selfClass.cthis.attr('data-source'));
  // console.log(selfClass.audioType);
  if (selfClass.audioType !== 'youtube') {

    if (window.WaveSurfer) {
      // console.log('wavesurfer already loaded');
      scrubModeWave__generateWaveData(selfClass, {
        'call_from': 'wavesurfer already loaded'
      });
    } else {


      if (o.pcm_notice == 'on') {
        selfClass.cthis.addClass('errored-out');
        selfClass.cthis.append('<div class="feedback-text pcm-notice">please wait while pcm data is generated.. </div>');
      }

      asyncLoadWaveSurfer(selfClass, self).then(r => console.log('[wavesurfer] loading done', r));

    }
  }
}


async function asyncLoadWaveSurfer(selfClass, self) {


  var scripts = document.getElementsByTagName("script");


  var baseUrl = '';
  for (var i23 in scripts) {
    if (scripts[i23] && scripts[i23].src) {
      if (scripts[i23].src.indexOf('audioplayer.js') > -1) {
        break;
      }
    }
  }
  var baseUrl_arr = String(scripts[i23].src).split('/');
  for (var i24 = 0; i24 < baseUrl_arr.length - 1; i24++) {
    baseUrl += baseUrl_arr[i24] + '/';
  }

  // console.log('baseUrl -' ,baseUrl);
  var wavesurferUrl = dzsapConstants.URL_WAVESURFER;
  if (baseUrl) {
    wavesurferUrl = baseUrl + 'wavesurfer.js';
  }

  var $ = jQuery;

  function tryToLoad_waveSurferScript(resolve, reject) {

    window.dzsap_wavesurfer_load_attempt++;

    if (window.dzsap_wavesurfer_load_attempt > 2) {
      wavesurferUrl = dzsapConstants.URL_WAVESURFER;
    }
    if (window.dzsap_wavesurfer_load_attempt < 6) {
      // console.log('load wavesurfer');
      $.ajax({
        url: wavesurferUrl,
        dataType: "script",
        success: function (arg) {
          //console.log(arg);
          scrubModeWave__generateWaveData(selfClass, {
            'call_from': 'load_script'
            , 'wavesurfer_url': wavesurferUrl
          });

          resolve('done');
        },
        error: function (arg) {

          // console.log('[wavesurfer] errored out ... ', this, arg);
          tryToLoad_waveSurferScript(resolve, reject);
        }
      });
    }
    if (window.dzsap_wavesurfer_load_attempt > 6) {
      reject('rejected');
    }
  }

  let promise = new Promise((resolve, reject) => {
    tryToLoad_waveSurferScript(resolve, reject);
  });

  let result = await promise; // wait until the promise resolves (*)

  // console.log('resolved',result);
  return result;

}

export function scrubModeWave__generateWaveData(selfClass, pargs) {

  var $ = jQuery;
  var o = selfClass.initOptions;

  var margs = {
    call_from: 'default'
  }
  var self = this;

  if (pargs) {
    $.extend(margs, pargs);
  }


  if (selfClass.src_real_mp3 !== 'fake') {

  } else {
    return false;
  }


  async function wavesurfer_renderPcm() {

    function asyncRenderPcm(resolve, reject) {
      // resolve(400);


      // -- make sure we are generating only once
      if (window.dzsap_generating_pcm) {
        setTimeout(function () {
          asyncRenderPcm(resolve, reject);
        }, 1000);
        return false;
      }
      window.dzsap_generating_pcm = true;


      var wavesurferConId = 'wavesurfer_' + Math.ceil(Math.random() * 10000);
      if (selfClass.identifier_pcm) {
        wavesurferConId = 'wavesurfer_' + selfClass.identifier_pcm;
      }
      selfClass.cthis.append('<div id="' + wavesurferConId + '" class="hidden"></div>');

      var wavesurfer = WaveSurfer.create({
        container: '#' + wavesurferConId
        , normalize: true
        , pixelRatio: 1
      });


      // -- we will not generate for this
      if (String(selfClass.cthis.attr('data-source')).indexOf('https://soundcloud.com') === 0 || selfClass.cthis.attr('data-source') === 'fake') {
        return;
      }
      if (String(selfClass.cthis.attr('data-source')).indexOf('https://api.soundcloud.com') === 0) {
      }


      // console.log('[wavesurfer] selfClass.src_real_mp3 - ' + selfClass.src_real_mp3, selfClass.src_real_mp3);
      try {
        wavesurfer.load(selfClass.src_real_mp3);
      } catch (err) {
        console.log("[wavesurfer] WAVE SURFER NO LOAD");
      }


      wavesurfer.on('ready', function () {
        //            wavesurfer.play();
        console.log('[dzsap] [wavesurfer] generating wave data for ', selfClass.identifier_pcm);

        var accuracy = 100;
        if (selfClass.$mediaNode_ && selfClass.$mediaNode_.duration && selfClass.$mediaNode_.duration > 1000) {
          accuracy = 100;
        }

        // console.log(selfClass.$mediaNode_, selfClass.$mediaNode_.duration);

        var pcmDataArr = [];
        var pcmDataString = '';
        if (wavesurfer && wavesurfer.exportPCM) {

          pcmDataString = wavesurfer.exportPCM(o.wavesurfer_pcm_length, accuracy, true);

          let isPcmDataArrValid = false;
          try {
            pcmDataArr = JSON.parse(pcmDataString);

            for (let i in pcmDataArr) {
              if (pcmDataArr[i] !== null && pcmDataArr[i] !== 0 && pcmDataArr[i] !== "0") {
                isPcmDataArrValid = true;
              }
            }
          } catch (err) {
            isPcmDataArrValid = false;
          }
          if (!isPcmDataArrValid) {
            pcmDataArr = wavesurfer.backend.getPeaks(margs.wavesurfer_pcm_length, 0, margs.wavesurfer_pcm_length);
          }

          for (let i in pcmDataArr) {
            if (pcmDataArr[i] !== null && pcmDataArr[i] !== 0 && pcmDataArr[i] !== "0") {
              pcmDataArr[i] = Math.abs(Number(Number(pcmDataArr[i]).toFixed(2)));
            }
          }
        } else {
          pcmDataArr = dzsapHelpers.generateFakeArrayForPcm();
        }

        pcmDataString = JSON.stringify(pcmDataArr);
        resolve({
          resolve_type: 'success',
          pcm_data: pcmDataString
        })
      });

      wavesurfer.on('error', function (err, err2) {
        reject({
          error_type: 'wavesurfer_error',
          error_message: err,
        })
      });


      setTimeout(() => {

        reject({
          error_type: 'wavesurfer_timeout',
          error_message: 'timeout',
        })

      }, dzsapConstants.WAVESURFER_MAX_TIMEOUT);
    }

    // -- end promise


    let promise = new Promise((resolve, reject) => {
      asyncRenderPcm(resolve, reject);
    });

    return promise;
  }

  wavesurfer_renderPcm().then(responsePcm => {
    // console.log('%c [dzsap] [wave] success rendering pcm - ', dzsapConstants.DEBUG_STYLE_PLAY_FUNCTIONS, responsePcm)

    scrubModeWave__sendPcm(selfClass, responsePcm.pcm_data);
    scrubModeWave__transitionIn(selfClass, responsePcm.pcm_data);
  }).catch(err => {

    var randomPcm = [];

    for (var i3 = 0; i3 < 200; i3++) {
      randomPcm[i3] = Math.abs(Number(Math.random()).toFixed(3));
    }
    randomPcm = JSON.stringify(randomPcm);

    console.log('%c [dzsap] [wave] error while generating pcm - ', dzsapConstants.DEBUG_STYLE_PLAY_FUNCTIONS, err, err.error_message)

    scrubModeWave__sendPcm(selfClass, randomPcm);
    scrubModeWave__transitionIn(selfClass, randomPcm);
  });

}

export function scrubModeWave__sendPcm(selfClass, pcmArray) {
  var $ = jQuery;


  try {
    if (pcmArray.constructor === Array) {
      pcmArray = String('[' + String(pcmArray) + ']');
    }
    // -- convert to absolute
    pcmArray = JSON.stringify(JSON.parse(String(pcmArray)).map(Math.abs));
  } catch (err) {
    console.log('%c [dzsap] [wave] error while generating pcm - ', dzsapConstants.DEBUG_STYLE_PLAY_FUNCTIONS, err, 'ar_str - ', pcmArray, typeof pcmArray);
  }

  selfClass.cthis.attr('data-pcm', pcmArray);
  if (selfClass._feed_fakeButton && selfClass._feed_fakeButton.attr) {
    selfClass._feed_fakeButton.attr('data-pcm', pcmArray);
  }
  if (selfClass._sourcePlayer && selfClass._sourcePlayer.attr) {
    selfClass._sourcePlayer.attr('data-pcm', pcmArray);
  }


  // console.log("which is fake player ? ", selfClass.cthis, selfClass._actualPlayer, _sourcePlayer);


  selfClass.cthis.find('.pcm-notice').fadeOut("fast");
  selfClass.cthis.removeClass('errored-out');


  // console.log('generating wave data for '+selfClass.cthis.attr('data-source'));
  // console.log('%c selfClass.identifier_pcm before- ','color: #dd0022; background-color: #eee;', selfClass.identifier_pcm, selfClass.cthis);

  if (!selfClass.identifier_pcm) {
    selfClass.identifier_pcm = selfClass.cthis.attr('data-source');


    if (selfClass.original_real_mp3) {
      selfClass.identifier_pcm = selfClass.original_real_mp3;
    }
  }


  // console.log('%c selfClass.identifier_pcm- ','color: #dd0022; background-color: #eee;', selfClass.identifier_pcm, selfClass.cthis);


  const data = {
    action: 'dzsap_submit_pcm'
    , postdata: pcmArray
    , playerid: selfClass.identifier_pcm
    , source: selfClass.cthis.attr('data-source')
  };


  window.dzsap_generating_pcm = false;


  if (selfClass.urlToAjaxHandler) {


    $.ajax({
      type: "POST",
      url: selfClass.urlToAjaxHandler,
      data: data,
      success: function (response) {

      }
    });
  }
}


/**
 * draw canvas here
 * @param $canvas_
 * @param pcm_arr
 * @param hexcolor
 * @param pargs
 * @param isProgressScrubContext
 * @returns {boolean}
 */
export function draw_canvas($canvas_, pcm_arr, hexcolor, pargs, isProgressScrubContext) {
  var margs = {
    'call_from': 'default',
    'is_sample': false,
    'selfClass': null,
    'sample_time_start': 0,
    'sample_time_end': 0,
    'sample_time_total': 0,
    'skinwave_wave_mode_canvas_waves_number': 2,
    'skinwave_wave_mode_canvas_waves_padding': 1,
  };

  var $ = jQuery;
  if (pargs) {
    margs = Object.assign(margs, pargs);
  }

  hexcolor = dzsapHelpers.sanitizeToHexColor(hexcolor);

  var _canvas = $($canvas_);
  var __canvas = $canvas_;
  let isWithinSample = false;
  var {selfClass, skinwave_wave_mode_canvas_waves_number, skinwave_wave_mode_canvas_waves_padding} = margs;

  // -- sanitize
  if (isNaN(Number(skinwave_wave_mode_canvas_waves_number))) {
    skinwave_wave_mode_canvas_waves_number = 2;
  }

  if (isNaN(Number(skinwave_wave_mode_canvas_waves_padding))) {
    if (skinwave_wave_mode_canvas_waves_number !== 1) {
      skinwave_wave_mode_canvas_waves_padding = 1;
    } else {

      skinwave_wave_mode_canvas_waves_padding = 0;
    }
  }


  if (selfClass) {
    var o = selfClass.initOptions;
  }
  // console.log('o - ', o);


  // console.log('[dzsap] draw_canvas() - ', margs, margs.call_from, 'hexcolor - ', hexcolor, _canvas);
  if (_canvas && _canvas.get(0)) {

  } else {
    return false;
  }

  var _canvasContext = _canvas.get(0).getContext("2d");

  var ar_str = pcm_arr;


  var waves = [];
  // console.log('selfClass - ', selfClass);
  if (selfClass && selfClass._scrubbar) {
    if (selfClass._scrubbarprog_canvas) {
      selfClass._scrubbarbg_canvas.width(selfClass._scrubbar.width());
      selfClass._scrubbarprog_canvas.width(selfClass._scrubbar.width());
      $canvas_.width = selfClass._scrubbar.width();
      $canvas_.height = selfClass._scrubbar.height();
    }
  }
  // ctx.translate(0.5, 0.5);
  // ctx.lineWidth = .5;

  _canvasContext.imageSmoothingEnabled = false;
  _canvasContext.imageSmoothing = false;
  _canvasContext.imageSmoothingQuality = "high";
  _canvasContext.webkitImageSmoothing = false;

  if (pcm_arr) {

  } else {
    setTimeout(function () {
      // draw_canvas(_arg,pcm_arr,hexcolor);
    }, 1000);
    return false;
  }

  if (typeof (ar_str) == 'object') {
    waves = ar_str;
  } else {
    try {

      waves = JSON.parse(ar_str);
    } catch (err) {
      // console.error('parse error - ',ar_str, ar_str!='');
    }
  }


  var barIndex = 0,
    max = 0;

  // console.log(ar);

  // -- normalizing
  for (barIndex = 0; barIndex < waves.length; barIndex++) {
    if ((waves[barIndex]) > max) {
      max = (waves[barIndex]);
    }
  }

  var ar_new = [];
  for (barIndex = 0; barIndex < waves.length; barIndex++) {
    ar_new[barIndex] = parseFloat(Math.abs(waves[barIndex]) / Number(max));
  }

  waves = ar_new;


  var widthCanvas;
  var heightCanvas;
  var gradient = null;


  if (selfClass) {

    __canvas.width = selfClass._scrubbar.width();
  }

  widthCanvas = __canvas.width;
  heightCanvas = __canvas.height;


  var barCount = skinwave_wave_mode_canvas_waves_number;
  var bar_space = skinwave_wave_mode_canvas_waves_padding;

  // console.log(bar_len);
  if (barCount == 1) {
    barCount = widthCanvas / barCount;
  }
  if (barCount == 2) {
    barCount = widthCanvas / 2;
  }
  if (barCount == 3) {
    barCount = (widthCanvas) / 3;
  }

  // console.log('bar_len - ',bar_len);
  // console.log('pcm_arr - ',pcm_arr);


  var reflection_size = parseFloat(o.skinwave_wave_mode_canvas_reflection_size);

  if (widthCanvas / barCount < 1) {
    barCount = Math.ceil(barCount / 3);

  }


  // console.log({reflection_size});
  var bar_w = Math.ceil(widthCanvas / barCount);
  var normal_size_ratio = 1 - reflection_size;

  // console.log("bar_w - ",bar_w);
  // console.log({normal_size_ratio});

  if (bar_w == 0) {
    bar_w = 1;
    bar_space = 0;
  }
  if (bar_w == 1) {
    bar_space = bar_space / 2;
  }
  // console.log('bar_w - ', bar_w, bar_space);


  // console.log('chh - ', chh, ' normal_size_ratio - ', normal_size_ratio, 'ar - ', ar);
  var lastBarHeight = 0;
  var searched_index = null;


  // -- left right gradient
  var temp_hex = hexcolor;
  temp_hex = temp_hex.replace('#', '');
  var hexcolors = []; // -- hex colors array
  if (temp_hex.indexOf(',') > -1) {
    hexcolors = temp_hex.split(',');
  }


  var progress_hexcolor = '';
  var progress_hexcolors = '';


  if (margs.call_from == 'spectrum') {
    progress_hexcolor = o.design_wave_color_progress;
    progress_hexcolor = progress_hexcolor.replace('#', '');
    progress_hexcolors = []; // -- hex colors array
    if (progress_hexcolor.indexOf(',') > -1) {
      progress_hexcolors = progress_hexcolor.split(',');

    }
  }


  var spectrum_isBarWithinProgress = false; // -- color the bar in progress colors

  // -- left right gradient END


  /**
   * draw with different color
   * @param i
   * @returns {boolean}
   */
  function isBeforeOrAfterSample(currBarIndex) {

    // console.log('sampleTimes - ', currBarIndex, selfClass.timeModel.sampleTimeStart, selfClass.timeModel.sampleTimeEnd, selfClass.timeModel.sampleTimeTotal);

    if ((currBarIndex / barCount < selfClass.timeModel.sampleTimeStart / selfClass.timeModel.sampleTimeTotal) || currBarIndex / barCount > selfClass.timeModel.sampleTimeEnd / selfClass.timeModel.sampleTimeTotal) {

      return true;
    }
    return false;
  }

  function view_drawBars(isReflection = false) {
    for (barIndex = 0; barIndex < barCount; barIndex++) {
      isWithinSample = false;
      _canvasContext.save();

      // console.log('ar[searched_index] - ', ar[searched_index]);
      searched_index = Math.ceil(barIndex * (waves.length / barCount));

      // -- we'll try to prevent
      if (barIndex < barCount / 5) {
        if (waves[searched_index] < 0.1) {
          waves[searched_index] = 0.1;
        }
      }
      if (waves.length > barCount * 2.5 && barIndex > 0 && barIndex < waves.length - 1) {
        waves[searched_index] = Math.abs(waves[searched_index] + waves[searched_index - 1] + waves[searched_index + 1]) / 3
      }
      // -- normalize end


      // var barh = Math.abs(ar[searched_index] * chh);
      let targetRatio = normal_size_ratio;
      if (isReflection) {
        targetRatio = reflection_size;
      }

      var barHeight = Math.abs(waves[searched_index] * heightCanvas * targetRatio);

      // -- let's try to normalize
      if (o.skinwave_wave_mode_canvas_normalize == 'on') {
        if(isNaN(lastBarHeight)){
          lastBarHeight = 0;
        }
        barHeight = barHeight / 1.5 + lastBarHeight / 2.5;
      }
      lastBarHeight = barHeight;


      _canvasContext.lineWidth = 0;
      barHeight = Math.floor(barHeight);
      // debugger;
      // if(isReflection){
      //   console.log('isReflection', {bar: waves[searched_index], barHeight, targetRatio, heightCanvas});
      // }

      // var y = chh * normal_size_ratio - barh_normal;
      var barPositionTop = isReflection ? heightCanvas * normal_size_ratio : Math.ceil(heightCanvas * targetRatio - barHeight);

      // if(isReflection){
      //   console.log('isReflection', {barPositionTop});
      // }
      _canvasContext.beginPath();
      _canvasContext.rect(barIndex * bar_w, barPositionTop, bar_w - bar_space, barHeight);

      // console.log('[dzsap] [waveform] draw rect props - ', i * bar_w, bar_w - bar_space ,barh_normal, ' bar_w - ', bar_w, 'bar_space - ',bar_space);
      // console.log('barh_normal - ', barh_normal, ' y - ', y);


      if (margs.call_from == 'spectrum') {
        if (barIndex / barCount < selfClass.timeCurrent / selfClass.timeTotal) {
          spectrum_isBarWithinProgress = true;
        } else {
          spectrum_isBarWithinProgress = false;
        }
      }


      if (selfClass.isSample) {
        isWithinSample = isBeforeOrAfterSample(barIndex);
      }
      // console.log({isWithinSample, spectrum_isBarWithinProgress});

      if (spectrum_isBarWithinProgress) {
        if (isReflection && o.skinwave_wave_mode_canvas_mode !== 'reflecto') {
          _canvasContext.fillStyle = dzsapHelpers.hexToRgb(progress_hexcolor, 0.25);
        } else {
          _canvasContext.fillStyle = isWithinSample ? dzsapHelpers.hexToRgb(progress_hexcolor, 0.5) : '#' + progress_hexcolor;
        }


        if (progress_hexcolors.length) {

          const startColor = isReflection && o.skinwave_wave_mode_canvas_mode !== 'reflecto' ? dzsapHelpers.hexToRgb('#' + progress_hexcolors[0], 0.25) : '#' + progress_hexcolors[0];
          const endColor = isReflection && o.skinwave_wave_mode_canvas_mode !== 'reflecto' ? dzsapHelpers.hexToRgb('#' + progress_hexcolors[1], 0.25) : '#' + progress_hexcolors[1];

          gradient = _canvasContext.createLinearGradient(0, 0, 0, heightCanvas);
          gradient.addColorStop(0, startColor);
          gradient.addColorStop(1, endColor);
          _canvasContext.fillStyle = gradient;
        }

      } else {
        /**
         * normal
         */

        // -- NORMAL not progress
        if (isReflection && o.skinwave_wave_mode_canvas_mode !== 'reflecto') {
          _canvasContext.fillStyle = dzsapHelpers.hexToRgb(hexcolor, 0.25);
        } else {
          // console.log({hexcolor});
          _canvasContext.fillStyle = isWithinSample ? dzsapHelpers.hexToRgb(hexcolor, 0.5) : '' + hexcolor;
        }

        // -- if we have gradient
        if (hexcolors.length) {
          const startColor = isReflection && o.skinwave_wave_mode_canvas_mode !== 'reflecto' ? dzsapHelpers.hexToRgb('#' + hexcolors[0], 0.25) : '' + hexcolors[0];
          const endColor = isReflection && o.skinwave_wave_mode_canvas_mode !== 'reflecto' ? dzsapHelpers.hexToRgb('#' + hexcolors[1], 0.25) : '' + hexcolors[1];

          gradient = _canvasContext.createLinearGradient(0, 0, 0, heightCanvas);
          gradient.addColorStop(0, startColor);
          gradient.addColorStop(1, endColor);
          _canvasContext.fillStyle = gradient;
        }
        // if (!isReflection && isProgressScrubContext) {
          // console.log('scrubProgress -  _canvasContext.fillStyle - ', _canvasContext.fillStyle, {isWithinSample});
        // }
        // if(isReflection){
        //   console.log('isReflection _canvasContext.fillStyle - ', _canvasContext.fillStyle);
        // }
      }


      if (!(isWithinSample && isProgressScrubContext)) {

        // console.log('ctx.fillStyle - ',ctx.fillStyle);
        _canvasContext.fill();
        _canvasContext.closePath();
      }


      _canvasContext.restore();

    }

  }


  _canvasContext.clearRect(0, 0, widthCanvas, heightCanvas);
  // console.log('bar_len - ', bar_len);
  view_drawBars();
  view_drawBars(true);

  // -- reflection
  setTimeout(function () {
    selfClass.scrubbar_reveal();
  }, 100)
}
