xquery version "1.0";
(:
    ART-DECOR® STANDARD COPYRIGHT AND LICENSE NOTE
    Copyright © ART-DECOR Expert Group and ART-DECOR Open Tools GmbH
    see https://docs.art-decor.org/copyright and https://docs.art-decor.org/licenses

    This file is part of the ART-DECOR® tools suite.
:)

import module namespace get ="http://art-decor.org/ns/art-decor-settings" at "art-decor-settings.xqm";
declare namespace svg="http://www.w3.org/2000/svg";
(:declare option exist:serialize "method=svg media-type=application/svg+xml omit-xml-declaration=no indent=yes";:)

let $transactionGroupId := request:get-parameter('id','2.16.840.1.113883.2.4.6.99.1.77.3.1')
(:let $scenarioId := '2.16.840.1.113883.2.4.6.99.1.77.3.1':)
let $transactionGroup   := $get:colDecorData//transaction[@id=$transactionGroupId]
let $actors             := $transactionGroup/ancestor::scenarios/actors/actor
let $language           := request:get-parameter('language',$transactionGroup/ancestor::decor/project/@defaultLanguage)
let $scenarioName       := $transactionGroup/ancestor::scenario/name[@language=$language]/text()
let $clientId           := ($transactionGroup//actors/actor[@role=('sender','stationary')]/@id)[1]
let $clientName         := $actors[@id=$clientId]/name[@language=$language]
let $serverId           := ($transactionGroup//actors/actor[@role=('receiver')]/@id)[1]
let $serverName         := $actors[@id=$serverId]/name[@language=$language]
let $transactionCount   := count($transactionGroup)
let $transactionNames   := 
    for $transaction in $transactionGroup
    return 
        if ($transaction/@model) then 
            <x>{concat($transaction/name[@language=$language],' (',$transaction/@model,')')}</x>
        else (
            <x>{$transaction/name[@language=$language]}</x>
        )
let $maxTransactionName := max($transactionNames/string-length())
let $maxActorName       := max(($clientName|$serverName)/string-length())
let $fontWidth          := 6
let $minActorboxWidth   := 80
let $sequenceBarWidth   := 10
let $minArrowLength     := 350
let $actorBoxWidth      := 
    if (20 + $maxActorName*$fontWidth > $minActorboxWidth) then
        20 + $maxActorName*$fontWidth
    else ($minActorboxWidth)
let $arrowLength        :=
    if (100 + $maxTransactionName*$fontWidth > $minArrowLength) then
        100 + $maxTransactionName*$fontWidth
    else($minArrowLength)
let $svgMargin          := 21
let $width              := ($svgMargin*2) + ($actorBoxWidth*2) + ( ($arrowLength - ($sequenceBarWidth div 2) - ($actorBoxWidth div 2))*(2 - 1))
let $widthPinkRect      := 10 + $maxTransactionName*$fontWidth
let $heightPinkRect     := 16
let $offsetPinkRectY    := 10
let $boxTextStyle       := 'font-family: Verdana, Arial, sans-serif;font-size:10px;font-weight:bold;text-align:center;text-anchor:middle;line-height:100%;fill:#000000;fill-opacity:1;stroke:none;'
let $arrowTextStyle     := 'font-family: Verdana, Arial, sans-serif;font-size:10px;font-weight:bold;text-align:center;text-anchor:middle;line-height:100%;fill:#000000;fill-opacity:1;stroke:none;'
let $pinkBoxTextStyle   := 'font-family: Verdana, Arial, sans-serif;font-size:10px;font-weight:normal;text-align:center;text-anchor:middle;line-height:100%;fill:#000000;fill-opacity:1;stroke:none;'
let $boxStyle           := 'fill:#c4e1ff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none'
let $barStyle           := 'fill:#c4e1ff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none'

let $transactionLabels :=  
    for $group at $position in $transactionGroup
    let $transactionName := $group/name[@language=$language]/text()
    return
    <g xmlns="http://www.w3.org/2000/svg">
        <rect y="{$offsetPinkRectY + ($position * 100)}" x="{($width div 2) - ($widthPinkRect div 2) }" height="{$heightPinkRect}" width="{$widthPinkRect}"
                    style="fill:#ffaaaa;fill-opacity:1">
        </rect>
        <text y="{$offsetPinkRectY  + ($position * 100) + ($heightPinkRect div 2) + 3}" x="{($width div 2) }"
                    style="{$pinkBoxTextStyle}">
            {$transactionName}
        </text>
    </g>

let $transactionInteractions :=  
    for $group at $position in $transactionGroup
    let $messageIn :=
        if ($group/transaction[1]/@model) then 
            concat($group/transaction[1]/name[@language=$language],' (',$group/transaction[1]/@model,')')
        else (
            $group/transaction[1]/name[@language=$language]/text()
        )
    let $messageOut :=
        if ($group/transaction[2]/@model) then 
            concat($group/transaction[2]/name[@language=$language],' (',$group/transaction[2]/@model,')')
        else (
            $group/transaction[2]/name[@language=$language]/text()
        )
    return
    <g id="interactionLabels" xmlns="http://www.w3.org/2000/svg">
        <text style="{$arrowTextStyle}" x="{($width div 2)}" y="{45 + ($position * 100)}" id="inMessage">
            {$messageIn}
        </text>
        <text style="{$arrowTextStyle}" x="{($width div 2)}" y="{80 + ($position * 100)}" id="outMessage">
            {$messageOut}
        </text>
    </g>

let $transactionArrows :=  
    for $group at $position in $transactionGroup
    return
    <g id="arrows" xmlns="http://www.w3.org/2000/svg">
        <g id="gArrowClientToServer">
            <path id="ArrowClientToServer" d="{concat('m ',($width div 2)- ($arrowLength div 2), ',', 50 + ($position*100), ' h ', $arrowLength)}"
                        style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:none">
                <desc>This is the initiating arrow</desc>
            </path>
            <!-- arrow head client to server -->
            <path d="{concat('m ', ($width div 2) + ($arrowLength div 2) - 10, ',', 45 + ($position*100), ' 0.2428,9.99706 c 3.8451,-1.75975 7.6902,-3.51949 11.5354,-5.27924 0,-0.002 0,-0.002 0,-0.002 0,0 0,0 -0,-0.002 -3.926,-1.57108 -7.852,-3.14216 -11.7781,-4.71324 z')}"
                        style="fill:#000000;fill-rule:evenodd;stroke:none">
            </path>
        </g>
        <g id="gArrowServerToClient">
            <path id="ArrowServerToClient" d="{concat('m ',($width div 2)- ($arrowLength div 2), ', ' , 85 + ($position*100), ' h ', $arrowLength)}"
                        style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:none">
                <desc>This is the responding arrow</desc>
            </path>
            <!-- The arrow head server to client -->
            <path d="{concat('m ',($width div 2)- ($arrowLength div 2) + 10,',', 90 + ($position*100), ' 0.4062,-9.99174 c -3.3774,1.28641 -6.7547,2.57283 -10.132,3.85925 0,0 0,0 0,0 -0.4815,0.18338 -0.9629,0.36676 -1.4444,0.55014 0,0 0,0 0,0 -0.076,0.0291 -0.153,0.0583 -0.2295,0.0874 0,0 0,0 0,0 0,0 0,0 0,0 -0.015,0.0176 -0.029,0.0231 -0.043,0.0246 0,0 0,0 0,0 -0.01,5.5e-4 -0.01,5.8e-4 -0.015,4.1e-4 -0,-6e-5 -0,-6e-5 -0,-6e-5 0,0 0,0 0,9e-5 0.01,2.6e-4 0.01,6.3e-4 0.015,0.002 0,0 0,0 0,0 0.014,0.003 0.028,0.009 0.041,0.028 0,0 0,0 0,0 0,0 0,0 0,0 0.074,0.0353 0.1478,0.0705 0.2216,0.10576 0.465,0.22185 0.93,0.44371 1.395,0.66556 3.2617,1.55631 6.5235,3.11262 9.7853,4.66892 z')}"
                        style="fill:#000000;fill-rule:evenodd;stroke:none">
            </path>
        </g>
    </g>
    
return
<svg xmlns="http://www.w3.org/2000/svg" id="svg2" version="1.1" height="{140 + ($transactionCount * 100)}" width="{$width}">
    <rect style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
                id="backgroundObject" width="{$width}" height="{140 + ($transactionCount * 100)}" x="0" y="0">
        <desc>Background rectangle in white to avoid transparency.</desc>
    </rect>
    <!-- Service name -->
    <text style="font-size:12px;font-weight:bold;text-align:start;line-height:125%;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family: Verdana, Arial, sans-serif;"
                x="{($width div 2)}" y="50" id="textService">
        <desc>Title of scenario</desc>
    </text>
    <!-- Client side objects -->
    <g id="client_objects">
        <!-- Client box (header) -->
        <g id="client_box">
            <rect y="20" x="{($width div 2) - ($arrowLength div 2) - ($sequenceBarWidth div 2) - ($actorBoxWidth div 2)}" height="50" width="{$actorBoxWidth}" id="clientBox" style="{$boxStyle}">
                <desc id="desc2842">Header box for client</desc>
            </rect>
            <text y="50" x="{($width div 2) - ($arrowLength div 2) - ($sequenceBarWidth div 2)}" style="{$boxTextStyle}">
                {data($clientName)}
            </text>
        </g>
        <!-- Client box to bar connect -->
        <path style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
                    d="m {($width div 2) - ($arrowLength div 2) - ($sequenceBarWidth div 2)}, 70 v 30" id="path3646">
            <!-- Client box to bar connector -->
        </path>
        <!-- Client bar -->
        <rect y="100" x="{($width div 2) - ($arrowLength div 2) - $sequenceBarWidth}" height="{20 + $transactionCount*100}" width="{$sequenceBarWidth}" id="rectClientBar" style="{$barStyle}"/>
    </g>
    <!-- Server side objects -->
    <g id="server_objects">
        <!-- Server box -->
        <g id="server_box">
            <rect y="20" x="{($width div 2) + ($arrowLength div 2) + ($sequenceBarWidth div 2) - ($actorBoxWidth div 2)}" height="50" width="{$actorBoxWidth}" id="rect2844" style="{$boxStyle}"/>
            <text y="50" x="{($width div 2) + ($arrowLength div 2) + ($sequenceBarWidth div 2)}" style="{$boxTextStyle}">
                {data($serverName)}
            </text>
        </g>
        <!-- Server box to bar line -->
        <path style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
                    d="{concat('m ', (($width div 2) + ($arrowLength div 2) + ($sequenceBarWidth div 2)) , ', 70 v 30')}" id="path2872"/>
        <!-- Server bar -->
        <rect y="100" x="{($width div 2) + ($arrowLength div 2)}" height="{20 + $transactionCount*100}" width="{$sequenceBarWidth}" id="rectServerBar" style="{$barStyle}"/>
    </g>
    {
        $transactionLabels,
        $transactionInteractions,
        $transactionArrows
    }
</svg>