<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Scattnlay web</title>
  <link rel="stylesheet" type="text/css" href="nmie.css">
<!--  <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>-->
  <script src="plotly-latest.min.js"></script>

  <!-- Yandex.Metrika counter -->
  <script type="text/javascript" >
    (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
      m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
    (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");

    ym(54984811, "init", {
      clickmap:true,
      trackLinks:true,
      accurateTrackBounce:true
    });
  </script>
  <noscript><div><img src="https://mc.yandex.ru/watch/54984811" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
  <!-- /Yandex.Metrika counter -->

</head>
<body>
<div id="Usage" style="font-size: small;">
<span style="text-decoration: underline;text-emphasis: before;">Usage:</span>
Feel free to use provided software, however, use it at your own risk. We make our best effort to verify
it is correct, however, we do not provide any warranty.
  <p>
If it was usefull for your project, please, cite in your related paper the following reference:
<div style="font-style: italic">Mie calculation of electromagnetic near-field for a multilayered sphere</div>
Konstantin Ladutenko, Umapada Pal, Antonio Rivera, Ovidio Peña-Rodríguez<br>
  <span style="font-weight: bold">Comp. Phys. Comm., vol. 214, pp. 225–230, 2017</span></p>
</div>
WL from <input type="number" id="fromWL" step="any" value="300.0">
to <input type="number" id="toWL" step="any" value="1000">
step <input type="number" id="stepWL" step="any" value="0.5"><br>
R: <input type="number" id="R" step="any" value="100">
Re(n): <input type="number" id="reN" step="any" value="4">
Im(n): <input type="number" id="imN" step="any" value="0.01"><br>
<button id="Evaluate" onclick=runMie() autofocus>Run Mie!</button> <span id="time"></span>
<div id="Selector"></div>
<div id="PlotQsca" style="height:70%;">
<!--     style="width:840px;height:580px;"-->
</div>
  <script src="nmie.js"></script>
  <script>
    'use strict';
    // var importObject = {
    //   imports: { nmie: arg => console.log(arg) }
    // };
    //
    // fetch('nmie.wasm').then(response =>
    //         response.arrayBuffer()
    // ).then(bytes =>
    //         WebAssembly.instantiate(bytes, importObject)
    // ).then(results => {
    //   results.instance.exports.nmie();
    // });
    const total_mode_n = 4;
    let mode_n, mode_types;
    let mode_names = ['E','H'];
    let WLs, layout, trace1, trace2;
    let Qsca, Qabs, Qsca_n, Qabs_n;
    const range = (start, stop, step = 1) =>
            Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step);
    if (!Array.prototype.last){
      Array.prototype.last = function(){
        return this[this.length - 1];
      };
    };
    // Module.addOnPostRun(() => {
    //   test.onclick =runMie()});
    function runMie() {
        document.getElementById("Usage").style.display = 'none';
        const nmie = new Module.nmie()
        let t0 = performance.now();
        let fromWL = parseFloat(document.getElementById("fromWL").value);
        let toWL = parseFloat(document.getElementById("toWL").value);
        let stepWL = parseFloat(document.getElementById("stepWL").value);
        let R = parseFloat(document.getElementById("R").value);
        let reN = parseFloat(document.getElementById("reN").value);
        let imN = parseFloat(document.getElementById("imN").value);
        Qsca = [], Qabs = [];
        Qsca_n = [[],[]], Qabs_n = [[],[]];
        nmie.ClearTarget();
        nmie.AddTargetLayerReIm(R, reN, imN)
        WLs = range(fromWL,toWL,stepWL)
        mode_n = range(1,total_mode_n+1)
        mode_types = range(0,2)
        mode_types.forEach(function(mode_type) {
          mode_n.forEach(function (n) {
            Qsca_n[mode_type].push([]);
            Qabs_n[mode_type].push([]);
          });
        });
        WLs.forEach(function(WL) {
          // console.log(WL)
          nmie.SetModeNmaxAndType(-1, -1);
          nmie.SetWavelength(WL);
          nmie.RunMieCalculation();
          Qsca.push(nmie.GetQsca());
          Qabs.push(nmie.GetQabs());
          mode_types.forEach(function(mode_type) {
            mode_n.forEach(function (n) {
              nmie.SetModeNmaxAndType(n,mode_type);
              nmie.RunMieCalculation();
              Qsca_n[mode_type][n-1].push(nmie.GetQsca());
              Qabs_n[mode_type][n-1].push(nmie.GetQabs());
            });
          });
        });
        // console.log('Qsca_n = ', Qsca_n);
        trace1 = {
          x: WLs,
          y: Qsca,
          type: 'scatter',
          name: 'Qsca'
        };

        trace2 = {
          x: WLs,
          y: Qabs,
          type: 'scatter',
          name: 'Qabs'
        };

        let data = [trace1, trace2];
        layout = {
          title: {
            text:'Mie calculation',
            // font: {
            //   family: 'Courier New, monospace',
            //   size: 24
            // },
            xref: 'paper',
            x: 0.05,
          },
          xaxis: {
            title: {
              text: 'Wavelength',
              // font: {
              //   family: 'Courier New, monospace',
              //   size: 18,
              //   color: '#7f7f7f'
              // }
            },
          },
          yaxis: {
            title: {
              text: 'Q',
              // font: {
              //   family: 'Courier New, monospace',
              //   size: 18,
              //   color: '#7f7f7f'
              // }
            }
          },
          margin: {
            l: 35,
            r: 25,
            b: 35,
            t: 25,
            pad: 4
          }
        };
        Plotly.newPlot('PlotQsca', data, layout, {showSendToCloud: true, displaylogo: false});
        let t1 = performance.now();
        document.getElementById("time").innerHTML = "It took " + ((t1 - t0)/1000).toFixed(2) + " s.";

        let tmp1 = " ";
        mode_types.forEach(function(mode_type) {
          tmp1 += mode_names[mode_type]+" -> ";
          mode_n.forEach(function (n) {
            tmp1 += n.toString()+
                    "<input type=\"checkbox\" id=\""+mode_names[mode_type]+n.toString()
                    +"\" unchecked onclick=\"replot();\">  ";
          });
          tmp1 += "<br>";
        });
        tmp1 +="Qabs <input type=\"checkbox\" id=\"Qabs\" checked onclick=\"replot();\">  ";
        tmp1 +="Qsca <input type=\"checkbox\" id=\"Qsca\" checked onclick=\"replot();\">  ";
        document.getElementById("Selector").innerHTML = tmp1;


      };

    function replot() {
      let checkBoxQabs = document.getElementById("Qabs");
      let checkBoxQsca = document.getElementById("Qsca");
      let data = [];
      if (checkBoxQabs.checked == true) data.push(trace2);
      if (checkBoxQsca.checked == true) data.push(trace1);
      mode_types.forEach(function(mode_type) {
        mode_n.forEach(function (n) {
          let checkBox = document.getElementById(mode_names[mode_type]+n.toString());
          if (checkBox.checked == false) return;
          if (checkBoxQsca.checked == true) {
            let trace_sca = {
              x: WLs,
              y: Qsca_n[mode_type][n - 1],
              type: 'scatter',
              name: 'Qsca ' + mode_names[mode_type] + n.toString()
            };
            data.push(trace_sca);
          };
          if (checkBoxQabs.checked == true) {
            let trace_abs = {
              x: WLs,
              y: Qabs_n[mode_type][n - 1],
              type: 'scatter',
              name: 'Qabs ' + mode_names[mode_type] + n.toString()
            };
            data.push(trace_abs);
          };
        });
      });
      Plotly.react('PlotQsca', data, layout, {showSendToCloud: true, displaylogo: false});
    }
  </script>
</body>
</html>