module fortplot_svg_axes
    !! Standalone SVG axes and label rendering

   use, intrinsic :: iso_fortran_env, only: wp => real64
   implicit none

   private
   public :: svg_render_ylabel_impl, svg_draw_axes_labels_impl

contains

   subroutine svg_render_ylabel_impl(pa_left, pa_bottom, pa_height, ylabel, svg_elem)
      real(wp), intent(in) :: pa_left, pa_bottom, pa_height
      character(len=*), intent(in) :: ylabel
      character(len=:), allocatable, intent(out) :: svg_elem
      real(wp) :: x, y
      character(len=1024) :: local_elem

      x = pa_left - 35.0_wp
      y = pa_bottom + pa_height*0.5_wp

      write (local_elem, '(A,F0.3,A,F0.3,A,A,A)') &
         '<text x="', x, '" y="', y, &
         '" font-family="sans-serif" font-size="12" '// &
         'text-anchor="middle" transform="rotate(-90 ', x, ' ', y, ')">', &
         trim(ylabel), '</text>'
      svg_elem = trim(local_elem)
   end subroutine svg_render_ylabel_impl

   subroutine svg_draw_axes_labels_impl(svg_content, pa_left, pa_right, pa_bottom, &
                                        pa_top, xscale, yscale, symlog_threshold, &
                                        x_min, x_max, y_min, y_max, &
                                        title, xlabel, ylabel, &
                                        x_date_format, y_date_format, &
                                        z_min, z_max, has_3d_plots)
      character(len=:), allocatable, intent(inout) :: svg_content
      real(wp), intent(in) :: pa_left, pa_right, pa_bottom, pa_top
      character(len=*), intent(in) :: xscale, yscale
      real(wp), intent(in) :: symlog_threshold
      real(wp), intent(in) :: x_min, x_max, y_min, y_max
      character(len=:), allocatable, intent(in), optional :: title, xlabel, ylabel
      character(len=*), intent(in), optional :: x_date_format, y_date_format
      real(wp), intent(in), optional :: z_min, z_max
      logical, intent(in) :: has_3d_plots
      character(len=1024) :: elem
      real(wp) :: mid_x, mid_y
      integer :: i
      real(wp) :: tick_x, tick_y, val
      character(len=32) :: val_str

      associate (xs => xscale, ys => yscale, st => symlog_threshold, &
                 zmi => z_min, zma => z_max, h3d => has_3d_plots)
      end associate
      if (present(x_date_format)) then
         associate (unused_xfmt => len_trim(x_date_format)); end associate
      end if
      if (present(y_date_format)) then
         associate (unused_yfmt => len_trim(y_date_format)); end associate
      end if

      write (elem, '(A,F0.3,A,F0.3,A,F0.3,A,F0.3,A)') &
         '<rect x="', pa_left, '" y="', pa_top, '" width="', pa_right - pa_left, &
         '" height="', pa_bottom - pa_top, '" fill="none" stroke="black"/>'
      svg_content = svg_content//elem//new_line('a')

      do i = 0, 4
         tick_x = pa_left + real(i, wp)/4.0_wp*(pa_right - pa_left)
         val = x_min + real(i, wp)/4.0_wp*(x_max - x_min)
         write (val_str, '(G10.3)') val
         write (elem, '(A,F0.3,A,F0.3,A,F0.3,A,F0.3,A)') &
            '<line x1="', tick_x, '" y1="', pa_bottom, &
            '" x2="', tick_x, '" y2="', pa_bottom + 5.0_wp, '" stroke="black"/>'
         svg_content = svg_content//elem//new_line('a')
         write (elem, '(A,F0.3,A,F0.3,A,A,A)') &
            '<text x="', tick_x, '" y="', pa_bottom + 18.0_wp, &
            '" font-family="sans-serif" font-size="10" text-anchor="middle">', &
            trim(adjustl(val_str)), '</text>'
         svg_content = svg_content//elem//new_line('a')
      end do

      do i = 0, 4
         tick_y = pa_top + real(i, wp)/4.0_wp*(pa_bottom - pa_top)
         val = y_max - real(i, wp)/4.0_wp*(y_max - y_min)
         write (val_str, '(G10.3)') val
         write (elem, '(A,F0.3,A,F0.3,A,F0.3,A,F0.3,A)') &
            '<line x1="', pa_left - 5.0_wp, '" y1="', tick_y, &
            '" x2="', pa_left, '" y2="', tick_y, '" stroke="black"/>'
         svg_content = svg_content//elem//new_line('a')
         write (elem, '(A,F0.3,A,F0.3,A,A,A)') &
            '<text x="', pa_left - 8.0_wp, '" y="', tick_y + 4.0_wp, &
            '" font-family="sans-serif" font-size="10" text-anchor="end">', &
            trim(adjustl(val_str)), '</text>'
         svg_content = svg_content//elem//new_line('a')
      end do

      mid_x = (pa_left + pa_right)/2.0_wp
      mid_y = (pa_top + pa_bottom)/2.0_wp

      if (present(title)) then
         if (len_trim(title) > 0) then
            write (elem, '(A,F0.3,A,F0.3,A,A,A)') &
               '<text x="', mid_x, '" y="', pa_top - 10.0_wp, &
               '" font-family="sans-serif" font-size="14" '// &
               'font-weight="bold" text-anchor="middle">', &
               trim(title), '</text>'
            svg_content = svg_content//elem//new_line('a')
         end if
      end if

      if (present(xlabel)) then
         if (len_trim(xlabel) > 0) then
            write (elem, '(A,F0.3,A,F0.3,A,A,A)') &
               '<text x="', mid_x, '" y="', pa_bottom + 35.0_wp, &
               '" font-family="sans-serif" font-size="12" text-anchor="middle">', &
               trim(xlabel), '</text>'
            svg_content = svg_content//elem//new_line('a')
         end if
      end if

      if (present(ylabel)) then
         if (len_trim(ylabel) > 0) then
            write (elem, '(A,F0.3,A,F0.3,A,F0.3,A,F0.3,A,A,A)') &
               '<text x="', pa_left - 45.0_wp, '" y="', mid_y, &
               '" font-family="sans-serif" font-size="12" '// &
               'text-anchor="middle" transform="rotate(-90 ', &
               pa_left - 45.0_wp, ' ', mid_y, ')">', trim(ylabel), '</text>'
            svg_content = svg_content//elem//new_line('a')
         end if
      end if
   end subroutine svg_draw_axes_labels_impl

end module fortplot_svg_axes
