AutoCopy application code

I wrote an app in AppleScript called ‘AutoCopy’ and here is the code.
AutoCopy is a simple app that saves a copy of any item in the Finder, as often as you choose.
Its purpose is to auto-save versions while you’re making changes to a file or several files inside a folder.
How to use: the fastest way is to pick the item you want to autocopy (it can be a single item or folder containing many items) and drag it onto the AutoCopy icon. You’re asked how often (in minutes) you want to save a copy.
Enter a number, and that’s it.
Open the below code in AppleScript Editor and save it as application:

(*
Script written in AppleScript Editor vers. 2.6.1, using AppleScript version 2.3.2  in OS X version 10.9.5.     
Author:  Steve Thompson
*)


--This routine runs when the app is launched by dragging an item onto its icon. 
on open draggedItem
	tell application "Finder"
		activate
		set chosenItem to draggedItem as alias
	end tell
	mainRoutine(chosenItem)
end open


-- This routine runs if you launch by double-clicking the app.
on run
	tell application "Finder"
		activate
		set theResult to display dialog "Want to auto-copy a File or a Folder ?" buttons ¬
			{"Cancel", "Folder", "File"} default button 3
	end tell
	set chosenItem to chooseItem(theResult)
	if chosenItem is false then return --program quits.
	mainRoutine(chosenItem)
end run


--Subroutines:
on mainRoutine(chosenItem)
	tell application "Finder"
		repeat while kind of chosenItem is "Volume"
			-- will keep repeating until they choose "Cancel" or anything that's not a disk.
			set theResult to display dialog ¬
				"Don't choose a disk!  You can choose a File or a Folder." buttons ¬
				{"Cancel", "Folder", "File"} default button 3
			set chosenItem to my chooseItem(theResult)
			if chosenItem is false then return --program quits.
		end repeat
		set {chosenItemName, chosenItemLocation} to {(name of chosenItem), (container of chosenItem)}
		--Ask user how often to make a copy:
		set {copyFrequency, waitTime} to my requestedcopyFrequency()
	end tell -- Because the next line of code must run outside of Finder.
	-- Begin repeat loop of this task:  Make new duplicate of chosenItem,  name it after current date and time
	--and put it in folder "versions".
	frequencyLoop(chosenItem, chosenItemName, chosenItemLocation, copyFrequency, waitTime)
end mainRoutine


on chooseItem(theResult)
	if button returned of theResult is "Cancel" then return false
	tell application "Finder"
		if button returned of theResult is "Folder" then
			set chosenItem to choose folder with prompt ¬
				"Choose Folder to AutoCopy" default location desktop as alias
		else -- if button returned is "File"
			set chosenItem to choose file with prompt "Choose File to AutoCopy" default location ¬
				desktop as alias
		end if
	end tell
	return chosenItem
end chooseItem

on requestedcopyFrequency()
	set copyFrequency to display dialog "Enter every number of minutes you want to " & return & ¬
		"save a copy:" default answer "1" with title "AutoCopy"
	set waitTime to display dialog ¬
		"AutoCopy will quit automatically if the item hasn't been " & return & ¬
		"modified after a certain number of minutes.  Enter the " & return & ¬
		"number of minutes AutoCopy should wait before quitting:" default answer "15" with title "AutoCopy"
	return {(text returned of copyFrequency as integer), (text returned of waitTime as integer)}
end requestedcopyFrequency

on frequencyLoop(chosenItem, chosenItemName, chosenItemLocation, copyFrequency, waitTime)
	set x to 0 --x keeps track of number of minutes it's been since a copy of item was made.
	repeat
		tell application "Finder"
			--Make sure folder "versions" exists in same folder as specified item.
			if not (exists folder (chosenItemName & "__versions") of chosenItemLocation) then
				set AutoCopyFolder to (make new folder at chosenItemLocation with properties ¬
					{name:chosenItemName & "__versions"})
			else
				set AutoCopyFolder to folder (chosenItemName & "__versions") of chosenItemLocation
			end if
			set AutoCopyFolder to (AutoCopyFolder as alias)
			my renameLoop(AutoCopyFolder as string, chosenItem)
			try
				set lastModified to modification date of chosenItem
				set theDateTime to my makeDateTime(lastModified)
				set newName to (theDateTime & "__" & chosenItemName as string)
				set AutoCopyFolder to (AutoCopyFolder as string)
				--Only make a new copy if there's not already one with an identical name in AutoCopyFolder.
				if not (exists item (AutoCopyFolder & newName)) then
					--First check if item with same name as chosenItem already exists in AutoCopyFolder:
					set duplicateItem to (AutoCopyFolder & chosenItemName) as string
					if (exists item duplicateItem) then
						set duplicateItem to (duplicateItem as alias)
						set lastModified to modification date of duplicateItem
						--Prepare to change its name to its modification date:
						set theDateTime to my makeDateTime(lastModified)
						--But if an item with exact same modification date exists, get rid of duplicate:
						if exists item (AutoCopyFolder & theDateTime & "__" & chosenItemName) then
							delete item duplicateItem
						else --change duplicate's name to modification date:
							set name of duplicateItem to (theDateTime & "__" & chosenItemName)
						end if
					end if
					--Make a new copy, but only if item with same modification date doesn't exist:
					if not (exists item (AutoCopyFolder & newName)) then
						copy item chosenItem to folder (AutoCopyFolder as string)
						set duplicateItem to result as alias
						set name of duplicateItem to newName
						set x to 0
					end if
				end if
			on error
				my itemDoesntExistMessage()
				return --program quits.
			end try
		end tell
		-- pause script for ((number of minutes user specified) * 60) seconds:
		repeat copyFrequency times
			delay 60
			set x to (x + 1) --x gets incremented plus-one for every minute.
			if x ≥ waitTime then return --program quits.
		end repeat
	end repeat
