#!/usr/bin/env perl
=head1 NAME

muralis - display wallpaper on your desktop.

=head1 VERSION

version 0.1003

=head1 SYNOPSIS

muralis --help | --manpage | --version

muralis --backends

muralis --provides I<backend>

muralis --list { --dir I<directory> } [ --exclude I<string> ]
[ --is_image I<string> ] [ --listformat I<format> ]
[ --match I<string> ] [ --outfile I<filename> ]

muralis [ --centre | --center ] [ --colours I<num> | --colors I<num> ]
[ --config_dir I<directory> ] [ --dir I<directory> ] [ --exclude I<string> ]
[ --is_image I<string> ] [ --fullscreen ] [ --match I<string> ]
[ --option I<string> ] [ --stretch ] [ --tile ] [ --unseen ]
[ --verbose ] [ --window I<window-id> ] [ --zoom I<percent> ]
--use I<backend>
( --random | --repeat_last | I<file> )

=head1 DESCRIPTION

The muralis script displays a given image file on the desktop
background (that is, the root window) of an X-windows display.

This tries to determine what size would best suit the image; whether to
show it fullscreen or normal size, whether to show it tiled or centred
on the screen.  Setting the options overrides this behaviour.

One can also repeat the display of the last-displayed image, changing the
display options as one desires.

This uses the an external program to display the image file; display backends
are implemented as plugins.  To find out which bckends are available, use the
--backends option to print a list of them.

This also depends on xwininfo to get information about the root window.

=head2 The Name

The name "muralis" comes from the Latin "muralis" which is the word from
which "mural" was derived.  I just thought it was a cool name for a wallpaper
script.

=head1 OPTIONS

Boolean options can be disabled by prefixing them with 'no'; for example,
--notile will turn off tiling of the image.

=over

=item --backends

List which display backends are available.  Note that this doesn't just check
which plugin modules are installed, but also checks whether the program used
by the backend is available.

=item --centre | --center

Centre the image on the root window.

=item --colours I<num> | --colors I<num>

Limit the number of colours used to display the image.  This is useful
for a 256-colour display.  Only supported by some backends.

=item --config_dir I<directory>

Alternative directory in which to look for muralis config files.

=item --dir I<directory>

Directory in which to look for image files.  This can be repeated
for more directories.

=item --exclude I<string>

If an image matches this, it is excluded from --random, --list, or --nth
display.

=item --is_image I<string>

What files are considered to be image files?  This is a regular
expression checked against the filenames to see if they are image
files.  By default, muralis checks for commonly known image extensions,
so that it doesn't try to display non-image files (such as text files)
which might be in the image directories.
Most of the time you don't need to use this option.

=item --fullscreen

The image will be zoomed to fit the size of the screen, keeping the aspect
ratio the same if the backend supports this.

=item --help

Print help message and exit.

=item --list

List all the images muralis knows about.  If --match is given,
this will restrict the list to those images matching the match-string.
(see --listformat)

=item --listformat I<format>

This defines the format used in the --list command.
The format is either "normal" or "fullname".
The normal format gives the directory names followed by the files in them.
The "fullname" format gives just the full names of the files.

=item --manpage

Print the full help documentation (manual page) and exit.
This will only work if you have perldoc installed.

=item --match I<string>

If using the --list or --random options, limit the image(s) to those 
which match the string.

=item --nth I<num>

Display the nth image.  If --match is given, limit the selection
to images which match the match-string.

=item --option I<string>

An additional option or options to pass on to the backend.
Used for uncommon options which are supported in one backend and not another.

=item --outfile

Output file for the --list command to print its output.  If this
argument is not given, list will list to standard output.

=item --provides I<backend>

What options will work for this backend?

=item --random

Pick a random image to display.  If --match is given, limit
the selection to images which match the match-string.

=item --repeat_last

Display the last image which was displayed.  This is useful to
re-display an image while overriding the default display options.

=item --stretch

The image will be zoomed to fit the size of the screen.  This does
not preserve the aspect ratio.  Some backends support both B<fullscreen> and
B<stretch>, while some support only one or the other, in which case they are
treated the same.

=item --tile

Tile the image to fill the root window.

=item --unseen

When using the --rand or --nth option, this selects the images from a list
of 'unseen' images.  This can be used to cycle through your images
without repeats.  If this option is not used, then the --random option
is truly random.

