# Album Plugin:	utils/create_plugin
# For info:	'album -plugin_info utils/create_plugin'
# For usage:	'album -plugin_usage utils/create_plugin'
use strict;

my $DESC = <<DESC;
Create a new plugin framework by answering a few simple questions
DESC

# name
# Usage?
#   You can view usage with:
#   % $opt->{PROGNAME} -plugin utils/mv -h",
# album::attempt_require
# options?

sub start_plugin {
	my ($opt,$plugin,$path) = @_;
	
	album::hook($opt,'pre_do_albums', \&create_plugin);
	
	return {
		author => 'David Ljung Madison',
		href => 'http://MarginalHacks.com/',
		version => '1.0',
		description => $DESC,
	};
}

sub mkdirR {
	my ($dir) = @_;
	my $now;
	foreach ( split('/',$dir) ) {
		$now .= "$_/";
		next if -d $now;
		mkdir($now,0755) || die("Couldn't mkdir [$now]\n");
	}
}

sub create_plugin {
	my ($opt,undef,$hookname) = @_;

	# Setup
	my $hooks = album::gather_hook_info($opt);

	# Find the name/category/path of the plugin
	#########################
	my ($path,$category,$name);
	$path = album::install_get_answer($opt,"name",undef,
		"\nWhat is the name of your plugin?  You can include the category as well");

	$name = $path;
	$name =~ s|.*plugins/||ig;

	if ($name =~ m|(.*)/([^/]+)|) {
		($category,$name) = ($1,$2);
	} else {
		$category = album::install_get_answer($opt,"category",undef,
			"\nWhat category?  i.e.: captions/exif, format, etc..?\n".
			"See the plugins directory for current categories");
		$path =~ s|\Q$name\E$|$category/$name|;
	}
	my $plugin = "$category/$name";

	my $file = $name;
	my $post = album::option($opt,'plugin_post');
	$file =~ s|(\Q$post\E)?$|$post|;
	$path =~ s|(\Q$post\E)?$|$post|;
	print "Creating plugin [$file] in category [$category]\n";

	# Setup the output
	#########################
	my $dir = $path;
	$dir =~ s|\Q$file\E$||;
	mkdirR($dir);

	if (-f $path) {
		print STDERR "\nPlugin $plugin already exists, overwrite?\n";
		exit unless album::install_get_yn($opt,'n');
	}

	open(PLUGIN,">$path")
		|| album::fatal($opt,"Couldn't create/write plugin! [$path]");

	# Get basic info
	#########################
	my $author = album::install_get_answer($opt,"name",undef,
		"\nWhat is the author's full name (no email/URL yet)");
	my $href = album::install_get_answer($opt,"URL",undef,
		"\nWhat is the author's URL or email");
	my $version = "1.0";
	my $desc = album::install_get_text($opt,"description",
		"\nNow enter a few lines describing what the plugin does and how to use it.");

	# Any options?
	#########################
	my (@options,@get_options);
	while(1) {
		my $option = album::install_get_answer($opt,"option",0,
			"\nList any plugin options here\n");
		$option =~ s/^-+//g;
		$option =~ s/.*:://g;
		last unless $option;

		my $default = album::install_get_answer($opt,"default",undef,
			"\nWhat is the default value?\n",1);

		my $typename = album::install_get_menu($opt,"type",
			"\nWhat option type is this?\n",
			qw(boolean number string array)
			);
		my $type="album::OPTION_STR";
		$type="album::OPTION_BOOL" if $typename eq 'boolean';
		$type="album::OPTION_NUM" if $typename eq 'number';
		$type="album::OPTION_ARR" if $typename eq 'array';

		my $usage = album::install_get_answer($opt,"usage",undef,
			"\nGive a one-line description for the usage.\n");

		push(@options,"\n	# Options\n") unless @options;
		my $defstr = $default ? " default=>$default," : "";
		push(@options,"	album::add_option(1,'$option', $type,$defstr usage=>\"$usage\");\n");
		push(@get_options,"\n	# Get options\n") unless @get_options;
		push(@get_options,"	my \$$option = album::option(\$opt, '$option');\n");

		print "\nAdded plugin option: [$option]\n";
	}

	# What hooks do they want to use?
	#########################
	my @hooks;
	my @subs;
	while(1) {
		my $hook = album::install_get_answer($opt,"hook",0,
			"\nNow enter any hooks you want to use.\n".
			"When done, just hit return\n".
			"To see a list of hook names, enter 'l' or 'list'\n".
			"To see a list of hook info, enter 'i' or 'info' (long)\n"
			);
		last unless $hook;
		if ($hook =~ /^l(ist)?$/i) {
			my @list = sort keys %$hooks;
			print "Hooks: @list\n";
			next;
		}
		if ($hook =~ /^i(nfo)?$/i) {
			album::list_hooks($opt, "list_hooks",undef,1);
			next;
		}
		unless ($hooks->{$hook}) {
			print STDERR "\nERROR: Unknown hook name!\n";
			next;
		}
		push(@hooks,"\n	# Setup the hooks\n") unless @hooks;
		push(@hooks,"	album::hook(\$opt, '$hook', \\&$hook);\n");
		my $hd = join("\n\t#   ",@{$hooks->{$hook}{description}});
		my $hr = join("\n\t# Returns: ",@{$hooks->{$hook}{returns}});
		my $args = $hooks->{$hook}{args};
		$args =~ s/'$hook'/\$hook/g;
		push(@subs,<<SUB);

sub $hook {
	my $args = \@_;
@get_options
	# Do plugin code for this hook:
	#   $hd


	# Return according to this description:
	# Returns: $hr
}
SUB
		print "\nAdded hook: [$hook]\n";
	}

	# Any attempted requires?
	#########################
	my @requires;
	my @check_requires;
	while(1) {
		my $req = album::install_get_answer($opt,"use",0,
			"\nPlugins need special code if they 'use' any modules\n".
			"that are not part of the standard perl distribution.\n\n".
			"If you need to 'use' any such modules, please enter them here.\n".
			"When done, just hit return\n"
			);
		last unless $req;
		my $rname = uc($req);
		$rname =~ s/[^A-Z]+/_/g;
		push(@requires,"\n# Plugin code for: 'use $req'\nmy \$$rname = album::attempt_require('$req');\n");
		push(@check_requires,"\n	unless (\$$rname) {\n",
			"		my \$err = \"$req is required and not installed!\\n\";\n",
			"		print STDERR \"\\n[Plugin: $name] \$err\\n\";\n",
			"		\$ret->{description} .= \"\\n\$err\";\n",
			"		return \$ret;\n",
			"	}\n");
		print "\nAdded require/use: [$req]\n";
	}


	# Write it out
	#########################
	print PLUGIN <<PLUGIN;
# Album Plugin: $plugin
# For info: 'album -plugin_info $plugin'
# For usage:  'album -plugin_usage $plugin'
use strict;		# Not required, but recommended
@requires
my \$DESCRIPTION = << 'DESCRIPTION';
$desc
DESCRIPTION

sub start_plugin {
	my (\$opt) = \@_;

	my \$ret = {
		author      => '$author',
		href        => '$href',
		version     => '$version',
		description => \$DESCRIPTION,
	};
@check_requires
@options
@hooks

	return \$ret;
}

@subs

# Plugins always end with:
1;
PLUGIN

	close PLUGIN;
	print "Written: $path\n";

	# We're done.
	return 1;
}

# Plugins always end with:
1;
