#macro(renderTitle $gui)
  <h1 class="h4 mb-3 text-center">$gui.label</h1>
#end

#macro(renderInfoIcon)
<div class="text-center">
  <img src="${login.appDataPath}/resources/info.svg?v=cde656f1" alt="Info icon">
</div>
#end

#macro(renderSuccessIcon)
<div class="success-icon">
  <img src="${login.appDataPath}/resources/success.svg?v=45e1a941" alt="Success icon">
</div>
#end

#macro(renderPasswordlessIcon)
<div class="text-center">
  <img src="${login.appDataPath}/resources/face.svg?v=a17cbb96" alt="Paswordless first icon">
  <img src="${login.appDataPath}/resources/finger.svg?v=08a4a146" alt="Paswordless second icon">
</div>
#end

#macro(renderFormLinks $gui)
  #set ($noLinks = true)
  #foreach ($guiElem in $gui.getGuiElems())
    #if ($guiElem.type == "link" && $guiElem.value != "")
      #if ($noLinks)
      <div class="form-group text-center">
        #set ($noLinks = false)
      #end
      <a class="link" title="${utils.escapeHtml($guiElem.label)}" href="$utils.escapeHtml($guiElem.value)">${utils.escapeHtml($guiElem.label)}</a>
    #end
  #end
  #if (!$noLinks)
  </div>
  #end
#end

#macro(renderInfo $guiElem)
  #set($cssClass = "text-primary")
  #if ($renderInfoCalled)
    #set($cssClass = "text-secondary")
  #end
  #if ($guiElem.name.endsWith('sub-icon'))
    <div class="sub-icon mb-3">
      <span class="text-dark">$guiElem.label</span>
    </div>
  #elseif ($guiElem.name.endsWith('bottom'))
    <div class="text-center mt-4 mb-0">
      <span class="text-secondary">$guiElem.label</span>
    </div>
  #elseif($guiElem.name == "selection")
    #set($methodName=$guiElem.value.replace("-registered", ""))
    #set($methodLabel=$text.get("info.method.$methodName"))
    #if($guiElem.value.endsWith('registered'))
      <button type="button" class="list-group-item list-group-item-action btn-selection-item disabled" value="$guiElem.value">
        <div>
          <span class="d-flex align-items-center gap-1">
            <img src="${login.appDataPath}/resources/${methodName}.svg" alt="${methodLabel}">
            <span class="selection-label">$utils.escapeHtml($methodLabel)</span>
          </span>
          <span class="d-flex selection-description">$utils.escapeHtml($guiElem.label)</span>
        </div>
        <img src="${login.appDataPath}/resources/success-solid.svg?v=d4a18981" alt="${methodLabel} registered">
      </button>
    #else
      <button name="selection" type="submit" class="list-group-item list-group-item-action btn-selection-item" value="$guiElem.value">
        <div>
          <span class="d-flex align-items-center gap-1">
            <img src="${login.appDataPath}/resources/${methodName}.svg" alt="${methodLabel}">
            <span class="selection-label">$utils.escapeHtml($methodLabel)</span>
          </span>
          <span class="d-flex selection-description">$utils.escapeHtml($guiElem.label)</span>
        </div>
        <img src="${login.appDataPath}/resources/chevron-right.svg?v=597ebf66" alt="Select ${methodLabel}">
      </button>
    #end
  ## special FIDO2 case
  #elseif(($gui.name == "fido2_onboard" || $gui.name == "fido2_auth") && $guiElem.name == "info")
    <div class="sub-title mb-40">
      <span class="text-dark">$guiElem.label</span>
    </div>
  ## special case: recovery codes
  #elseif ($guiElem.name == "displayrecoverycodes")
    <span class="hidden" id="recovery-codes-raw">$guiElem.label</span>
    <div id="recovery-codes" class="recovery-codes-wrapper printable"></div>
  ## special case: OATH copyable secret key
  #elseif ($guiElem.name.endsWith('readonly-copyable'))
    <div class="icon-inside mb-4">
      ## skip name to prevent submitting
      <input readonly type="text" class="form-control text-truncate" id="${guiElem.name}" value="$utils.escapeHtml($guiElem.label)" title="${guiElem.label}">
      <button class="icon-button nevis-blue-icon text-nevis-blue" type="button" onclick="copyToClipboard('${guiElem.name}')">
        ## Use inline svg due to color changing
        <svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg" aria-labelledby="copyTitle">
          <title id="copyTitle">Copy setup key icon</title>
          <path d="M6.66683 13.8333H5.00016C4.07969 13.8333 3.3335 13.0871 3.3335 12.1666V5.49992C3.3335 4.57944 4.07969 3.83325 5.00016 3.83325H11.6668C12.5873 3.83325 13.3335 4.57944 13.3335 5.49992V7.16659M8.3335 17.1666H15.0002C15.9206 17.1666 16.6668 16.4204 16.6668 15.4999V8.83325C16.6668 7.91278 15.9206 7.16659 15.0002 7.16659H8.3335C7.41302 7.16659 6.66683 7.91278 6.66683 8.83325V15.4999C6.66683 16.4204 7.41302 17.1666 8.3335 17.1666Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>
      </button>
    </div>
  #elseif($guiElem.name == "authcloud_info") ## special Access App case
    <div class="sub-icon my-4">
      <span class="text-dark" id="$guiElem.name">$guiElem.label</span>
    </div>
    #if($gui.name == "authcloud_onboard") ## prepare hidden access app installed info for mobile platform
      <span id="info.access_app.installed" class="d-none">$utils.escapeHtml($text.get("info.access_app.installed"))</span>
    #end
  #elseif(($gui.name == "authcloud_onboard" || $gui.name == "authcloud_login") && $guiElem.name == "abort") ## special Access App case
    <div class="text-center mt-4">
      <span id="$guiElem.name" class="text-secondary">$guiElem.label</span>
    </div>
  #elseif($guiElem.name != "policyInfo.title" && $guiElem.name.startsWith('policy'))
    <div class="my-2">
      <span class="text-secondary" id="$guiElem.name">$guiElem.label</span>
    </div>
  #else
    <div class="text-center my-3">
      <span class="$cssClass" id="$guiElem.name">$guiElem.label</span>
    </div>
  #end
  #set($renderInfoCalled = true)
