@startuml Classes_Hierarchy
class "Action" as a {
  -CompleteRobot robot

  +Action(CompleteRobot robot)

  #CompleteRobot getRobot()
  #void groundRobot()
  +void act()
  +void act(Direction dir)
}

enum Direction {
  LEFT
  RIGHT
  DOWN
}

class "ActionStep" as aSt {
  -double maxAngle
  -double minAngle
  -double turnAngle
  -double lastDistance

  +ActionStep(CompleteRobot robot)
  +ActionStep(CompleteRobot robot, double maxAngle, double minAngle, double turnAngle)

  #double getTurnAngle()
}

class "ActionSquat" as aSq {
  +ActionSquat(CompleteRobot robot)
}

interface "Drawable" as d {
  +void drawSelf(Draw draw)
  +void move(double xShift, double yShift)
}

abstract class "DrawableCircle" as dC {
  -double radius
  -double x
  -double y
  -Color fillColor
  -Drawable[] bodyparts

  +DrawableCircle(double x, double y, double radius, Color fillColor)
  
  +void drawSelf(Draw draw)
  +void move(double xShift, double yShift)

  +double getX()
  +double getY()
  +double getRadius()

  +void addChild(Drawable newPart)
  -void drawChildren(Draw draw)
  -void moveChildren(double xShift, double yShift)
}

class "Eye" as dCE {
  +Eye(double x, double y, double radius)
}

class "Head" as dCH {
  -Eye lEye
  -Eye rEye

  +Head(double x, double y, double radius)

  +Eye getEye(int index)
  +double getForeHeadY()
}

class "HeadTorso" as dCHT {
  -Torso torso

  +HeadTorso(double x, double y, double radius)

  #double[] getTorsoXCoords()
  #double[] getTorsoYCoords()

  +boolean isTorsoTouched(double x, double y)
  +boolean isTorsoHTouched(double x)
  +boolean isTorsoVTouched(double y)
}

class "HeadTorsoArms" as dCHTA {
  -LimbSegment lArm, rArm;

  +HeadTorsoArms(double x, double y, double radius)

  +LimbSegment getArm(int index)
}

class "HeadTorsoArmsLegs" as dCHTAL {
  -LimbSegment lLeg, rLeg;

  +HeadTorsoArmsLegs(double x, double y, double radius)

  +LimbSegment getLeg(int index)
}

abstract class "DrawableRectangle" as dR {
  -double x
  -double y
  -double l
  -double w
  -double rotation
  -Color fillColor
  -Drawable[] bodyparts

  +DrawableRectangle(double x, double y, double l, double w, double rotation, Color fillColor)
  
  +void drawSelf(Draw draw)
  +void move(double xShift, double yShift)

  +double[] getXCoords()
  +double[] getYCoords()
  +double getX()
  +double getY()
  +double getXEnd()
  +double getYEnd()
  +double getRotation()
  +double getW()
  +double getL()
  +void setX(double x)
  +void setY(double y)

  +void rotate(double angle)

  +void addChild(Drawable newPart)
  -void drawChildren(Draw draw)
  -void moveChildren(double xShift, double yShift)
}

interface "Touchable" as tb{
  +boolean isTouched(double x, double y)
  +boolean isHTouched(double x)
  +boolean isVTouched(double y)
}

class Basin {
  -Water water
  -BasinWall lWall
  -BasinWall rWall
  -BasinFloor floor
  
  +Basin(double x, double y, double size)
  +void drawTopLayer(Draw draw)
}

class BasinFloor {
  +BasinFloor(double x, double y, double size)
}

class BasinWall {
  +BasinWall(double x, double y, double size)
}

class Water {
  +Water(double x, double y, double size)
}

class "Torso" as dRT {
  +Torso(double x, double y, double h, double w)
  +Torso(double x, double y, double radius)
}

class "LimbSegment" as LimbSegment {
  -LimbSegment nextSegment
  -boolean isLeftLimb
  -boolean hasNextSegment

  +LimbSegment(double x, double y, double h, double w, boolean isExtremity, boolean isLeftLimb)
  +LimbSegment(double x, double y, double radius, boolean isLeftLimb)
  
  -void addSegment(LimbSegment segment)
  -void addForeLimb()
  -void addExtremity()

  +void rotate(double angle)
  +double getExtremityXEnd()
  +double getExtremityYEnd()
}

class "CompleteRobot" as CR {
  -ActionStep moveAction
  -Action curentAction
  -Speech speech

  +CompleteRobot(double x, double y, double radius)

  #changeMoveAction(ActionStep newMoveAction)
  #changeAction(Action newAction)

  #void act()
  #void act(Direction dir)
  +void gotoX(double destX, String destLabel)
  -void moveLeft()
  -void moveRight()
  #void say(String speechText)
}

class "CrabCompleteRobot" as CCR {
  +CrabCompleteRobot(double x, double y, double radius)
}

class "HandWashingCompleteRobot" as HWCR {
    +HandWashingCompleteRobot(double x, double y, double radius)
    
    -boolean bothHandsCanFit(Touchable obj)
    -void soakHands()
    +void squat()
    +void useBasin(Basin basin)
}

class Speech {
  -String speechText
  -double x
  -double y
  public Speech(double x, double y)
  public void changeText(String newText)
}

class "RobotClient" as RC {
  -Draw draw
  -Basin basin
  -HandWashingCompleteRobot hwRobot
  -CompleteRobot anyRobot
  -Color bgColor

  +RobotClient()

  -void drawAll()
  +void mousePressed(double mouseX, double mouseY)
  {static} +void main(String[] args)
}

a "1" *-- "1" CR : controls
a <|-- aSt
aSt <|-- aSq
d <|.. dC
dC <|-- dCE
dC <|-- dCH
dCH "1" *-- "2" dCE : has
dCH <|-- dCHT
dCHT <|-- dCHTA
dCHTA "1" *-- "2" LimbSegment : has
dCHTA <|-- dCHTAL
dCHTAL "1" *-- "2" LimbSegment : has
d <|.. dR
dR <|-- Basin
tb <|.. Basin
dR <|-- BasinFloor
Basin "1" *-- "1" BasinFloor : has
dR <|-- BasinWall
Basin "1" *-- "2" BasinWall : has
dR <|-- Water
tb <|.. Water
Basin "1" *-- "1" Water : has
dR <|-- dRT
tb <|.. dRT
dCHT "1" *-- "1" dRT : has
dR <|-- LimbSegment
LimbSegment "1" *-- "(0,1)" LimbSegment : has
dCHTAL <|-- CR
CR "1" *-- "1" aSt : uses
CR "1" *-- "1" a : uses
CR "1" *-- "1" Speech : uses
CR <|-- CCR
CR <|-- HWCR
d <|.. Speech
dC "1" *-- "many" d : contains
dR "1" *-- "many" d : contains
RC "1" *-- "1" Basin : has
RC "1" *-- "1" HWCR : has
RC "1" *-- "1" CR : has
@enduml
