const canvas = document.getElementById ('canvas');
const ctx = canvas.getContext ('2d');

const bg = (
    function ()
    {
      const _ = document.createElement ('canvas');
      const img = new Image ();

      _.width = 1920;
      _.height = 1080;

      const ctx = _.getContext ('2d');

      img.onload = (
          function ()
          {
            ctx.drawImage (img, 0, 0);
          });

      img.src = './assets/bg.jpg';

      return _;
    }) ();

const nizikaList = Array (24).fill ().map (
    function (__, i)
    {
      const _ = document.createElement ('canvas');
      const img = new Image ();

      _.width = 300;
      _.height = 300;

      const ctx = _.getContext ('2d');

      img.onload = (
          function ()
          {
            ctx.drawImage (img, 0, 0);
            replaceColorWithTransparent (_);
          });

      img.src = `./assets/nizika/${String (i + 1).padStart (3, '0')}.png`;

      return _;
    });

const kitaList = Array (40).fill ().map (
    function (__, i)
    {
      const _ = document.createElement ('canvas');
      const img = new Image ();

      _.width = 428;
      _.height = 240;

      const ctx = _.getContext ('2d');

      img.onload = (
          function ()
          {
            ctx.drawImage (img, 0, 0);
          });

      img.src = `./assets/kita/${String (i + 41).padStart (3, '0')}.png`;

      return _;
    });

const upperKita = document.createElement ('canvas');

const runawayGuitar = new Audio ('./assets/kita.wav');

let canvasX;
let canvasY;
let frame = 0;

let nizikaData = [];
let kitaData = [];

const nizikaVel = 5;

let runawayFlag = false;
let runawayFrame = 0;

preprocess ();

window.setInterval (() => reDraw (), 16);


function
preprocess ()
{
  canvas.addEventListener ('click',
      function f (e)
      {
        this.removeEventListener ('click', f);

        kitaData.push ({x: e.clientX,
                        y: e.clientY});

        runawayFlag = true;
        runawayFrame = frame;

        runawayGuitar.play ();
      });

  upperKita.width = 428;
  upperKita.height = 240;

  reDraw ();
}


function
reDraw ()
{
  canvasX = window.innerWidth;
  canvasY = window.innerHeight;

  canvas.width = canvasX;
  canvas.height = canvasY;

  ctx.drawImage (bg, 0, 0, canvasX, canvasY);

  if (!(runawayFlag))
    {
      nizikaData.push ({x: Math.random () * canvasX,
                        y: Math.random () * canvasY});
    }

  if (nizikaData.length > 100)
    nizikaData.shift ();

  kitaData.forEach (
      function (kita)
      {
        ctx.drawImage (kitaList[frame % 40], kita.x - 214, kita.y - 120);
      });

  nizikaData.forEach (
      function (nizika)
      {
        ctx.drawImage (nizikaList[frame % 24], nizika.x - 150, nizika.y - 150);

        if (runawayFlag)
          {
            const l = Math.sqrt (Math.pow (kitaData[0].x - nizika.x, 2)
                                 + Math.pow (kitaData[0].y - nizika.y, 2));
            const t = Math.atan2 (kitaData[0].y - nizika.y,
                                  kitaData[0].x - nizika.x);

            nizika.x += nizikaVel * Math.cos (t);
            nizika.y += nizikaVel * Math.sin (t);
          }
      });

  if (runawayFlag)
    {
      changeAlpha (upperKita, kitaList[frame % 40],
                   Math.max (runawayFrame - frame + 85, 0) * 3);
      ctx.drawImage (upperKita, kitaData[0].x - 214, kitaData[0].y - 120);
    }

  ++frame;
}


function
replaceColorWithTransparent (canvas)
{
  const context = canvas.getContext ('2d');
  const imageData = context.getImageData (0, 0, canvas.width, canvas.height);
  const pixels = imageData.data;

  for (let i = 0; i < pixels.length; i += 4)
    {
      const r = pixels[i];
      const g = pixels[i + 1];
      const b = pixels[i + 2];

      if (r < 64 && g >= 96 && b < 96)
        pixels[i + 3] = 0;
    }

  context.putImageData (imageData, 0, 0);
}


function
changeAlpha (toCanvas, canvas, alpha)
{
  const toCtx = toCanvas.getContext ('2d');

  const ctx = canvas.getContext ('2d');
  const imageData = ctx.getImageData (0, 0, canvas.width, canvas.height);
  const pxs = imageData.data;

  for (let i = 0; i < pxs.length; i += 4)
    pxs[i + 3] = alpha;

  toCtx.putImageData (imageData, 0, 0);
}

