import math
import drawsvg as draw
import os
from pathlib import Path

images_path = Path(os.path.realpath(__file__)).parent.joinpath('src').joinpath('images')

# Define arrowhead marker
arrow = draw.Marker(0,0,10,10, refX="10", refY="5", markerWidth="6", markerHeight="6", orient='auto-start-reverse')
arrow.append(draw.Path(d='M 0 0 L 10 5 L 0 10 z', fill='black'))

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def force_diagram():
    d = draw.Drawing(600, 600, origin='center')

    # Outline drawing area
    d.append(draw.Rectangle(-300,-300,600,600, fill='white'))

    # Coordinate system
    c = translate(coordinate_system(), -230, -230)
    d.append(c)

    # Define group
    g = draw.Group(fill='black', stroke='black', stroke_width=1.5)

    A = Point(0, -200)
    B = Point(0, 200)
    steering_angle = 20

    w = 300
    g.append(draw.Rectangle(-w/2,-280, w, 560, fill='none', stroke_width=1))
    wheel = draw.Rectangle(-15,-40, 30, 80, fill='none', stroke_width=1)
    g.append(translate(rotate(wheel, steering_angle), -w/2, A.y))
    g.append(translate(rotate(wheel, steering_angle), w/2, A.y))
    g.append(translate(wheel, -w/2, B.y))
    g.append(translate(wheel, w/2, B.y))

    # Center of Mass
    g.append(draw.Circle(0, 0, 3))
    g.append(text("CM", 0, 0, angle=180))

    # Velocity vector
    g.append(draw.Line(0, 0, -50, -160, marker_end=arrow))
    g.append(text("v", -50, -160, angle=-110))

    # Point A
    g.append(text("A", A.x, A.y, angle=180))
    g.append(draw.Circle(A.x, A.y, 3))
    g.append(draw.Line(A.x, A.y, 80, -170, marker_end=arrow))
    g.append(text("F_A", 80, -170))

    # Point B
    g.append(text("B", B.x, B.y, angle=180))
    g.append(draw.Circle(B.x, B.y, 3))
    g.append(draw.Line(B.x, B.y, 70, 200, marker_end=arrow))
    g.append(text("F_B", 70, 200))

    d.append(translate(g, 100, 0))
    d.save_svg(f'{images_path}/force_diagram.svg')

def coordinate_system():
    g = draw.Group(stroke='black', stroke_width=1.5)

    g.append(draw.Line(0, 0, 50, 0, marker_end=arrow))
    g.append(text("x", 50, 0))

    g.append(draw.Line(0, 0, 0, 50, marker_end=arrow))
    g.append(text("y", 0, 50, angle=90))

    # Arc
    cx = 0
    cy = 0
    r = 50
    start = 120
    end = -30
    start_angle = math.radians(start)
    end_angle = math.radians(end)

    x0 = cx + r * math.cos(start_angle)
    y0 = cy + r * math.sin(start_angle)
    x1 = cx + r * math.cos(end_angle)
    y1 = cy + r * math.sin(end_angle)

    # SVG arc path from (x0, y0) to (x1, y1) around center
    path_d = f'M {x0} {y0} A {r} {r} 0 1 1 {x1} {y1}'
    arc = draw.Path(d=path_d, fill='none', marker_end=arrow)
    g.append(arc)

    return g

# Wrap in translated group
def translate(t, x, y):
    g = draw.Group(transform=f"translate({x},{y})")
    g.append(t)
    return g

# Wrap in rotated group
def rotate(t, a):
    g = draw.Group(transform=f"rotate({a})")
    g.append(t)
    return g

def text(text, x, y, offset=20, angle=0):
    angle = math.radians(angle)
    x = x + offset * math.cos(angle)
    y = y + offset * math.sin(angle)

    return draw.Text(text, 18, x, y, stroke_width=1, center=True)

force_diagram()

