!include pumla_global_cfg.puml

!$PUMVarShowDescr = %true()
!$PUMVarShowInterfaces = %true()
!$PUMVarShowBody = %true()
!$PUMVarShowBodyInternals = %true()
!$PUMVarShowTaggedValues = %true()
!$PUMVarShowInstantiationRel = %true()
!$PUMVarShowConnections = %true()

!$internal_finalize_string = ""
!$internal_relations_on_diagram = ""

' --------------------------------------------
' put an element referenced by path and filename
' by including its file
'
!unquoted procedure _PUMPutElement($folderpath,$filename)
!include $allelems.modelrepopath/%substr($folderpath,2)/$filename
!endprocedure

' --------------------------------------------
' put an element referenced by path and filename
' by including its file
'
!unquoted function _PUMElement($folderpath,$filename)
!$retval = "!include " + $allelems.modelrepopath + "/" + %substr($folderpath,2) + $filename
!return $retval
!endfunction

' ---------------------------------------------


' ############################################

' ---------------------------------------------
' inject child elements for the referenced
' parent element
'
!unquoted procedure PUMLAInjectChildElements($parentalias)
!foreach $el in $allelems.elements
    !if ($el.parent == $parentalias)
        !include $el.path/$el.filename
    !endif
!endfor
!endprocedure

' ############################################

' ---------------------------------------------
' put the referenced element onto the diagdam
'
!unquoted procedure PUMLAPutElement($elemalias)
!foreach $el in $allelems.elements
    !if ($el.alias == $elemalias)
        _PUMPutElement($el.path,$el.filename)
    !endif
!endfor
!endprocedure

' ############################################

' ---------------------------------------------
' put all elements within the model repo onto
' the diagram. Mixing of class & component elements
' is enabled by wrapping class elements into notes.
!unquoted procedure PUMLAPutAllElementsMix()
!foreach $el in $allelems.elements
    !if ($el.type == "class")
        !$nn = $el.name + "_" + $el.type
        note as $nn #white
        {{
        !include $allelems.modelrepopath/%substr($el.path,2)/$el.filename
        }}
        end note
    !else
        _PUMPutElement($el.path,$el.filename)
    !endif
!endfor
!endprocedure

' ---------------------------------------------
' put all elements within the model repo onto
' the diagram. in order to allow class and component
' elements, component elements like [ds] cannot be shown
' therefore, internals are deactivated.
!unquoted procedure PUMLAPutAllElements()
!$old_sbi = %get_variable_value("$PUMVarShowBodyInternals")
!$PUMVarShowBodyInternals = %false()
allowmixing
!foreach $el in $allelems.elements
    _PUMPutElement($el.path,$el.filename)
!endfor
!$PUMVarShowBodyInternals = $old_sbi
!endprocedure

' ---------------------------------------------
' put all classes within the model repo onto
' the diagram
!unquoted procedure PUMLAPutAllClasses()
!foreach $el in $allelems.elements
    !if ($el.type == "class")
        _PUMPutElement($el.path,$el.filename)
    !endif
!endfor
!endprocedure

' ############################################
' ---------------------------------------------
' put all relations of the model repo
' onto the diagram
!unquoted procedure PUMLAPutAllRelations()
!foreach $el in $allrelations.relations
    PUMLAPutRelation($el.id)
!endfor
!endprocedure

' ############################################

' ---------------------------------------------
' put all connections of the model repo
' onto the diagram
!unquoted procedure PUMLAPutAllConnections()
!foreach $el in $allconnections.connections
    PUMLAPutConnection($el.id)
!endfor
!endprocedure

' ############################################
' ---------------------------------------------
' create an instance of an element that exists
' in the json model repo. Internal txt creation.
!unquoted function _PUMLACreateInstanceOf($elemalias, $instalias, $instname)
!$retval = "[**ERROR:** Element **" + $elemalias + "** not in model repository!]"
!foreach $el in $allelems.elements
    !if ($el.alias == $elemalias)
        !if ($PUMVarShowInstantiationRel)
            !$iname = $instname
        !else
            !$iname = $instname + "::" + $el.name
        !endif
        $elt = "ERROR - no valid type"
        !if (($el.type  == "-") || ($el.type  == ""))
            !$elt = "rectangle"
        !else
            !$elt = $el.type
        !endif
        !$sts = ""
        !foreach $st in $el.stereotypes
            !$sts = $sts + " <<" + $st + ">>"
        !endfor
        !$retval = $elt + ' "' + $iname + '"' + $sts + ' <<instance>> as ' + $instalias
    !endif
!endfor
!return $retval
!endfunction


