"""
A fibre, for bearing tension
"""
import cadquery as Cq
from dataclasses import dataclass
import nhf.utils

def tension_fibre(
        length: float,
        hole_diam: float,
        hole_twist: float=0,
        thickness: float=0.5) -> Cq.Workplane:
    """
    A fibre which holds tension, with an eyes on each end.

    """
    eye_female = Cq.Solid.makeTorus(
        radius1=hole_diam/2 + thickness/2,
        radius2=thickness/2,
        dir=(1,0,0),
    )
    hole_length_male = hole_diam * 2.5
    hole_height_male = hole_diam * 1.2
    eye_male = Cq.Solid.makeBox(
        length=hole_length_male + thickness * 2,
        width=thickness,
        height=hole_height_male + thickness * 2,
    ).located(
        Cq.Location((-hole_length_male/2-thickness, -thickness/2, -hole_height_male/2-thickness))
    ).cut(Cq.Solid.makeBox(
        length=hole_length_male,
        width=thickness,
        height=hole_height_male,
    ).located(Cq.Location((-hole_length_male/2, -thickness/2, -hole_height_male/2))))
    height = length - hole_diam - thickness
    assert height > 0, "String is too short to support the given hole sizes"
    h1 = length/2 - hole_diam/2 - thickness/2
    h2 = length/2 - hole_height_male - thickness/2
    result = (
        Cq.Workplane('XY')
        .cylinder(
            radius=thickness/2,
            height=h1,
            centered=(True, True, False),
        )
        .copyWorkplane(Cq.Workplane('YX'))
        .cylinder(
            radius=thickness/2,
            height=h2,
            centered=(True, True, False),
        )
        .union(eye_female.located(Cq.Location((0, 0,length/2))))
        .union(eye_male.located(Cq.Location((0, 0,-length/2+hole_height_male/2+thickness/2), (0,0,1), hole_twist)))
    )
    result.copyWorkplane(Cq.Workplane(Cq.Plane(origin=(0,0,length/2), normal=(1,0,0)))).tagPlane("female")
    conn1_normal, _ = (Cq.Location((0,0,0),(0,0,1),hole_twist) * Cq.Location((1,0,0))).toTuple()
    result.copyWorkplane(Cq.Workplane(Cq.Plane(origin=(0,0,-length/2), normal=conn1_normal))).tagPlane("male")
    return result