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

function addSelection(view, n, viewElementWidth, yOffset){

    function rect(x, y, w, h) {
      return "M"+[x,y]+" l"+[w,0]+" l"+[0,h]+" l"+[-w,0]+"z";
    }

    var selection = view.append("path")
      .attr("class", "selection")
      .attr("visibility", "hidden");

    var startSelection = function(start) {
        selection.attr("d", rect(start[0], start[0], 0, 0))
          .attr("visibility", "visible");
    };

    function inBounderiesX(pos, move){
      var newPos = pos;
      if(pos < 0) newPos = 0; 
      if (pos > view.attr("width")) newPos = view.attr("width");
      return newPos - move;
    }

    function inBounderiesY(pos, move){
      var newPos = pos;
      if(pos < 0) newPos = 0; 
      if (pos > view.attr("height")) newPos = view.attr("height");
      return newPos - move;
    }

    var moveSelection = function(start, moved) {
        selection.attr("d", rect(start[0], start[1], inBounderiesX(moved[0], start[0]), inBounderiesY(moved[1], start[1])));
    };

    var endSelection = function(start, end) {
      selection.attr("visibility", "hidden");
    };

    view.on("mousedown", function() {
      var subject = d3.select(window), parent = this.parentNode,
          start = d3.mouse(parent);
        startSelection(start);
        subject
          .on("mousemove.selection", function() {
            moveSelection(start, d3.mouse(parent));
          }).on("mouseup.selection", function() {
            endSelection(start, d3.mouse(parent));

              //if the chain is not zoomed, zoom to the section          
              var beginChain = Math.floor((((start[1]<d3.mouse(parent)[1]) ? start[1] : d3.mouse(parent)[1]))/45);
              if(beginChain < 0) beginChain = 0;
              var endChain = Math.floor((((start[1]>d3.mouse(parent)[1]) ? start[1] : d3.mouse(parent)[1]) - yOffset )/45);
              if(endChain > proteins.length-1) endChain = proteins.length-1;

              if(view === superposition) {
                beginChain = 0;
                endChain = proteins.length-1;
              }
              
              var beginRange = Math.floor((((start[0]<d3.mouse(parent)[0]) ? start[0] : d3.mouse(parent)[0]) - 20)/viewElementWidth);
              if(beginRange < 0) beginRange = 0;
              var endRange = Math.floor((((start[0]>d3.mouse(parent)[0]) ? start[0] : d3.mouse(parent)[0]) - 20)/viewElementWidth);
              if(endRange > alignedSS[n].length) endRange = alignedSS[n].length;
              
              if((endRange - beginRange)*elementWidth < 48) {
                //do nothing for such a small zoom
                //console.log("fuck it.");
                displayMessage("Zoom selection is too narrow.");
                setTimeout(function () {
                    displayMessage(getProteinNames());
                }, 2000);
              } else {
                displayMessage(getProteinNames());
                // console.log("Chains: " + beginChain + ", "  + endChain);
                // console.log("Range: " + beginRange + ", "  + endRange);
                for (var i = beginChain; i < endChain + 1; i++) {
                  if(juxtaZoom[i][0] === 0 && juxtaZoom[i][1] === alignedSS[i].length) juxtaZoom[i] = [beginRange, endRange];
                }
                redrawD3();
              }
            // console.log(start);
            // console.log(d3.mouse(parent));
            subject.on("mousemove.selection", null).on("mouseup.selection", null);
          });
    });

}

function drawJuxtaposition(n){

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

  radialGradient.append("stop")
      .attr("offset", "0%")
      .attr("stop-color", (n===reference) ? colorMolecule[n] : "gray");

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

  juxtaposition.append("circle")
          .attr("cx", xoffset/2)
          .attr("cy", n*45 + 45)
          .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);
            displayMessage("Selected " + proteins[chain] + " as reference chain.");
            if(chain !== reference) {
              reference = chain;
              redrawD3();
            }
          });

  var startAA = juxtaZoom[n][0];
  var endAA = juxtaZoom[n][1];
  var thisElementWidth = (width-100)/(endAA-startAA);
  
  if(juxtaElementSet) {
    juxtaElementWidth = thisElementWidth;
    juxtaElementSet = false;
  }

  var globalI = 0;

  if(n !== reference) {
    juxtaposition.append("line")
            .attr('x1', xoffset)
            .attr('y1', 45 + n*45)
            .attr('x2', thisElementWidth*(endAA-startAA))
            .attr('y2', 45 + n*45)
            .style('stroke', 'lightgray')
            .style('stroke-width', 1)
  }

  var lastHeight = 0;

  for (var i = startAA; i < endAA - 1; i++) {
      var ss = alignedSS[n].charAt(i);
      var initHeight = 45 + n*45;
      var endHeight = 45 + n*45;

      var start = i;
      while (alignedSS[n].charAt(i+1) === ss) i++;
      var gap = i - start + 1;

      if(n!==reference && (ss == 'H' || ss == 'E')) {
        if(alignedSS[reference].charAt(start) == '-') {
          initHeight -= 15;
        } else {
          //console.log(atomDiffs[n][start]);
          initHeight -= (15 < atomDiffs[n][start])? 15 : atomDiffs[n][start];
        } 
        if(alignedSS[reference].charAt(i) == '-') {
          endHeight -= 15;
          lastHeight = endHeight;
        } else {
          endHeight -= (15 < atomDiffs[n][i]) ? 15 : atomDiffs[n][i];
          lastHeight = endHeight;
        }
      }

      if(n!==reference && ss == 'C') {
          if(lastHeight !== 0) initHeight = lastHeight;
          if (alignedSS[n].charAt(i+1) === 'H' || alignedSS[n].charAt(i+1) === 'E') {
            if(alignedSS[reference].charAt(i+1) == '-') {
              endHeight -= 15;
            } else {
              endHeight -= (15 < atomDiffs[n][i+1]) ? 15 : atomDiffs[n][i+1];
            }
          } else {
            lastHeight = 0;
          }
      }

      if(n!==reference && ss == '-') lastHeight = 0;

      if (ss === 'E') drawSSglyph(juxtaposition, n, i, thisElementWidth, globalI, gap, initHeight, endHeight, colorMolecule[n], ss);
      if (ss === 'H') drawSSglyph(juxtaposition, n, i, thisElementWidth, globalI, gap, initHeight, endHeight, colorMolecule[n], ss);
      if (ss === '-') drawRect(juxtaposition, thisElementWidth, globalI,  gap, initHeight, endHeight, 3, "lightgray");
      if (ss === 'C') drawRect(juxtaposition, thisElementWidth, globalI,  gap, initHeight, endHeight, 3, colorMolecule[n]);

      globalI += Math.round( gap * thisElementWidth);
  }

  addSelection(juxtaposition, n, juxtaElementWidth, 45);
}