// Cohen-Sutherland clipping algorithm for line P0=(x0,y0) to P1=(x1,y1)
// and clip rectangle with diagonal from (xmin,ymin) to (xmax,ymax).
function clip(x0,y0,x1,y1,xmin,xmax,ymin,ymax) {
  accept = false;  
  done = false;
  outcode0 = compOutCode(x0,y0,xmin,xmax,ymin,ymax); 
  outcode1 = compOutCode(x1,y1,xmin,xmax,ymin,ymax);
  while(!done) {

    if ((outcode0=="[]") && (outcode1=="[]")) { 
      // Trivial accept and exit.
      accept = true; 
      done = true;
//    } else if ((outcode0!="[]") && (outcode1!="[]")) { 
//      done = true;
    } else if (((outcode0.indexOf("[TOP]")>-1) &&    (outcode1.indexOf("[TOP]")>-1)) ||
               ((outcode0.indexOf("[BOTTOM]")>-1) && (outcode1.indexOf("[BOTTOM]")>-1)) ||
               ((outcode0.indexOf("[LEFT]")>-1) &&   (outcode1.indexOf("[LEFT]")>-1)) ||
               ((outcode0.indexOf("[RIGHT]")>-1) &&  (outcode1.indexOf("[RIGHT]")>-1))) {
      // Logical intersection is true, so trivial reject and exit.
      done = true;
      accept = false;
    } else {
      // Failed both tests, so calculate the line segment to clip
      // from an outside point to an intersection with clip edge.
      // At least one endpoint is outside the clip rectangle; pick it.
      if (outcode0!="[]") {
        outcodeOut = outcode0;
      } else {
        outcodeOut = outcode1;
      }
      // Now find intersection point;
      // use formulas y=y0+slope*(x-x0),x=x0+(1/slope)*(y-y0).
      if (outcodeOut.indexOf("[TOP]")>-1) {
        if (y0 == y1) {
          accept = false;  
          done   = true;
        } else {
          x = x0 + ((x1 - x0) * ((y0 - ymin) / (y0 - y1)));
          y = ymin;
        }
      }
      if (outcodeOut.indexOf("[BOTTOM]")>-1) {
        if (y0 == y1) {
          accept = false;  
          done   = true;
        } else {
          x = x0 + ((x1 - x0) * ((ymax- y0) / (y1 - y0)));
          y = ymax;
        }
      } else if (outcodeOut.indexOf("[RIGHT]")>-1) {
        if (x0 == x1) {
          accept = false;  
          done   = true;
        } else {
          y = y0 + ((y1 - y0) * ((xmax - x0) / (x1 - x0)));  // okay
          x = xmax;
        }
      } else if (outcodeOut.indexOf("[LEFT]")>-1) {
        if (x0 == x1) {
          accept = false;  
          done   = true;
        } else {
          y = y0 + ((y1 - y0) * ((xmin - x0) / (x1 - x0)));
          x = xmin;
        }
      }

      if (!done) {
        // Now we move outside point to intersection point to clip,
        // and get ready for next pass.
        if (outcodeOut == outcode0) {
          x0 = x; 
          y0 = y; 
          outcode0 = compOutCode(x0,y0,xmin,xmax,ymin,ymax);
        } else {
          x1 = x; 
          y1 = y; 
          outcode1 = compOutCode(x1,y1,xmin,xmax,ymin,ymax);
        }
      }
    }
  }
  return [accept, Math.round(x0), Math.round(y0), Math.round(x1), Math.round(y1)];
}

function compOutCode(x,y,xmin,xmax,ymin,ymax) {
  var code = "[]";
  if (y > ymax) { 
    code = "[BOTTOM]"
  } else if (y < ymin) { 
    code = "[TOP]"; 
  }
  if (x > xmax) { 
    code = code + "[RIGHT]";
  } else if (x < xmin) {
    code = code + "[LEFT]";
  }
  return code;
}

