
$(document).ready(function(){



  Cropper.setDefaults({
      viewMode: 1,
      autoCropArea: 0.9
  })

  // Grab elements, create settings, etc.
  var video = document.getElementById('video');
  var snapCanvas = document.getElementById('canvas');
  var snapContext = snapCanvas.getContext('2d');
  var simuCanvas = document.getElementById("simuCanvas");
  var simuContext = simuCanvas.getContext("2d");

  var simuLastPoint = { x: 0, y: 0, color: 0};
  var simuZoom = 1;
  var binary_level = 100
  var url = document.location.origin
  var cropper = null
  var snap = null


  /*
  Helpers
  */

  var errBack = function(e) {
    console.log('An error has occurred!', e)
  };

  var Point = function( l ){
    return {
      "x" : l[0],
      "y" : l[1],
      "color" : l[2]
    }
  }

  /**
  Take a new snapshot from the camera and store it
  **/
  function videoToSnap(){
    showSnap(video, video.width, video.height)
  }

  function showSnap(src, width, height){
    canvas.height = height
    cropper && cropper.destroy()
    snapContext.drawImage(src, 0, 0, width, height);
    snap =  snapContext.createImageData(width, height); 
    snap.data.set( snapContext.getImageData(0, 0, width, height).data )
    binary(snapContext)
    $(".result").show()
    cropper = new Cropper(snapCanvas);
    // Animation removed: it was causing problems with the send button. Fix.
    //$('html, body').animate({scrollTop: $("#result").offset().top}, 2000);
  }

  function doContrast(){
    let cropperData = {}
    if( cropper ){
     	cropperData = cropper.getData() 
    	cropper.destroy()
    }
    snapContext.putImageData(snap,0,0)
    binary(snapContext)
    cropper = new Cropper(snapCanvas);
    setTimeout( () => { cropper.setData(cropperData) ; },30)
  }


  /*
     To convert image into binary , we will threshold it.
     Based upon the threshold value
     thresh_red, thresh_blue, thresh_green ==> are the respective red, blue and green color threshold values. Any thing above this threshold value will be denoted by white color and anything below will be black
   */
  function binary(context){
      var image = context.getImageData(0, 0, context.canvas.width, context.canvas.height);
      var channels = image.data.length/4;
      for(var i=0;i<channels;i++){
          var r = image.data[i*4 + 0];
          var g = image.data[i*4 + 1];
          var b = image.data[i*4 + 2];
          if( r>= binary_level ){
              image.data[i*4 + 0] = 255;
              image.data[i*4 + 1] = 255;
              image.data[i*4 + 2] = 255;
          }else{
              image.data[i*4 + 0] = 0;
              image.data[i*4 + 1] = 0;
              image.data[i*4 + 2] = 0;
          }
      }
      context.putImageData(image, 0,  0);

  }


  function processFiles(files) {
    var file, img;
    var _URL = window.URL || window.webkitURL;
    if ((file = files[0])) {
        img = new Image();
        var objectUrl = _URL.createObjectURL(file);
        img.onload = function () {
            let w = 640;
            let h = 640 * this.height / this.width;
            showSnap(this,w,h);
        };
        img.src = objectUrl;
    }

  }


  // Draws every segment received, except black colored target ones
  var drawSimu = function() {
    pointsList = document.pointsList
      if (pointsList.length > 0)
      {
      	simuContext.clearRect(0,0,simuCanvas.width,simuCanvas.height);
        simuLastPoint = new Point(pointsList[0])
        for (var i = 0; i < pointsList.length; i+=1)
        {
          point = new Point(pointsList[i])
          // if the target is black, skip drawing
          if( point.color != 0){
            simuContext.beginPath()
            simuContext.shadowBlur = 5;
            simuContext.shadowColor = 'rgba(255, 255, 255, 1)';
            simuContext.lineWidth = 2;
            simuContext.strokeStyle = "#"+(point.color + Math.pow(16, 6)).toString(16).slice(-6);
            simuContext.moveTo(simuLastPoint.x * simuZoom, simuLastPoint.y * simuZoom);
            simuContext.lineTo(point.x * simuZoom, point.y * simuZoom);
            simuContext.stroke();
            simuContext.closePath()
          }
          simuLastPoint = point
        }
      }
  }

  function refreshImageList(){
    var imageList = localStorage.getItem("imageList") ? JSON.parse(localStorage.getItem("imageList"))  : []
    if( 0 == imageList.length){
      $("#preview").hide()
      return
    }
    $("#preview").show()
    html = ''
    for( id in imageList.reverse()){
      hash_name = imageList[id]
      html += `<li class="list-group-item"><a href="#${hash_name}" class="hash_name btn-sm btn btn-secondary" rel="${hash_name}">${hash_name}</a></li>`
    }
    $("#imageList").html(`<ul class="list-group">${html}</ul>`)
  }



  var showImage  = function(e){
    var el = $(e.target)
    if( ! el.hasClass("hash_name") ) { return; }
    var hash_name = el.attr("rel")
    var u  = `${url}/hash_name/${hash_name}`
    $.ajax({
      timeout: 3000,
      url: `${url}/hash_name/${hash_name}`,
      dataType: "json",

    }).done(function(d,m,j){
        if( d.errors ){
          msg =  d.errors.join(" / ")
          $("#messages").html(`<div class="alert alert-danger" role="alert">Something went wrong: ${msg}</div>`)
          return
        }
        $("#messages").html("")
        document.pointsList = d.points_list
        drawSimu()
      })
    .fail(function(d,m,jq){
        $("#messages").html(`<div class="alert alert-danger" role="alert">Ooops... Something went wrong: ${jq}</div>`)
      })
  }

  // Trigger photo take
  $('.snap').on('click', function() {
    videoToSnap()
  });

  $( "#slider" ).slider({
    range: false,
    value: 100,
    animate: 300,
    min : 0,
    max : 255,
    change: function(event,ui){
        binary_level = ui.value
        doContrast()
      }
  });

  $(".contrast").on("click",function(el){
    let btn = el.target
    let val = Number($(btn).attr("rel"))
    let new_binary_level = binary_level + val;
    if( new_binary_level >= 0 && new_binary_level <= 255){
      binary_level = new_binary_level
      $("#slider").slider("option","value",binary_level)
    }
  })

  
  $("#imageList").on("click", showImage)
  $("#messages").on("click", showImage)

  $("#send").on("click",function(){
    var cropCanvas = cropper.getCroppedCanvas();
    image_data = cropCanvas.toDataURL();
    $("#messages").html('<div class="alert alert-primary" role="alert">Sending...</div>')

    $.ajax({
  timeout: 3000,
        url: url + "/image",
        method:"POST",
        dataType: "json",
        data:{
            image_data : image_data,
            text : $("#text").val()
          },

      }).done(function(d,m,j){
          if( d.errors ){
            msg =  d.errors.join(" / ")
            $("#messages").html(`<div class="alert alert-danger" role="alert">Something went wrong: ${msg}</div>`)
            return
          }
          $("#messages").html(`<div class="alert alert-success" role="alert">OK, your image will be available in a few seconds as <a href="#${d.hash_name}" class="hash_name btn btn-sm btn-secondary" rel="${d.hash_name}">${d.hash_name}</a></div>`)
          imageList = localStorage.getItem("imageList") ? JSON.parse(localStorage.getItem("imageList"))  : []
          imageList.push(d.hash_name)
          localStorage.setItem("imageList",JSON.stringify(imageList))
          refreshImageList()
        })
      .fail(function(d,m,jq){
          $("#messages").html(`<div class="alert alert-danger" role="alert">Ooops... Something went wrong: ${jq}</div>`)

        })
  })

  $('#uploadBtn').on('click', function(e) {
      e.stopPropagation();
      e.preventDefault();
      //trigger default file upload button
      uploadInput.click();
  });
   
  $('#uploadInput').on('change', function() {
      //retrieve selected uploaded files data
      var files = $(this)[0].files;
      processFiles(files);    
      return false;
  });

  refreshImageList()

})