#end

#macro(renderHidden $guiElem)
  ## prepare hidden deep link label for mobile app
  #if ($guiElem.name == "info.deeplink")
    ## patched by authcloud_login.js
    <span id="info.login.access_app" class="d-none">$utils.escapeHtml($guiElem.value)</span>
  #elseif ($guiElem.name == "saml.logoutURLs")
    <script src="${login.appDataPath}/resources/saml_idp_logout.js?v=3a0c7b23"></script>
    <script>
      var sp_urls = '$guiElem.value'.split(',');
      var final_url = '$gui.getGuiElem("saml.logoutURL").value';
      handleLogout(sp_urls, final_url);
    </script>
  #else
    <input type="hidden" name="$guiElem.name" value="$utils.escapeHtml($guiElem.value)">
  #end
#end

#macro(renderText $guiElem)
  #set ($extraClass = "")
  ## highlight failed input validation
  #if ($guiElem.validationFailed)
    #set ($extraClass = "border-danger")
  #end
  ## special case email/SMS verification
  #if ($guiElem.name == "isiwebotp")
    <div class="verification-code-wrapper my-4">
      <label for="${guiElem.name}" class="verification-code-label form-label">${guiElem.label}</label>
      <input id="${guiElem.name}" name="${guiElem.name}" type="text" placeholder="______" maxlength="6"
             class="verification-code-input form-control $extraClass"
             value="$utils.escapeHtml($guiElem.value)" autofocus autocomplete="one-time-code">
    </div>
  #else
    #set ($autocomplete = "username")
    #if ($gui.getGuiElem("fido2_attestation_options"))
      #set ($autocomplete = "username webauthn")
    #end
    #set ($inputWrapperClass = "my-4") ## default spacing around the input: 24px top and bottom
    <div class="$inputWrapperClass">
      #if ($guiElem.label && $guiElem.label.length() > 0)
        <label for="${guiElem.name}" class="form-label $extraClass">${guiElem.label}</label>
      #end

    #if ($guiElem.name == "isiwebuserid") ## loginId or email
      <input name="isiwebuserid" type="text" class="form-control $extraClass"
             id="isiwebuserid" value="$utils.escapeHtml($guiElem.value)" required autofocus autocomplete="$autocomplete">
      <div class="invalid-feedback" id="isiwebuserid-invalid-feedback">
        <span>$guiElem.validationMessage</span>
      </div>
    #elseif($guiElem.name == "isiwebrecovery") ## special case recovery code input
      <input name="${guiElem.name}" type="${guiElem.type}"
             placeholder="____-____-____-____"  maxlength="19"
             class="recovery-code-input form-control"
             id="${guiElem.name}"
             value="$utils.escapeHtml($guiElem.value)" autofocus>
    #elseif($gui.name.endsWith("OATH_Authentication") && $guiElem.name == "response") ## special case time based one time password code input
      <div class="totp-code-wrapper">
        <input name="${guiElem.name}" type="number" inputmode="numeric" pattern="[0-9]{6}"
               placeholder="______" maxlength="6"
               class="totp-code-input form-control $extraClass"
               id="${guiElem.name}"
               value="$utils.escapeHtml($guiElem.value)" autofocus autocomplete="one-time-code" oninput="formatNumberInput('${guiElem.name}')">
      </div>
    #elseif ($guiElem.type == "pw-text")
      <div class="icon-inside">
        <input name="${guiElem.name}" type="password" class="form-control $extraClass" id="${guiElem.name}" autofocus autocomplete="current-password">
        <button class="icon-button" type="button" onclick="toggleEye('${guiElem.name}', '${guiElem.name}-eye', '${login.appDataPath}')">
          <img id="${guiElem.name}-eye" src="${login.appDataPath}/resources/eye.svg?v=d43998e8">
        </button>
      </div>
    #else
      <input name="${guiElem.name}" type="${guiElem.type}"
             class="form-control $extraClass" id="${guiElem.name}" value="$utils.escapeHtml($guiElem.value)" autofocus>
    #end
    </div>
  #end