' ############################################
' ---------------------------------------------
' create an instance of an element that exists
' in the json model repo and put it onto
' the diagram.
!unquoted procedure PUMLACreateAndPutInstanceOf($elemalias, $instalias, $instname="")
!if ($instname == "")
!$instname = $instalias
!endif
_PUMLACreateInstanceOf($elemalias,$instalias, $instname)
!if ($PUMVarShowInstantiationRel)
PUMLAPutElement($elemalias)
$instalias ..> $elemalias : instance of
!endif
!endprocedure

' ############################################
' ---------------------------------------------
' create an instance of an element that exists
' in the json model repo.
!unquoted procedure PUMLAInstanceOf($elemalias, $instalias, $instname="")
!if ($instname == "")
!$instname = $instalias
!endif
!if ($PUMVarShowBody)
_PUMLACreateInstanceOf($elemalias,$instalias, $instname)
!endif
!endprocedure

' ############################################
' ---------------------------------------------
' this commands gives you an overview
' on the contents of the model repository
' along with the alias names that you can
' use to access/re-use the elements.
!unquoted procedure PUMLACheatSheet()
note as PUMLAUPCheatSheet
    **PUMLA Cheat Sheet**

    **Model Repository contents:**
    |= name |= alias |
!foreach $el in $allelems.elements
    | $el.name | $el.alias |
!endfor
end note
!endprocedure

' ############################################
' ---------------------------------------------
' this commands gives you an overview
' on the contents of the model repository.
' It puts all elements with all attributes into
' a table to help you manage your architecture
' artefacts.
!unquoted procedure PUMLACheatSheetAllAttributes()
note as PUMLAUPCheatSheetAllAttributes
    **PUMLA Cheat Sheet with all attributes**

    Model Repository Path: $allelems.modelrepopath
    Model Repository File: $allelems.modelrepofile

    **Model Repository contents:**
    |= name |= alias |= type |= stereotypes |= parent |= instclass |= filename |= path |
!foreach $el in $allelems.elements
    !$sts = ""
    !$lmax = 0
    !foreach $st in $el.stereotypes
        !$lmax = $lmax + 1
    !endfor
    !$l = 0
    !foreach $st in $el.stereotypes
        !$sts = $sts + $st
        !$l = $l + 1
        !if ($l < $lmax)
            !$sts = $sts + ", "
        !endif
    !endfor
    !if ($sts=="")
        !$sts="-"
    !endif
    | $el.name | $el.alias | $el.type | $sts | $el.parent | $el.instclassalias | $el.filename | $el.path |
!endfor
end note
!endprocedure

' ############################################
' ---------------------------------------------
' this commands gives you an overview
' on the contents of the relations repository.
' It puts all elements with all attributes into
' a table to help you manage your architecture
' artefacts.
!unquoted procedure PUMLARelCheatSheetAllAttributes()
note as PUMLAUPRelCheatSheetAllAttributes
    **PUMLA Relations Cheat Sheet with all attributes**

    Model Repository Path: $allrelations.modelrelationrepopath
    Model Repository File: $allrelations.modelrelationrepofile

    **Model Relations Repository contents:**
    |= id |= start |= type |= end |= text |= filename |= path |
!foreach $el in $allrelations.relations
    | $el.id | $el.start | $el.reltype | $el.end | $el.reltxt | $el.filename | $el.path |
!endfor
end note
!endprocedure

' ############################################
' ---------------------------------------------
' this commands gives you an overview
' on the contents of the connections repository.
' It puts all elements with all attributes into
' a table to help you manage your architecture
' artefacts.
!unquoted procedure PUMLAConCheatSheetAllAttributes()
note as PUMLAUPConCheatSheetAllAttributes
    **PUMLA Connections Cheat Sheet with all attributes**

    Model Repository Path: $allconnections.modelconnectionrepopath
    Model Repository File: $allconnections.modelconnectionrepofile

    **Model Connections Repository contents:**
    |= id |= start |= type |= end |= text |= filename |= path |
!foreach $el in $allconnections.connections
    | $el.id | $el.start | $el.contype | $el.end | $el.contxt | $el.filename | $el.path |
!endfor
end note
!endprocedure

' ############################################
' ---------------------------------------------
' default footer with pumla git repo reference.
' can be overwritten or turned off with the
' global variable.
!if ($PUMVarShowPUMLAFooterNote)
center footer created with help of **pumla**: https://github.com/DrMarkusVoss/pumla
!endif

' ############################################
' ---------------------------------------------
' internal use of an existing model repo element.
!unquoted procedure PUMLAPutInternalElement($elemalias)
!if ($PUMVarShowBodyInternals)
PUMLAPutElement($elemalias)
!endif
!endprocedure

