!include <font-awesome/common>
@startuml Rhodey Class Diagram
skinparam classAttributeIconSize 0
title Rhodey War Simulator
hide circle
skinparam linetype ortho

' ===== CLASSES =====

rectangle AllianceGroups{
    class Alliance
    class AllianceMember
    class Conglomerate
    Class Country
    class Faction
}

class Conglomerate{
    - name: string
    + add(Conglomerate)*: void
    + print(): void
    + ~Conglomerate()
}

class AllianceMember {
    name: string
    

}
class Alliance{
    - members: vector<Conglomerate*>

}

class Weapon {
    - weaponName: string
    - dmg: int
}

class ReasonForWar {
    reason: string

}
class ReasonEndWar {
    reason :string
}
class ChangesThroughoutWar {
    Research: int
    TreatyNegotiations: int // not sure about data type for this one but was thinking on a scale of 1-100 and when its 100 a treaty agreement has been reached.
    Recruitment: int
}

class War{
    - participants: vector<Conglomerate*>
    - reasonForWar: string
    - reasonEndWar: string
    - battles: vector<Battle*>
    - state: WarPhases
    + request(): void
    + setState(phase: WarPhases): void
}


class WarPhases{
    #war: War*
    {abstract} + handle(): void
    {abstract} + changeState(): void

}

class Dispute{
    + handle(): void
    + changeState(): void
}

class Conflict{
    + handle(): void
    + changeState(): void
}

class Hostilities{
    + handle(): void
    + changeState(): void
}

class PostHostilitiesConflict{
    + handle(): void
    + changeState(): void
}

class PostHostilitiesDispute{
    + handle(): void
    + changeState(): void
}

class DisputeSettled{
    + handle(): void
    + changeState(): void
}






rectangle Military{
    class Military{
        - BattleGroups: Forces**
        - Spies: SpyAgency**
        {abstract} + move(): void
        ~Military()
    }

    class Forces{
        - name: string
        - army: Army
        - navy: Navy
        - airforce: Airforce
        {abstract} + move(): void
        ~Military()
    }

    class Army{
        - name: string
        - numSoldiers: int
        - numCommanders: int
        - numTanks: int
        - numTrucks: int
        - units: Entity**
        + move(): void
        ~Army()
    }

    class Navy{
        - name: string
        - numCargoShips: int
        - numWarShips: int
        - numCarriers: int
        - numSubmarines: int
        - numFighters: int
        - units: Entity**
        + move(): void
        ~Navy()
    }

    class AirForce{
        - name: string
        - numFighters: int
        - numBombers: int
        - units: Entity**
        + move(): void
        ~AirForce()
    }
}



class EntityFactory
class TroopFactory
class VehicleFactory
class ResearchFactory

class UnitFactory{
    # name: string
    # hp: int
    # dmg: int
    + unitFactory()
    ~ unitFactory()
    + {abstract} makeUnit(): Entity*
    
}

class TruckFactory{
    + TruckFactory()
    ~ TruckFactory()
    + makeUnit(): Entity*   
}

class TankFactory{
    + TankFactory()
    ~ TankFactory()
    + makeUnit(): Entity*   
}

class SoldierFactory{
    + SoldierFactory()
    ~ SoldierFactory()
    + makeUnit(): Entity*   
}

class CommanderFactory{
    + CommanderFactory()
    ~ CommanderFactory()
    + makeUnit(): Entity*   
}

class CarrierFactory{
    + CarrierFactory()
    ~ CarrierFactory()
    + makeUnit(): Entity*   
}

class CargoShipFactory{
    + CargoShipFactory()
    ~ CargoShipFactory()
    + makeUnit(): Entity*   
}

class WarshipFactory{
    + WarshipFactory()
    ~ WarshipFactory()
    + makeUnit(): Entity*   
}

class SubmarineFactory{
    + SubmarineFactory()
    ~ SubmarineFactory()
    + makeUnit(): Entity*   
}

class FighterFactory{
    + FighterFactory()
    ~ FighterFactory()
    + makeUnit(): Entity*   
}

class BomberFactory{
    + BomberFactory()
    ~ BomberFactory()
    + makeUnit(): Entity*   
}

class CargoPlaneFactory{
    + CargoPlaneFactory()
    ~ CargoPlaneFactory()
    + makeUnit(): Entity*   
}




class Faction{
    - sizeOfArmy: int
    - population: int
    - economy: int
    - morale: int
    - forces: Military
}

class Country{
    - sizeOfArmy: int
    - population: int
    - economy: int
    - morale: int
    - attrition: int
    - forces: Military
    - locations: Location**
    - Allies: Countries**
    - trainingFacilitys : TroopFactory **
    - vehicleFactories : VehicleFactory **
}

class Location{
    - name: string
    - description: string
    - terrain: string
    - population: int

}

class Battle{
    - country: Country*
    - location: Location*
    - attackingForces: Forces**
    - defendingForces: Forces**
    + Battle(Forces~**, Forces~**, Location*, Country*)
    + start(): void
    + end(): void
    ~Battle()
}



