property prefsFileName : "com.apprenticealf.dedrm.plist"
property tempFileName : "DeDRM_temp.log"
property prefsFolderName : "com.apprenticealf.dedrm"
property newKeysFolderName : "newKeys"
property handledExtensions : {"epub", "pdf", "prc", "azw", "azw1", "tpz", "azw3", "azw4", "mobi", "pobi", "pdb"}

global python
global oldAppleScript

global eReaderTool
global MobipocketTool
global KindlePIDTool
global BNKeyGenTool
global BNKeyFetchTool
global BNePubTool
global KindleKeyTool
global NookKeyTool
global AdobeKeyGenTool
global AdobeePubTool
global ePubTestTool
global AdobePDFTool
global ZipFixTool
global ProgressApp

global PIDs
global UDIDs
global bnKeys
global KindleSerialList
global AndroidKeyList
global KindleKeyList
global AdeptKeyList

global ErrorList
global WarningList
global CompletedList
global ErrorCount
global WarningCount
global CompletedCount
global totalebooks
global completedebooks
global outputFolder
global logFilePath
global tempfilepath

global paraend

on writetolog(logstring)
	try
		set fileRef to open for access logFilePath with write permission
		write logstring & "
" to fileRef starting at eof as «class utf8»
		close access fileRef
	end try
end writetolog

on clearlog()
	try
		set fileRef to open for access logFilePath with write permission
		set eof fileRef to 0
		close access fileRef
	end try
end clearlog

on cleartemp()
	try
		set fileRef to open for access tempfilepath with write permission
		set eof fileRef to 0
		close access fileRef
	end try
end cleartemp

on readtemp()
	set tempContents to ""
	try
		set fileRef to open for access tempfilepath
		if (get eof fileRef) > 0 then
			set tempContents to read fileRef from 1 as «class utf8»
		end if
		close access fileRef
	end try
	return tempContents
end readtemp

on readtemplist()
	set templist to {}
	try
		set fileRef to open for access tempfilepath
		if (get eof fileRef) > 0 then
			set tempContents to paragraphs of (read fileRef from 1 as «class utf8»)
		end if
		close access fileRef
	end try
	repeat with nextLine in tempContents
		if length of nextLine is greater than 0 then
			copy nextLine to the end of templist
		end if
	end repeat
	return templist
end readtemplist

on quotedtemppath()
	set tempFile to POSIX path of file tempfilepath
	return quoted form of tempFile
end quotedtemppath

on folderexists(inputFolder)
	try
		--display dialog "test -d " & quoted form of (POSIX path of inputFolder)
		do shell script "test -d " & quoted form of (POSIX path of inputFolder)
		return true
	end try
	
	return false
end folderexists

on fileexists(inputFile)
	try
		do shell script "test -f " & quoted form of (POSIX path of inputFile)
		return true
	end try
	
	return false
end fileexists

on GetFileExtension(fileName)
	set fileExtension to ""
	if fileName contains "." then
		set oldTIDs to AppleScript's text item delimiters
		set AppleScript's text item delimiters to "."
		set fileExtension to the last text item of fileName
		set AppleScript's text item delimiters to oldTIDs
	end if
	return fileExtension
end GetFileExtension

on GetFileNameOnly(fileName)
	set fileNameOnly to fileName
	if fileName contains "." then
		set oldTIDs to AppleScript's text item delimiters
		set AppleScript's text item delimiters to "."
		set fileNameOnly to (text items 1 through -2 of fileName) as string
		set AppleScript's text item delimiters to oldTIDs
	end if
	return fileNameOnly
end GetFileNameOnly

on GetTools()
	set paraend to "
