class JtsAlgorithms implements GeomAlgorithms {

  public static IMultiCurve<ILineString> offsetCurve(ILineString line,
      double distance) {
    double d = Math.abs(distance);
    if (d == 0) {
      IMultiCurve<ILineString> result = new GM_MultiCurve<ILineString>();
      result.add(line);
      return result;
    }

    int orientationIndex = (int) (d / distance);
    try {
      // removing duplicate coordinates from the input linestring.
      LineString lineString = JtsAlgorithms
          .getLineStringWithoutDuplicates((LineString) JtsGeOxygene
              .makeJtsGeom(line));
      BufferParameters bufParams = new BufferParameters();
      bufParams.setSingleSided(true);
      // bufParams.setEndCapStyle(BufferParameters.CAP_SQUARE);
      Geometry buffer = BufferOp.bufferOp(lineString, distance, bufParams);
      // lineString.buffer(distance, 4, BufferParameters.CAP_SQUARE);
      // System.out.println("SS " + buffer);
      if (lineString != null) {
        buffer = lineString.buffer(d, 4, BufferParameters.CAP_ROUND);
        // System.out.println(buffer);
        Polygon polygon = null;
        if (!(buffer instanceof Polygon)) {
          JtsAlgorithms.logger.error("Can't compute offsetcurve of " + //$NON-NLS-1$
              buffer.getGeometryType());
          return null;
        }
        polygon = (Polygon) buffer;
        IMultiCurve<ILineString> result = new GM_MultiCurve<ILineString>();
        // build the offset curve for the exterior ring
        ILineString r = JtsAlgorithms.getOffsetCurveFromRing(
            polygon.getExteriorRing(), lineString, orientationIndex, d);
        if ((r != null) && !r.isEmpty() && (r.coord().size() != 1)) {
          result.add(r);
        } // modif JFG
        // go through all interior rings
        for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
          LineString ring = polygon.getInteriorRingN(i);
          // build the offset curve for the interior ring
          r = JtsAlgorithms.getOffsetCurveFromRing(ring, lineString,
              orientationIndex, d);
          if ((r != null) && !r.isEmpty() && (r.coord().size() != 1)) {
            result.add(r);
          } // modif JFG
        }
        return result;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  public  JtsAlgorithms();

}