@startuml
skinparam classAttributeIconSize 0

namespace GRF {
	class incidenceMatrix {
		- vertexNumber : unsigned int
		- edgeNumber : unsigned int
		
		# inMatrix : vector<vector<int>>	

		+ incidenceMatrix()
		+ incidenceMatrix(v : unsigned int, e : unsigned int)
	
		+ makeCon(vtx1 : unsigned int, vtx2 : unsigned int, edge : unsigned int) : void			

		+ addEdge(vtx1 : unsigned int, vtx2 : unsigned int) : void

		+ removeEdge(unsigned int edg)
		+ removeVertex(unsigned int vtx)

		+ getVertexNumber() : unsigned int
		+ getEdgeNumber() : unsigned int
		+ getLoop(key : unsigned int) : vector<int>
		+ getSpanningTree(key : unsigned int) : incidenceMatrix
		+ getVertexCon(vtx : unsigned int, i : unsigned int) : unsigned int	
		+ getEdges(vtx : unsigned int) : vector<unsigned int>
		+ getEdges(vtx1 : unsigned int, vtx2 : unsigned int) : vector<unsigned int>
		+ getVertex(edge : unsigned int) : pair<unsigned int, unsigned int>
		+ getConNum(vtx : unsigned int) : unsigned int
	
	}
	class adjacencyMatrix {
		- vertexNumber : unsigned int;
		- adjMatrix : vector<vector<int>>

		+ adjacencyMatrix()
		+ adjacencyMatrix(vertexNum : unsigned int)

		+ insertEdge(vtx1 : unsigned int, vtx2 : unsigned int)
		+ insertVertex(vtx: unsigned int)
		+ removeVertex(vtx : unsigned int)
		+ query(i : unsigned int, j : unsigned int) : int

		+ getVertexNumber() : unsigned int
	}
}

namespace CMP {
	enum type {
		RESISTOR
		VCC
	}

	abstract class Component {
		# label : string
		# vtxs : pair
		# voltage : double
		# current : double
	
		+ Component(l : string, vtx1 : unsigned int, vtx2 : unsigned int)
		+ {abstract} ~Component()

		+ getLabel() : string
		+ setLabel(newLabel : string) : void	

		+ getVoltage() : double
		+ {abstract} setVoltage(v : double) : void

		+ getCurrent() : double
		+ {abstract} setCurrent(i : double) : void

		+ getNodes() : pair<unsigned int, unsigned int>
	
		+ {abstract} getType() : enum type		
		
	} 

	class Resistor implements Component {
		- resistance : double

		+ Resistor(l : string, res : double, vtx1 : unsigned int, vtx2 : unsigned int) 
		+ ~Resistor()

		+ setCurrent(i : double) : void	
		+ setVoltage(v : double) : void

		+ getResistance() : double	
		+ setResistance(r : double) : void
	
		+ getType() : enum type

	}
	
	class Vcc implements Component {
		+ Vcc(l : string, vol : double, negative : unsigned int, positive : unsigned int)
		+ ~Vcc()

		+ getType() : enum type

		+ setCurrent(i : double) : void
		+ setVoltage(v : double) : void
	}

	Component "1" *-- "1" type
}

namespace CCT {

	
	class Circuit extends GRF.incidenceMatrix {
		- components : vector<Component*>
		- circuitMatrix : vector<vector<int>>
		- chords : vector<unsigned int>
		
		- updateComponents(currents : vector<double>)

		- Solve() : void

		+ Circuit()
		+ ~Circuit()
		
		+ initialize() : void
		+ reset() : void

		+ addComponent(t : enum type, l : string, value : double, vtx1 : unsigned int, vtx2 : unsigned int) : void

		+ editComponent(label : string, value : double) : void

		+ editComponent(label : string, newLabel : string) : void
	
		+ removeComponent(l : string) : void
	
		+ removeComponent(edge : unsigned int) : void	

		+ getVoltage(l : string) : double
		+ getCurrent(l : string) : double 

	}

}


