#!/usr/bin/perl
#
# qad.pm
#
# Console driver for a simple HTTP-driven daemon we can deploy to arbitrary
# hardware.

package consoles::qad;

use strict;
use Mojo::Base 'consoles::video_base', -signatures;
use bmwqemu ();
use LWP;
use Mojo::JSON qw/to_json from_json/;

BEGIN {
    print "qad.pm console loaded.\n";
}

sub disable ($self) {
    $self->{qad} = undef;
}

sub new ($class, $console, $args)
{
    my $self = bless({class => $class}, $class);
    $self->init($args);
    return $self;
}

sub init ($self, $args) {
    $self->{qad}->{ua} = LWP::UserAgent->new;
    $self->{mouse}->{x} = -1;
    $self->{mouse}->{y} = -1;
    $self->{mouse}->{x_scale} = $args->{x_scale};
    $self->{mouse}->{y_scale} = $args->{y_scale};
    $self->{qad}->{screeneventno} = $args->{screeneventno};
    $self->{qad}->{touchdeviceeventno} = $args->{touchdeviceeventno};
    $self->{qad}->{keyboarddeviceeventno} = $args->{keyboarddeviceeventno};
    $self->{qad}->{serverurl} = $args->{serverurl};
}

# We're a touchscreen -- log where OQA wants the mouse, and physically click
# there on a click event.
sub mouse_move_to ($self, $x, $y)
{
    $self->{mouse}->{x} = $x;
    $self->{mouse}->{y} = $y;
    my $jdoc = to_json({event => $self->{qad}->{touchdeviceeventno}, x => $x*$self->{mouse}->{x_scale}, y => $y*$self->{mouse}->{y_scale}});
    my $r = HTTP::Request->new('POST', $self->{qad}->{serverurl}.'/move');
    $r->header('Content-Type', 'application/json');
    $r->content($jdoc);
    bmwqemu::diag "mouse_move_to: $jdoc";
    $self->{qad}->{ua}->request($r);
}

sub mouse_button ($self, $args)
{
    my $button = $args->{button};
    my $bstate = $args->{bstate};
    my $jdoc = to_json({event => $self->{qad}->{touchdeviceeventno}, value => $bstate});
    bmwqemu::diag "mouse_button: $jdoc";
    my $r = HTTP::Request->new('POST', $self->{qad}->{serverurl}.'/button');
    $r->header('Content-Type', 'application/json');
    $r->content($jdoc);
    $self->{qad}->{ua}->request($r);
    return {};
}

sub touch($self, $x, $y, $duration)
{
    $self->{mouse}->{x} = $x;
    $self->{mouse}->{y} = $y;
    my $jdoc = to_json({event => $self->{qad}->{touchdeviceeventno}, x => $x*$self->{mouse}->{x_scale}, y => $y*$self->{mouse}->{y_scale}, duration => $duration});
    my $r = HTTP::Request->new('POST', $self->{qad}->{serverurl}.'/touch');
    $r->header('Content-Type', 'application/json');
    $r->content($jdoc);
    bmwqemu::diag "touch: $jdoc";
    print $self->{qad}->{ua}->request($r);
}

sub swipe ($self, $x, $y, $x2, $y2, $direction, $velocity)
{
    my $jdoc = to_json({event => $self->{qad}->{touchdeviceeventno}, x => $x*$self->{mouse}->{x_scale}, y => $y*$self->{mouse}->{y_scale},  x2 => $x2*$self->{mouse}->{x_scale}, y2 => $y2*$self->{mouse}->{y_scale}, velocity => $velocity, direction => $direction});
    my $r = HTTP::Request->new('POST', $self->{qad}->{serverurl}.'/swipe');
    $r->header('Content-Type', 'application/json');
    $r->content($jdoc);
    bmwqemu::diag "swipe: $jdoc";
    print $self->{qad}->{ua}->request($r);
}

sub request_screen_update ($self, $args = undef) {
    my $screenurl = $self->{qad}->{serverurl} . "/screen/" . $self->{qad}->{screeneventno};
    my $res = $$self{qad}{ua}->get($screenurl);
    $$self{qad}{framebuffer} = $res->decoded_content;
}

sub current_screen ($self)
{
    $self->request_screen_update();
    my $img = tinycv::from_ppm($self->{qad}->{framebuffer});
    return $img;
}

1;
