package XFD;

=head1 NAME

XML::Filter::Dispatcher::Runtime - runtime routines for compiled X::F::D code

=head1 SYNOPSIS

   Used in code generated by X::F::D

=head1 DESCRIPTION

Most of these functions are meant to be called as pseudo-methods using
XML::Filter::Dispatcher's queue dispatch mechanism.

=over

=cut

sub import() {
    my $call_pkg = caller;
    for ( grep defined &$_, keys %{__PACKAGE__ . "::"} ) {
        *{"$call_pkg"} = \&{__PACKAGE__ . "::$_"}
            unless defined \&{__PACKAGE__ . "::$_"};
    }
}

use strict;
use vars qw( $ctx );

sub _p_first_precursor();
sub emit_trace_SAX_message;
sub is_tracing();

## TODO: Autoload most of these

sub nodeset2hash_start {
    my ( $handler, $start_element, $characters, $end_element ) = @_;

    push @{$ctx->{ChildCtx}->{start_element}},
        [ $start_element, $handler],
        [ \&nodeset2hash_start, @_[0..4] ];

    push @{$ctx->{ChildCtx}->{characters}},[ $characters, $handler];
    push @{$ctx->{EndSubs}}, [ $end_element, $handler ]
        if $ctx->{EventType} eq "start_element";
}


sub nodeset2struct_start {
    my ( $handler, $start_element, $characters, $end_element ) = @_;

    push @{$ctx->{ChildCtx}->{start_element}},
        [ $start_element, $handler],
        [ \&nodeset2struct_start, @_[0..4] ];

    push @{$ctx->{ChildCtx}->{characters}},[ $characters, $handler];

    push @{$ctx->{EndSubs}}, [ $end_element, $handler ]
        if $ctx->{EventType} eq "start_element";
}


sub nodeset2string_start {
    my ( $postponement, $precursor_number ) = @_;

    push @{$ctx->{ChildCtx}->{start_element}},
        [ \&nodeset2string_start, @_[0..2] ];

    push @{$ctx->{ChildCtx}->{characters}},[
        \&nodeset2string_characters,
        $postponement,
        $precursor_number,
    ];
}

sub nodeset2string_characters {
    my ( $postponement, $precursor_number, $data ) = @_;

    $postponement->[_p_first_precursor+$precursor_number] .= $data->{Data};
    emit_trace_SAX_message "EventPath: '$data->{Data}' added to precursor $precursor_number (postponement ", int $postponement, ")" if is_tracing;

}


1;