class SpyAgency{
    # workFor: Country*
    # spyingOn: Country*d
    # status: string
    + SpyAgency(spyingFor Country*, spyingOn Country*)
    + update(): void
    ~SpyAgency()
}

class Spy{
     {abstract} + update(): void
}






' == Entities == '
rectangle "Entities" {
    

    class Entity{
        - name: string
        - hp: int
        - dmg: int
        - weapons: Weapon**
        {abstract} + attack(): void
        {abstract} + defend(): void


    }



    class Troop{
        {abstract} + attack(): void
        {abstract} + defend(): void

    }

    class Vehicle{
        - capacity: int
        {abstract} + attack(): void
        {abstract} + defend(): void
    }

    class GroundVehicle{
        {abstract} + attack(): void
        {abstract} + defend(): void
    }

    class Truck{
        + attack(): void
        + defend(): void
    }

    class Tank{
        + attack(): void
        + defend(): void
    }

    class AirVehicle{
        {abstract} + attack(): void
        {abstract} + defend(): void
    }

    class Fighter{
        + attack(): void
        + defend(): void
    }

    class Bomber{
        + attack(): void
        + defend(): void
    }

    class CargoPlane{

        + attack(): void
        + defend(): void
    }

    class WaterVehicle{

        {abstract} + attack(): void
        {abstract} + defend(): void
    }


    class CargoShip{

        + attack(): void
        + defend(): void
    }

    class Warship{

        + attack(): void
        + defend(): void
    }

    class Submarine{

        + attack(): void
        + defend(): void
    }

    class Carrier{

        + attack(): void
        + defend(): void
    }

    class Soldier{

        {abstract} + attack(): void
        {abstract} + defend(): void
    }

    class Commander{
        + attack(): void
        + defend(): void
        + command(): void
    }
}

' Different strategy states'
rectangle "Strategy States" {
    class BattleStrategy
    class DefensiveStrategy
    class OffensiveStrategy
    class ResearchiveStrategy
    class Spy
    class RedistributeTroops
    class RandD
    class BuildVehicle
    class BuildWeapon
    class RecruitSoldiers
}

' ===== RELATIONSHIPS =====
Entity o-- Weapon
Entity <|-- Troop
Entity <|-- Vehicle
Troop <|-- Soldier
Troop <|-- Commander
Vehicle <|-- GroundVehicle
Vehicle <|-- AirVehicle
Vehicle <|-- WaterVehicle
GroundVehicle <|-- Truck
GroundVehicle <|-- Tank
AirVehicle <|-- Fighter
AirVehicle <|-- Bomber
AirVehicle <|-- CargoPlane
WaterVehicle <|-- Warship
WaterVehicle <|-- Carrier
WaterVehicle <|-- Submarine
WaterVehicle <|-- CargoShip

UnitFactory <|-- TruckFactory
UnitFactory <|-- TankFactory
UnitFactory <|-- SoldierFactory
UnitFactory <|-- CommanderFactory
UnitFactory <|-- WarshipFactory
UnitFactory <|-- SubmarineFactory
UnitFactory <|-- CarrierFactory
UnitFactory <|-- CargoShipFactory
UnitFactory <|-- FighterFactory
UnitFactory <|-- BomberFactory
UnitFactory <|-- CargoPlaneFactory


TruckFactory .l.> Truck : <<instantiates>>
TankFactory .l.> Tank : <<instantiates>>
SoldierFactory .l.> Soldier : <<instantiates>>
CommanderFactory .l.> Commander : <<instantiates>>
WarshipFactory .l.> Warship : <<instantiates>>
SubmarineFactory .l.> Submarine : <<instantiates>>
CarrierFactory .l.> Carrier : <<instantiates>>
CargoShipFactory .l.> CargoShip : <<instantiates>>
FighterFactory .l.> Fighter : <<instantiates>>
BomberFactory .l.> Bomber : <<instantiates>>
CargoPlaneFactory .l.> CargoPlane : <<instantiates>>



Forces *-- Army
Forces *-- Navy
Forces *-- AirForce

Military o-- Forces

Army o-- Entity
Navy o-- Entity
AirForce o-- Entity

Country o-- Location
Country *-- Military

Battle o-- Country
Battle o-- Forces

SpyAgency <|-- Spy
Military o-- SpyAgency

AllianceMember <|-- Country
AllianceMember <|-- Faction
Conglomerate <|-- Alliance
Conglomerate <|-- AllianceMember
Conglomerate o-- Alliance
BattleStrategy o-- Conglomerate
DefensiveStrategy <|-- BattleStrategy
OffensiveStrategy <|-- BattleStrategy
ResearchiveStrategy <|-- BattleStrategy

Dispute <|-- WarPhases
Conflict <|-- WarPhases
Hostilities <|-- WarPhases
PostHostilitiesConflict <|-- WarPhases
PostHostilitiesDispute <|-- WarPhases
DisputeSettled <|-- WarPhases

War o- WarPhases
War o-- Conglomerate
WarPhases o- War
War o-- Battle





@enduml
