@startuml
abstract class Printer {
- int id
- String name
- String manufacturer
+ Printer(int,String,String)
+ int getId()
+ Spool[] getCurrentSpools()
+ void setCurrentSpools(ArrayList<Spool>)
+ boolean printFits(Print)
+ String toString()
+ String getName()
}

class Print {
- String name
- int height
- int width
- int length
- ArrayList<Double> filamentLength
- int printTime
+ Print(PrintSpecifics)
+ String toString()
+ String getName()
+ double getLength()
+ int getHeight()
+ int getWidth()
+ ArrayList<Double> getFilamentLength()
}

class FacadeManager{
-SpoolManager spoolManager
-PrintManager printManager
-PrinterManager printerManager
-PrintTaskManager printTaskManager
-PrintStrategy printStrategy
}

class ReadFiles{
- void readPrintsFromFile(String)
- void readPrintersFromFile(String)
- void readSpoolsFromFile(String)
}

class Main {
- Scanner scanner
- FacadeManager facade
+ void main(String[])
+ void run(String[])
+ void menu()
- void startPrintQueue()
- void exit()
- void changePrintStrategy()
- void registerPrintCompletion()
- void registerPrinterFailure()
- void addNewPrintTask()
- void showPrints()
- void showSpools()
- void showPrinters()
- void showPendingPrintTasks()
+ int menuChoice(int)
+ String stringInput()
+ int numberInput()
+ int numberInput(int,int)
}

class MultiColor {
- int maxColors
- Spool spool2
- Spool spool3
- Spool spool4
+ MultiColor(PrinterSpecifics, int)
+ void setCurrentSpools(ArrayList<Spool>)
+ Spool[] getCurrentSpools()
+ String toString()
+ int getMaxColors()
}

class PrinterSpecifics{
- int id
- String printerName
- String manufacturer
- int maxX
- int maxY
- int maxZ
}

class PrintTask {
- Print print
- List<String> colors
- FilamentType filamentType
+ PrintTask(Print,List<String>,FilamentType)
+ List<String> getColors()
+ FilamentType getFilamentType()
+ Print getPrint()
+ String toString()
}

class SpoolManager{
- List<Spool> spools
- List<Spool> freeSpools
+ boolean containsSpool(List<Spool>,String)
+ void addSpool(Spool)
+ List<Spool> getSpools()
+ Spool getSpoolByID(int)
}

class PrintSpecifics{
- String name
- int height
- int width
- int length
- ArrayList<Double> filamentLength
- int printTime
}

class PrintManager{
- List<Print> prints
+ void addPrint(PrintSpecifics)
+ List<Print> getPrints()
+ Print findPrint(String)
+ Print findPrint(int)
}

class PrintTaskManager{
- List<PrintTask> pendingPrintTasks
- Map<Printer,PrintTask> runningPrintTasks
+ void selectPrintTask(Printer)
+ PrintTask getPrinterCurrentTask(Printer)
+ List<PrintTask> getPendingPrintTasks()
+ void addPrintTask(String,List<String>,FilamentType)
}


class PrinterManager {
- List<Printer> printers
- List<Printer> freePrinters
+ void addPrinter(int, PrinterSpecifics, int)
+ void startInitialQueue()
+ List<Printer> getPrinters()
+ void registerPrinterFailure(int)
+ void registerCompletion(int)
- void printError(String)
}

class HousedPrinter {
+ HousedPrinter(PrinterSpecifics)
}

class StandardFDM {
- int maxX
- int maxY
- int maxZ
- Spool currentSpool
+ StandardFDM(PrinterSpecifics)
+ void setCurrentSpools(ArrayList<Spool>)
+ void setCurrentSpool(Spool)
+ Spool getCurrentSpool()
+ Spool[] getCurrentSpools()
+ boolean printFits(Print)
+ int CalculatePrintTime(String)
+ String toString()
}

class Spool {
- int id
- String color
- FilamentType filamentType
- double length
+ Spool(int,String,FilamentType,double)
+ int getId()
+ boolean spoolMatch(String,FilamentType)
+ boolean reduceLength(double)
+ String getColor()
+ FilamentType getFilamentType()
+ String toString()
}

enum FilamentType {
+  PLA
+  PETG
+  ABS
}

enum PrintStrategy{
+ LessSpoolChanges
+ EfficientSpoolUsage
}

@enduml