' SPDX-FileCopyrightText: 2025 None
'
' SPDX-License-Identifier: CC-BY-SA-4.0

@startuml plantuml

' o-- has-a relationship
' ..> uses
' *-- contains (can not exist without it)

node "Meaning of Arrows" {
    () "Class A" as ClassA
    () "Class B" as ClassB
    () "Class C" as ClassC
    () "Class D" as ClassD
    () "Class E" as ClassE
    () "Class F" as ClassF
    () "Class G" as ClassG
    () "Class H" as ClassH

    ClassA ..> ClassB : uses\n(association)
    ClassC o-- ClassD : has a pointer to\n(aggregation)
    ClassE *-- ClassF : owns/contains\n(composition)
    ClassG <|-- ClassH: is inherited by\n(inheritance)
}

class Canvas extends QWidget {
    -overlay: QImage
    -canvas: QImage
    +canvas(): QImage
    +overlay(): QImage

    .. Signals ..
    +mousePressed(): QMouseEvent*
    +mouseReleased(): QMouseEvent*
    +mouseMoved(): QMouseEvent*
    +tablet(): QTabletEvent*
    +wheel(): QWheelEvent*
    +resizeEventCalled()
    +resizeStart()
    +resizeEnd()
    +destroyed()
}

class Controller extends QObject {
    -m_context: ApplicationContext*
    .. Slots ..
    +mousePressed(QMouseEvent*)
    +mouseMoved(QMouseEvent*)
    +mouseReleased(QMouseEvent*)
    +tablet(QTabletEvent*)
    +wheel(QWheelEvent*)
}


Controller o-- ApplicationContext
Canvas ..> Controller : signal-slot

class QWidget extends QObject
class QFrame extends QWidget
class ToolBar extends QFrame {
    +curTool(): Tool&
    +addTool(tool: Tool*): void

    .. Signals ..
    +toolChanged(): Tool&
}
ToolBar *-- Tool

class PropertyBar extends QFrame {
    .. Slots ..
    +toolChanged(Tool&): void
}
class ActionBar extends QFrame

ToolBar ..> PropertyBar: signal-slot

class ApplicationContext extends QObject {
    +renderingContext(): RenderingContext&
    +UIContext(): UIContext&
    +SpatialContext(): SpatialContext&
    +SelectionContext(): SelectionContext&
}

class RenderingContext {
    +canvas(): Canvas&
    +canvasPainter(): QPainter&
    +overlayPainter(): QPainter&
    +markForUpdate(region: QRect): void
    +markForRender(): void
    +fps(): int
    +zoomFactor(): qreal
    +setZoomFactor(val: qreal): void
}

RenderingContext *-- Canvas

class UIContext {
    +toolBar(): ToolBar&
    +propertyBar(): PropertyBar&
    +actionBar(): ActionBar&
    +event(): Event&
}

UIContext *-- ToolBar
UIContext *-- PropertyBar
UIContext *-- ActionBar
UIContext *-- Event

class SpatialContext {
    +quadTree(): QuadTree&
    +cacheGrid(): CacheGrid&
    +coordinateTransformer(): CoordinateTransformer&
    +offsetPos(): QPointF
    +setOffsetPos(QPointF): void
}

SpatialContext *-- QuadTree
SpatialContext *-- CacheGrid
SpatialContext *-- CoordinateTransformer

class SelectionContext {
    +selectedItems(): set of Item*
    +selectionBox(): QRectF
}

ApplicationContext *-- RenderingContext
ApplicationContext *-- UIContext
ApplicationContext *-- SpatialContext
ApplicationContext *-- SelectionContext

QuadTree *-- Item

class CacheCell {
    +rect(): QRect
    +point(): QPoint
    +dirty(): bool
    +setDirty(bool): void
    +image(): QImage&
    +painter(): QPainter&
}

