#! C:\usr\bin\perl.exe

###############################################################################
###############################################################################
#
# To copy a file or directory automatically incrementing version number and
#  (if it was a file) opens the new file
#
#			Version 9
#
#	by Andrew Hardwick, http://duramecho.com, 2002/3/7 - 2003/6/19
#
#	Released under GNU Public Licence.
#
###############################################################################
###############################################################################
#
# How to configure the settings
#
# To specify which, if any application, newly duplicated files are to be
# 	opened in (typically for editing), put pairs of values in the 'OpenWith'
#	setting. The first of each pair is the file extension to match & the
#	second is the path to the program to open it in.
#
###############################################################################
###############################################################################
#
# How To Use from a Command Prompt
#
# Run it in Perl (it might need the '#!' first line altered to point to the
#	Perl executable) with the path (the complete path not just the file name)
#   to the file to duplicate as it parameter.
#
# It expects file names to be of the form <anything><number>.<extension> and
# 	(base) directory names to be of the form <anything><number> .
#
###############################################################################
###############################################################################
#
# How To Use from the M$ Windows 'Send To' menu.
#
# To install:
#	Create a shortcut in the 
#	'C:\Documents and Settings\<user name>\SendTo' folder (Win2k) or
#	'C:\Winnt\profiles\<user name>\SendTo' folder (WinNT4) folder. edit the 
#	shortcut not to point to a file but to 'perl <path to this file>'.
#	(The explicit 'perl' addition is needed even for Active State Perl
#	which associates *.pl files with perl.exe so the parameter passing works.)
#
# To use:
#	Click with the secondary mouse button on file in Explorer and select the
#	shortcut.
#
###############################################################################
###############################################################################

# Include libraries
use File::Copy;	# For file copying
use File::Find;	# For directory tree traversing
use strict;		# Disenable automatic variables

###############################################################################
# Settings
###############################################################################
# Change these to be the paths to the programs you want to open the files
#  with specified extensions. (Remember '/' for Unix but '\' for M$Win32.
###############################################################################

my %OpenWith=
(	'txt' =>'C:\WINNT\system32\notepad.exe',
	'pl'  =>'C:\Program Files\UltraEdit\UEDIT32.EXE',
	'c'   =>'C:\Program Files\UltraEdit\UEDIT32.EXE',
	'cpp' =>'C:\Program Files\UltraEdit\UEDIT32.EXE',
	'h'   =>'C:\Program Files\UltraEdit\UEDIT32.EXE',
	'html'=>'C:\Program Files\SoftQuad\HoTMetaL PRO 5\hmpro5.exe',
	'cdr' =>'C:\Program Files\Corel\Draw70\programs\coreldrw.exe',
	'jpg' =>'C:\Program Files\Corel\Draw70\programs\photopnt.exe',
	'png' =>'C:\Program Files\Corel\Draw70\programs\photopnt.exe',
	'doc' =>'C:\Program Files\Microsoft Office\Office\WINWORD.EXE',
	'xls' =>'C:\Program Files\Microsoft Office\Office\EXCEL.EXE',
	'ppt' =>'C:\Program Files\Microsoft Office\Office\POWERPNT.EXE');

##############################################################################
# Main routine
###############################################################################

{	# Get old file name from command line & add the current working dir
	my $CopyFrom=$ARGV[0];
	die "Failed: Source file does not exist." unless -e $CopyFrom;
	# Convert DOS style directory dividers to Unix style ones
	$CopyFrom=~s/\\/\//g;
	# Separarate into path, version number & extention
	my ($Path,$Version,$Extension);
	if(-f $CopyFrom)
	{	($Path,$Version,$Extension)=($CopyFrom=~m/(^.*?)(\d+)(\.[^.]+?)$/);}
	elsif(-d $CopyFrom)
	{	($Path,$Version)=($CopyFrom=~m/(^.*?)(\d+)$/);
		$Extension='';}
	else
	{	die "Failed: That is not a file or a directory."}
	# Assume version number = 0 if none found
	unless($Version)
	{	$Version='0';
		if(-f $CopyFrom)
		{	($Path,$Extension)=($CopyFrom=~m/(^.*?)(\.[^.]+?)$/);}
		elsif(-d $CopyFrom)
		{	$Path=$CopyFrom;
			$Extension='';}}
	# Generate new number
	my $NewVersion=$Version++;
	# Pad with leading zeros to same length if shorter
	if(length($NewVersion)<length($Version))
	{	$NewVersion='0'x(length($NewVersion)-length($Version)).$NewVersion;}
	# Generate next file name
	my $CopyTo=$Path.$Version.$Extension;
	# Copy as a file or directory appropriately
	die "Failed: Destination file already exists." if -e $CopyTo;
	print "$CopyFrom->$CopyTo\n";
	if(-f $CopyFrom)
	{	# Copy file
		copy($CopyFrom,$CopyTo);
		# Open it if it has a specified program to open it with
		OpenFile($CopyTo);}
	else
	{	# Copy directory tree
		Xcopy($CopyFrom,$CopyTo);}}

###############################################################################
# Recursive copy
###############################################################################
# Copies a folder, its sub folders & files therein.
# Paramter 1: Source folder path.
# Paramter 2: Destination folder path.
###############################################################################

sub Xcopy
{	my ($CopyFrom,$CopyTo)=@_;
	my ($Source,$RelativePath,$Destination);
	# Traverse file tree (highest level directory first)
	find(		sub
				{	$Source=$File::Find::name;
					$RelativePath=$Source;
					$RelativePath=~s/^\Q$CopyFrom\E//;
					$Destination=$CopyTo.$RelativePath;
					# print "$Source\n ->$Destination\n";
					if(-f $Source)
					{	# Copy file
						copy($Source,$Destination);}
					else
					{	# Make a duplicate directory if necessary
						unless($Destination eq '..'||$Destination eq '.')
						{	unless(-e $Destination)
							{	mkdir($Destination,0775);}}}}
			,$CopyFrom);}

###############################################################################
# Open file
###############################################################################
# Open file as a separate process in appropriate application if the file
#  type, determined by the file extension, has a registered opening
#  application.
###############################################################################
# Paramter 1: Path to file to run.
###############################################################################

sub OpenFile
{	my $Path=$_[0];
	$Path=~/\.(.*?)$/;
	my $Type=$1;
	if(exists($OpenWith{$Type}))
	{	if($^O eq 'MSWin32')
		{	# M$ Windows so DOSify the file path
			$Path=~s/\//\\/g;
			# Contorted run to avoid M$ Office command line awkwardness
			#  ('exec' passes parameters directly, not as a single line
			#  parsed by the shell, & M$ Word 2k does not accept file names
			#  containing spaces that way).
			exec("cmd","/R","start","\"\"",
				"\"$OpenWith{$Type}\"","\"$Path\"");}
		else
		{	# Assume Unix compatible so simply run it normally
			exec("\"$OpenWith{$Type}\"","\"$Path\"");}}}

###############################################################################

