// Utility Sink
// A stainless steel sink unit with a configurable number of rectangular basins and under-counter storage compartments.

// Set units
@settings(defaultLengthUnit = mm, kclVersion = 1.0)

// Define parameters
tableHeight = 850
tableWidth = 1200
tableDepth = 600

profileThickness = 13
metalThickness = 2

blockCount = 1
blockWidth = (tableWidth - profileThickness) / blockCount
blockHeight = tableHeight - metalThickness - 0.5
blockDepth = tableDepth - profileThickness

blockSubdivisionCount = 2
blockSubdivisionWidth = blockWidth / blockSubdivisionCount

// Geometry
floorPlane = startSketchOn(XY)

// legs
legHeight = blockHeight - profileThickness
legCount = blockCount + 1

legBody = startProfile(floorPlane, at = [0, 0])
  |> yLine(length = profileThickness)
  |> xLine(length = profileThickness)
  |> yLine(length = -profileThickness)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [1, 0], instances = legCount, distance = blockWidth)
  |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth)
  |> extrude(length = legHeight)

// lower belt
lowerBeltHeightAboveTheFloor = 150
lowerBeltLengthX = blockWidth - profileThickness

lowerBeltPlane = startSketchOn(offsetPlane(XY, offset = lowerBeltHeightAboveTheFloor))
lowerBeltBodyX = startProfile(lowerBeltPlane, at = [profileThickness, 0])
  |> yLine(length = profileThickness)
  |> xLine(length = lowerBeltLengthX)
  |> yLine(length = -profileThickness)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [1, 0], instances = blockCount, distance = blockWidth)
  |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth)
  |> extrude(length = profileThickness)

lowerBeltLengthY = blockDepth - profileThickness
lowerBeltBodyY = startProfile(lowerBeltPlane, at = [0, profileThickness])
  |> yLine(length = lowerBeltLengthY)
  |> xLine(length = profileThickness)
  |> yLine(length = -lowerBeltLengthY)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [1, 0], instances = 2, distance = tableWidth - profileThickness)
  |> extrude(length = profileThickness)

// pillars
pillarHeightAboveTheFloor = lowerBeltHeightAboveTheFloor + profileThickness
pillarPlane = startSketchOn(offsetPlane(XY, offset = pillarHeightAboveTheFloor))
pillarTotalHeight = blockHeight - profileThickness - pillarHeightAboveTheFloor

pillarBody = startProfile(pillarPlane, at = [blockSubdivisionWidth, 0])
  |> yLine(length = profileThickness)
  |> xLine(length = profileThickness)
  |> yLine(length = -profileThickness)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [1, 0], instances = blockCount, distance = blockWidth)
  |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth)
  |> extrude(length = pillarTotalHeight)

// upper belt
upperBeltPlane = startSketchOn(offsetPlane(XY, offset = blockHeight))

upperBeltBodyX = startProfile(upperBeltPlane, at = [0, 0])
  |> yLine(length = profileThickness)
  |> xLine(length = tableWidth)
  |> yLine(length = -profileThickness)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [0, 1], instances = 2, distance = blockDepth)
  |> extrude(length = -profileThickness)

upperBeltLengthY = blockDepth - profileThickness
upperBeltBodyY = startProfile(upperBeltPlane, at = [0, profileThickness])
  |> yLine(length = upperBeltLengthY)
  |> xLine(length = profileThickness)
  |> yLine(length = -upperBeltLengthY)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [1, 0], instances = 2, distance = tableWidth - profileThickness)
  |> extrude(length = -profileThickness)

// sink
tableTopPlane = startSketchOn(offsetPlane(XY, offset = tableHeight))
tableTopBody = startProfile(tableTopPlane, at = [0, 0])
  |> yLine(length = tableDepth)
  |> xLine(length = tableWidth)
  |> yLine(length = -tableDepth)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> extrude(length = -metalThickness)

sinkCount = blockCount
sinkWidth = blockWidth / 2
sinkLength = tableDepth - 150
sinkDepth = 200
sinkOffsetFront = 40
sinkOffsetLeft = (blockWidth - sinkWidth) / 2
sinkSpacing = tableWidth - sinkWidth - (sinkOffsetLeft * 2)

sinkPlaneOutside = startSketchOn(tableTopBody, face = START)
sinkBodyOutside = startProfile(sinkPlaneOutside, at = [-sinkOffsetLeft, sinkOffsetFront])
  |> yLine(length = sinkLength)
  |> xLine(length = -sinkWidth)
  |> yLine(length = -sinkLength)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [-1, 0], instances = sinkCount, distance = sinkSpacing)
  |> extrude(length = sinkDepth)