class CacheGrid {
    +queryCells(QRect): QVector<CacheCell*>
    +cell(QPoint): CacheCell*
    +markDirty(QRect): void
    +markAllDirty(): void
}

CacheGrid *-- CacheCell

class OrderedList {
    +insert(item: Item*): void
    +remove(item: Item*): void
    +bringForward(item: Item*): void
    +sendBackward(item: Item*): void
    +sendToBack(item: Item*): void
    +bringToFront(item: Item*): void
    +hasItem(item: Item*): bool
}

class QuadTree {
    -m_capacity: int
    +insertItem(): void
    +deleteItem(Item*): void
    +updateItem(Item*, oldBoundingBox: QRectF): void
    +queryItems(shape: *): QVector<Item*>
}

QuadTree *-- OrderedList
OrderedList ..> Item

class Event {
    +pos(): QPointF
    +button(): Qt::MouseButton
    +pressure(): qreal
    +setPos(QPointF): void
    +setButton(Qt::MouseButton): void
    +setPressure(qreal): void
}

abstract class Item
abstract class Polygon extends Item
class Freeform extends Item
class Arrow extends Polygon
class Rectangle extends Polygon
class Line extends Polygon
class Ellipse extends Polygon

abstract class ItemFactory
class RectangleFactory extends ItemFactory
class EllipseFactory extends ItemFactory
class LineFactory extends ItemFactory
class ArrowFactory extends ItemFactory
class FreeformFactory extends ItemFactory

ItemFactory ..> Item

abstract class Tool {
    -m_properties: map ToolPropertyType to ToolProperty
    +mouseMoved(ApplicationContext*): void
    +mousePressed(ApplicationContext*): void
    +mouseReleased(ApplicationContext*): void
}

Tool ..> ApplicationContext

abstract class PolygonDrawingTool extends Tool
class FreeformTool extends Tool
class EraserTool extends Tool
class MoveTool extends Tool
class EllipseTool extends PolygonDrawingTool
class LineTool extends PolygonDrawingTool
class RectangleTool extends PolygonDrawingTool
class ArrowTool extends PolygonDrawingTool
class SelectionTool extends Tool {
    - m_curState: SelectionToolState
}

abstract class SelectionToolState {
    +mouseMoved(ApplicationContext*): void
    +mousePressed(ApplicationContext*): void
    +mouseReleased(ApplicationContext*): void
}
class SelectionToolMoveState extends SelectionToolState
class SelectionToolResizeState extends SelectionToolState
class SelectionToolRotateState extends SelectionToolState

SelectionTool ..> SelectionToolState

class ItemProperty {
    +value(): QVariant
    +setValue(): void
}

Item *-- ItemProperty

enum ItemPropertyType {
    StrokeWidth
    StrokeColor
}

ItemProperty ..> ItemPropertyType

Tool *-- ItemFactory

class PropertyManager {
    -m_properties: map ToolPropertyType to ToolProperty
    +getToolProperty(type: ToolPropertyType)
}

abstract class ToolProperty {
    +value(): QVariant
    +name(): QString
    +widget(): QWidget*
}

class ToolStrokeColor extends ToolProperty
class ToolStrokeWidth extends ToolProperty
class ToolEraserSize extends ToolProperty

Tool o-- ToolProperty
Tool ..> PropertyManager

enum ToolPropertyType {
    StrokeWidth
    StrokeColor
    EraserSize
}

PropertyManager ..> ToolPropertyType
PropertyManager ..> ToolProperty

abstract class Command {
    +execute(): void
    +undo(): void
}

class InsertItemCommand extends Command
class RemoveItemCommand extends Command
class MoveItemCommand extends Command

class UndoRedoManager

UndoRedoManager ..> Command
SpatialContext *-- UndoRedoManager

class QWindow extends QObject
class QLayout extends QObject
class BoardLayout extends QLayout
class Window extends QWindow
Window *-- BoardLayout
Window *-- Controller
Window *-- ApplicationContext

@enduml
