
var width = document.getElementById("juxtaposition").clientWidth - 10;
var xoffset = 20;
var elementWidth = 1; //width/alignedResidues[0].length;

var vizOffset = d3.select("#vizOffset").append("svg")
                                    .attr("width", width-10)
                                    .attr("height", 10);

var sequenceAlignment = d3.select("#sequenceAlignment").append("svg")
                                    .attr("width", width-20)
                                    .attr("height", 100);

var BallColors = [];

//init sequenceAlignment ball colours, juxtaZoom 
function initShit(){
  for (var i = 0; i < proteins.length; i++) {
      BallColors[i] = ['green', 'red'];
      juxtaZoom[i] = [0, ss[i].length];
  }
  globalZoom = [0, ss[0].length];
}

function redrawD3(){
    // sequenceAlignment.selectAll("*").remove();
    juxtaposition.selectAll("*").remove();
    superposition.selectAll("*").remove();
    loopDetail.selectAll("*").remove();

    for (var i = 0; i < proteins.length; i++) {
        // drawSequenceAlignment(i);
        drawJuxtaposition(i);
        drawSuperposition(i);
    }

    drawLoopsDetails();
    // for (var i = 0; i < proteins.length; i++) {
    //     if(i!==reference)drawSuperposition(i);
    // }
    // drawSuperposition(reference);
}