sinkPlaneInside = startSketchOn(tableTopBody, face = END)
sinkBodyInside = startProfile(
       sinkPlaneInside,
       at = [
         sinkOffsetLeft + metalThickness,
         sinkOffsetFront + metalThickness
       ],
     )
  |> yLine(length = sinkLength - (metalThickness * 2))
  |> xLine(length = sinkWidth - (metalThickness * 2))
  |> yLine(length = -sinkLength + metalThickness * 2)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [1, 0], instances = sinkCount, distance = sinkSpacing)
  |> extrude(length = -sinkDepth)

// tap
tapPlate = startSketchOn(offsetPlane(XY, offset = tableHeight))
  |> circle(%, center = [blockWidth / 2, tableDepth - 55], radius = 40)
  |> patternLinear2d(axis = [1, 0], instances = sinkCount, distance = sinkSpacing)
  |> extrude(length = 5)
tapPillar = startSketchOn(offsetPlane(XY, offset = tableHeight))
  |> circle(%, center = [blockWidth / 2, tableDepth - 55], radius = 15)
  |> patternLinear2d(axis = [1, 0], instances = sinkCount, distance = sinkSpacing)
  |> extrude(length = 170)
tapNose = startSketchOn(offsetPlane(XZ, offset = 55 - tableDepth))
  |> circle(%, center = [blockWidth / 2, tableHeight + 100], radius = 10)
  |> patternLinear2d(axis = [1, 0], instances = sinkCount, distance = sinkSpacing)
  |> extrude(length = sinkWidth / 2.5)
tapHandle = startSketchOn(offsetPlane(XZ, offset = 55 - tableDepth))
  |> circle(%, center = [blockWidth / 2, tableHeight + 150], radius = 4)
  |> patternLinear2d(axis = [1, 0], instances = sinkCount, distance = sinkSpacing)
  |> extrude(length = 70)

// door panels
doorGap = 2
doorWidth = blockSubdivisionWidth - profileThickness - (doorGap * 2)
doorStart = profileThickness + doorGap
doorHeightAboveTheFloor = pillarHeightAboveTheFloor + doorGap
doorHeight = blockHeight - doorHeightAboveTheFloor - profileThickness - doorGap
doorCount = blockCount * blockSubdivisionCount

doorPlane = startSketchOn(offsetPlane(XY, offset = doorHeightAboveTheFloor))
doorBody = startProfile(doorPlane, at = [doorStart, 0])
  |> yLine(length = profileThickness)
  |> xLine(length = doorWidth)
  |> yLine(length = -profileThickness)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [1, 0], instances = doorCount, distance = blockSubdivisionWidth)
  |> extrude(length = doorHeight)
  |> patternLinear3d(
       %,
       instances = 2,
       distance = blockDepth,
       axis = [0, 1, 0],
     )

// side panels
panelWidth = blockDepth - profileThickness - (doorGap * 2)
panelCount = doorCount + 1
panelSpacing = tableWidth - profileThickness
panelBody = startProfile(doorPlane, at = [0, doorStart])
  |> yLine(length = panelWidth)
  |> xLine(length = profileThickness)
  |> yLine(length = -panelWidth)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
  |> patternLinear2d(axis = [1, 0], instances = 2, distance = panelSpacing)
  |> extrude(length = doorHeight)

// handle
handleDepth = 40
handleWidth = 120
handleFillet = 20
handleHeightAboveTheFloor = 780
handleOffset = doorStart + doorWidth / 2 - (handleWidth / 2)
handleLengthSegmentA = handleDepth - handleFillet
handleLengthSegmentB = handleWidth - (handleFillet * 2)

handlePlane = startSketchOn(offsetPlane(XY, offset = handleHeightAboveTheFloor))

handleProfilePath = startProfile(handlePlane, at = [0 + handleOffset, 0])
  |> yLine(length = -handleLengthSegmentA)
  |> tangentialArc(endAbsolute = [
       handleFillet + handleOffset,
       -handleDepth
     ])
  |> xLine(length = handleLengthSegmentB)
  |> tangentialArc(endAbsolute = [
       handleOffset + handleWidth,
       -handleLengthSegmentA
     ])
  |> yLine(length = handleLengthSegmentA)
handleSectionPlane = startSketchOn(XZ)
handleProfileSection = circle(
  handleSectionPlane,
  center = [
    handleOffset,
    handleHeightAboveTheFloor
  ],
  radius = 2,
)
handleBody = sweep(handleProfileSection, path = handleProfilePath)
  |> patternLinear3d(axis = [1, 0, 0], instances = doorCount, distance = blockSubdivisionWidth)
