// Sash Window
// A traditional wooden sash window with two vertically sliding panels and a central locking mechanism

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

// Window state: 0 for closed, 1 for open
windowState = 0

// Basic window dimensions
windowWidth = 500
windowHeight = 1000

// Frame thickness and depth
frameWidth = 30
frameDepth = 50

// Number of divisions per sash (horizontal and vertical)
sashOpeningCountHorizontal = 2
sashOpeningCountVertical = 1

// Derived dimensions
sashWidth = windowWidth - (frameWidth * 2)
sashHeight = (windowHeight - (frameWidth * 2)) / 2 + frameWidth / 2
sashDepth = frameDepth / 2 - 2
sashTravelDistance = sashHeight * windowState * 0.8

// Function to create panel with frame and openings
fn panelFn(plane, offset, width, height, depth, perimeter, divisionThickness, openingCountHorizontal, openingCountVertical) {
  // Create panel base shape
  panelPlane = startSketchOn(offsetPlane(XZ, offset = offset))
  panelShape = startProfile(panelPlane, at = [-width / 2, -height / 2])
    |> yLine(length = height)
    |> xLine(length = width)
    |> yLine(length = -height)
    |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
    |> close()
  panelBody = extrude(panelShape, length = depth)

  // Create opening grid within the panel
  voidAreaWidth = width - (perimeter * 2)
  voidAreaHeight = height - (perimeter * 2)

  divisionTotalThicknessHorizontal = divisionThickness * openingCountHorizontal - divisionThickness
  divisionTotalThicknessVertical = divisionThickness * openingCountVertical - divisionThickness
  voidWidth = (voidAreaWidth - divisionTotalThicknessHorizontal) / openingCountHorizontal
  voidHeight = (voidAreaHeight - divisionTotalThicknessVertical) / openingCountVertical

  voidStepHorizontal = voidWidth + divisionThickness
  voidStepVertical = voidHeight + divisionThickness
  voidPlane = startSketchOn(panelBody, face = END)
  voidShape = startProfile(
         voidPlane,
         at = [
           -voidAreaWidth / 2,
           -voidAreaHeight / 2
         ],
       )
    |> yLine(length = voidHeight)
    |> xLine(length = voidWidth)
    |> yLine(length = -voidHeight)
    |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
    |> close()
    |> patternLinear2d(
         %,
         instances = openingCountHorizontal,
         distance = voidStepHorizontal,
         axis = [1, 0],
       )
    |> patternLinear2d(
         %,
         instances = openingCountVertical,
         distance = voidStepVertical,
         axis = [0, 1],
       )
  voidBody = extrude(voidShape, length = -depth)
    |> appearance(color = "#a55e2c")
  return panelBody
}

// Create main window frame
frame = panelFn(
  plane = XZ,
  offset = -frameDepth / 2,
  width = windowWidth,
  height = windowHeight,
  depth = frameDepth,
  perimeter = frameWidth,
  divisionThickness = 10,
  openingCountHorizontal = 1,
  openingCountVertical = 1,
)

// Create bottom sliding sash
bottomSash = panelFn(
       plane = XZ,
       offset = (frameDepth / 2 - sashDepth) / 2,
       width = sashWidth,
       height = sashHeight,
       depth = sashDepth,
       perimeter = frameWidth,
       divisionThickness = 10,
       openingCountHorizontal = sashOpeningCountHorizontal,
       openingCountVertical = sashOpeningCountVertical,
     )
  |> translate(
       %,
       x = 0,
       y = 0,
       z = frameWidth / 2 - (sashHeight / 2),
     )
  |> translate(
       %,
       x = 0,
       y = 0,
       z = sashTravelDistance,
     ) // open / close

  // Latch mechanism on bottom sash
// Create latch plate
latchPlateWidth = 13
latchPlateLength = 30
latchPlateThickness = 1

latchPlatePlane = startSketchOn(offsetPlane(XY, offset = frameWidth / 2))
latchPlateShape = startProfile(
       latchPlatePlane,
       at = [
         -latchPlateLength / 2,
         -latchPlateWidth / 2
       ],
     )
  |> yLine(length = latchPlateWidth)
  |> xLine(length = latchPlateLength)
  |> yLine(length = -latchPlateWidth)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
latchPlateBody = extrude(latchPlateShape, length = latchPlateThickness)
  |> translate(
       %,
       x = 0,
       y = -frameDepth / 4,
       z = 0,
     )
  |> translate(
       %,
       x = 0,
       y = 0,
       z = sashTravelDistance,
     ) // open / close

// Create latch cylinder
latchCylinderHeight = 5
latchCylinderPlane = startSketchOn(offsetPlane(latchPlatePlane, offset = latchPlateThickness))
latchCylinderShape = startProfile(latchCylinderPlane, at = [40, -1])
  |> xLine(length = -35)
  |> arc(interiorAbsolute = [-5, 0], endAbsolute = [5, 1])
  |> xLine(length = 35)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
latchCylinderBody = extrude(latchCylinderShape, length = latchCylinderHeight)
  |> translate(
       %,
       x = 0,
       y = -frameDepth / 4,
       z = 0,
     )
  |> translate(
       %,
       x = 0,
       y = 0,
       z = sashTravelDistance,
     ) // open / close
  |> rotate(
       %,
       roll = 0,
       pitch = 0,
       yaw = -90 * windowState,
     )

// Create top fixed sash
topSash = panelFn(
       plane = XZ,
       offset = -(frameDepth / 2 - sashDepth) / 2 - sashDepth,
       width = sashWidth,
       height = sashHeight,
       depth = sashDepth,
       perimeter = frameWidth,
       divisionThickness = 10,
       openingCountHorizontal = sashOpeningCountHorizontal,
       openingCountVertical = sashOpeningCountVertical,
     )
  |> translate(
       %,
       x = 0,
       y = 0,
       z = sashHeight / 2 - (frameWidth / 2),
     )

// Create latch nut on the top sash
latchNutPlane = startSketchOn(XZ)
latchNutShape = startProfile(
       latchNutPlane,
       at = [
         -latchPlateLength / 2,
         -latchPlateWidth / 2
       ],
     )
  |> yLine(length = latchPlateWidth)
  |> xLine(length = latchPlateLength)
  |> yLine(length = -latchPlateWidth)
  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
  |> close()
latchNutPlateBody = extrude(latchNutShape, length = latchPlateThickness)