"
	set ASnumber to (text 1 thru 3 of (AppleScript's version as text) as real)
	set oldAppleScript to (ASnumber < 2.0)
	set python to "/usr/local/bin/python"
	if not fileexists(python) then
		set python to "/usr/bin/python"
	end if
	set pythonversion to "2.3"
	try
		set pythonversion to do shell script python & " -c \"from sys import version; print version[:3]\""
	end try
	-- display dialog pythonversion
	if (pythonversion is not "2.5") and (pythonversion is not "2.6") and (pythonversion is not "2.7") then
		set dialogresult to (display dialog "This AppleScript requires Python 2.7x.

	Please install python 2.7x and try again." buttons {"Quit"} default button 1 with title "DeDRM" with icon stop)
		return false
	end if
	-- we always want a space after the command
	set python to python & " "
	
	set eReaderTool to POSIX path of (path to resource "erdr2pml.py")
	set MobipocketTool to POSIX path of (path to resource "k4mobidedrm.py")
	set KindlePIDTool to POSIX path of (path to resource "kindlepid.py")
	set BNKeyGenTool to POSIX path of (path to resource "ignoblekeygen.py")
	set BNKeyFetchTool to POSIX path of (path to resource "ignoblekeyfetch.py")
	set BNePubTool to POSIX path of (path to resource "ignobleepub.py")
	set KindleKeyTool to POSIX path of (path to resource "kindlekey.py")
	set NookKeyTool to POSIX path of (path to resource "ignoblekey.py")
	set AdobeKeyGenTool to POSIX path of (path to resource "adobekey.py")
	set AdobeePubTool to POSIX path of (path to resource "ineptepub.py")
	set ePubTestTool to POSIX path of (path to resource "epubtest.py")
	set AdobePDFTool to POSIX path of (path to resource "ineptpdf.py")
	set ZipFixTool to POSIX path of (path to resource "zipfix.py")
	set ProgressApp to POSIX path of (path to resource "DeDRM Progress.app")
	if not fileexists(eReaderTool) then
		set dialogresult to (display dialog "The eReader script (erdr2pml.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(MobipocketTool) then
		--display dialog MobipocketTool
		set dialogresult to (display dialog "The Mobipocket script (k4mobidedrm.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(KindlePIDTool) then
		--display dialog KindlePIDTool
		set dialogresult to (display dialog "The KindlePID script (kindlepid.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(BNKeyGenTool) then
		set dialogresult to (display dialog "The B&N Key Generation script (ignoblekeygen.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(BNKeyFetchTool) then
		set dialogresult to (display dialog "The B&N Key Fetch script (ignoblekeyfetch.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(BNePubTool) then
		set dialogresult to (display dialog "The B&N script (ignobleepub.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(NookKeyTool) then
		set dialogresult to (display dialog "The B&N Key Retrieval script (ignoblekey.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(KindleKeyTool) then
		set dialogresult to (display dialog "The Kindle Key Generation script (kindlekey.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(AdobeKeyGenTool) then
		set dialogresult to (display dialog "The Adobe Key Generation script (adobekey.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(AdobePDFTool) then
		set dialogresult to (display dialog "The Adobe PDF script (ineptpdf.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(AdobeePubTool) then
		set dialogresult to (display dialog "The Adobe ePub script (ineptepub.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not fileexists(ePubTestTool) then
		set dialogresult to (display dialog "The ePub encryption test script (epubtesttool.py) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	if not folderexists(ProgressApp) then
		set dialogresult to (display dialog "The Progress dialog application (DeDRM Progress.app) is missing from this package. Get a fresh copy." buttons {"Quit", "Continue Anyway"} default button 1 with title "DeDRM" with icon stop)
		if button returned of dialogresult is "Quit" then
			return false
		end if
	end if
	return true
end GetTools

on unlockmobifile(encryptedFile)
	--check it's a mobi file.
	set BOOKMOBI to "NOTAMOBI"
	try
		set BOOKMOBI to read file encryptedFile from 61 for 8
	end try
	if BOOKMOBI is not "BOOKMOBI" and BOOKMOBI is not "TEXtREAd" then
		set TOPAZ to "NOT"
		try
			set TOPAZ to read file encryptedFile from 1 for 4
		end try
		if TOPAZ is not "TPZ0" then
			set ErrorCount to ErrorCount + 1
			set ErrorList to ErrorList & encryptedFile & " is neither a Kindle not a Mobipocket file.
"
			return
		end if
	end if
	set encryptedFilePath to POSIX path of file encryptedFile
	tell application "Finder"
		set parent_folder to (container of file encryptedFile) as text
		set fileName to (name of file encryptedFile) as text
	end tell
	set fileExtension to "." & GetFileExtension(fileName)
	set fileName to GetFileNameOnly(fileName)
	if outputFolder is "" or not folderexists(outputFolder) then
		set dedrmFolder to POSIX path of file parent_folder
	else
		set dedrmFolder to POSIX path of file outputFolder
	end if
	set shellcommand to python & (quoted form of MobipocketTool)
	repeat with KindleKeyPath in KindleKeyList
		set shellcommand to shellcommand & " -k " & quoted form of KindleKeyPath
	end repeat
	repeat with AndroidKeyPath in AndroidKeyList
		set shellcommand to shellcommand & " -a " & quoted form of AndroidKeyPath
	end repeat
	set Serialstring to GetSerialstring()
	if Serialstring is not "" then set shellcommand to shellcommand & " -s " & quoted form of Serialstring
	set PIDstring to GetPIDstring()
	if PIDstring is "" then
		set PIDstring to GetUDIDPIDs()
	else
		set PIDstring to PIDstring & "," & GetUDIDPIDs()
	end if
	
	if PIDstring is not "" then set shellcommand to shellcommand & " -p " & quoted form of PIDstring
	set shellcommand to shellcommand & " " & (quoted form of encryptedFilePath) & " " & (quoted form of dedrmFolder)
	set shellcommand to shellcommand & " > " & quotedtemppath()
	--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
	writetolog("shellcommand: " & shellcommand)
	cleartemp()
	set DecodingError to false
	set shellresult to ""
	set ErrorText to ""
	set decoded to true
	try
		do shell script shellcommand
	on error ErrorText number errnum
		set DecodingError to true
		set decoded to false
	end try
	set shellresult to readtemp()
	writetolog("shellresult: " & shellresult & " " & ErrorText)
	if decoded then
		set decoded to ((offset of "No key found" in shellresult) is 0)
	end if
	if not decoded then
		DecodingError = true
		set newKeyList to GetKindleKeys()
		if length of newKeyList > 0 then
			set shellcommand to python & (quoted form of MobipocketTool)
			repeat with KindleKeyPath in newKeyList
				set shellcommand to shellcommand & " -k " & quoted form of KindleKeyPath
			end repeat
			set shellcommand to shellcommand & " " & (quoted form of encryptedFilePath) & " " & (quoted form of dedrmFolder)
			set shellcommand to shellcommand & " > " & quotedtemppath()
			--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
			writetolog("shellcommand: " & shellcommand)
			cleartemp()
			set DecodingError to false
			set shellresult to ""
			set ErrorText to ""
			set decoded to true
			try
				do shell script shellcommand
			on error ErrorText number errnum
				set DecodingError to true
				set decoded to false
			end try
			set shellresult to readtemp()
			writetolog("shellresult: " & shellresult & " " & ErrorText)
			if decoded then
				set DecodingError to not ((offset of "No key found" in shellresult) is 0)
			end if
			if not DecodingError then
				set KindleKeyList to KindleKeyList & newKeyList
			end if
		end if
	end if
	if DecodingError then
		set ErrorCount to ErrorCount + 1
		set ErrorList to ErrorList & fileName & fileExtension & " couldn't be decrypted.
"
	else if (offset of "not encrypted" in shellresult) > 0 then
		set WarningCount to WarningCount + 1
		set WarningList to WarningList & fileName & fileExtension & " is not encrypted.
"
	else
		set CompletedCount to CompletedCount + 1
		set CompletedList to CompletedList & fileName & fileExtension & paraend
	end if
end unlockmobifile

on unlockpdbfile(encryptedFile)
	--check it's an eReader file.
	set PNRdPPrs to "NOT_eREADER"
	try
		set PNRdPPrs to read file encryptedFile from 61 for 8
	end try
	if PNRdPPrs is not "PNRdPPrs" then
		set ErrorCount to ErrorCount + 1
		set ErrorList to ErrorList & encryptedFile & " is not an eReader file.
"
		return
	end if
	set encryptedFilePath to POSIX path of file encryptedFile
	tell application "Finder"
		set parent_folder to (container of file encryptedFile) as text
		set fileName to (name of file encryptedFile) as text
	end tell
	set fileExtension to "." & GetFileExtension(fileName)
	set fileName to GetFileNameOnly(fileName)
	if outputFolder is "" or not folderexists(outputFolder) then
		set dedrmFolder to parent_folder
	else
		set dedrmFolder to outputFolder
	end if
	set pmlFile to dedrmFolder & fileName & "_Source:" & fileName & ".pml"
	set clearFile to dedrmFolder & fileName & "_Source:" & fileName & ".pdb"
	set clearFileNew to dedrmFolder & fileName & "_Source:" & fileName & "_nodrm.pdb"
	set clearFileNewName to fileName & "_nodrm.pdb"
	set sourcePath to POSIX path of file dedrmFolder & fileName & "_Source/"
	set pmlzFilePath to POSIX path of file dedrmFolder & fileName & "_nodrm.pmlz"
	if length of GeteReaderKeystring() is 0 then
		GeteReaderKeys("DeDRM Configure for eReader")
	end if
	set shellresult to "Error: No eReader keys supplied. Can't decrypt."
	repeat with BNKey in bnKeys
		set encryptionName to first item of BNKey
		set encryptionNumber to second item of BNKey
		if length of encryptionName > 0 and length of encryptionNumber > 0 then
			set shellcommand to python & (quoted form of eReaderTool) & " " & (quoted form of encryptedFilePath) & " " & (quoted form of sourcePath) & " " & (quoted form of encryptionName) & " " & (quoted form of encryptionNumber)
			set shellcommand to shellcommand & " > " & quotedtemppath()
			--display dialog "shellcommand: " & shellcommand buttons {"OK"} default button 1 giving up after 10
			writetolog("shellcommand: " & shellcommand)
			set shellresult to "no result"
			cleartemp()
			set DecodingError to false
			set ErrorText to ""
			try
				do shell script shellcommand
			on error ErrorText
				set DecodingError to true
			end try
			set shellresult to readtemp()
			writetolog("shellresult: " & shellresult & " " & ErrorText)
			--display dialog shellresult
			if not DecodingError then
				-- try to run dropbook and move compiled book to same folder as encrypted book
				try
					try
						tell application "Finder" to set DropBook to (application file id "PPDr") as string
					on error
						error "Couldn't find DropBook application"
					end try
					-- now also compile back up into pdb file using DropBook if it's on this system
					tell application DropBook to open file pmlFile
					delay 1 -- probably don't need this, but just in case.
					tell application DropBook to quit -- DropBook will quit only after the compilation has happened
					try
						tell application "Finder"
							set name of file clearFile to clearFileNewName
							move clearFileNew to dedrmFolder
						end tell
					on error errmsg
						error "DropBook failed to compile the source folder into a pdb file."
					end try
				on error errmsg
					set WarningCount to WarningCount + 1
					set WarningList to (WarningList & fileName & fileExtension & " couldn't be compiled back to pdb:
" & errmsg as text) & "
"
				end try
				-- try to compress source folder contensts to a pmlz file for easy import into Calibre
				try
					set shellcommand to "cd " & quoted form of sourcePath & "; zip -r " & quoted form of pmlzFilePath & " *"
					--display dialog shellcommand
					writetolog("shellcommand: " & shellcommand)
					set zipshellresult to ""
					set zipshellresult to do shell script shellcommand
					writetolog("shellresult: " & zipshellresult)
					--display dialog zipshellresult
					tell application "Finder"
						-- move source folder to the trash
						move dedrmFolder & fileName & "_Source" to trash
					end tell
				on error errmsg
					set WarningCount to WarningCount + 1
					set WarningList to (WarningList & fileName & fileExtension & "source folder couldn't be compressed to pmlz:
" & errmsg as text) & "

"
				end try
				-- we've done the decrypting so exit the loop.
				exit repeat
			end if
		end if
	end repeat
	try
		if (offset of "incorrect eReader version 10" in shellresult) > 0 then
			set WarningCount to WarningCount + 1
			set WarningList to WarningList & fileName & fileExtension & " is not encrypted.
"
		else if DecodingError then
			set ErrorCount to ErrorCount + 1
			set ErrorList to (ErrorList & fileName & fileExtension & " couldn't be decoded:
" & ErrorText as text) & "
"
		else
			set CompletedCount to CompletedCount + 1
			set CompletedList to CompletedList & fileName & fileExtension & paraend
		end if
	end try
end unlockpdbfile

on unlockepubfile(encryptedFile)
	set encryptedFilePath to POSIX path of file encryptedFile
	tell application "Finder"
		set parent_folder to (container of file encryptedFile) as text
		set fileName to (name of file encryptedFile) as text
	end tell
	set fileExtension to "." & GetFileExtension(fileName)
	set fileName to GetFileNameOnly(fileName)
	
	set decoded to false
	-- first we must fix any possible zip problems with the epub
	if outputFolder is "" or not folderexists(outputFolder) then
		set fixedFilePath to POSIX path of file (parent_folder & fileName & "_fixed" & fileExtension)
	else
		set fixedFilePath to POSIX path of file (outputFolder & fileName & "_fixed" & fileExtension)
	end if
	set shellcommand to python & (quoted form of ZipFixTool) & " " & (quoted form of encryptedFilePath) & " " & (quoted form of fixedFilePath)
	set shellcommand to shellcommand & " > " & quotedtemppath()
	writetolog("shellcommand: " & shellcommand)
	cleartemp()
	set ZipErrorText to ""
	set ZipFixError to false
	try
		--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
		do shell script shellcommand
	on error errmsg
		set ZipErrorText to errmsg
		set ZipFixError to true
	end try
	set shellresult to readtemp()
	writetolog("shellresult: " & shellresult & " " & ZipErrorText)
	--display dialog shellresult
	
	if ZipFixError then
		set ErrorCount to ErrorCount + 1
		set ErrorList to ((ErrorList & fileName & fileExtension & " had a problem with ZipFix:
" & ZipErrorText as text) & "
")
		return
	end if
	
	--check it's an ePub file.
	set ePubSig to "NOT_ePub"
	try
		set ePubSig to read POSIX file fixedFilePath from 31 for 28
	end try
	--display dialog ePubSig
	if ePubSig is not "mimetypeapplication/epub+zip" then
		set ErrorCount to ErrorCount + 1
		set ErrorList to ErrorList & encryptedFile & " is not an ePub file.
"
		tell application "Finder"
			move alias ((POSIX file fixedFilePath) as text) to trash
		end tell
		return
	end if
	
	if outputFolder is "" or not folderexists(outputFolder) then
		set unlockedFilePath to POSIX path of file (parent_folder & fileName & "_nodrm" & fileExtension)
	else
		set unlockedFilePath to POSIX path of file (outputFolder & fileName & "_nodrm" & fileExtension)
	end if
	set shellresult to "no keys"
	set ErrorText to ""
	
	-- get encryption type
	set TryBandNePub to true
	set TryAdobeePub to true
	set shellcommand to python & (quoted form of ePubTestTool) & " " & (quoted form of fixedFilePath)
	set shellcommand to shellcommand & " > " & quotedtemppath()
	--display dialog "shellcommand: " & shellcommand buttons {"OK"} default button 1 giving up after 10
	writetolog("shellcommand: " & shellcommand)
	cleartemp()
	set TestError to false
	set ErrorText to ""
	try
		do shell script shellcommand
	on error ErrorText
		set TestError to true
	end try
	set shellresult to readtemp()
	writetolog("shellresult: " & shellresult & " " & ErrorText)
	--display dialog shellresult
	if not TestError then
		if (offset of "B&N" in shellresult) > 0 then
			set TryAdobeePub to false
		else if (offset of "Adobe" in shellresult) > 0 then
			set TryBandNePub to false
		else if (offset of "Unencrypted" in shellresult) > 0 then
			set TryAdobeePub to false
			set TryBandNePub to false
		end if
	end if
	
	
	-- first we'll try the Barnes & Noble keys
	if TryBandNePub then
		set decoded to decodebandnepub(fixedFilePath, unlockedFilePath, bnKeys)
		if not decoded then
			set newKeyList to GetNookKeys()
			set decoded to decodebandnepub(fixedFilePath, unlockedFilePath, newKeyList)
			if decoded then
				set bnKeys to bnKeys & newKeyList
			end if
		end if
		
	end if
	
	if (not decoded) and TryAdobeePub then
		set decoded to decodeadobeepub(fixedFilePath, unlockedFilePath, AdeptKeyList)
		if not decoded then
			set newKeyList to GetAdeptKeys()
			set decoded to decodeadobeepub(fixedFilePath, unlockedFilePath, newKeyList)
			if decoded then
				set AdeptKeyList to AdeptKeyList & newKeyList
			end if
		end if
	end if
	
	if decoded then
		set CompletedCount to CompletedCount + 1
		set CompletedList to CompletedList & fileName & fileExtension & paraend
	else if not TryAdobeePub and not TryBandNePub then
		set WarningCount to WarningCount + 1
		set WarningList to (WarningList & fileName & " doesn't seem to be encrypted.
")
	else if shellresult is "no keys" then
		set ErrorCount to ErrorCount + 1
		set ErrorList to (ErrorList & fileName & fileExtension & " couldn't be decoded: no keys.
")
	else
		set ErrorCount to ErrorCount + 1
		set ErrorList to ((ErrorList & fileName & fileExtension & " couldn't be decoded:
" & ErrorText as text) & "
")
	end if
	
	tell application "Finder"
		move alias ((POSIX file fixedFilePath) as text) to trash
	end tell
end unlockepubfile

on decodebandnepub(fixedFilePath, unlockedFilePath, keyList)
	set decoded to false
	repeat with BNKey in keyList
		set keyfilepath to third item of BNKey
		if length of keyfilepath > 0 then
			set shellcommand to python & (quoted form of BNePubTool) & " " & (quoted form of keyfilepath) & " " & (quoted form of fixedFilePath) & " " & (quoted form of unlockedFilePath)
			set shellcommand to shellcommand & " > " & quotedtemppath()
			--display dialog "shellcommand: " & shellcommand buttons {"OK"} default button 1 giving up after 10
			writetolog("shellcommand: " & shellcommand)
			cleartemp()
			set DecodingError to false
			set ErrorText to ""
			try
				do shell script shellcommand
			on error ErrorText
				set DecodingError to true
			end try
			set shellresult to readtemp()
			writetolog("shellresult: " & shellresult & " " & ErrorText)
			--display dialog shellresult
			if not DecodingError then
				set decoded to true
				exit repeat
			end if
		end if
	end repeat
	return decoded
end decodebandnepub

on decodeadobeepub(fixedFilePath, unlockedFilePath, keyList)
	set decoded to false
	repeat with AdeptKey in keyList
		set shellcommand to python & (quoted form of AdobeePubTool) & " " & (quoted form of AdeptKey) & " " & (quoted form of fixedFilePath) & " " & (quoted form of unlockedFilePath)
		set shellcommand to shellcommand & " > " & quotedtemppath()
		--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
		writetolog("shellcommand: " & shellcommand)
		cleartemp()
		set DecodingError to false
		set ErrorText to ""
		try
			do shell script shellcommand
		on error ErrorText
			set DecodingError to true
		end try
		set shellresult to readtemp() as text
		writetolog("shellresult: " & shellresult & " " & ErrorText)
		--display dialog shellresult
		if not DecodingError then
			set decoded to true
			exit repeat
		end if
	end repeat
	return decoded
end decodeadobeepub


on unlockpdffile(encryptedFile)
	--check it's an ePub file.
	set PDFSig to "NOT_PDF"
	try
		set PDFSig to read file encryptedFile from 1 for 4
	end try
	--display dialog PDFSig
	if PDFSig is not "%PDF" then
		set ErrorCount to ErrorCount + 1
		set ErrorList to ErrorList & encryptedFile & " is not a PDF file.
"
		return
	end if
	set encryptedFilePath to POSIX path of file encryptedFile
	tell application "Finder"
		set parent_folder to (container of file encryptedFile) as text
		set fileName to (name of file encryptedFile) as text
	end tell
	set fileExtension to "." & GetFileExtension(fileName)
	set fileName to GetFileNameOnly(fileName)
	
	set decoded to "NO"
	-- first we must check we have a PDF script
	if not fileexists(AdobePDFTool) then
		set ErrorCount to ErrorCount + 1
		set ErrorList to ErrorList & encryptedFile & " is a PDF file and no ineptpdf script found.
"
		return
	end if
	
	if outputFolder is "" or not folderexists(outputFolder) then
		set unlockedFilePath to POSIX path of file (parent_folder & fileName & "_nodrm" & fileExtension)
	else
		set unlockedFilePath to POSIX path of file (outputFolder & fileName & "_nodrm" & fileExtension)
	end if
	set decoded to false
	set shellresult to "no keys"
	set ErrorText to ""
	
	repeat with AdeptKey in AdeptKeyList
		set shellcommand to python & (quoted form of AdobePDFTool) & " " & (quoted form of AdeptKey) & " " & (quoted form of encryptedFilePath) & " " & (quoted form of unlockedFilePath)
		set shellcommand to shellcommand & " > " & quotedtemppath()
		--display dialog "shellcommand: " default answer shellcommand buttons {"OK"} default button 1 giving up after 10
		writetolog("shellcommand: " & shellcommand)
		cleartemp()
		set DecodingError to false
		set ErrorText to ""
		try
			do shell script shellcommand
		on error ErrorText
			set DecodingError to true
		end try
		set shellresult to readtemp()
		writetolog("shellresult: " & shellresult & " " & ErrorText)
		--display dialog shellresult
		if not DecodingError then
			set decoded to true
			exit repeat
		end if
	end repeat
	
	if decoded then
		set CompletedCount to CompletedCount + 1
		set CompletedList to CompletedList & fileName & fileExtension & paraend
	else if shellresult is "no keys" then
		set ErrorCount to ErrorCount + 1
		set ErrorList to (ErrorList & fileName & fileExtension & " couldn't be decoded: no keys.
")
	else
		set ErrorCount to ErrorCount + 1
		set ErrorList to ((ErrorList & fileName & fileExtension & " couldn't be decoded:
" & ErrorText as text) & "
")
	end if
end unlockpdffile

on handlefile(droppedFile)
	tell application "Finder"
		set fileName to (name of file droppedFile) as text
	end tell
	writetolog("Processing file: " & fileName)
	set fileExtension to GetFileExtension(fileName)
	set fileName to GetFileNameOnly(fileName)
	if fileExtension is "prc" or fileExtension is "mobi" or fileExtension is "pobi" or fileExtension is "azw" or fileExtension is "azw1" or fileExtension is "tpz" or fileExtension is "azw3" or fileExtension is "azw4" then
		set completedebooks to completedebooks + 1
		IncProgress(fileName, completedebooks)
		unlockmobifile(droppedFile as text)
	else if fileExtension is "pdb" then
		set completedebooks to completedebooks + 1
		IncProgress(fileName, completedebooks)
		unlockpdbfile(droppedFile as text)
	else if fileExtension is "epub" then
		set completedebooks to completedebooks + 1
		IncProgress(fileName, completedebooks)
		unlockepubfile(droppedFile as text)
	else if fileExtension is "pdf" then
		set completedebooks to completedebooks + 1
		IncProgress(fileName, completedebooks)
		unlockpdffile(droppedFile as text)
	end if
end handlefile

on handlefolder(droppedFolder)
	tell application "Finder" to set fileList to (every file in folder droppedFolder)
	tell application "Finder" to set folderList to (every folder in folder droppedFolder)
	repeat with this_item in fileList
		if not ProgressActive() then
			exit repeat
		end if
		handlefile(this_item as text)
	end repeat
	repeat with this_item in folderList
		if not ProgressActive() then
			exit repeat
		end if
		handlefolder(this_item as text)
	end repeat
end handlefolder

on countfile(droppedFile)
	tell application "Finder"
		set fileName to (name of file droppedFile) as text
	end tell
	set fileExtension to GetFileExtension(fileName)
	set fileName to GetFileNameOnly(fileName)
	--display dialog "fileName: " & fileName & "
	--extension: " & fileExtension
	if fileExtension is in handledExtensions then
		set totalebooks to totalebooks + 1
	end if
end countfile

on GetSerialstring()
	set Serialstring to ""
	repeat with Serial in KindleSerialList
		if Serialstring is "" then
			set Serialstring to Serial
		else
			set Serialstring to Serialstring & "," & Serial
		end if
	end repeat
	return Serialstring
end GetSerialstring

on GetPIDstring()
	set PIDstring to ""
	repeat with PID in PIDs
		if PIDstring is "" then
			set PIDstring to PID
		else
			set PIDstring to PIDstring & "," & PID
		end if
	end repeat
	return PIDstring
end GetPIDstring

on GetUDIDstring()
	set UDIDstring to ""
	repeat with UDIDPair in UDIDs
		if UDIDstring is "" then
			set UDIDstring to first item of UDIDPair
		else
			set UDIDstring to UDIDstring & "," & first item of UDIDPair
		end if
	end repeat
	return UDIDstring
end GetUDIDstring

on GetUDIDPIDs()
	set UDIDPIDs to ""
	repeat with UDIDPair in UDIDs
		if UDIDPIDs is "" then
			set UDIDPIDs to second item of UDIDPair
		else
			set UDIDPIDs to UDIDPIDs & "," & second item of UDIDPair
		end if
	end repeat
	return UDIDPIDs
end GetUDIDPIDs

on GetAdeptstring()
	set Adeptstring to ""
	repeat with AdeptKeyFile in AdeptKeyList
		set AppleTypeFile to POSIX file (AdeptKeyFile as text)
		tell application "Finder"
			set fileName to name of file (AppleTypeFile as text)
		end tell
		
		if Adeptstring is "" then
			set Adeptstring to fileName
		else
			set Adeptstring to Adeptstring & "
" & fileName
		end if
	end repeat
	return Adeptstring
end GetAdeptstring

on GetAndroidstring()
	set Androidstring to ""
	repeat with AndroidKeyFile in AndroidKeyList
		set AppleTypeFile to POSIX file (AndroidKeyFile as text)
		tell application "Finder"
			set fileName to name of file (AppleTypeFile as text)
		end tell
		
		if Androidstring is "" then
			set Androidstring to fileName
		else
			set Androidstring to Androidstring & "
" & fileName
		end if
	end repeat
	return Androidstring
end GetAndroidstring

on GetKindlestring()
	set Kindlestring to ""
	repeat with KindleKeyFile in KindleKeyList
		set AppleTypeFile to POSIX file (KindleKeyFile as text)
		tell application "Finder"
			set fileName to name of file (AppleTypeFile as text)
		end tell
		
		if Kindlestring is "" then
			set Kindlestring to fileName
		else
			set Kindlestring to Kindlestring & "
" & fileName
		end if
	end repeat
	return Kindlestring
end GetKindlestring

on GeteReaderKeystring()
	set Keystring to ""
	repeat with key in bnKeys
		if length of first item of key > 0 and length of second item of key > 0 then
			if Keystring is "" then
				set Keystring to first item of key & ":" & second item of key
			else
				set Keystring to Keystring & "
" & first item of key & ":" & second item of key
			end if
		end if
	end repeat
	return Keystring
end GeteReaderKeystring

on GetBNKeystring()
	set BNKeystring to ""
	repeat with BNKey in bnKeys
		if (length of BNKey > 2) and ((length of (third item of BNKey)) > 0) then
			if BNKeystring is "" then
				set BNKeystring to first item of BNKey
			else
				set BNKeystring to BNKeystring & "
" & first item of BNKey
			end if
		end if
	end repeat
	return BNKeystring
end GetBNKeystring

on DeleteeReaderKeys()
	set newKeys to {}
	repeat with BNKey in bnKeys
		if length of third item of BNKey > 0 then
			
			set newKeys to newKeys & {{first item of BNKey, "", third item of BNKey}}
		end if
	end repeat
	set bnKeys to newKeys
end DeleteeReaderKeys

on DeleteBNKeys()
	set newKeys to {}
	repeat with BNKey in bnKeys
		if length of second item of BNKey > 0 then
			
			set newKeys to newKeys & {{first item of BNKey, second item of BNKey, ""}}
		end if
	end repeat
	set bnKeys to newKeys
end DeleteBNKeys


on GetUDIDs(DialogTitle)
	set UDID to ""
	repeat
		set UDIDstring to GetUDIDstring()
		if UDIDstring is "" then
			set DialogPrompt to "Enter any iPod/iPhone/iPad UDIDs (40 characters) one at a time. Note: This only works for older versions of Kindle for iOS."
			set FinishedButton to "Close"
		else
			set DialogPrompt to "Current UDIDs: " & UDIDstring & ".

Enter any additional iPod/iPhone/iPad UDIDs (40 characters) one at a time:"
			set FinishedButton to "Close"
		end if
		set dialogresult to (display dialog DialogPrompt default answer UDID buttons {"Delete All", "Add", FinishedButton} with title DialogTitle default button 2)
		if button returned of dialogresult is "Add" then
			set UDID to text returned of dialogresult
			set UDIDlength to length of UDID
			if UDIDlength is 40 then
				set shellresult to ""
				set scriptError to ""
				set shellcommand to python & (quoted form of KindlePIDTool) & " " & (quoted form of UDID)
				writetolog("shellcommand: " & shellcommand)
				try
					set shellresult to do shell script shellcommand
				on error errmsg
					set shellresult to ""
					set scriptError to "KindlePID Script failed:" & " " & errmsg
				end try
				writetolog("shellresult: " & scriptError & " " & shellresult)
				--display dialog shellresult
				
				if shellresult is not "" then
					set PID to (text -10 thru -1 of shellresult)
					if UDIDs contains {{UDID, PID}} then
						display dialog "UDID " & UDID & " is already in your list of UDIDs." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
					else
						display dialog "The equivalent UDID for UDID " & UDID & " is " & PID & ". Adding to list." buttons {"OK"} default button 1 with title "DeDRM" with icon note
						set UDIDs to UDIDs & {{UDID, PID}}
						set UDID to ""
					end if
				else
					writetolog(scriptError)
					display dialog "Error generating PID from this UDID, error message was: " & scriptError buttons {"OK"} default button 1 with title "DeDRM" with icon caution
				end if
			else
				display dialog "UDIDs must be 40 characters." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
			end if
		else if button returned of dialogresult is "Delete All" then
			if UDIDstring is not "" then
				try
					set dialogresult to (display dialog "Are you sure you want to delete all stored UDIDs?" buttons {"Cancel", "Delete"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Delete" then
					set UDIDs to {}
				end if
			end if
		else
			set UDID to text returned of dialogresult
			if UDID is not "" then
				try
					set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Yes, Move on" then
					exit repeat
				end if
			else
				exit repeat
			end if
		end if
	end repeat
end GetUDIDs

on GetPIDs(DialogTitle)
	set PID to ""
	repeat
		set PIDstring to GetPIDstring()
		if PIDstring is "" then
			set DialogPrompt to "Enter any Mobipocket PIDs one at a time:"
			set FinishedButton to "Close"
		else
			set DialogPrompt to "Current PIDs: " & PIDstring & ".

Enter any additional Mobipocket PIDs one at a time:"
			set FinishedButton to "Close"
		end if
		set dialogresult to (display dialog DialogPrompt default answer PID buttons {"Delete All", "Add", FinishedButton} with title DialogTitle default button 2)
		if button returned of dialogresult is "Add" then
			set PID to text returned of dialogresult
			set PIDlength to length of PID
			if PIDlength is 8 or PIDlength is 10 then
				if PIDs contains PID then
					display dialog "PID" & PID & " is already in your list of PIDs." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
				else
					set PIDs to PIDs & PID
					set PID to ""
				end if
			else
				display dialog "PIDs must be 8 or 10 characters long, and UDIDs must be 40 characters." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
			end if
		else if button returned of dialogresult is "Delete All" then
			if PIDstring is not "" then
				try
					set dialogresult to (display dialog "Are you sure you want to delete all stored PIDs?" buttons {"Cancel", "Delete"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Delete" then
					set PIDs to {}
				end if
			end if
		else
			set PID to text returned of dialogresult
			if PID is not "" then
				try
					set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Yes, Move on" then
					exit repeat
				end if
			else
				exit repeat
			end if
		end if
	end repeat
end GetPIDs

on GetSerials(DialogTitle)
	set Serial to ""
	repeat
		set Serialstring to GetSerialstring()
		if Serialstring is "" then
			set DialogPrompt to "Enter any Kindle (not Kindle Fire) Serial Numbers one at a time:"
			set FinishedButton to "Close"
		else
			set DialogPrompt to "Current Kindle Serial Numbers: " & Serialstring & ".

Enter any additional Kindle (not Kindle Fire) Serial Numbers one at a time:"
			set FinishedButton to "Close"
		end if
		set dialogresult to (display dialog DialogPrompt default answer Serial buttons {"Delete All", "Add", FinishedButton} with title DialogTitle default button 2)
		if button returned of dialogresult is "Add" then
			set Serial to text returned of dialogresult
			set Seriallength to length of Serial
			if Seriallength is 16 then
				set KindleSerialList to KindleSerialList & Serial
				set Serial to ""
			else
				display dialog "Kindle Serial Numbers are 16 characters long." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
			end if
		else if button returned of dialogresult is "Delete All" then
			if Serialstring is not "" then
				try
					set dialogresult to (display dialog "Are you sure you want to delete all stored Kindle Serial Numbers?" buttons {"Cancel", "Delete"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Delete" then
					set KindleSerialList to {}
				end if
			end if
		else
			set Serial to text returned of dialogresult
			if Serial is not "" then
				try
					set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Yes, Move on" then
					exit repeat
				end if
			else
				exit repeat
			end if
		end if
	end repeat
end GetSerials

on GetOutputFolder(DialogTitle)
	set newFolder to ""
	try
		tell me to activate
		repeat
			
			if folderexists(outputFolder) then
				set DialogPrompt to "The deDRMed ebooks will be saved to the following folder:
" & (outputFolder) & "

"
			else
				set outputFolder to ""
				set DialogPrompt to "The deDRMed ebooks will be saved in the same folder as the original DRMed ebooks.

"
			end if
			set DialogPrompt to DialogPrompt & "To keep this choice, click 'Close', otherwise select the option you want by clicking on one of the other buttons."
			set dialogresult to (display dialog DialogPrompt buttons {"Use Same Folder as DRMed Ebooks", "Choose Output Folder…", "Close"} with title DialogTitle default button 3)
			if button returned of dialogresult is "Choose Output Folder…" then
				try
					if outputFolder is "" then
						set outputFolder to ((choose folder with prompt "DRM Application
Please choose the Output Folder for DeDRMed ebooks.") as text)
					else
						set outputFolder to ((choose folder with prompt "DRM Application
Please choose the Output Folder for DeDRMed ebooks." default location alias outputFolder) as text)
					end if
				end try
			else if button returned of dialogresult is "Use Same Folder as DRMed Ebooks" then
				set outputFolder to ""
			else
				exit repeat
			end if
			--on error errormessage
			--	display dialog errormessage
		end repeat
	end try
	WritePrefs()
end GetOutputFolder

on GeteReaderKeys(DialogTitle)
	set keyText to ""
	repeat
		set Keystring to GeteReaderKeystring()
		if Keystring is "" then
			set DialogPrompt to "Please enter any "
			set FinishedButton to "Close"
		else
			set DialogPrompt to "eReader keys:
" & Keystring & "


Please enter any additional "
			set FinishedButton to "Close"
		end if
		set DialogPrompt to DialogPrompt & "eReader Name,Number key pairs one at a time. The name is usually your name as on your credit card, but might be your user name. Only the last 8 digits of the Number are needed. If you enter more digits, only the last eight will be stored or displayed. Please separate the name and number with a colon (:) and click \"Add\"."
		set dialogresult to (display dialog DialogPrompt default answer keyText with title DialogTitle buttons {"Delete All", "Add", FinishedButton} default button 2)
		if button returned of dialogresult is "Add" then
			set keyText to text returned of dialogresult
			if not (keyText contains ":") then
				display dialog "Name and Number must be separated by a colon (:)." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
			else
				set oldTIDs to AppleScript's text item delimiters
				set AppleScript's text item delimiters to ":"
				set keyNumber to the last text item of keyText
				set keyName to (text items 1 through -2 of keyText) as string
				set AppleScript's text item delimiters to oldTIDs
				
				if ((length of keyNumber) = 16 or (length of keyNumber) = 15 or (length of keyNumber) = 8) and (length of keyName) > 0 then
					set bnKeys to bnKeys & {{keyName, (text -8 thru -1 of keyNumber), ""}}
					set keyText to ""
				else
					display dialog "Key numbers must be 8 or 15 or 16 characters long (no spaces) and the key name must not be absent." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
				end if
			end if
		else if button returned of dialogresult is "Delete All" then
			if Keystring is not "" then
				try
					set dialogresult to (display dialog "Are you sure you want to delete all stored Name:Number key pairs?" buttons {"Cancel", "Delete"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Delete" then
					DeleteeReaderKeys()
					GetNookKey()
				end if
			end if
			set keyText to ""
		else
			set keyText to text returned of dialogresult
			if keyText is not "" then
				try
					set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Yes, Move on" then
					exit repeat
				end if
			else
				exit repeat
			end if
		end if
	end repeat
end GeteReaderKeys

on GetBNKeys(DialogTitle)
	set bnKeyText to ""
	repeat
		set BNKeystring to GetBNKeystring()
		if BNKeystring is "" then
			set DialogPrompt to "Please enter any "
			set FinishedButton to "Close"
		else
			set DialogPrompt to "Current B&N/Nook keys:
" & BNKeystring & "


Please enter any additional "
			set FinishedButton to "Close"
		end if
		set DialogPrompt to DialogPrompt & "Barnes & Noble/Nook account email addresses and passwords one at a time.  Please separate the address and password with a colon (:)and click \"Add\".  Note that your account password will only be used to retrieve the key and will not be stored.
		
*** Retrieving the account key may take a couple of minutes, please be patient. ***

Or to add a an already generated .b64 file, just click \"Add\" with nothing in the text field."
		set dialogresult to (display dialog DialogPrompt default answer bnKeyText with title DialogTitle buttons {"Forget All", "Add", FinishedButton} default button 2)
		if button returned of dialogresult is "Add" then
			set bnKeyText to text returned of dialogresult
			if bnKeyText is "" then
				try
					set newFile to (choose file with prompt "Please select a Barnes & Noble (.b64) key file") as text
					-- copy to prefs
					AddbnKey(newFile)
				on error message
					if message does not contain "cancel" then
						display dialog message
					end if
				end try
			else if not (bnKeyText contains ":") then
				display dialog "Email address and password must be separated by a colon (:)." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
			else
				set oldTIDs to AppleScript's text item delimiters
				set AppleScript's text item delimiters to ":"
				set keyEmail to the first text item of bnKeyText
				set keyPassword to (text items 2 through -1 of bnKeyText) as string
				set AppleScript's text item delimiters to oldTIDs
				
				if (keyEmail contains "@") and (length of keyPassword) > 0 then
					-- get the B&N key from this pair
					set shellresult to ""
					set scriptError to ""
					set success to true
	set userPrefsPath to path to preferences from user domain as string
	set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
	if not folderexists(preferencesFolderPath) then
		tell application "Finder"
			set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
		end tell
	end if
					set keyfileName to GetUniqueName(preferencesFolderPath, keyEmail & ".b64")
					set keyfilepath to POSIX path of (preferencesFolderPath & keyfileName)
					set shellcommand to python & (quoted form of BNKeyFetchTool) & " " & (quoted form of keyEmail) & " " & (quoted form of keyPassword) & " " & quoted form of keyfilepath
					set shellcommand to shellcommand & " > " & quotedtemppath()
					
					writetolog("shellcommand: " & shellcommand)
					cleartemp()
					try
						do shell script shellcommand
					on error scriptError
						set success to false
					end try
					set shellresult to readtemp()
					writetolog("shellresult: " & scriptError & " " & shellresult)
					--display dialog shellresult
					if success then
						set bnKeys to bnKeys & {{keyEmail, "", keyfilepath}}
						set bnKeyText to ""
					else
						display dialog "Error generating key from this info, error message was: " & scriptError buttons {"OK"} default button 1 with title "DeDRM" with icon caution
					end if
				else
					display dialog "Key numbers must be 8 or 15 or 16 characters long (no spaces) and the key name must not be absent." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
				end if
			end if
		else if button returned of dialogresult is "Forget All" then
			if BNKeystring is not "" then
				try
					set dialogresult to (display dialog "Are you sure you want to forget all stored Barnes & Noble/Nook keys?" buttons {"Cancel", "Forget"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Forget" then
					DeleteBNKeys()
				end if
			end if
			set bnKeyText to ""
		else
			set bnKeyText to text returned of dialogresult
			if bnKeyText is not "" then
				try
					set dialogresult to (display dialog "You entered some text, but didn't click Add. Are you sure you want to more on to the next dialog?" buttons {"Whoops", "Yes, Move on"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Yes, Move on" then
					exit repeat
				end if
			else
				exit repeat
			end if
		end if
	end repeat
end GetBNKeys

on GetAdeptKeyFiles(DialogTitle)
	repeat
		set Adeptstring to GetAdeptstring()
		if Adeptstring is "" then
			set DialogPrompt to "To add Adobe Digital Editions (Adept) key files, click the Add… button. "
			set dialogresult to (display dialog DialogPrompt buttons {"Add…", "Close"} with title DialogTitle default button 1)
		else
			set DialogPrompt to "Current Adobe Digital Editions (Adept) key files:
" & Adeptstring & "

To add extra key files (.der), click the Add… button."
			set dialogresult to (display dialog DialogPrompt buttons {"Forget All", "Add…", "Close"} with title DialogTitle default button 2)
		end if
		if button returned of dialogresult is "Add…" then
			try
				set newFile to (choose file with prompt "Please select an Adobe Digital Editions (.der) key file") as text
				-- copy to prefs
				AddAdeptKey(newFile)
			on error message
				if message does not contain "cancel" then
					display dialog message
				end if
			end try
			
		else if button returned of dialogresult is "Forget All" then
			try
				set dialogresult to (display dialog "Are you sure you want to forget all extra Adobe Digital Editions Adept key files?" buttons {"Cancel", "Forget"} default button 1 with title "DeDRM")
			end try
			if button returned of dialogresult is "Forget" then
				set AdeptKeyList to {}
			end if
		else
			exit repeat
		end if
	end repeat
end GetAdeptKeyFiles

on GetKindleKeyFiles(DialogTitle)
	repeat
		set Kindlestring to GetKindlestring()
		if Kindlestring is "" then
			set DialogPrompt to "To add Kindle for Mac key files (.k4i), click the Add… button. "
			set FinishedButton to "Close"
		else
			set DialogPrompt to "Current Kindle for Mac key files:
" & Kindlestring & "

To add extra key files (.k4i), click the Add… button."
			set FinishedButton to "Close"
		end if
		set dialogresult to (display dialog DialogPrompt buttons {"Forget All", "Add…", FinishedButton} with title DialogTitle default button 2)
		if button returned of dialogresult is "Add…" then
			try
				set newFile to (choose file with prompt "Please select a Kindle for Mac/PC (.k4i) key file") as text
				-- copy to prefs
				AddKindleKey(newFile)
			on error message
				if message does not contain "cancel" then
					display dialog message
				end if
			end try
			
		else if button returned of dialogresult is "Forget All" then
			if Kindlestring is not "" then
				try
					set dialogresult to (display dialog "Are you sure you want to forget all extra Kindle for Mac key files?" buttons {"Cancel", "Forget"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Forget" then
					set KindleKeyList to {}
				end if
			end if
		else
			exit repeat
		end if
	end repeat
end GetKindleKeyFiles

on GetAndroidKeyFiles(DialogTitle)
	repeat
		set Androidstring to GetAndroidstring()
		if Androidstring is "" then
			set DialogPrompt to "To add Kindle for Android backup files (.ab), click the Add… button. "
			set FinishedButton to "Close"
		else
			set DialogPrompt to "Current Kindle for Android backup files:
" & Androidstring & "

To add extra backup files (.ab), click the Add… button."
			set FinishedButton to "Close"
		end if
		set dialogresult to (display dialog DialogPrompt buttons {"Forget All", "Add…", FinishedButton} with title DialogTitle default button 2)
		if button returned of dialogresult is "Add…" then
			try
				set newFile to (choose file with prompt "Please select a Kindle for Android backup (.ab) file") as text
				-- copy to prefs
				AddAndroidKey(newFile)
			on error message
				if message does not contain "cancel" then
					display dialog message
				end if
			end try
			
		else if button returned of dialogresult is "Forget All" then
			if Androidstring is not "" then
				try
					set dialogresult to (display dialog "Are you sure you want to forget all Kindle for Android backup files?" buttons {"Cancel", "Forget"} default button 1 with title "DeDRM")
				end try
				if button returned of dialogresult is "Forget" then
					set AndroidKeyList to {}
				end if
			end if
		else
			exit repeat
		end if
	end repeat
end GetAndroidKeyFiles


on GetAdeptKeys()
	set newKeyList to {}
	set userPrefsPath to path to preferences from user domain as string
	set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
	if not folderexists(preferencesFolderPath) then
		tell application "Finder"
			set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
		end tell
	end if
	set newKeysFolderPath to preferencesFolderPath & newKeysFolderName & ":"
	if not folderexists(newKeysFolderPath) then
		tell application "Finder"
			set newKeysFolder to make new folder at preferencesFolderPath with properties {name:newKeysFolderName}
		end tell
	end if
	set scriptError to ""
	set shellresult to ""
	set success to true
	set shellcommand to python & (quoted form of AdobeKeyGenTool) & " " & quoted form of (POSIX path of (newKeysFolderPath))
	set shellcommand to shellcommand & " > " & quotedtemppath()
	writetolog("shellcommand: " & shellcommand)
	cleartemp()
	try
		do shell script shellcommand
	on error scriptError
		set success to false
	end try
	set shellresult to readtemp()
	writetolog("shellresult: " & shellresult & " " & scriptError)
	--display dialog shellresult
	if success then
		--get all the files from newKeysFolder and add those that aren't duplicates
		tell application "Finder" to set fileList to (every file in folder newKeysFolderPath)
		repeat with this_item in fileList
			set userAdeptKeyPath to this_item as text
			set dupfile to false
			repeat with AdeptKey in AdeptKeyList
				set shellcommand to "cmp -s " & (quoted form of AdeptKey) & " " & quoted form of (POSIX path of (userAdeptKeyPath))
				try
					--writetolog("shellcommand: " & shellcommand)
					do shell script shellcommand
					-- shellcommand will error on the files being different
					--writetolog("result: duplicate")
					
					set dupfile to true
					exit repeat
				on error scriptError
					--writetolog("result: different")
					-- do nothing
				end try
			end repeat
			if not dupfile then
				repeat with AdeptKey in newKeyList
					set shellcommand to "cmp -s " & (quoted form of AdeptKey) & " " & quoted form of (POSIX path of (userAdeptKeyPath))
					try
						--writetolog("shellcommand: " & shellcommand)
						do shell script shellcommand
						-- shellcommand will error on the files being different
						--writetolog("result: duplicate")
						
						set dupfile to true
						exit repeat
					on error scriptError
						--writetolog("result: different")
						-- do nothing
					end try
				end repeat
			end if
			if not dupfile then
				-- move to the preferences folder, making sure the name's unique
				set newFilename to GetUniqueName(preferencesFolderPath, "AdobeKey.der")
				tell application "Finder"
					set name of file userAdeptKeyPath to newFilename
					set userAdeptKeyPath to newKeysFolderPath & newFilename
					move file userAdeptKeyPath to preferencesFolderPath with replacing
				end tell
				set newKeyList to newKeyList & (POSIX path of (preferencesFolderPath & newFilename))
			end if
		end repeat
	end if
	-- delete new keys folder
	tell application "Finder" to move newKeysFolderPath to trash
	--display dialog newKeyList as text
	return newKeyList
end GetAdeptKeys

on GetKindleKeys()
	set newKeyList to {}
	set userPrefsPath to path to preferences from user domain as string
	set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
	if not folderexists(preferencesFolderPath) then
		tell application "Finder"
			set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
		end tell
	end if
	set newKeysFolderPath to preferencesFolderPath & newKeysFolderName & ":"
	if not folderexists(newKeysFolderPath) then
		tell application "Finder"
			set newKeysFolder to make new folder at preferencesFolderPath with properties {name:newKeysFolderName}
		end tell
	end if
	set scriptError to ""
	set shellresult to ""
	set success to true
	set shellcommand to python & (quoted form of KindleKeyTool) & " " & quoted form of (POSIX path of (newKeysFolderPath))
	set shellcommand to shellcommand & " > " & quotedtemppath()
	writetolog("shellcommand: " & shellcommand)
	cleartemp()
	try
		do shell script shellcommand
	on error scriptError
		set success to false
	end try
	set shellresult to readtemp()
	writetolog("shellresult: " & shellresult & " " & scriptError)
	--display dialog shellresult
	if success then
		--get all the files from newKeysFolder and add those that aren't duplicates
		tell application "Finder" to set fileList to (every file in folder newKeysFolderPath)
		repeat with this_item in fileList
			set userKeyPath to this_item as text
			set dupfile to false
			repeat with key in KindleKeyList
				set shellcommand to "cmp -s " & (quoted form of key) & " " & quoted form of (POSIX path of (userKeyPath))
				try
					--writetolog("shellcommand: " & shellcommand)
					do shell script shellcommand
					-- shellcommand will error on the files being different
					--writetolog("result: duplicate")
					
					set dupfile to true
					exit repeat
				on error scriptError
					--writetolog("result: different")
					-- do nothing
				end try
			end repeat
			if not dupfile then
				repeat with key in newKeyList
					set shellcommand to "cmp -s " & (quoted form of key) & " " & quoted form of (POSIX path of (userKeyPath))
					try
						--writetolog("shellcommand: " & shellcommand)
						do shell script shellcommand
						-- shellcommand will error on the files being different
						--writetolog("result: duplicate")
						
						set dupfile to true
						exit repeat
					on error scriptError
						--writetolog("result: different")
						-- do nothing
					end try
				end repeat
			end if
			if not dupfile then
				-- move to the preferences folder, making sure the name's unique
				set newFilename to GetUniqueName(preferencesFolderPath, "KindleKey.der")
				tell application "Finder"
					set name of file userKeyPath to newFilename
					set userKeyPath to newKeysFolderPath & newFilename
					move file userKeyPath to preferencesFolderPath with replacing
				end tell
				set newKeyList to newKeyList & (POSIX path of (preferencesFolderPath & newFilename))
			end if
		end repeat
	end if
	-- delete new keys folder
	tell application "Finder" to move newKeysFolderPath to trash
	return newKeyList
end GetKindleKeys

on GetNookKeys()
	set newKeyList to {}
	set userPrefsPath to path to preferences from user domain as string
	set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
	if not folderexists(preferencesFolderPath) then
		tell application "Finder"
			set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
		end tell
	end if
	set newKeysFolderPath to preferencesFolderPath & newKeysFolderName & ":"
	if not folderexists(newKeysFolderPath) then
		tell application "Finder"
			set newKeysFolder to make new folder at preferencesFolderPath with properties {name:newKeysFolderName}
		end tell
	end if
	set scriptError to ""
	set shellresult to ""
	set success to true
	set shellcommand to python & (quoted form of NookKeyTool) & " " & quoted form of (POSIX path of (newKeysFolderPath))
	set shellcommand to shellcommand & " > " & quotedtemppath()
	writetolog("shellcommand: " & shellcommand)
	cleartemp()
	try
		do shell script shellcommand
	on error scriptError
		set success to false
	end try
	set shellresult to readtemp()
	writetolog("shellresult: " & shellresult & " " & scriptError)
	--display dialog shellresult
	if success then
		--get all the files from newKeysFolder and add those that aren't duplicates
		tell application "Finder" to set fileList to (every file in folder newKeysFolderPath)
		--display dialog (count of fileList)
		repeat with this_item in fileList
			set userKeyPath to this_item as text
			set dupfile to false
			repeat with key in bnKeys
				set keyfilepath to third item of key
				if length of keyfilepath > 0 then
					set shellcommand to "cmp -s " & (quoted form of keyfilepath) & " " & quoted form of (POSIX path of (userKeyPath))
					try
						--writetolog("shellcommand: " & shellcommand)
						do shell script shellcommand
						-- shellcommand will error on the files being different
						--writetolog("result: duplicate")
						--display dialog "Deuplicate: " & userKeyPath & "//" & keyfilepath
						set dupfile to true
						exit repeat
					on error scriptError
						--writetolog("result: different")
						-- do nothing
					end try
				end if
			end repeat
			if not dupfile then
				repeat with key in newKeyList
					set keyfilepath to third item of key
					if length of keyfilepath > 0 then
						set shellcommand to "cmp -s " & (quoted form of keyfilepath) & " " & quoted form of (POSIX path of (userKeyPath))
						try
							--writetolog("shellcommand: " & shellcommand)
							do shell script shellcommand
							-- shellcommand will error on the files being different
							--writetolog("result: duplicate")
							--display dialog "Deuplicate: " & userKeyPath & "//" & keyfilepath
							set dupfile to true
							exit repeat
						on error scriptError
							--writetolog("result: different")
							-- do nothing
						end try
					end if
				end repeat
			end if
			if not dupfile then
				-- move to the preferences folder, making sure the name's unique
				set newFilename to GetUniqueName(preferencesFolderPath, "Nook Study Key.b64")
				tell application "Finder"
					set name of file userKeyPath to newFilename
					set userKeyPath to newKeysFolderPath & newFilename
					move file userKeyPath to preferencesFolderPath with replacing
				end tell
				set newKeyList to newKeyList & {{newFilename, "", (POSIX path of (preferencesFolderPath & newFilename))}}
			end if
		end repeat
	end if
	-- delete new keys folder
	tell application "Finder" to move newKeysFolderPath to trash
	return newKeyList
end GetNookKeys

on encodeAsBase64(theFilePath)
	set posixfilepath to POSIX path of file theFilePath
	set base64path to POSIX path of file ((path to me as text) & "Contents:Resources:encodebase64.py")
	return do shell script python & quoted form of base64path & " " & quoted form of posixfilepath
end encodeAsBase64

on AddAdeptKey(keyfile)
	set fileExtension to GetFileExtension(keyfile)
	if fileExtension is "der" then
		set newPrefsFile to CopyToPrefs(keyfile)
		set AdeptKeyList to AdeptKeyList & POSIX path of newPrefsFile
	else
		display dialog "Adobe Adept key files generated by adeptkey.py must have a .der extension." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
	end if
end AddAdeptKey

on AddKindleKey(keyfile)
	set fileExtension to GetFileExtension(keyfile)
	if fileExtension is "k4i" then
		set newPrefsFile to CopyToPrefs(keyfile)
		set KindleKeyList to KindleKeyList & POSIX path of newPrefsFile
	else
		display dialog "Kindle key files generated by kindlekey.py must have a .k4i extension." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
	end if
end AddKindleKey

on AddAndroidKey(keyfile)
	set fileExtension to GetFileExtension(keyfile)
	if fileExtension is "ab" or fileExtension is "db" or fileExtension is "xml" then
		set newPrefsFile to CopyToPrefs(keyfile)
		set AndroidKeyList to AndroidKeyList & POSIX path of newPrefsFile
	else
		display dialog "Android back files generated by use of \"adb backup com.amazon.kindle\" must have a .ab extension." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
	end if
end AddAndroidKey

on AddbnKey(keyfile)
	set fileExtension to GetFileExtension(keyfile)
	if fileExtension is "b64" then
		set newPrefsFile to CopyToPrefs(keyfile)
		tell application "Finder"
			set keyfileName to (name of file newPrefsFile) as text
		end tell
		set fileName to GetFileNameOnly(keyfileName)
		set bnKeys to bnKeys & {{fileName, "", POSIX path of newPrefsFile}}
	else
		display dialog "Barnes & Noble key files must have a .b64 extension." buttons {"OK"} default button 1 with title "DeDRM" with icon caution
	end if
end AddbnKey

on GetUniqueName(folderPath, fileName)
	set newFilename to fileName
	if fileexists(folderPath & fileName) then
		-- first find new name that's unique to folder
		set namecount to 2
		set fileExtension to GetFileExtension(fileName)
		set fileNameOnly to GetFileNameOnly(fileName)
		repeat
			set newFilename to fileNameOnly & " " & (namecount as text) & "." & fileExtension
			if not fileexists(folderPath & newFilename) then
				exit repeat
			end if
			set namecount to namecount + 1
		end repeat
	end if
	return newFilename
end GetUniqueName

on CopyToPrefs(keyfilepath)
	tell application "Finder"
		set keyfileName to (name of file keyfilepath) as text
	end tell
	set keyfileApplepath to POSIX file (POSIX path of keyfilepath)
	set userPrefsPath to path to preferences from user domain as string
	set userTempPath to path to temporary items from user domain as string
	set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
	if not folderexists(preferencesFolderPath) then
		tell application "Finder"
			set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
		end tell
	end if
	if fileexists(preferencesFolderPath & keyfileName) then
		-- copy to temporary items folder, rename, and then we can copy from there to the preferences folder
		-- first find new name
		set namecount to 2
		set fileExtension to GetFileExtension(keyfileName)
		set keyfileNameOnly to GetFileNameOnly(keyfileName)
		repeat
			set newkeyfileName to keyfileNameOnly & " " & (namecount as text) & "." & fileExtension
			if not fileexists(preferencesFolderPath & newkeyfileName) and not fileexists(userTempPath & newkeyfileName) then
				exit repeat
			end if
			set namecount to namecount + 1
		end repeat
		-- rename to new name
		set newkeyfilepath to userTempPath & newkeyfileName
		tell application "Finder"
			set tempfilepath to duplicate file keyfileApplepath to folder userTempPath with replacing
			set name of tempfilepath to newkeyfileName
			move file newkeyfilepath to preferencesFolderPath
		end tell
		set newFile to preferencesFolderPath & newkeyfileName
	else
		tell application "Finder"
			set newFile to duplicate file keyfileApplepath to folder preferencesFolderPath with replacing
		end tell
	end if
	
	return newFile as text
end CopyToPrefs

on ReadPrefs()
	-- read any existing keys from the preferences
	set PIDs to {}
	set UDIDs to {}
	set bnKeys to {}
	set KindleKeyList to {}
	set AndroidKeyList to {}
	set KindleSerialList to {}
	set AdeptKeyList to {}
	set outputFolder to (path to desktop as string)
	set logFilePath to (path to desktop as string) & "DeDRM.log"
	set userPrefsPath to path to preferences from user domain as string
	set preferencesFolderPath to userPrefsPath & prefsFolderName & ":"
	if not folderexists(preferencesFolderPath) then
		tell application "Finder"
			set preferencesFolder to make new folder at userPrefsPath with properties {name:prefsFolderName}
		end tell
	end if
	set preferencesFilePath to userPrefsPath & prefsFileName
	set tempfilepath to preferencesFolderPath & tempFileName
	
	if fileexists(POSIX path of file preferencesFilePath) then
		tell application "System Events"
			try
				set PIDs to value of property list item "PIDs" of property list file preferencesFilePath
			end try
			try
				set UDIDs to value of property list item "UDIDs" of property list file preferencesFilePath
			end try
			try
				set KindleSerialList to value of property list item "KindleSerials" of property list file preferencesFilePath
			end try
			try
				set bnKeys to value of property list item "bnKeys" of property list file preferencesFilePath
			end try
			try
				set AdeptKeyList to value of property list item "AdeptKeys" of property list file preferencesFilePath
			end try
			try
				set AndroidKeyList to value of property list item "AndroidKeys" of property list file preferencesFilePath
			end try
			try
				set KindleKeyList to value of property list item "KindleKeys" of property list file preferencesFilePath
			end try
			try
				set outputFolder to value of property list item "OutputFolder" of property list file preferencesFilePath
			end try
		end tell
	end if
	
	
	set newList to {}
	repeat with i from 1 to count AndroidKeyList
		if fileexists(AndroidKeyList's item i) then set newList's end to AndroidKeyList's item i
	end repeat
	set AndroidKeyList to newList
	
	set newList to {}
	repeat with i from 1 to count AdeptKeyList
		if fileexists(AdeptKeyList's item i) then set newList's end to AdeptKeyList's item i
	end repeat
	set AdeptKeyList to newList
	
	set newList to {}
	repeat with i from 1 to count KindleKeyList
		if fileexists(KindleKeyList's item i) then set newList's end to KindleKeyList's item i
	end repeat
	set KindleKeyList to newList
	
	set newList to {}
	repeat with i from 1 to count bnKeys
		if (item 3 of bnKeys's item i) is "" or fileexists(item 3 of bnKeys's item i) then set newList's end to bnKeys's item i
	end repeat
	set bnKeys to newList
	
end ReadPrefs

on CreatePlist(filePath)
	set theEmptyPListData to "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict/>
</plist>"
	
	set thePListFile to open for access filePath with write permission
	set eof of thePListFile to 0
	write theEmptyPListData to thePListFile starting at eof
	close access thePListFile
	
end CreatePlist

on WritePrefsOld()
	-- write keys to the preferences from older AppleScript
	set preferencesFilePath to (path to preferences from user domain as string) & prefsFileName
	CreatePlist(preferencesFilePath)
	tell application "System Events"
		tell contents of property list file preferencesFilePath
			set value to ({|PIDs|:PIDs} & {|UDIDs|:UDIDs} & {|AndroidKeys|:AndroidKeyList} & {|KindleSerials|:KindleSerialList} & {|KindleKeys|:KindleKeyList} & {|bnKeys|:bnKeys} & {|AdeptKeys|:AdeptKeyList} & {|OutputFolder|:outputFolder})
			
		end tell
	end tell
end WritePrefsOld

on WritePrefs()
	if oldAppleScript then
		WritePrefsOld()
	else
		-- write keys to the preferences for AppleScript 2.0 and later
		set preferencesFilePath to (path to preferences from user domain as string) & prefsFileName
		-- we still need to create an empty file in Yosemite, apparently
		CreatePlist(preferencesFilePath)
		tell application "System Events"
			set the base_dict to make new property list item with properties {kind:record}
			set myPrefs to make new property list file with properties {contents:base_dict, name:preferencesFilePath}
			make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"PIDs", value:PIDs}
			make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"UDIDs", value:UDIDs}
			make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"AndroidKeys", value:AndroidKeyList}
			make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"KindleSerials", value:KindleSerialList}
			make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"KindleKeys", value:KindleKeyList}
			make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"bnKeys", value:bnKeys}
			make new property list item at end of property list items of contents of myPrefs with properties {kind:list, name:"AdeptKeys", value:AdeptKeyList}
			make new property list item at end of property list items of contents of myPrefs with properties {kind:string, name:"OutputFolder", value:outputFolder}
		end tell
	end if
end WritePrefs


on InitProgress(maxcount)
	try
		if totalebooks > 1 then
			launch application ((path to resource "DeDRM Progress.app") as string)
			tell application ((path to resource "DeDRM Progress.app") as string)
				activate
				set contents of «class texF» "maintext" of window "main" to "Decrypting " & maxcount & " ebooks."
				set contents of «class texF» "subtext" of window "main" to "Decrypting book 0: "
				set «class maxV» of «class proI» "bar" of window "main" to maxcount
				set «class conT» of «class proI» "bar" of window "main" to 0
			end tell
		end if
	end try
	
end InitProgress

on ProcessItems(some_items)
	try
		set ErrorList to ""
		set WarningList to ""
		set CompletedList to ""
		set ErrorCount to 0
		set WarningCount to 0
		set CompletedCount to 0
		set totalebooks to 0
		set completedebooks to 0
		repeat with this_item in some_items
			if (folder of (info for this_item) is true) then
				tell application "Finder" to set totalebooks to totalebooks + (count of (every file in entire contents of folder this_item whose name extension is in handledExtensions))
			else
				countfile(this_item as text)
			end if
		end repeat
		if totalebooks is 1 then
			set TotalText to "There is 1 ebook to be decrypted."
		else
			set TotalText to "There are " & totalebooks & " ebooks to be decrypted."
		end if
		writetolog(TotalText)
		InitProgress(totalebooks)
		repeat with this_item in some_items
			if totalebooks > 1 and not ProgressActive() then
				exit repeat
			end if
			if (folder of (info for this_item) is true) then
				handlefolder(this_item as text)
			else
				handlefile(this_item as text)
			end if
		end repeat
		endProgress()
	on error errmsg number errnum
		set errorReport to "An unexpected error occurred. Please report on Apprentice Alf's blog.

Error Message: " & errmsg & "
Error Number: " & errnum
		writetolog(errorReport)
		display notification errorReport with title "DeDRM" subtitle "Unexpected Error"
		--display dialog errorReport with title "DeDRM" buttons {"Bother"} default button 1 with icon stop
	end try
	if WarningList is not "" then
		set WarningText to ""
		if WarningCount is 1 then
			set WarningText to "There was a warning with 1 ebook:"
		else
			set WarningText to "There were warnings with " & WarningCount & " ebooks:"
		end if
		writetolog(WarningText)
		writetolog(WarningList)
		--set dialogresult to display dialog WarningText & "
		
		--" & WarningList buttons {"OK"} with title "DeDRM" default button 1
		display notification WarningList with title "DeDRM" subtitle WarningText
	end if
	if ErrorList is not "" then
		set ErrorText to ""
		if ErrorCount is 1 then
			set ErrorText to "There was an error with 1 ebook:"
		else
			set ErrorText to "There were errors with " & ErrorCount & " ebooks:"
		end if
		writetolog(ErrorText)
		writetolog(ErrorList)
		--set dialogresult to display dialog ErrorText & "
		
		--" & ErrorList buttons {"Bother"} with title "DeDRM" default button 1
		display notification ErrorList with title "DeDRM" subtitle ErrorText
	end if
	if CompletedCount > 0 then
		set CompletedText to ""
		if CompletedCount is 1 then
			set CompletedText to "Successfully de-drmed 1 ebook:"
		else
			set CompletedText to "Successfully de-drmed " & CompletedCount & " ebooks:"
		end if
		writetolog(CompletedText)
		writetolog(CompletedList)
		--set dialogresult to display dialog CompletedText & "
		
		--" & CompletedList buttons {"Thanks"} with title "DeDRM" default button 1
		display notification CompletedList with title "DeDRM" subtitle CompletedText
	end if
	return CompletedCount + WarningCount + ErrorCount
end ProcessItems

on ProgressActive()
	tell application "System Events" to set progactive to count (every process whose name is "DeDRM Progress")
	if progactive > 0 then return true
	return false
end ProgressActive

on IncProgress(booktitle, doingcount)
	try
		if ProgressActive() then
			tell application ((path to resource "DeDRM Progress.app") as string)
				set contents of «class texF» "subtext" of window "main" to "Decrypting book " & doingcount & ": " & booktitle
				set «class conT» of «class proI» "bar" of window "main" to doingcount
			end tell
		end if
	end try
end IncProgress

on endProgress()
	try
		if ProgressActive() then tell application ((path to resource "DeDRM Progress.app") as string) to quit
	end try
end endProgress


on run
	if GetTools() then
		ReadPrefs()
		clearlog()
		repeat
			set dialogresult to display dialog "To remove DRM from an ebook, click ‘Select Ebook…’
To configure this software, click ‘Configure…’

When the DeDRM application is not running, you can also remove DRM from ebooks by dropping them onto the DeDRM application icon in the Finder.

For details of the ebook formats  which this application can handle, see the ReadMe file or visit http://apprenticealf.wordpress.com/
Please only use this application on your own books. Authors, publishers and ebook stores need to make money to produce more ebooks.
Don't cheat them.

This application is by Apprentice Alf and Apprentice Harper based on an AppleScript script by Paul Durrant and uses python scripts produced by Apprentice Alf, CMBDTC, The Dark Reverser, DiapDealer, i♥cabbages, some_updates, Apprentice Harper and others.
The AppleScript part of this application is free software released into the public domain, see http://unlicense.org/
The application icon is adapted from the Authors Against DRM logo at
http://readersbillofrights.info/AAD and is under the Creative Commons Attribution-ShareAlike licence.

The included Python scripts are all free to use, but have a variety of licences. See the individual files for details.
" with title "DeDRM by Apprentice Alf" buttons {"Quit", "Select Ebook…                                      ", "Configure…                                      "} default button 1 with icon note
			if button returned of dialogresult is "Quit" then exit repeat
			if button returned of dialogresult is "Select Ebook…                                      " then
				set DRMebook to ""
				try
					set DRMebook to {choose file with prompt "Please select a DRMed ebook"}
				end try
				if DRMebook is not "" then
					if ProcessItems(DRMebook) is 0 then
						display dialog "That was a file that this script cannot process." with title "DeDRM" buttons {"OK"} default button 1 with icon note
					end if
					WritePrefs()
				end if
			else
				set choice to true
				repeat while choice is not false
					set choice to choose from list {"eInk Kindle eBooks", "Barnes and Noble (nook) ebooks", "Mobipocket eBooks", "eReader ebooks", "Adobe Digital Editions ebooks", "Kindle for Mac ebooks", "Output Folder"} with prompt "Choose a Configuration Option:" with title "DeDRM Configuration" OK button name "Configure..." cancel button name "Finished"
					if choice contains "Barnes and Noble (nook) ebooks" then
						GetBNKeys("DeDRM Configure for Barnes and Noble (nook)")
					else if choice contains "eInk Kindle eBooks" then
						GetSerials("DeDRM Configure for eInk Kindle")
					else if choice contains "Mobipocket eBooks" then
						GetPIDs("DeDRM Configure for Mobipocket")
					else if choice contains "eReader ebooks" then
						GeteReaderKeys("DeDRM Configure for eReader")
					else if choice contains "Kindle for Mac ebooks" then
						GetKindleKeyFiles("DeDRM Configure Kindle for Mac")
					else if choice contains "Kindle for Android ebooks" then
						GetAndroidKeyFiles("DeDRM Configure Kindle for Android")
					else if choice contains "Adobe Digital Editions ebooks" then
						GetAdeptKeyFiles("DeDRM Configure Adobe Digital Editions")
					else if choice contains "Output Folder" then
						GetOutputFolder("DeDRM Configure Output Folder")
					end if
				end repeat
				WritePrefs()
			end if
		end repeat
	end if
end run

on open some_items
	--display dialog (some_items as text)
	if GetTools() then
		ReadPrefs()
		clearlog()
		
		if ProcessItems(some_items) is 0 then
			display notification "No ebooks found in the dropped items. DeDRM can handle Mobipocket, Kindle, eReader, Adobe ePub, Barnes & Noble ePub and Adobe PDF. Please try again." with title "DeDRM"
		end if
		WritePrefs()
		delay 1 --> allow time for any notifications to trigger
	end if
end open

