<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Videos</title>

  <link rel="stylesheet" href="./styles.css"/>
</head>
<body>
  <div class="controls">
    <div class="rgb">
      <label for="red">Red min</label>
      <input type="range" name="rmin" min="0" max="255" />
      <label for="red">Red máx</label>
      <input type="range" name="rmax" min="0" max="255" />

      <label for="green">Green min</label>
      <input type="range" name="gmin" min="0" max="255" />
      <label for="green">Green máx</label>
      <input type="range" name="gmax" min="0" max="255" />

      <label for="blue">Blue min</label>
      <input type="range" name="bmin" min="0" max="255" />
      <label for="blue">Blue máx</label>
      <input type="range" name="bmax" min="0" max="255" />
    </div>

    <div class="toggle-filters">
      <label for="toggleFilters">Red Filter</label>
      <input type="radio" name="toggleFilters" value="redEffect">
      <label for="toggleFilters">RGB Split</label>
      <input type="radio" name="toggleFilters" value="rgbSplit">
      <label for="toggleFilters">Green Screen</label>
      <input type="radio" name="toggleFilters" value="greenScreen">
      <label for="toggleFilters">No Filter</label>
      <input type="radio" name="toggleFilters" value="noFilter" checked>
    </div>

    <input type="button" name="takeScreenshot" class="btn" value="Take Screenshot">
  </div>

  <div class="player">
    <canvas id="canvas" width="640" height="480"></canvas>
    <video width="640" height="480"></video>
  </div>

  <div class="screenshots"></div>

  <script src="./scripts.js"></script>
</body>
</html>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  height: 100vh;
  background: linear-gradient(to right, #4e54c8, #8f94fb);
}

.player {
  height: 480px;
  width: 640px;
  position: relative;
}

video {
  width: 160px;
  height: 120px;
  position: absolute;
  top: -30px;
  right: -30px;
  z-index: 10;
}

canvas {
  position: absolute;
  z-index: 1;
  background: #fff;
}

.screenshots {
  margin: -100px 100px 0;
  width: 90%;
  height: 130px;
}

.screenshots img {
  width: 120px;
  padding: 12px 10px 30px;
  box-shadow: 0 0 3px rgba(0,0,0,0.2);
  background: white;
  margin-right: 15px;
}

.controls {
  width: 20vw;
  margin-right: 80px;
  margin-bottom: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}

.controls .rgb {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 30px;
}

.controls .rgb * {
  margin-bottom: 10px;
}

.controls > * {
  margin: 5px 5px;
}

.controls .toggle-filters {
  display: flex;
  align-items: center;
  text-align: center;
  margin-bottom: 40px;
}

.btn {
  width: 120px;
  height: 30px;
  background: #db0bcb;
  color: #fff;
  border-radius: 5px;
  border: none;
  outline: none;
}

.screenshots a:nth-child(5n+1) img { transform: rotate(10deg); }
.screenshots a:nth-child(5n+2) img { transform: rotate(-2deg); }
.screenshots a:nth-child(5n+3) img { transform: rotate(8deg); }
.screenshots a:nth-child(5n+4) img { transform: rotate(-11deg); }
.screenshots a:nth-child(5n+5) img { transform: rotate(12deg); }

@media screen and (max-width: 550px) {
  body {
    justify-content: space-around;
    flex-direction: column;
  }

  canvas,
  .player {
    width: 280px;
    height: 180px;
  }

  .player {
    align-self: flex-end;
    left: -30px;
  }

  video {
    width: 120px;
    height: 90px;
    top: -20px;
    right: -20px;
  }

  .controls {
    width: 89vw;
    margin: 0;
    font-size: 14px;
  }

  .controls .rgb {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    margin: 0;
  }

  .controls .rgb label {
    width: 62px;
  }

  .controls .rgb input[type="range"] {
    flex-direction: row;
    flex-wrap: wrap;
    margin: 0 10px;
  }

  .controls .toggle-filters {
    margin: 0;
    position: absolute;
    top: 130px;
    width: 120px;
    align-self: flex-start;
    flex-wrap: wrap;
  }

  .controls .toggle-filters label {
    margin: 5px 10px 5px 0;
    display: inline-block;
  }

  .controls .btn {
    position: absolute;
    top: 260px;
    width: 120px;
    align-self: flex-start;
    margin: 0;
  }

  .screenshots {
    height: 65px;
    margin: 0;
  }

  .screenshots img {
    width: 10%;
    padding: 4px 6px 16px;
  }
}
const canvas = document.querySelector('canvas'),
      video = document.querySelector('video'),
      screenshotButton = document.querySelector('input[name="takeScreenshot"]'),
      context = canvas.getContext('2d');

function startCam() {
  let media = navigator.mediaDevices.getUserMedia({ video: true, audio: false });

  media.then(stream => {
    video.srcObject = stream;
    video.play();
  })
  .catch(error => console.log('Video could not be loaded', error));
}

function drawToCanvas() {
  return setInterval(() => {
    let width = video.width,
        height = video.height;

    context.drawImage(video, 0, 0, width, height);

    let pixels = context.getImageData(0, 0, width, height);
    pixels = setFilter(pixels);

    context.putImageData(pixels, 0, 0);
  }, 16);
}

function takeScreenshot() {
  let screenshot = canvas.toDataURL('image/jpeg'),
      link = document.createElement('a');

  link.href = screenshot;
  link.setAttribute('download', 'photo');
  link.textContent = 'Download Image';
  link.innerHTML = `<img src="${screenshot}" alt="Screenshot">`;

  document.querySelector('.screenshots').append(link);
}

function redEffect(pixels) {
  for (var i = 0; i < pixels.data.length; i += 4) {
    pixels.data[i + 0] = pixels.data[i + 0] + 100;
    pixels.data[i + 1] = pixels.data[i + 1] - 50;
    pixels.data[i + 2] = pixels.data[i + 2] * 0.5;
  }

  return pixels;
}

function rgbSplit(pixels) {
  for (var i = 0; i < pixels.data.length; i += 4) {
    pixels.data[i - 150] = pixels.data[i + 0];
    pixels.data[i + 500] = pixels.data[i + 1];
    pixels.data[i - 550] = pixels.data[i + 2];
  }

  return pixels;
}

function greenScreen(pixels) {
  const levels = {};

  document.querySelectorAll('.rgb input').forEach(input => {
    levels[input.name] = input.value;
  });

  for (var i = 0; i < pixels.data.length; i++) {
    let red = pixels.data[i + 0];
    let green = pixels.data[i + 1];
    let blue = pixels.data[i + 2];
    let alpha = pixels.data[i + 3];

    if (red >= levels.rmin
      && green >= levels.gmin
      && blue >= levels.bmin
      && red <= levels.rmax
      && green <= levels.gmax
      && blue <= levels.bmax) {
        pixels.data[i + 3] = 0;
      }
  }

  return pixels;
}

function setFilter(pixels) {
  const filter = document.querySelector('.toggle-filters input:checked');
  return filter.value == 'noFilter' ? pixels : window[filter.value](pixels);
}

startCam();

video.addEventListener('canplay', drawToCanvas);
screenshotButton.addEventListener('click', takeScreenshot);