' ############################################
' ---------------------------------------------
' define a re-usable Connection
!unquoted procedure PUMLAConnection($startalias, $endalias, $contype, $contxt="", $conid="")
' empty by intention... the macro name will only be parsed
' by the pumla.py script and the connection then put into
' the model repo. The PlantUML code comes when you put
' a connection from the repo to a diagram.
!endprocedure

' ############################################
' ---------------------------------------------
' put a re-usable connection onto the diagram.
' connections only exist between interfaces.
' otherwise it is a relation, not a connection.
' therefore, if interfaces are not shown, also
' the connections cannot be shown.
!unquoted procedure PUMLAPutConnection($conid)
!foreach $el in $allconnections.connections
    !if ($el.id == $conid)
        !if (%not(%variable_exists($$el.id)))
            !if ($PUMVarShowInterfaces)
            !if ($PUMVarShowConnections)
            !if ($el.contxt=="")
                !$conadr = ""
            !else
                !$conadr = " : " $el.contxt
            !endif
            $el.start $el.contype $el.end $conadr
            ' set global variable to indicate that the connection
            ' is already put onto the diagram
            %set_variable_value($$el.id, "%true()")
            !endif
            !endif
        !endif
    !endif
!endfor
!endprocedure

' ############################################
' ---------------------------------------------
' define a re-usable interface and put it on
' the diagram.
!unquoted procedure PUMLAPutInterface($ifname, $ifalias, $elemalias, $type="")
!if ($PUMVarShowInterfaces)
!if ($type=="")
    !$constr = "--"
!elseif ($type=="in")
    !$constr = ")-->"
!elseif ($type=="out")
    !$constr = "<--"
!elseif ($type=="inout")
    !$constr = "<-->"
!else
    !$constr= "--"
!endif
interface "$ifname" as $ifalias
$ifalias $constr $elemalias
!endif
!endprocedure

' ############################################
' ---------------------------------------------
' define a re-usable relation
!unquoted procedure PUMLARelation($startalias, $endalias, $reltype, $reltxt="", $relid="")
' empty by intention... the macro name will only be parsed
' by the pumla.py script and the relation then put into
' the model repo. The PlantUML code comes when you put
' a relation from the repo to a diagram.
!endprocedure

' ############################################
' ---------------------------------------------
' put a relation with given id onto the diagram
!unquoted procedure PUMLAPutRelation($relid)
!foreach $el in $allrelations.relations
    !if ($el.id == $relid)
        !if (%not(%variable_exists($$el.id)))
            !if ((%not($el.reltxt == "instance of")) || ($PUMVarShowInstantiationRel))
            $el.start $el.reltype $el.end : $el.reltxt
            ' set global variable to indicate that the relation
            ' is already put onto the diagram
            %set_variable_value($$el.id, "%true()")
            !endif
        !endif
    !endif
!endfor
!endprocedure

' ############################################
' ---------------------------------------------
' put all relations related to given element alias
' to the diagram
!unquoted procedure PUMLAPutRelationsForElement($elemalias, $reltype="")
!foreach $el in $allrelations.relations
    !if ($reltype == "")
        !$reltype = $el.reltype
    !endif
    !if ((($el.start == $elemalias) || ($el.end == $elemalias)) && ($el.reltype  == $reltype))
        ' make sure to not put the same relation twice
        !if (%not(%variable_exists($$el.id)))
            !if ((%not($el.reltxt == "instance of")) || ($PUMVarShowInstantiationRel))
                $el.start $el.reltype $el.end : $el.reltxt
                ' set global variable to indicate that the relation
                ' is already put onto the diagram
                %set_variable_value($$el.id, "%true()")
            !endif
        !endif
    !endif
!endfor
!endprocedure

' ############################################
' ---------------------------------------------
' put all connections related to given element alias
' to the diagram
!unquoted procedure PUMLAPutConnectionsForElement($elemalias)
!foreach $el in $allconnections.connections
    !if ($el.contxt == "")
        !$conadder = ""
    !else
        !$conadder = " : " + $el.contxt
    !endif
    !if ((%strpos($el.start, $elemalias) > 0) || (%strpos($el.end, $elemalias) >0))
        ' make sure to not put the same relation twice
        !if (%not(%variable_exists($$el.id)))
            $el.start $el.contype $el.end $conadder
            ' set global variable to indicate that the relation
            ' is already put onto the diagram
            %set_variable_value($$el.id, "%true()")
        !endif
    !endif
!endfor
!endprocedure

