submodule(fortplot_figure_core) fortplot_figure_core_impl_plots

    !! Plot operations implementations
    !!
    !! Single Responsibility: Handle all plot creation and data addition
    !! operations including line plots, contours, surfaces, pcolormesh,
    !! scatter, histograms, boxplots, and specialized plots.
    !! Extracted from fortplot_figure_core_impl to maintain file size compliance.

    implicit none

contains

    !! ── Initialization ────────────────────────────────────────────────

    module subroutine initialize(self, width, height, backend, dpi)
        class(figure_t), intent(inout) :: self
        integer, intent(in), optional :: width, height
        character(len=*), intent(in), optional :: backend
        real(wp), intent(in), optional :: dpi

        call core_initialize(self%state, self%plots, self%streamlines, &
                              self%subplots_array, self%subplot_rows, &
                              self%subplot_cols, self%current_subplot, &
                              self%title, self%xlabel, self%ylabel, &
                              self%plot_count, width, height, backend, dpi)
    end subroutine initialize

    !! ── Basic plot operations ─────────────────────────────────────────

    module subroutine add_plot_real(self, x, y, label, linestyle, color)
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x(:), y(:)
        character(len=*), intent(in), optional :: label, linestyle
        real(wp), intent(in), optional :: color(3)

        call core_add_plot(self%plots, self%state, x, y, label, linestyle, color, &
                            self%plot_count)
    end subroutine add_plot_real

    module subroutine colorbar(self, plot_index, label, location, fraction, pad, &
                                shrink, ticks, ticklabels, label_fontsize)
        class(figure_t), intent(inout) :: self
        integer, intent(in), optional :: plot_index
        character(len=*), intent(in), optional :: label, location
        real(wp), intent(in), optional :: fraction, pad, shrink
        real(wp), intent(in), optional :: ticks(:)
        character(len=*), intent(in), optional :: ticklabels(:)
        real(wp), intent(in), optional :: label_fontsize

        if (self%subplot_rows > 0 .and. self%subplot_cols > 0) then
            call log_error("colorbar: Subplot grids are not supported yet")
            return
        end if

        call core_colorbar(self%state, self%plots, self%plot_count, &
                            plot_index=plot_index, &
                            label=label, location=location, fraction=fraction, pad=pad, &
                            shrink=shrink, ticks=ticks, ticklabels=ticklabels, &
                            label_fontsize=label_fontsize)
    end subroutine colorbar

    module subroutine add_contour(self, x_grid, y_grid, z_grid, levels, label)
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x_grid(:), y_grid(:), z_grid(:, :)
        real(wp), intent(in), optional :: levels(:)
        character(len=*), intent(in), optional :: label

        call core_add_contour(self%plots, self%state, x_grid, y_grid, z_grid, &
                               levels, label, self%plot_count)
    end subroutine add_contour

    module subroutine add_contour_filled(self, x_grid, y_grid, z_grid, levels, &
                                            cmap, show_colorbar, label, colormap)
        !! Add a filled contour plot to the figure
        !!
        !! `cmap` is the matplotlib-canonical keyword; `colormap` is a
        !! backward-compatible alias.
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x_grid(:), y_grid(:), z_grid(:, :)
        real(wp), intent(in), optional :: levels(:)
        character(len=*), intent(in), optional :: cmap, label, colormap
        logical, intent(in), optional :: show_colorbar

        call core_add_contour_filled(self%plots, self%state, x_grid, y_grid, &
                                        z_grid, levels=levels, cmap=cmap, &
                                        show_colorbar=show_colorbar, label=label, &
                                        colormap=colormap, plot_count=self%plot_count)
    end subroutine add_contour_filled

    module subroutine add_contourf(self, x_grid, y_grid, z_grid, levels, &
                                    cmap, show_colorbar, label, colormap)
        !! Add a filled contour plot to the figure
        !!
        !! Matplotlib-canonical alias for add_contour_filled.
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x_grid(:), y_grid(:), z_grid(:, :)
        real(wp), intent(in), optional :: levels(:)
        character(len=*), intent(in), optional :: cmap, label, colormap
        logical, intent(in), optional :: show_colorbar

        call self%add_contour_filled(x_grid, y_grid, z_grid, levels=levels, &
                                      cmap=cmap, show_colorbar=show_colorbar, &
                                      label=label, colormap=colormap)
    end subroutine add_contourf

    module subroutine add_surface(self, x_grid, y_grid, z_grid, label, cmap, &
                                   show_colorbar, alpha, edgecolor, linewidth, filled, &
                                   colormap)
        !! Add a 3D surface plot to the figure
        !!
        !! `cmap` is the matplotlib-canonical keyword; `colormap` is a
        !! backward-compatible alias.
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x_grid(:), y_grid(:), z_grid(:, :)
        character(len=*), intent(in), optional :: label, cmap, colormap
        logical, intent(in), optional :: show_colorbar, filled
        real(wp), intent(in), optional :: alpha, linewidth
        real(wp), intent(in), optional :: edgecolor(3)

        call core_add_surface(self%plots, self%state, x_grid, y_grid, z_grid, &
                              label=label, cmap=cmap, show_colorbar=show_colorbar, &
                              alpha=alpha, edgecolor=edgecolor, linewidth=linewidth, &
                              filled=filled, plot_count=self%plot_count, &
                              colormap=colormap)
    end subroutine add_surface

    module subroutine add_pcolormesh(self, x, y, c, cmap, vmin, vmax, edgecolors, &
                                      linewidths, colormap)
        !! Add a pcolormesh plot to the figure
        !!
        !! `cmap` is the matplotlib-canonical keyword; `colormap` is a
        !! backward-compatible alias.
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x(:), y(:), c(:, :)
        character(len=*), intent(in), optional :: cmap, colormap
        real(wp), intent(in), optional :: vmin, vmax
        real(wp), intent(in), optional :: edgecolors(3)
        real(wp), intent(in), optional :: linewidths

        call core_add_pcolormesh(self%plots, self%state, x, y, c, cmap=cmap, &
                                  vmin=vmin, vmax=vmax, edgecolors=edgecolors, &
                                  linewidths=linewidths, plot_count=self%plot_count, &
                                  colormap=colormap)
    end subroutine add_pcolormesh

    !! ── Specialized plot operations ───────────────────────────────────

    module subroutine streamplot(self, x, y, u, v, density, color, &
                                  linewidth, rtol, &
                                  atol, max_time, arrowsize, arrowstyle)
        use fortplot_plotting_advanced, only: streamplot_impl
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x(:), y(:), u(:, :), v(:, :)
        real(wp), intent(in), optional :: density
        real(wp), intent(in), optional :: color(3)
        real(wp), intent(in), optional :: linewidth
        real(wp), intent(in), optional :: rtol, atol, max_time
        real(wp), intent(in), optional :: arrowsize
        character(len=*), intent(in), optional :: arrowstyle

        call streamplot_impl(self, x, y, u, v, density=density, color=color, &
                              linewidth=linewidth, rtol=rtol, atol=atol, &
                              max_time=max_time, arrowsize=arrowsize, &
                              arrowstyle=arrowstyle)
    end subroutine streamplot

    module subroutine quiver(self, x, y, u, v, scale, color, width, headwidth, &
                              headlength, units, pivot, scale_units, angles, colormap, &
                              alpha)
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x(:), y(:), u(:), v(:)
        real(wp), intent(in), optional :: scale
        real(wp), intent(in), optional :: color(3)
        real(wp), intent(in), optional :: width, headwidth, headlength
        character(len=*), intent(in), optional :: units, pivot, scale_units, angles
        character(len=*), intent(in), optional :: colormap
        real(wp), intent(in), optional :: alpha

        call core_quiver(self%plots, self%state, self%plot_count, x, y, u, v, &
                          scale, color, width, headwidth, headlength, units, &
                          pivot, scale_units, angles=angles, colormap=colormap, &
                          alpha=alpha)
    end subroutine quiver

    module subroutine add_hist(self, data, bins, density, label, color, &
                            range, weights, cumulative, orientation, alpha)
        !! Add a histogram plot (matplotlib-compatible).
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: data(:)
        integer, intent(in), optional :: bins
        logical, intent(in), optional :: density
        character(len=*), intent(in), optional :: label
        character(len=*), intent(in), optional :: color
        real(wp), intent(in), optional :: range(2)
        real(wp), intent(in), optional :: weights(:)
        logical, intent(in), optional :: cumulative
        character(len=*), intent(in), optional :: orientation
        real(wp), intent(in), optional :: alpha

        real(wp) :: color_rgb(3)
        logical :: has_color

        if (present(color) .and. len_trim(color) > 0) then
            call resolve_color_string_or_rgb(color_str=color, context='hist', &
                                             rgb_out=color_rgb, has_color=has_color)
            if (has_color) then
                call core_hist(self%plots, self%state, self%plot_count, data, bins, &
                               density, label, color_rgb, range=range, weights=weights, &
                               cumulative=cumulative, orientation=orientation, &
                               alpha=alpha)
            else
                call core_hist(self%plots, self%state, self%plot_count, data, bins, &
                               density, label, range=range, weights=weights, &
                               cumulative=cumulative, orientation=orientation, &
                               alpha=alpha)
            end if
        else
            call core_hist(self%plots, self%state, self%plot_count, data, bins, &
                           density, label, range=range, weights=weights, &
                           cumulative=cumulative, orientation=orientation, &
                           alpha=alpha)
        end if
    end subroutine add_hist

    module subroutine boxplot(self, data, position, width, label, show_outliers, &
                               horizontal, color)
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: data(:)
        real(wp), intent(in), optional :: position
        real(wp), intent(in), optional :: width
        character(len=*), intent(in), optional :: label
        logical, intent(in), optional :: show_outliers
        logical, intent(in), optional :: horizontal
        real(wp), intent(in), optional :: color(3)

        call core_boxplot(self%plots, self%state, self%plot_count, data, &
                           position, width, &
                           label, show_outliers, horizontal, color, &
                           self%state%max_plots)
    end subroutine boxplot

    module subroutine scatter(self, x, y, s, c, marker, markersize, color, &
                               colormap, alpha, edgecolor, facecolor, linewidth, &
                               vmin, vmax, label, show_colorbar)
        !! Scatter with deferred-shape `s(..)` to accept scalar or array.
        class(figure_t), intent(inout) :: self
        real(wp), contiguous, intent(in) :: x(:), y(:)
        real(wp), intent(in), optional :: s(..), c(:)
        character(len=*), intent(in), optional :: marker, colormap, label
        real(wp), intent(in), optional :: markersize, alpha, linewidth, vmin, vmax
        real(wp), intent(in), optional :: color(3), edgecolor(3), facecolor(3)
        logical, intent(in), optional :: show_colorbar

        real(wp) :: default_color(3)

        default_color = next_plot_color(self%state)

        call core_scatter(self%plots, self%state, self%plot_count, x, y, s, c, &
                           marker, markersize, color, colormap, alpha, edgecolor, &
                           facecolor, linewidth, vmin, vmax, label, show_colorbar, &
                           default_color)
    end subroutine scatter

end submodule fortplot_figure_core_impl_plots
