package Pcore::Selenium::WebElement;

package    # hide from pause
  Selenium::Remote::WebElement;

use Pcore;
no warnings qw[redefine];

# FIND_ELEMENT FAMILY
sub find_child_element {
    my $self = shift;
    return $self->{driver}->find_child_element( $self, @_ );
}

sub find_child_elements {
    my $self = shift;
    return $self->{driver}->find_child_elements( $self, @_ );
}

sub find_child_element_local {
    my $self   = shift;
    my $params = \@_;
    return try {
        return $self->{driver}->find_child_element( $self, @{$params} );
    }
    catch {
        return;
    };
}

sub find_child_elements_local {
    my $self   = shift;
    my $params = \@_;
    return try {
        return $self->{driver}->find_child_elements( $self, @{$params} );
    }
    catch {
        return;
    };
}

sub send_keys {
    my $self   = shift;
    my $res    = { 'command' => 'sendKeysToElement', 'id' => $self->{id} };
    my $params = { 'value' => [ map { q[] . $_ } @_ ] };
    $self->_execute_command( $res, $params );
    return $self;
}

sub screenshot {
    my $self = shift;
    my %args = (
        inclide_flash => 0,
        @_
    );
    $self->set_wmode if $args{include_flash};
    my $location = $self->get_element_location;
    my $size     = $self->get_size;
    return $self->{driver}->screenshot( left => $location->{x}, top => $location->{y}, width => $size->{width}, height => $size->{height} );
}

sub trigger {
    my $self = shift;
    my $ev   = shift;
    $self->{driver}->execute_script( "arguments[0].$ev()", $self );
    return $self;
}

sub set_attribute {
    my $self  = shift;
    my $attr  = shift;
    my $value = shift;
    $value =~ s/'/\\'/smg;
    $self->{driver}->execute_script( "arguments[0].$attr = '$value'", $self );
    return $self;
}

sub set_wmode {
    my $self = shift;
    if ( $self->get_tag_name eq 'embed' ) {
        my $js = <<'JS';
            if (!arguments[0].getAttribute('wmode') || arguments[0].getAttribute('wmode').toLowerCase() == 'window'){
                var embed = arguments[0].cloneNode(true);
                embed.setAttribute('wmode', 'transparent');
                arguments[0].parentNode.replaceChild(embed, arguments[0]);
            }
JS
        $self->{driver}->execute_script( $js, $self );
    }
    else {
        $self->{driver}->set_wmode( parent => $self );
    }
    return $self;
}

sub get_image {
    my $self = shift;
    my %args = (
        method => 'screenshot',    # screenshot | canvas
        @_
    );

    unless ( $self->get_tag_name eq 'img' ) {
        die 'Not an img tag';
    }
    else {
        if ( $args{method} eq 'screenshot' ) {
            return $self->screenshot;
        }
        elsif ( $args{method} eq 'canvas' ) {
            my $js = <<'JS';
                var canvas = document.createElement('canvas');
                canvas.width = arguments[0].width;
                canvas.height = arguments[0].height;
                var ctx = canvas.getContext('2d');
                ctx.drawImage(arguments[0], 0, 0);
                var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                return {data: imageData.data, width: canvas.width, height: canvas.height};
JS
            my $data = $self->{driver}->execute_script( $js, $self );

            state $init = !!require Imager;

            my $x = 0;

            my $y = 0;

            my $img = Imager->new( xsize => $data->{width}, ysize => $data->{height} );

            for ( my $i = 0; $i <= $#{ $data->{data} }; $i += 4 ) {
                $img->setpixel( x => $x, y => $y, color => Imager::Color->new( $data->{data}->[$i], $data->{data}->[ $i + 1 ], $data->{data}->[ $i + 2 ], $data->{data}->[ $i + 3 ] ) );
                if ( ++$x == $data->{width} ) {
                    $x = 0;
                    $y++;
                }
            }
            my $image;
            $img->write( data => \$image, type => 'png' );
            return { data => \$image, type => 'png', width => $data->{width}, height => $data->{height} };
        }
        else {
            die 'Unknown get_image method';
        }
    }
}

1;
## -----SOURCE FILTER LOG BEGIN-----
##
## PerlCritic profile "pcore-script" policy violations:
## +------+----------------------+----------------------------------------------------------------------------------------------------------------+
## | Sev. | Lines                | Policy                                                                                                         |
## |======+======================+================================================================================================================|
## |    2 | 130                  | ControlStructures::ProhibitCStyleForLoops - C-style "for" loop used                                            |
## +------+----------------------+----------------------------------------------------------------------------------------------------------------+
##
## -----SOURCE FILTER LOG END-----
__END__