CCT.Circuit "1" o-- "0..*" CMP.Component
	
namespace NM {

	Class Matrix {
		- realMatrix : vector<vector<double>>
		- rowNumber : int
		- colNumber : int
	
		+ Matrix(r : unsigned int)
		+ Matrix(r : unsigned int, c : unsigned int)

		+ operator* (m1 : Matrix&) : Matrix
		+ operator*= (m1 : Matrix&) : void
		
		+ operator+ (m1 : Matrix&) : Matrix
		+ operator+= (m1 Matrix&) : void

		+ operator- (m1 : Matrix&) : Matrix
		+ operator-= (m1 Matrix&) : void

		+ operator= (m1 : const Matrix&)

		+ operator[] (index : unsigned int) : vector<double>&

		+ operator- () : Matrix

		+ transpose() : Matrix

		+ Abs() : Matrix

		+ getCol(col : unsigned int) : vector<double>
		+ getColNumber() : unsigned int
		+ getRowNumber() : unsigned int

		+ swapLines() : void
	}

	class EquationSystem{
		- A : Matrix
		- B : Matrix 	
		- x : Matrix
	
		- gaussSeidel(tol : double, maxIter : int) : void
		- sassenfeldCriteria() : void
	
		- findPivot(startI : unsigned int) : void
		- gaussJordan() : void

		+ EquationSystem(a : Matrix, b : Matrix)

		+ getSolution(tol : double, maxIter : int) : Matrix
		
	}
	Matrix "*" --* "1" EquationSystem
}

NM.EquationSystem "1" --* "1" CCT.Circuit

enum orien {
	VERTICAL
	HORIZONTAL
}

abstract class GraphicComponent extends QObject {
	# orientation : enum orien 

	# x : int
	# y : int

	# vertexArea1 : QRect
	# vertexArea2 : QRect

	# boundRect : QRect
	# map QPixmap

	# vertex1 : unsigned int
	# vertex2 : unsigned int

	# componentType : type
	# QString label : QString
	# value : double

	+ explicit GraphicComponent(x : int, y : int, vtx1 : unsigned int, vtx2 : unsigned int, s : enum orien, parent : QObject* = nullptr)
	
	+ clickedArea(x : int, y : int) : int

	+ draw(painter : QPainter*, color : QColor = QColor()) : void
	+ getHeight() : int
	+ getWidth() : int
	+ getBottom() : QPoint
	+ getTop() : QPoint
	+ getLeft() : QPoint
	+ getRight() : QPoint
	+ getBoundRect() : QRect

	+ getOrientation() : enum orien 

	+ void setVertex1(unsigned int vtx);
	+ void setVertex2(unsigned int vtx);

	+ getVertex1() : unsigned int
	+ getVertex2() : unsigned int
	+ getLabel() : string

	+ {abstract} getType() : type
	+ getValue() : double
	+ setValue(double newValue) : void

	+ getVertex1Point() : QPoint 
	+ getVertex2Point() : QPoint

	+ void updateName() : void
}

orien "1" --* "1" GraphicComponent

class Resistor implements GraphicComponent {
	+ explicit Resistor(x : int, y : int, vtx1 : unsigned int, vtx2 : unsigned int, s : enum orien = VERTICAL, parent : QObject* = nullptr)
	+ getType() : type
}

class Vcc implements GraphicComponent {
	+ explicit Vcc(x : int, y : int, vtx1 : unsigned int, vtx2 : unsigned int, s : enum orien = VERTICAL, parent : QObject* = nullptr)
	+ getType() : type
}


enum cmpStyle {
	VCC90
	VCC180
	RES90
	RES180
	NONE
}
enum stats {
	UNSAVED
	MODIFIED
	OK
	ERROR
}
enum mode {
	EDIT
	QUERY
}

class Diagram extends QWidget {
	- circuit : Circuit

	- fileName : string 