end frequencyLoop


--Make function that will run at beginning of every loop iteration in frequencyLoop.
--It checks modification dates of every item in a folder, and renames each
--item after the modification date.  If multiple items share a mod date (and are same filetype), only one can remain.
on renameLoop(folderStringPath, chosenItem)
	tell application "System Events"
		--get every visible item in the folder:
		set theItems to every item of item folderStringPath whose visible is true
		set modDatesAndExtensions to {}
		repeat with i in theItems
			set end of modDatesAndExtensions to ¬
				{modified:modification date of i, name extension:¬
					name extension of i}
		end repeat
		--Find out if any items match, both in mod date and extension, and if so, keep only one:
		set removedItems to item 2 of my removeDuplicates(modDatesAndExtensions)
		if (count of removedItems) > 0 then
			repeat with i in removedItems
				delete (item i of theItems)
			end repeat
		end if
		set theItems to every item of item folderStringPath whose visible is true
		--Make sure the names of the items all begin with mod dates:
		repeat with i in theItems
			set theDateTime to my makeDateTime(modification date of i)
			set formattedNm to (theDateTime & "__" & chosenItem's name as string)
			if ((i's name does not start with theDateTime) or ("copy" is in i's name)) and ¬
				(i's name extension is chosenItem's name extension) then
				set name of i to formattedNm
			else if (i's name does not start with theDateTime) then
				set name of i to (theDateTime & "__" & (i's name) as string)
			end if
		end repeat
	end tell
	--return modDatesAndExtensions
end renameLoop

--Returns list of two items: first is modified version of lst with duplicates removed.
--Second item is list of indexes of removed items.
on removeDuplicates(lst)
	local lst, itemRef, res, itm
	try
		if lst's class is not list then error "not a list." number -1704
		script k
			property l : lst
			property res : {}
			property indx : {}
		end script
		repeat with i from 1 to count of k's l
			set itm to (item i of k's l)
			if k's res does not contain {itm} then
				set k's res's end to itm
			else
				set k's indx's end to i
			end if
		end repeat
		return {k's res, k's indx}
	on error eMsg number eNum
		return false
	end try
end removeDuplicates



--This function returns a specially formatted date-time string, i.e, "140211-201412"
on makeDateTime(dateObject)
	set shortString to short date string of dateObject
	set theList to explode(shortString, "/")
	if (count of (LI(1, theList))) = 1 then
		setLI(1, theList, ("0" & (item 1 of theList)))
	end if
	if (count of (item 2 of theList)) = 1 then
		setLI(2, theList, ("0" & (item 2 of theList)))
	end if
	set theDate to (item 3 of theList) & (item 1 of theList) & (item 2 of theList)
	set AppleScript's text item delimiters to ""
	set theTime to time of dateObject
	set theHour to (round (theTime / 3600) rounding down) as string
	set hourInt to theHour as integer
	set hourSecs to (hourInt * 3600)
	set minSecs to ((theTime - hourSecs) / 60)
	set theMin to (round minSecs rounding down) as string
	set minInt to theMin as integer
	set minSecs to (minInt * 60)
	set theSec to (theTime - hourSecs - minSecs) as string
	if ((count of theHour) = 1) then set theHour to ("0" & theHour)
	if ((count of theMin) = 1) then set theMin to ("0" & theMin)
	if ((count of theSec) = 1) then set theSec to ("0" & theSec)
	return (theDate & "-" & theHour & theMin & theSec) as string
end makeDateTime


on itemDoesntExistMessage()
	display dialog ¬
		"The item no longer exists.  Either its name changed or it was deleted.  I'm quitting. Bye." with title ¬
		"AutoCopy" buttons {"OK"} default button 1 giving up after 10
end itemDoesntExistMessage

--This function is just for creating a short-hand way of accessing a list item.
--ItemNum can be a single integer, or a list of two integers for accessing a range of items:
on LI(itemNum, theList)
	if class of itemNum is integer then
		return (item itemNum of theList)
	else if class of itemNum is list then
		return (items (item 1 of itemNum as integer) thru ¬
			(item 2 of itemNum as integer) of theList)
	end if
end LI

--This function is for assigning a value to a list item:
on setLI(itemNum, theList, theValue)
	set item itemNum of theList to theValue
end setLI

-- This function separates pieces of a string into list items, using theDelimit
-- as the separator:
on explode(theString, theDelimit)
	set origDelimit to AppleScript's text item delimiters
	set AppleScript's text item delimiters to theDelimit
	set theResult to every text item of theString
	set AppleScript's text item delimiters to origDelimit
	return theResult
end explode

--This function re-assembles a list of strings into a single string,
--using theDelimit as glue to reconnect each string.
on implode(textList, theDelimit)
	set origDelimit to AppleScript's text item delimiters
	set AppleScript's text item delimiters to theDelimit
	set theString to (textList as string)
	set AppleScript's text item delimiters to origDelimit
	return theString
end implode

The script fails in any locale that does not use the / as a delimiter - which is most of them, I think.

Here’s a bit of locale-agnostic code to get the datestamp:

set dateObject to (current date)
set sep to "-"

tell dateObject to set {year:y, month:m, day:d, hours:hh, minutes:mm, seconds:ss} to it

set dateStamp to (y * 10000 + m * 100 + d) as text
set timeStamp to (hh * 10000 + mm * 100 + ss) as text
if (count timeStamp) = 5 then set timeStamp to "0" & timeStamp
return dateStamp & sep & timeStamp