#!/usr/bin/perl

use strict;
use File::Spec;

# Library path bootstrap
my @path;
if (defined $ENV{PAR_TEMP}) { # See PAR.pm
	@path = ($ENV{PAR_TEMP}, 'inc');
}
else {
	my $binary = File::Spec->rel2abs($0);
	my ($vol, $dirs, undef) = File::Spec->splitpath($binary);
	@path = ($vol, $dirs, File::Spec->updir);
}
my $libdir = File::Spec->catdir(@path, 'lib');
unshift @INC, $libdir if -d $libdir;

eval q/use File::BaseDir ()/;
die $@ if $@;

# i18n initialization
$Zim::CODESET = 'utf8';
eval {
	require I18N::Langinfo;
	I18N::Langinfo->import(qw(langinfo CODESET));
	$Zim::CODESET = langinfo(CODESET()) || 'utf8';
};
warn "No langinfo available. Defaulting to utf8\n" if $@;
#warn "CODESET: $Zim::CODESET\n";

# Data dir bootstrap
my $sharedir = File::Spec->catdir(@path, 'share');
if (-d $sharedir) {
	$ENV{XDG_DATA_DIRS} =
		join ':', $sharedir, File::BaseDir->xdg_data_dirs;
}

# Load core modules
eval q/
	use Gtk2 '-init';
	use Zim::GUI;
	use Zim::Repository;
/
.($^O eq 'MSWin32' ? 'use Zim::Win32;' : '');
die $@ if $@;

# Parse command line options
my ($root, $page, $name, $pidfile);
my $settings = { read_only => 0 };
my @geometry;

while ($ARGV[0] =~ /^-/) {
	$_ = shift @ARGV;
	
	if (/^(--version|-v)$/) {
		print $Zim::GUI::LONG_VERSION;
		exit;
	}
	elsif (/^--read-?only$/) { $$settings{read_only} = 1 }
	elsif (/^--doc$/) {
		($root) = grep {-d $_}
			map File::Spec->catdir($_, 'zim', 'doc'),
			File::BaseDir->xdg_data_dirs;
		$$settings{read_only} = 1;
	}
	elsif (/^--export$/)   { $$settings{export} = shift @ARGV }
	elsif (/^--name$/)     { $name = shift @ARGV              }
	elsif (/^--pidfile$/)  { $pidfile = shift @ARGV           }
	elsif (/^--geometry$/) { 
		my $g = shift @ARGV;
		$g = /^(\d+)[xX](\d+)(?:\+(\d+)\+(\d+))?$/ or next;
		@geometry = ($1, $2, $3, $4);
	}
	elsif (/^--?\w/)       { exit_usage() } # include --help etc.
	
	last if /^--?$/;
}

# Initialize application
my $zim = Zim::GUI->new(settings => $settings);

if (defined $pidfile) {
	if (open PID, '>', $pidfile) {
		print PID "$$\n";
		close PID;
		$zim->{pidfile} = $pidfile;
	}
	else { warn "Could not write pidfile: $pidfile\n" }
}

unless (defined $root) { # for example: zim --doc pagename
	if (@ARGV) {
		exit_usage() if @ARGV > 2;
		($root, $page) = @ARGV;
		unless ($root =~ '/' or -e $root) {
			$name = $root;
			$root = Zim::Repository->lookup_by_name($name);
			exit_not_found($name) unless defined $root;
		}
	}
	elsif (defined $name) {
		$root = Zim::Repository->lookup_by_name($name);
		exit_not_found($name) unless defined $root;
	}
	elsif ($$settings{default_root}) {
		$root = $$settings{default_root};
	}
}
else {
	exit_usage() if @ARGV > 1;
	($page) = @ARGV;
}

if (defined $root) { show_window($name, $root) }
else { $zim->prompt_repository_dialog(\&show_window) }

Gtk2->main;

unlink $pidfile if defined $pidfile;
exit;

sub show_window {
	my ($name, $root) = @_;

	$zim->{name} = $name;
	#warn "root: $root\n";
	$$settings{read_only} = 1 if -e $root and ! -w $root;

	my $rep;	
	eval {
		$rep = Zim::Repository->new(undef, ':', $root);
		$rep->{config}{read_only} = $$settings{read_only};
		$zim->set_repository($rep);
	};
	$zim->exit_error($@) if $@;

	if (exists $$settings{export}) { # FIXME this doesn't belong here
		my %opts = map split('=', $_, 2), split ',', $$settings{export};
		$opts{verbose} = 1 unless defined $opts{verbose};
		my $o = {
			resolve => 1,
			recurse => defined($opts{recurse}) ? $opts{recurse} : 1
		};
		$page = ':' unless length $page;
		my $s = $rep->get_selection($o, $page);
		$s->export(\%opts);
		exit 0;
	}

	# Initialize application
	$zim->gui_init;

	if ($page) {
		eval { # dies when page does not exist in read-only mode
			$page = $rep->resolve_page($page);
			$zim->load_page($page);
		};
	}

	$zim->gui_show;
	if (@geometry) {
		$zim->{window}->resize(@geometry[0,1]);
		$zim->{window}->move(@geometry[2,3]) if @geometry > 2;
	}
}

sub exit_usage {
	print STDERR << "EOT";
Usage: $0 ROOT_DIR [PAGE]

  ROOT_DIR is the directory to store all docs, for example ~/zim/
  PAGE     is the page you want to open, this argument is optional

  To view the manual try "$0 --doc"
EOT
	unlink $pidfile if defined $pidfile;
	exit 1;
}

sub exit_not_found {
	print STDERR "$0: No such repository: $_[0]\n";
	exit 2;
}

1;

__END__

=head1 NAME

zim - A desktop wiki and outliner

=head1 SYNOPSIS

B<zim> [I<OPTIONS>] [I<REPOSITORY> [I<PAGE>]]

=head1 DESCRIPTION

B<Zim> is a desktop wiki writtin in perl using Gtk2.

Try to execute C<zim --doc> to view the user manual.

=head1 OPTIONS

=over 4

=item B<--doc>

Open the zim documentation.

=item B<--export> I<OPTIONS>

Export pages to another format.

=item B<--name> I<REPOSITORY>

Open repository by name.

=item B<--pidfile> I<FILE>

Write the process id of to I<FILE>.

=item B<-v>, B<--version>

Print version and copyright information and quit.

=back

=head1 AUTHOR

Jaap Karssenberg E<lt>pardus@cpan.orgE<gt>

Copyright (c) 2005 Jaap G Karssenberg and RL Zwart. All rights
reserved. This program is free software; you can redistribute it and/or
modify it under the same terms as Perl.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MER-
CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the GNU
General Public License or the Artistic License for more details.

=head1 SEE ALSO

L<Zim>(3)

=cut
