package Graphics::Grid::Driver;

# ABSTRACT: Role for Graphics::Grid driver implementations

use Graphics::Grid::Role;

our $VERSION = '0.001'; # VERSION

use List::AllUtils qw(reduce);
use Types::Standard qw(Enum Str InstanceOf Num);

use Graphics::Grid::GPar;
use Graphics::Grid::Util qw(dots_to_cm);


has grid => (
    is            => 'rw',
    weak_ref      => 1,
    lazy_required => 1,
);


has [ 'width', 'height' ] => (
    is      => 'rw',
    isa     => Num,
    default => 1000,
);


has dpi => (
    is      => 'rw',
    isa     => Num,
    default => 96
);


has current_vptree => (
    is      => 'rw',
    isa     => InstanceOf ['Graphics::Grid::ViewportTree'],
    trigger => sub {
        my $self = shift;
        $self->_set_vptree(@_);
    },
    init_arg => undef,
);

has [qw(_current_vp_width_cm _current_vp_height_cm)] =>
  ( is => 'rw', init_arg => undef );


has current_gp => (
    is       => 'rw',
    isa      => InstanceOf ['Graphics::Grid::GPar'],
    default  => sub { $_[0]->default_gpar },
    init_arg => undef,
);

# driver specific 
sub _set_vptree { }

requires 'data';
requires 'write';

requires 'draw_circle';
requires 'draw_points';
requires 'draw_polygon';
requires 'draw_polyline';
requires 'draw_rect';
requires 'draw_segments';
requires 'draw_text';


classmethod default_gpar() {
    state $gp;
    unless ($gp) {
        $gp = Graphics::Grid::GPar->new(
            col        => "black",
            fill       => "white",
            alpha      => 1,
            lty        => "solid",
            lwd        => 1,
            lineend    => 'round',
            linejoin   => 'round',
            linemitre  => 1,
            fontface   => 'plain',
            fontfamily => "sans",
            fontsize   => 11,
            lineheight => 1.2,
            lex        => 1,
            cex        => 1,
        );
    }
    return $gp;
}

method current_vp_width() {
    return $self->_current_vp_width_cm;
}

method current_vp_height() {
    return $self->_current_vp_height_cm;
}

method _transform_width_to_cm(
    $unitlike, $idx,
    $gp        = $self->current_gp,
    $length_cm = $self->current_vp_width
  )
{
    return $unitlike->transform_to_cm( $self->grid, $idx, $gp, $length_cm );
}

method _transform_height_to_cm(
    $unitlike, $idx,
    $gp        = $self->current_gp,
    $length_cm = $self->current_vp_height
  )
{
    return $unitlike->transform_to_cm( $self->grid, $idx, $gp, $length_cm );
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Graphics::Grid::Driver - Role for Graphics::Grid driver implementations

=head1 VERSION

version 0.001

=head1 ATTRIBUTES

=head2 grid

L<Graphics::Grid> object.
Usually this attribute is set by the grid object when it creates or sets
the driver object.

=head2 width

Width of the device, in resolution dots.

Default is 1000.

=head2 height

Height of the device, in resolution dots.

Default is 1000.

=head2 dpi

=head2 current_vptree

=head2 current_gp

=head1 CLASS METHODS

=head2 default_gpar()

=head1 SEE ALSO

L<Graphics::Grid>

=head1 AUTHOR

Stephan Loyd <sloyd@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2018-2023 by Stephan Loyd.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
