package MiscUtils;

use strict;
require Exporter;
require Carp;

our @ISA = qw(Exporter);
our @EXPORT = qw(rindent indent mkdirs swap_dirs filter_text array_to_hash debug);
our $VERSION = v1.1;

sub rindent {
	my $ident = shift();
	my $tmp = '';

	while ($ident--) {
		$tmp .= "\t";
	}

	return $tmp;
}

sub indent {
	my ($indent, $fh) = @_;

	if ($fh) { print $fh rindent ($indent); }
	else { print rindent ($indent); }
}

sub mkdirs {
	my $full_path = $_[0];
	return if (-d $full_path);
	return if ($full_path !~ m|/|g);
	$full_path =~ s|^((?:(?:[A-Z]:)?/)?.+)/(?:.+)?$|$1/|;
	my @all_dirs = split(/\//, $full_path);
	my ($dir, $tmp_dir) = ();
	foreach $dir (@all_dirs) {
		$tmp_dir .= "$dir/";
		if (!-e $tmp_dir) {
			if (!mkdir($tmp_dir)) {
				return 0;
			}
		}
	}

	return 1;
}

sub swap_dirs {
	my ($path, $from, $to) = @_;
	$path =~ s/^$from/$to/i;
	return 	($path);
}

sub filter_text {
	my $dirty_text = shift();

	# trim
	$dirty_text =~ s/^ +//;		$dirty_text =~ s/ +$//;

	# "smart" quotes X{
	$dirty_text =~ tr/\x93\x94/"/;	$dirty_text =~ tr/\x92/'/;

	# convert special chars
	$dirty_text =~ s/&/&amp;/g;
	$dirty_text =~ s/</&lt;/g;	$dirty_text =~ s/>/&gt;/g;
	$dirty_text =~ s/"/&quot;/g;	$dirty_text =~ s/'/&#39;/g;

	return $dirty_text;
}

sub debug {
	my ($whatnot, $name, $indent) = @_;

	$name = 'VARIABLE' if (!$name);
	$whatnot = '(empty)' if (!$whatnot);

	if (ref($whatnot) eq 'ARRAY') {
		$indent++;
		for (my $i = 0; $i < scalar(@{ $whatnot }); $i++) {
			debug ($whatnot->[$i], "${name}\[$i\]", $indent);
		}
		$indent--;
	}
	elsif (ref($whatnot) eq 'HASH') {
		$indent++;
		foreach my $item (keys %{ $whatnot }) {
			debug ($whatnot->{$item}, "${name}\{$item\}", $indent);
		}
		$indent--;
	}
	elsif (ref($whatnot) eq 'SCALAR') {
		debug ($$whatnot, $name, $indent);
	}
	elsif (ref($whatnot) eq 'CODE') {
		debug ('a code reference', $name, $indent);
	}
	else {
		print ("debug: ");
		while ($indent--) { print "\t"; }
		print ("$name is $whatnot\n");
	}
}

1;

__END__

=head1 NAME

MiscUtils - Misc. Utils

=head1 SYNOPSIS

	use MiscUtils;
	my $path_and_or_file_name_that_may_or_may_not_exist = '/xtra/shared/mp3/james/laid.mp3';
	mkdirs($path_and_or_file_name_that_may_or_may_not_exist);
	debug ($path_and_or_file_name_that_may_or_may_not_exist);

=head1 DESCRIPTION

Something a bit different here. Yes, there are a few crappy functions to use for yourself that I have found useful for me, but that's not the point. The point of this module is for B<YOU> to put B<YOUR> code that you find yourself reusing often in here.

Purists will hate this because it's "Not portable" and it kinda goes against module-writing. Also, it's more than you need (normally), so why include it all? I thought it was kind of an alright idea, and you don't have to use your own functions (if you feel these are sufficent).

=head1 INCLUDED FUNCTIONS

=head2 rindent
	print rindent (3) . "3 tabs over\n";
Returns x number of indents.

=head2 indent
	indent (3, \*STDERR);
	print STDERR "3 tabs over on STDERR\n";

Prints (optionally on a filehandle) x number of indents.

=head2 mkdirs
	my $path_and_or_file_name_that_may_or_may_not_exist = '/xtra/shared/mp3/james/laid.mp3';
	mkdirs($path_and_or_file_name_that_may_or_may_not_exist);

If you were to run this example you can rest assured the directories /xtra/, /xtra/shared, /xtra/shared/mp3, and /xtra/shared/mp3/james would be there. I found this pretty useful in many of my scripts.

=head2 swap_dirs
	sub swap_dirs {
		my ($path, $from, $to) = @_;
		$path =~ s/^$from/$to/i;
		return 	($path);
	}

Should be pretty obvious, but I'll give you the lowdown. Takes a path/filename ('/xtra/shared/mp3') a base ('/xtra/') and a replacement ('/home/lackluster/'). This would return '/home/lackluster/shared/mp3'. GREAT for relative path stuff.

=head2 filter_text
	# "smart" quotes
	# \x93 => "
	# \x94 => "
	# \x92 => '
	#
        # "ugly" chars
	# & => &amp
	# < => &lt;
	# " => &quot;
	# > => &gt;
	# ' => &#39;

	print XML filter_text ($xml_data);

Trims and transforms

=head2 debug
	debug (\%hash_ref, 'this_cool_hash');
	debug (\@arr_ref, 'my super-cool array');
	debug (\$scalar_ref, 'sref');
	debug ($var);

Simple recursive debugging in pretty print. Not as super-cool as L<Data::Dumper>.

=head1 AUTHOR

BPrudent (xlacklusterx@hotmail.com)
Brandon Prudent