#end

#macro(renderButton $guiElem)

  ## special cases: FIDO2
  #if ($guiElem.name == "onclick")
    <button class="btn btn-primary w-100" type="button" onclick="startFido2();">
      $utils.escapeHtml($guiElem.label)
    </button>

  ## special cases: recovery codes
  #elseif ($guiElem.name == "copyrecoverycode")
    <button class="btn btn-secondary btn-recovery-code" type="button" onclick="copyToClipboard('recovery-codes')">
      $utils.escapeHtml($guiElem.label)
    </button>
    #set ($btnPrimaryUsed = false)
  #elseif ($guiElem.name == "downloadrecoverycode")
    <button class="btn btn-secondary btn-recovery-code" type="button" onclick="downloadRecoveryCodes('recovery-codes')">
      $utils.escapeHtml($guiElem.label)
    </button>
  #elseif ($guiElem.name == "printrecoverycode")
    <button class="btn btn-secondary btn-recovery-code" type="button" onclick="window.print();">
      $utils.escapeHtml($guiElem.label)
    </button>

  ## default rendering
  #elseif ($guiElem.value != "disabled") ## do not show button if the value is disabled

    #set ($btnWrapperClass = "text-center mt-4")
    #if ($guiElem.name.endsWith('bottom'))
      #set ($btnWrapperClass = "${btnWrapperClass} mb-0")
    #else
      #set ($btnWrapperClass = "${btnWrapperClass} mb-4")
    #end

    #set ($btnClass = "btn w-100")
    #if ($guiElem.cssClass && !$guiElem.cssClass.isEmpty())
      #set ($btnClass = "${btnClass} ${guiElem.cssClass}")
    #else
      #if (!$btnPrimaryUsed)
        #set ($btnClass = "${btnClass} btn-primary")
        #set ($btnPrimaryUsed = true)
      #else
        #set ($btnClass = "${btnClass} btn-secondary")
      #end
    #end

    <div class="$btnWrapperClass">
      <button name="$guiElem.name" type="submit" class="$btnClass"
              value="$utils.escapeHtml($guiElem.value)">$guiElem.label</button>
    </div>
  #end
#end

#macro(renderError $guiElem)
  #if($guiElem.name.startsWith('policy'))
    <div class="my-2">
      <span class="text-danger" id="$guiElem.name">$guiElem.label</span>
    </div>
  #else
    <div class="text-center my-4">
      <span class="text-danger" id="$guiElem.name">$guiElem.label</span>
    </div>
  #end
#end

#macro(renderRadio $guiElem)
  <div class="form-check">
    <input id="${guiElem.name}" name="${guiElem.name}" type="radio" class="form-check-input" value="$utils.escapeHtml($guiElem.value)" autofocus>
    <label for="${guiElem.name}" class="form-check-label">${guiElem.label}</label>
  </div>
#end

#macro(renderCheckbox $guiElem)
  <div class="form-check">
    <label for="${guiElem.name}" class="form-check-label">${guiElem.label}</label>
    <input id="${guiElem.name}" name="${guiElem.name}" type="checkbox" class="form-check-input" value="$utils.escapeHtml($guiElem.value)"
      #if ($guiElem.checked)
        checked
      #end
    >
  </div>
