#  You may distribute under the terms of either the GNU General Public License
#  or the Artistic License (the same terms as Perl itself)
#  (C) Paul Evans, 2014-2016 -- leonerd@leonerd.org.uk

package Tickit::Debug 0.73;

use v5.14;
use warnings;

use constant DEBUG => _enabled();

use Exporter 'import';
our @EXPORT = qw( DEBUG );

=head1 NAME

C<Tickit::Debug> - debug logging support for C<Tickit>


This module implements the debug logging logic for L<Tickit>. It is controlled
by a number of environment variables. It exports a constant called C<DEBUG>
which will be true if the debug logging is enabled; allowing code to
efficiently skip over it if it isn't.

Debug messages themselves each have a flag name, which is a short string
identifying the Tickit subsystem or kind of event that caused it. A given
subset of these flags can be enabled for printing. Flags not enabled will not
be printed.


=head1 FLAGS

Each flag name starts with a upper-case letters indicating the subsystem it
relates to, then lower-case letters to indicate the particular kind of event
or message.

=head2 B (RenderBuffer)

=head3 Bd

Drawing operations

=head3 Bf


=head3 Bs

State stack save/restore

=head3 Bt

Transformations (translate, clip, mask)

=head2 I (Input)

=head3 Ik

Keyboard events

=head3 Im

Mouse events

=head3 Ir

Resize events

=head2 W (Window)

=head3 Wd

Rectangles of damage queued on the root window for re-expose

=head3 Wh

Hierarchy changes on Windows (creates, deletes, re-orderings)

=head3 Ws

Calls to C<< $win->scrollrect >>

=head3 Wsr

Calls to C<< $term->scrollrect >> on the root window as part of scrollrect

=head3 Wx

Expose events on Windows; which may result in calls to its C<on_expose>
handler. As this event is recursive, it prints an indent.




A comma-separated list of the flags or flag categories to enable for printing.
Each potential flag exists in a category, given by the leading upper-case
letters of its name. Entire categories can be enabled by name, as can
individual flags.

See the L</FLAGS> list above for the available flags.


If set, debug logging is sent directly to the opened filehandle given by this
file descriptor number, rather than opening a log file.

Typically this is most useful to start a C<Tickit>-based application in a new
terminal but have its debug logging printed to STDERR of the original terminal
the new one was launched from. For example

 $ TICKIT_DEBUG_FD=3 TICKIT_DEBUG_FLAGS=... $TERM perl my-tickit-app.pl 3>&2

This requests that C<Tickit::Debug> log to file descriptor 3, which has been
created by copying the original shell's standard error output, and so logging
is printed to the shell this was run from.


Gives the name of a file to open and write logging to, if C<TICKIT_DEBUG_FD>
is not set. If this is not set either, a filename will be generated using the
PID of the process, named as



=head1 METHODS


=head2 log

   Tickit::Debug->log( $flag => $format, @args )

Prints a line to the debug log if the specified C<$flag> is present in the set
of enabled flags.

Any arguments that are C<CODE> references are called and replaced by the
list of values they return, then the line itself is generated by calling
C<sprintf> using the format string and the given arguments. It is then
printed to the log, prefixed by the flag name and with a linefeed appended.

It is not necessary to include the C<\n> linefeed in the C<$format> itself.


sub log :method
   my ( $flag, $format, @args ) = @_;

   return unless _enabled();

   my $message = sprintf $format, map { ref eq "CODE" ? $_->() : $_ } @args;

   _log( $flag, $message );

=head1 AUTHOR

Paul Evans <leonerd@leonerd.org.uk>