	- status : enum stats 
	- mode : enum mode
	- selectedButton : enum cmpStyle

	- playButton : QPushButton*
	- editButton : QPushButton*

	- drawList : vector<GraphicComponent*>

	- selectedComponent : GraphicComponent*

	- connections : adjacencyMatrix

	- wireCounter : unsigned int
	- vtxCounter : unsigned int

	- editMenu : QMenu*
	- queryMenu : QMenu*

	- cursorLocation : QPoint
	- selectedPrev : QPoint
	
	- clickedStack : stack<pair<int, GraphicComponent*>>

	- {static} backgroundColor : QColor
	- {static} gridColor : QColor
	- {static} componentColor : QColor
	- {static} selectedColor : QColor 

	# paintEvent(event : QPaintEvent*) : void
	# mousePressEvent(event : QMouseEvent*) : void
	# mouseMoveEvent(event : QMouseEvent*) : void

	+ explicit Diagram(parent : QWidget* = nullptr)

	+ getFileName() : QString 
	+ setFileName(QString file) : void

	+ save() : void
	+ load() : void

	+ getStatus() : enum stats 

	+ setSelectedButton(button : enum cmpStyle) : void 

	+ insert(x : int, y : int) : void

	+ {static} setBGColor() : void
	+ {static} getBGColor() : void
	
	+ {static} setGridColor() : void
	+ {static} getGridColor() : void
	
	+ {static} setComponentColor() : void
	+ {static} getComponentColor() : void

	+ {static} setSelectedColor() : void
	+ {static} getSelectedColor() : void

	+ modified(checked : bool = false) : void

	+ loadError(checked : bool = false) : void

	+ statusBarText(str : QString) : void

	+ queryMode() : void
	+ editMode() : void

	+ showEditDialog() : void

	+ edit(newValue : double) : void
	+ remove() : void
	+ query() : void
}

mode "1" --* "1" Diagram
cmpStyle "1" --* "1" Diagram
stats "1" --* "1" Diagram

GRF.adjacencyMatrix "1" --* "1" Diagram
CCT.Circuit "1" --* "1" Diagram

GraphicComponent "0..*" --o "1" Diagram

class MainWindow extends QMainWindow {
	- explicit MainWindow(parent QWidget* = nullptr)

	- MainWindow(const MainWindow&)

	- operator=(MainWindow&) : MainWindow

	- {static} instance : MainWindow* 

	- diagrams : list<Diagram*> 

	- mainBar : QMenuBar*

	- fileMenu : QMenu*
	- openFileAct : QAction*
	- saveFileAct : QAction*
	- saveFileAsAct : QAction*
	- newFileAct : QAction*
	
	- statusBar : QStatusBar* 
	- initialTab : QWidget* 

	
	- prefMenu : QMenu*
	- setBGColorAct : QAction*
	- setGridColorAct : QAction*
	- setComponentColorAct : QAction*
	- setSelectedColorAct : QAction*
	- resetConfigAct : QAction*

	- helpMenu : QMenu*
	- tutorialAct : QAction*

	- toolbar : QToolBar*

	- statusBar : QStatusBar*	

	- tabs : QTabWidget* 

	- initializeMenu() : void
	- initializeToolbar() : void
	- initializeTabs() : void
	- initializeStatusBar() : void

	- loadConfig() : void
	- saveConfig() : void

	+ {static} getMainWindow() : MainWindow* 

	+ newFile() : void
	+ openFile() : void
	+ saveFile() : void
	+ saveFileAs() : void
	+ openFile() : void
	+ closeFile(index : int) : void

	+ setTabStatus(modified : bool) : void	
	
	+ drawRes90() : void
	+ drawRes180() : void
	+ drawVcc90() : void
	+ drawVcc180() : void

	+ setBGColor() : void
	+ setGridColor() : void
	+ setComponentColor() : void
	+ setSelectedColor() : void

	+ resetConfig()
}

Diagram "0..*" --o "1" MainWindow

@enduml
