udfStrPermutation
str udfStrPermutation (str, int)
;==========================================================================================================================================
;
; Permutation of a string.
;
;
; Detlev Dalitz.20090408.
;==========================================================================================================================================

GoSub Define_Functions

; Create report filename in user temp folder.
strFileOut = FileCreateTemp ("DD.")
If 1 == FileExist (strFileOut) Then FileDelete (strFileOut)
strFileOut = ItemReplace ("txt", -1, strFileOut, ".")

; Set global pointer to use from within recursively called function.
ptrFileOut = PtrGlobalDefine (strFileOut)

; Set global pointer to use from within recursively called function.
blnRunSilent = @TRUE
ptrRunSilent = PtrGlobalDefine (blnRunSilent)

; For sure delete existing outputfile.
Terminate (2 == FileExist (strFileout), "Terminated.", "Output file is in read deny mode:" : @LF : strFileout)
blnResult = FileDelete (strFileOut)

; Ask user for a string to permute. String should not be too long!  10 chars ==> 3.628.800 permutations!
strIn = udfAskLine ("Permutation", "Enter a string to permute (not too long!).", "abcd", 0)
If strIn == "" Then Exit

; Ask for supressing status window.
intYesNo = udfAskYesNo ("Permutation", "Do you want a silent run? (report file at end)")
If intYesNo == -1 Then Exit

; Append simple DateTime stamp to diskfile.
intBytesWritten = udfFilePutAppend (*PtrGlobal (strFileOut), TimeYmdHms () : @CRLF)

If intYesNo == @NO
   blnRunSilent = @FALSE
   BoxOpen ("Permutation of a string", "")
   WinPlaceSet (@NORMAL, "", "350 375 650 475")
   intCount = udfStrPermutation (strIn, "", 0)
   BoxShut ()
Else
   intCount = udfStrPermutation (strIn, "", 0)
EndIf

; Append number of permutations to diskfile.
intBytesWritten = udfFilePutAppend (*PtrGlobal (strFileOut), intCount : " entries." : @CRLF)

; Append simple DateTime stamp to diskfile.
intBytesWritten = udfFilePutAppend (*PtrGlobal (strFileOut), TimeYmdHms () : @CRLF)

; Show report text file.
If 1 == FileExist (strFileOut) Then Run (strFileOut, "")

Exit


;==========================================================================================================================================
:Define_Functions
;==========================================================================================================================================
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfStrPermutation (strString, strPermuted, intCount)
intLen = StrLen (strString)
If intLen == 1
   intCount = intCount + 1
   strPermuted = strPermuted : strString
   If !*PtrGlobal (blnRunSilent)
      BoxTitle (intCount)
      BoxText (strPermuted)
   EndIf
   intBytesWritten = udfFilePutAppend (*PtrGlobal (strFileOut), strPermuted : @CRLF) ; Write permuted string to diskfile.
Else
   ; Distribute this node into n nodes and expand next lower node.
   For intPos = 1 To intLen
      intCount = udfStrPermutation (StrSub (strString, 1, intPos - 1) : StrSub (strString, intPos + 1, -1), strPermuted : StrSub (strString, intPos, 1), intCount)
   Next
EndIf
Return intCount
;..........................................................................................................................................
; Recursively called function which calls itself to expand each node of the n-ary tree.
;
; Detlev Dalitz.20090408.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFilePutAppend (strFilename, strString)
If strString == "" Then Return 0
If !DirMake (FilePath (strFilename)) Then Return 0
hdlBB = BinaryAlloc (StrLen (strString))
BinaryPokeStr (hdlBB, 0, strString)
While @TRUE
   ErrorMode (@OFF)
   LastError ()
   intResult = BinaryWriteEx (hdlBB, 0, strFilename, FileSize (strFilename), BinaryEodGet (hdlBB))
   ErrorMode (@ON)
   intLastError = LastError ()
   If (intLastError == 0) Then Break
   Pause ("WinBatch Error: udfFilePutAppend()", "LastError: " : intLastError)
EndWhile
hdlBB = BinaryFree (hdlBB)
Return (intResult)
;..........................................................................................................................................
; Returns number of bytes written.
;
; Detlev Dalitz.20090408.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfAskLine (strTitle, strPrompt, strDefault, intFormat)
Return AskLine (strTitle, strPrompt, strDefault, intFormat)
:CANCEL
Return "" ; Return empty string if Dialog has been cancelled resp. closed by escape key.
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfAskYesNo (strTitle, strQuestion)
Return AskYesNo (strTitle, strQuestion)
:CANCEL
Return -1 ; Return integer -1 if Dialog has been cancelled resp. closed by escape key.
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------

;==========================================================================================================================================
Return ; from Define_Functions
;==========================================================================================================================================