@startuml ClassDiagram_group01


title ClassDiagram_group01

skinparam ClassAttributeIconSize 0

interface MathInterface{
	+ {abstract} execute(stack : Stack<ComplexNumber>) : void
}

abstract class MathOperation{
	- numOperands: int
	+ MathOperation()	
	+ MathOperation(numOperands : int)
	+ abstract execute(stack : Stack<ComplexNumber>)
	# MinOperandsToOperate(size : int) : boolean
}

class SumOperation{
	+ SumOperation()
	+ execute(stack : Stack<ComplexNumber>) : void
}

class DifferenceOperation{
	+ DifferenceOperation()
	+ execute(stack : Stack<ComplexNumber>) : void
}

class DivisionOperation{
	+ DivisionOperation()
	+ execute(stack : Stack<ComplexNumber>) : void
}

class MultiplicationOperation{
	+ MultiplicationOperation()
	+ execute(stack : Stack<ComplexNumber>) : void
}

class SqrtOperation{
	+ SqrtOperation()
	+ execute(stack : Stack<ComplexNumber>) : void
}

class InverionOperation{
	+ InversionOperation()
	+ execute(stack : Stack<ComplexNumber>) : void
}

interface StackInterface{
	+ {abstract} execute(stack : Stack<ComplexNumber>): void
}

abstract class StackOperation{
	- numOperands: int
	+ StackOperation()	
	+ StackOperation(numOperands : int)
	+ abstract execute(stack : Stack<ComplexNumber>) : void
	# MinOperandsToOperate(size : int) : boolean
}

class ClearOperation{
        + ClearOperation()
        + execute(stack : Stack<ComplexNumber>) : void
}

class DropOperation{
        + DropOperation()
        + execute(stack : Stack<ComplexNumber>) : void
}

class DupOperation{
        + DupOperation()
        + execute(stack : Stack<ComplexNumber>) : void
}

class SwapOperation{
        + SwapOperation()
        + execute(stack : Stack<ComplexNumber>) : void
}

class OverOperation{
        + OverOperation()
        + execute(stack : Stack<ComplexNumber>) : void
}

interface VariablesInterface{
	+ {abstract} execute(variables : Variables, stack : Stack<ComplexNumber>, name : char): void
}

abstract class VariablesOperation{
	- numOperands: int
	+ VariablesOperation()	
	+ VariablesOperation(numOperands : int)
	+ abstract execute(variables : Variables, stack : Stack<ComplexNumber>, name : char) : void
	# MinOperandsToOperate(size : int) : boolean
}

class SaveIntoVarOperation{
        + SaveIntoVarOperation()
        + execute(variables : Variables, stack : Stack<ComplexNumber>, name : char) : void
}

class GetFromVarOperation{
        + GetFromVarOperation()
        + execute(variables : Variables, stack : Stack<ComplexNumber>, name : char) : void
}

class MinusVarOperation{
        + MinusVarOperation()
        + execute(variables : Variables, stack : Stack<ComplexNumber>, name : char) : void
}

class PlusVarOperation{
        + PlusVarOperation()
        + execute(variables : Variables, stack : Stack<ComplexNumber>, name : char) : void
}

class Variables{
    + Variables()
    + get(name : char) : ComplexNumber
    + set(name : char, value : ComplexNumber) : void
}

class ComplexNumber{
    - a : double
    - b : double
    + ComplexNumber(a : double,b : double)
    + ComplexNumber(a : double)
    + ComplexNumber(text : String)
    + getA() : double
    + getB() : double 
    + setA(a : double) : void
    + setB(b : double) : void
}

class InputDistinguisher{
    + InputDistinguisher()
    + isComplexNumber(text : String) : boolean
    + isStackOperation(text : String) : boolean
    + isVariablesOperation (text : String) : boolean
    + isMathOperation (text : String) : boolean
}

class Exception{
    + Exception()
    + Exception(msg : Stirng)        
}

class MathErrorException{
    + MathErrorException()
    + MathErrorException(msg : Stirng)
}
class StackErrorException{
    + StackErrorException()
    + StackErrorException(msg : Stirng)
}
class SyntaxErrorException{
    + SyntaxErrorException()
    + SyntaxErrorException(msg : Stirng)
}

class ScientificCalculator{
    - complexNumbersStack : Stack<ComplexNumber>
    - variables : Variables
    - inputDistinguisher : InputDistinguisher
    + Calculator()
    + getTop12Numbers(stack : Stack<ComplexNumber>) : List<ComplexNumber>
    + calculate(input : String) : void 
    + calculateMathOperation(operation : String) : void
    + calculateStackOperation(operation : String) : void
    + calculateVariablesOperation(operation : String) : void
}

ComplexNumber "many" o-- "1" ScientificCalculator
Variables "many" *-- "1" ScientificCalculator
InputDistinguisher "1" *-- "1" ScientificCalculator
MathErrorException <.. Exception : throws
SyntaxErrorException <.. Exception : throws
StackErrorException <.. Exception : throws

class MathOperation implements MathInterface
class SumOperation extends MathOperation
class DifferenceOperation extends MathOperation
class DivisionOperation extends MathOperation
class MultiplicationOperation extends MathOperation
class SqrtOperation extends MathOperation
class InverionOperation extends MathOperation

class StackOperation implements StackInterface 
class ClearOperation extends StackOperation 
class DropOperation extends StackOperation
class DupOperation extends StackOperation
class SwapOperation extends StackOperation
class OverOperation extends StackOperation

class VariablesOperation implements VariablesInterface 
class SaveIntoVarOperation extends VariablesOperation
class GetFromVarOperation extends VariablesOperation
class MinusVarOperation extends VariablesOperation
class PlusVarOperation extends VariablesOperation

ScientificCalculator "1" --o "many" MathOperation
ScientificCalculator "1" --o "many" StackOperation
ScientificCalculator "1" --o "many" VariablesOperation

@enduml