#end

#macro(renderImage $guiElem)
  <div class="text-center">
    <img src="${guiElem.value}" alt="${guiElem.name}" class="img-fluid">
  </div>
#end

#macro(renderGuiElem $guiElem)
  #if ($guiElem.name.startsWith('social_') || $guiElem.type == "link")
    ## do nothing, will be rendered later
  #elseif ($guiElem.name == "info-icon")
    #renderInfoIcon()
  #elseif ($guiElem.name == "passwordless-icon")
    #renderPasswordlessIcon()
  #elseif ($guiElem.name == "success-icon")
    #renderSuccessIcon()
  #elseif ($guiElem.type == "error" && $guiElem.label && $guiElem.label.length() > 0)
    #renderError($guiElem)
  #elseif ($guiElem.type == "info" && $guiElem.label && $guiElem.label.length() > 0)
    #renderInfo($guiElem)
  #elseif ($guiElem.type == "text" || $guiElem.type == "pw-text")
    #renderText($guiElem)
  #elseif ($guiElem.type == "submit" || $guiElem.type == "button" || $guiElem.type == "reset")
    #renderButton($guiElem)
    ## after buttons were rendered, we enforce usage of the secondary color for subsequent info elements
    #set($renderInfoCalled = true)
  #elseif ($guiElem.type == "radio")
    #renderRadio($guiElem)
  #elseif ($guiElem.type == "checkbox")
    #renderCheckbox($guiElem)
  #elseif ($guiElem.type == "image" && $guiElem.value != "")
    #renderImage($guiElem)
  #elseif ($guiElem.type == "hidden")
    #renderHidden($guiElem)
  #end
#end

#macro(renderGeneric $gui)
  #foreach ($guiElem in $gui.getGuiElems())
    #renderGuiElem($guiElem)
  #end
#end

#macro(renderSocialLoginButton $button)
  #if ($button.name != "")
    <button name="$button.name" class="btn social-login-button" value="true">
      #if ($button.name.startsWith('social_generic_'))
        ## the generic social login pattern allows to customize the icon
        #if ($button.icon != "")
          <img src="${login.appDataPath}/$button.icon" alt="social login logo" width="18" height="18">
        #else
          $button.label
        #end
      #else
        #set ($logoName = $button.name.substring(7))
        <img src="${login.appDataPath}/resources/${logoName}.svg" alt="${logoName} logo" width="18" height="18">
      #end
    </button>
  #end
#end

#macro(renderSocialLoginButtons $gui)
  #set ($socialLoginButtonFound = false) 
  #foreach ($guiElem in $gui.getGuiElems())
    #if ($guiElem.name.startsWith('social_'))
      #set ($socialLoginButtonFound = true)
    #end
  #end
  #if ($socialLoginButtonFound)
    <p class="horizontal-line mt-5 mb-3">$text.get('info.continue.social')</p>
    <div class="social-login-buttons">
      ## loop again to respect order
      #foreach ($guiElem in $gui.getGuiElems())
        #if ($guiElem.name.startsWith('social_'))
          #renderSocialLoginButton($guiElem)
        #end
      #end
    </div>
  #end
#end

#macro(renderHeader $gui)
  <div class="d-flex justify-content-between w-100 h-icon-button">
    <button id="logout-btn" class="btn p-0" aria-label="Close">X</button>
    #set ($languages = $login.defaultsBundle.getString("application.languages").split("[,\\s]+"))
    #if ($languages.size() > 1)
      #set ($activeLangLabel = $text.get("language.$login.localeCode"))
      <button class="btn btn-language-selector dropdown-toggle ms-auto" type="button" id="language-switch-btn" data-bs-toggle="dropdown" aria-expanded="false">
        <span class="lang-label">$activeLangLabel</span>
        <img src="${login.appDataPath}/resources/chevron-down.svg?v=cfb90b1c" class="ms-2" alt="Down">
      </button>
      <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="language-switch-btn">
        #foreach ($lang in $languages)
          #set ($langLabelPropertyName = "language." + $lang) ## Strings can't be concatenated in the text.get below, had to outsource.
          #set ($langLabel = $text.get($langLabelPropertyName))
          #set ($langTarget = $utils.escapeHtmlAttribute($gui.target('language', $lang)))
          <li>
            <a class="dropdown-item" href="$langTarget">$langLabel</a>
          </li>
      #end
    </ul>
    #end
  </div>
#end