The 'unseen' list is in the '~/.muralis/unseen' file, which is
automatically updated or created whenever the --unseen option is used.
Note that if this file exists and the --unseen option is used, muralis does
not check the image directories, so if you have added a new directory to
your options, you will need to delete the 'unseen' file in order
to reset the list of unseen images.

=item --use I<backend>

Which backend to use.  See L<backends>.

=item --verbose

Print informational messages.

=item --version

Print version information and exit.

=item --window I<window-id>

Display on the given window, rather than the root window.
This is useful for window-managers which take over the desktop display.
Only works for backends which provide this option.

=item --zoom I<percent>

Enlarge or reduce the size of the image by the given percent.

=back

=head1 ENVIRONMENT

=over

=item HOME

muralis looks in the HOME directory for config files.

=back

=head1 FILES

Configuration files for muralis are placed in the $HOME/.muralis
directory (which is created if it doesn't exist).

=over

=item ~/.muralis/config

Configuration file; contains command-line arguments in Getopt::ArgvFile format.

=item ~/.muralis/last

The name of the most recently displayed image.

=item ~/.muralis/unseen

Contains a list of unseen image files.

=back

=head1 REQUIRES

    Getopt::Long
    Pod::Usage
    Getopt::ArgvFile
    File::Basename
    File::Find::Rule
    Image::Info
    X11::Muralis;

=head1 SEE ALSO

perl(1)
Getopt::Long
Getopt::ArgvFile
Pod::Usage
X11::Muralis

=cut
use strict;
use warnings;

use Getopt::Long 2.34;
use Getopt::ArgvFile justload=>1;
use Pod::Usage;
use File::Basename;
use X11::Muralis;

our $VERSION = $X11::Muralis::VERSION;

#========================================================
# Subroutines

sub init_data ($) {
    my $data_ref = shift;

    $data_ref->{manpage} = 0;
    $data_ref->{verbose} = 0;
} # init_data

sub process_args ($) {
    my $data_ref = shift;

    my $ok = 1;

    # use .(script)rc or .(script)/config
    my $nameBuilder=sub
    {
	my $sname=basename($_[0]);
	[".${sname}rc", ".${sname}/config"];
    };
    Getopt::ArgvFile::argvFile(
			       home=>1,
			       current=>1,
			       startupFilename=>$nameBuilder);

    pod2usage(2) unless @ARGV;

    my $op = new Getopt::Long::Parser;
    $op->configure(qw(auto_version auto_help));
    $op->getoptions($data_ref,
	       'verbose!',
	       'manpage',
	       'backends',
	       'list',
	       'listformat=s',
	       'outfile=s',
	       'dir=s@',
	       'config_dir=s',
	       'is_image=s',
	       'tile!',
	       'fullscreen!',
	       'stretch!',
	       'zoom=n',
	       'option=s',
	       'nth=n',
	       'colors|colours=n',
	       'center|centre!',
	       'match=s',
	       'exclude=s',
	       'random',
	       'unseen!',
	       'recursive!',
	       'repeat_last',
	       'provides=s',
	       'window=s',
	       'use=s',
	      ) or pod2usage(2);

    if ($data_ref->{'manpage'})
    {
	pod2usage({ -message => "$0 version $X11::Muralis::VERSION",
		    -exitval => 0,
		    -verbose => 2,
	    });
    }

} # process_args

#========================================================
# Main

MAIN: {
    my %data = ();

    init_data(\%data);
    process_args(\%data);
    my $obj = X11::Muralis->new(%data);
    if ($data{backends})
    {
	$obj->list_backends();
    }
    elsif ($data{provides})
    {
	my %prov = $obj->provides($data{provides});
	foreach my $key (sort keys %prov)
	{
	    if ($prov{$key})
	    {
		print $key, "\n";
	    }
	}
    }
    elsif ($data{list})
    {
	$obj->list_images(%data);
    }
    elsif (!$data{use})
    {
	print STDERR "No backend given.\n";
	pod2usage(2);
    }
    else
    {
	$obj->display_image(%data,filename=>$ARGV[0]);
    }
}

=head1 BUGS

Please report any bugs or feature requests to the author.

=head1 AUTHOR

    Kathryn Andersen (RUBYKAT)
    perlkat AT katspace dot com
    http://www.katspace.org/tools/muralis

=head1 COPYRIGHT AND LICENCE

Copyright (c) 2005-2016 by Kathryn Andersen

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

=cut

# vim:ts=8 sw=4 sts=4 ai
__END__