*!* Show all permutations for a given set of characters
GetCharPermutations("PERMUTE")
PROCEDURE GetCharPermutations(tcCharacters)
LOCAL lnMembers, lnCounter, loProgress, lnTemp, lnTemp2, lnLoopCounter, lnTotalPermutations, lnPermutationsDone
SET ESCAPE ON
lnMembers = LEN(tcCharacters)
lnTotalPermutations = 1
lnPermutationsDone = 0
DIMENSION tcSet(lnMembers)
DIMENSION aryIndice(lnMembers)
FOR lnLoopCounter = 1 TO lnMembers
tcSet(lnLoopCounter) = SUBSTR(tcCharacters, lnLoopCounter, 1)
lnTotalPermutations = lnTotalPermutations * lnLoopCounter
ENDFOR
aryIndice = -1
CREATE CURSOR crsResult (permute c(lnMembers))
loProgress = CREATEOBJECT("progress", "Processing...", 0, lnTotalPermutations, 0)
loProgress.show()
DO WHILE .T.
IF(aryIndice(1) < 0)
lnCounter = 1
DO WHILE lnCounter < lnMembers + 1
aryIndice(lnCounter) = lnCounter - 1
lnCounter = lnCounter + 1 && was above
ENDDO
lnBeginning = lnMembers +1
lnEnd = lnMembers
DO WHILE lnBeginning < lnEnd
lnTemp2 = aryIndice(lnBeginning)
aryIndice(lnBeginning) = aryIndice(lnEnd)
lnBeginning = lnBeginning + 1
aryIndice(lnEnd) = lnTemp2
lnEnd = lnEnd - 1
ENDDO
lnPermutationsDone = lnPermutationsDone + 1
loProgress.VALUE = lnPermutationsDone
INSERT INTO crsResult (permute) VALUES (LEFT(DisplayString(lnMembers, @tcSet, @aryIndice), lnMembers))
LOOP
ELSE
lnCounter = lnMembers - 1
DO WHILE lnCounter >= 1 AND aryIndice(lnCounter) >= aryIndice(lnCounter + 1)
lnCounter = lnCounter - 1
ENDDO
IF(lnCounter < 1)
EXIT
ELSE
lnLeast = lnCounter + 1
lnTemp = lnCounter + 2
DO WHILE lnTemp < lnMembers + 1
IF(aryIndice(lnTemp) < aryIndice(lnLeast) AND aryIndice(lnTemp) > aryIndice(lnCounter))
lnLeast = lnTemp
ENDIF
lnTemp = lnTemp + 1 && was above
ENDDO
lnTemp2 = aryIndice(lnCounter)
aryIndice(lnCounter) = aryIndice(lnLeast)
aryIndice(lnLeast) = lnTemp2
IF (lnMembers > lnCounter)
lnBeginning = lnCounter + 1
lnEnd = lnMembers
DO WHILE lnBeginning < lnEnd
lnTemp2 = aryIndice(lnBeginning)
aryIndice(lnBeginning) = aryIndice(lnEnd)
lnBeginning = lnBeginning + 1
aryIndice(lnEnd) = lnTemp2
lnEnd = lnEnd - 1
ENDDO
lnBeginning = lnMembers + 1
lnEnd = lnMembers
DO WHILE lnBeginning < lnEnd
lnTemp2 = aryIndice(lnBeginning)
aryIndice(lnBeginning) = aryIndice(lnEnd)
lnBeginning = lnBeginning + 1
aryIndice(lnEnd) = lnTemp2
lnEnd = lnEnd - 1
ENDDO
ENDIF
lnPermutationsDone = lnPermutationsDone + 1
loProgress.VALUE = lnPermutationsDone
INSERT INTO crsResult (permute) VALUES (LEFT(DisplayString(lnMembers, @tcSet, @aryIndice), lnMembers))
LOOP
ENDIF
ENDIF
ENDDO
RELEASE loProgress
IF MESSAGEBOX("Done processing '" + tcCharacters + "' would you like to browse the results?",36,"PROCESS FINISHED") = 6
GO TOP IN "crsResult"
BROWSE
ENDIF
ENDPROC
FUNCTION DisplayString(tcMembers, tcSet, tcIndice)
LOCAL lnCounter, lcString
lcString = []
FOR lnCounter = 1 TO tcMembers
IF (tcIndice(lnCounter) + 1) != 0
lcString = lcString + TRANSFORM(tcSet(tcIndice(lnCounter)+1))
ENDIF
ENDFOR
RETURN ALLTRIM(lcString)
ENDFUNC
DEFINE CLASS progress AS FORM
AUTOCENTER = .T.
ALWAYSONTOP = .T.
TOP = 0
LEFT = 0
HEIGHT = 74
WIDTH = 298
DOCREATE = .T.
CAPTION = ""
TITLEBAR = 0
BORDERSTYLE = 2
VALUE = 0
NAME = "frmProgress"
MIN = 0
MAX = 100
PROCEDURE INIT
LPARAMETERS tcTitle, tnMin, tnMax, tnValue
LOCAL lnCounter, lnLeft, lcShapeName
THIS.ADDOBJECT("shape26", "Shape")
WITH THIS.shape26
.TOP = 23
.LEFT = 12
.HEIGHT = 25
.WIDTH = 277
.BACKSTYLE = 0
.SPECIALEFFECT = 0
.VISIBLE = .T.
ENDWITH
THIS.ADDOBJECT("title", "label")
WITH THIS.TITLE
.BACKSTYLE = 0
.CAPTION = ""
.HEIGHT = 18
.LEFT = 12
.TOP = 3
.WIDTH = 277
.VISIBLE = .T.
ENDWITH
THIS.ADDOBJECT("percentage", "label")
WITH THIS.percentage
.FONTBOLD = .T.
.ALIGNMENT = 2
.BACKSTYLE = 0
.CAPTION = ""
.HEIGHT = 18
.LEFT = 12
.TOP = 52
.WIDTH = 277
.FORECOLOR = RGB(0,128,192)
.VISIBLE = .T.
ENDWITH
lnLeft = 13
FOR lnCounter = 1 TO 25 && Easier than adding and removing them should progress go backwards at some point
lcShapeName = "Shape" + TRANSFORM(lnCounter)
THIS.ADDOBJECT(lcShapeName, "Shape")
WITH THIS.&lcShapeName
.TOP = 24
.LEFT = lnLeft
.HEIGHT = 23
.WIDTH = 10
.BORDERSTYLE = 0
.SPECIALEFFECT = 1
.VISIBLE = .F.
.BACKCOLOR = RGB(0,128,192)
ENDWITH
lnLeft = lnLeft + 11
ENDFOR
IF TYPE("tcTitle") = "C"
THIS.TITLE.Caption = tcTitle
ENDIF
IF TYPE("tnMin") = "N"
THIS.MIN = tnMin
ENDIF
IF TYPE("tnMax") = "N"
THIS.MAX = tnMax
ENDIF
IF TYPE("tnValue") = "N"
THIS.VALUE = tnValue
ENDIF
ENDPROC
PROCEDURE value_assign
LPARAMETERS vNewVal
LOCAL lnCounter, lcShapeName, lnPercentage
THIS.LOCKSCREEN = .T.
lnPercentage = INT(m.vNewVal/(THIS.MAX - THIS.MIN)*100)
FOR lnCounter = 1 TO 25
lcShapeName = "Shape" + TRANSFORM(lnCounter)
this.&lcShapeName..VISIBLE = lnCounter <= (lnPercentage/4)
ENDFOR
THIS.percentage.Caption = TRANSFORM(lnPercentage) + "%"
THIS.LOCKSCREEN = .F.
IF lnPercentage = 100 && Show this for a .5 seconds so user can see it
INKEY(.5,"H")
ENDIF
THIS.VALUE = m.vNewVal
ENDPROC
PROCEDURE max_assign
LPARAMETERS vNewVal
THISFORM.VALUE = THISFORM.VALUE && in case max is changed refresh progress bar
THIS.MAX = m.vNewVal
ENDPROC
PROCEDURE min_assign
LPARAMETERS vNewVal
THISFORM.VALUE = THISFORM.VALUE && in case min is changed refresh progress bar
THIS.MIN = m.vNewVal
ENDPROC
ENDDEFINE