function drawSequenceAlignment(n){

  sequenceAlignmentRects[n] = [];

  //console.log("Reqriting sequence alignment for protein num: " + n);

  sequenceAlignment.append("text")
          .attr("y", n*45 + 10)
          .attr("x", xoffset)
          .attr('text-anchor', 'left')
          .attr("class", "myLabel")
          .text(proteins[n]);

  var radialGradient = sequenceAlignment.append("defs")
    .append("radialGradient")
      .attr("id", "radial-gradient");

  radialGradient.append("stop")
      .attr("offset", "0%")
      .attr("stop-color", BallColors[n][0]);

  radialGradient.append("stop")
      .attr("offset", "100%")
      .attr("stop-color", "#fff");

  sequenceAlignment.append("circle")
          .attr("cx", xoffset/2)
          .attr("cy", n*45 + 25)
          .attr("r", 5)
          .attr("fill", "url(#radial-gradient)")//BallColors[n][0])
          .on("click", function(d) {
            var chain = Math.round((this.cy.animVal.value - 25)/45);
            viewer.get(proteins[chain]).setOpacity((BallColors[chain][0]==="green")? 0 : 1);
            viewer.requestRedraw();
            BallColors[chain] = [BallColors[chain][1], BallColors[chain][0]]
            radialGradient.select("stop").transition().attr("offset", "0%").attr("stop-color", BallColors[n][0]);
            d3.select(this).style("fill", "url(#radial-gradient)");
          });

  for (var i = 0; i < alignedResidues[n].length; i++) {
    var aminoacid = alignedResidues[n].charAt(i);
    var rect = sequenceAlignment.append("rect")
      .attr("height", 20)
      .attr("width", Math.round(elementWidth)+2)
      .attr("x", xoffset + Math.floor(i*elementWidth))
      .attr("y", 15 + n*45)
      .style("fill", function(d) {
           var returnColor;
           if(highlighted[n] - i === 0) {
              returnColor = "#66FF00";
           } else if(highlighted[n] - i < 4 && highlighted[n] - i > 0) {
              returnColor = blendColors("#66FF00", colorMolecule[n], (highlighted[n] - i) /4);
           } else if(highlighted[n] - i > -4 && highlighted[n] - i < 0) {
              returnColor = blendColors(colorMolecule[n], "#66FF00", 1-(Math.abs(highlighted[n] - i)) /4);
           } else if (aminoacid === '-') { returnColor = "lightgray";
           } else { returnColor = colorMolecule[n];}
           return returnColor;
       })
      .on("click", function(){
            var chain = Math.round((this.y.animVal.value - 15)/45);
            //console.log(chain);
            // console.log(proteins[chain]);
            var pos = sequenceAlignmentRects[chain].findIndex(x => x === this);
            //var pos = Math.round((this.x.animVal.value - 10)/(elementWidth * 0.95));
            if(alignedResidues[chain].charAt(pos) != '-'){
                if(highlighted[chain] === pos) {
                    highlighted[chain] = 9999;
                    //redrawD3Single(chain);
                    redrawD3();
                    resetViewerSelection(chain);
                } else {
                    highlighted[chain] = pos;
                    //redrawD3Single(chain);
                    redrawD3();
                    //this.style.fill == "#66FF00";
                    highlightPV(chain, alignToNotAlign[chain][pos]);
                }
            }
      });
      sequenceAlignmentRects[n][i] = rect._groups[0][0];     
  }

  if(juxtaZoom[n][0] !== 0 || juxtaZoom[n][1] !== alignedSS[n].length){
    var xPos = xoffset + juxtaZoom[n][0]*elementWidth;
    var length = xoffset + juxtaZoom[n][1]*elementWidth - xPos;

    var juxtaZoomGroup = sequenceAlignment.append("g")
    .attr("id", "handle")
    .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended)
        );

    //removal
    var quadPoints = (xPos+length - 4) + " " + (17 + n*45) + ", "
                        + (xPos+length - 6) + " " + (17 + n*45) + ", "
                        + (xPos+length - 20) + " " + (33 + n*45) + ", "
                        + (xPos+length - 18) + " " + (33 + n*45);

    juxtaZoomGroup.append("polygon")
              .attr("fill", "white")
              .style("opacity", 0.5)
              .attr("points", quadPoints); 

    quadPoints = (xPos+length - 4) + " " + (33 + n*45) + ", "
                        + (xPos+length - 6) + " " + (33 + n*45) + ", "
                        + (xPos+length - 20) + " " + (17 + n*45) + ", "
                        + (xPos+length - 18) + " " + (17 + n*45);

    juxtaZoomGroup.append("polygon")
              .attr("fill", "white")
              .style("opacity", 0.5)
              .attr("points", quadPoints); 

    juxtaZoomGroup.append("rect")
      .attr("height", 26)
      .attr("width", 24)
      .attr("x", xPos+length-24)
      .attr("y", 12 + n*45)
      .style("fill", "gray")
      .style("opacity", 0.5);

    //adjust juxtazoom
    juxtaZoomGroup.append("rect")
      .attr("height", 26)
      .attr("width", length - 22)
      .attr("x", xPos-1)
      .attr("y", 12 + n*45)
      .style("fill", "gray")
      .style("opacity", 0.5)
      .style('cursor', 'move');

      var dragStart = 0;

    function dragstarted(d) {
      //dragStart = 0;
    }

    function dragged(d) {
      dragStart += d3.event.dx;
      //console.log(xPos+length+dragStart);
      if((xPos+dragStart) >=xoffset-1 && Math.round((xPos+length+dragStart)/elementWidth) < alignedSS[n].length) d3.select(this).attr("transform", "translate(" + dragStart + "," + 0 + ")");
    }

    function dragended(d) {
      if(dragStart === 0) {
        juxtaZoom[n]=[0, alignedSS[n].length];
      } else {
        var dragedPos0 = Math.round(juxtaZoom[n][0]+dragStart/elementWidth);
        var dragedPos1 = Math.round(juxtaZoom[n][1]+dragStart/elementWidth);
        if((xPos+dragStart) < xoffset) {
          dragedPos0 = 0;
          dragedPos1 = juxtaZoom[n][1] - juxtaZoom[n][0];
        }
        if(Math.round((xPos+length+dragStart)/elementWidth) > alignedSS[n].length) {
          dragedPos1 = alignedSS[n].length;
          dragedPos0 = alignedSS[n].length - (juxtaZoom[n][1] - juxtaZoom[n][0]);
        }

        juxtaZoom[n] = [Math.floor(dragedPos0), Math.floor(dragedPos1)];
      }
      redrawD3();
    }

  }

  //Draw Global zoom bar
  if(n === (proteins.length-1)){
    var dragStart = 0;
      globalZoom = [-1, alignedSS[n].length+1];
      var numOfZooms = 0;

      juxtaZoom.forEach(function(element){
          if(element[0]!=0 || element[1]!=alignedSS[n].length){
          numOfZooms++;
          if(globalZoom[0] > element[0] || globalZoom[0] === -1) globalZoom[0] = element[0];
          if(globalZoom[1] < element[1] || globalZoom[1] === alignedSS[n].length+1) globalZoom[1] = element[1];
          console.log(globalZoom[0]);
        }
      });

      var xPos = xoffset + globalZoom[0]*elementWidth;
      var length = xoffset + globalZoom[1]*elementWidth - xPos;

      if(numOfZooms > 1){

        var globalZoomOffset = 0;

        sequenceAlignment.append("rect")
          .attr("id", "handle")
          .attr("height", 10)
          .attr("width", length)
          .attr("x", xPos)
          .attr("y", 50 + n*45)
          .style("fill", "gray")
          .style("opacity", 0.5)
          .call(d3.drag()
              .on("start", dragstarted)
              .on("drag", globalDragged)
              .on("end", globalDragended)
              );

          function globalDragged(d) {
            globalZoomOffset += d3.event.dx;
            //console.log(xPos+length+dragStart);
            if((xPos+globalZoomOffset) >= xoffset && Math.round((xPos+length+globalZoomOffset-xoffset)/elementWidth) < alignedSS[n].length) d3.selectAll("#handle").attr("transform", "translate(" + globalZoomOffset + "," + 0 + ")");
          }

        function globalDragended(d) {
          if(globalZoomOffset === 0) {
            juxtaZoom.forEach(function(element){
                element[0] = 0;
                element[1] = alignedSS[n].length;
            });
            globalZoom = [0, alignedSS[n].length];

          } else {
            juxtaZoom.forEach(function(element){

              if(element[0]!==0 || element[1]!==alignedSS[n].length){

                var element0 = Math.round(element[0]+globalZoomOffset/elementWidth);
                var element1 = Math.round(element[1]+globalZoomOffset/elementWidth);
                if(element0 < 0) {
                  element0 = 0;
                  element1 = element[1] - element[0];
                }
                if(element1 > alignedSS[n].length) {
                  element1 = alignedSS[n].length;
                  element0 = alignedSS[n].length - (element[1] - element[0]);
                }

                element[0] = element0;
                element[1] = element1;

              }
            });
          }

          redrawD3();
        }
      } else {
        globalZoom = [0, alignedSS[n].length];
      }
      
    }
  }

  function blendColors(c0, c1, p) {
      var f=parseInt(c0.slice(1),16),t=parseInt(c1.slice(1),16),R1=f>>16,G1=f>>8&0x00FF,B1=f&0x0000FF,R2=t>>16,G2=t>>8&0x00FF,B2=t&0x0000FF;
      return "#"+(0x1000000+(Math.round((R2-R1)*p)+R1)*0x10000+(Math.round((G2-G1)*p)+G1)*0x100+(Math.round((B2-B1)*p)+B1)).toString(16).slice(1);
  }