
*************************************************************
DEFINE CLASS wwCollection AS Relation
*************************************************************
*: Author: Rick Strahl
*:         (c) West Wind Technologies, 2005
*:Contact: http://www.west-wind.com
*:Created: 08/19/2005
*************************************************************

*** Custom Properties

*** Stock Properties
DIMENSION aItems[1] 
COUNT = 0

************************************************************************
* wwCollection :: Add
****************************************
***  Function:
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION Add(Value)

THIS.Count = THIS.Count + 1
DIMENSION THIS.aItems[this.Count]
this.aItems[this.Count] = Value

ENDFUNC

************************************************************************
* wwCollection :: Insert
****************************************
***  Function: Inserts an item into the array at the specified
***            Position.
***    Assume:
***      Pass: Value
***              Value to insert
***
***            Position
***              Position to insert it *before*. New item becomes
***              the item at this position. Existing item is shifted down
***    Return: nothing
************************************************************************
FUNCTION InsertAt(Value,Position)

DIMENSION this.aItems[this.Count + 1]
IF AINS(this.aItems,Position) = 1 
   this.aItems[Position] = Value
   this.Count = this.Count + 1
ENDIF

ENDFUNC
*  wwCollection :: Insert

************************************************************************
* wwCollection :: Item
****************************************
***  Function: Returns an item out of the collection
***    Assume:
***      Pass: Key  -  numeric index or Key String value
***    Return: value or .NULL. if not found
************************************************************************
FUNCTION Item(Index)
RETURN this.aItems[Index]
ENDFUNC

************************************************************************
* wwCollection :: Remove
****************************************
***  Function:
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION Remove(Index)
LOCAL lnRow
THIS.Count = THIS.Count - 1
ADEL(this.aItems,Index)
ENDFUNC

FUNCTION Dispose
THIS.aItems=null
ENDFUNC

FUNCTION Destroy
THIS.aItems=null
ENDFUNC

************************************************************************
* wwCollection :: Clear
****************************************
***  Function:
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION Clear()

THIS.Count = 0
THIS.aItems = .f.

ENDFUNC
*  wwCollection :: Clear

ENDDEFINE
*EOC wwCollection 

*************************************************************
DEFINE CLASS wwNameValueCollection AS Relation
*************************************************************
*: Author: Rick Strahl
*:         (c) West Wind Technologies, 2005
*:Contact: http://www.west-wind.com
*:Created: 08/18/2005
***************************

DIMENSION aItems[1,2] 
COUNT = 0

************************************************************************
* wwNameValueCollection :: Add
****************************************
***  Function: FastAdd Adds items without checking for uniqueness first
***    Assume: Considerably faster than regular Add. Use when you know
***            items are added only once.
***      Pass:
***    Return:
************************************************************************
FUNCTION FastAdd(Key,Value)

THIS.Count = THIS.Count + 1

IF PARAMETERS() = 1
   Value = Key
   Key = TRANSFORM(this.Count)
ENDIF
   
DIMENSION THIS.aItems[this.Count,2]
this.aItems[this.Count,1] = Key
this.aItems[this.Count,2] = Value

ENDFUNC

************************************************************************
* wwNameValueCollection :: Add
****************************************
***  Function: Adds an item to the collection by first checking
***            for existance. If found overwrites existing value
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION Add(Key,Value)
LOCAL lnIndex

lnIndex = THIS.GetIndex(Key)
IF lnIndex = 0
   THIS.FastAdd(Key,Value)
ELSE
   THIS.aItems[lnIndex,1] = Key
   THIS.aItems[lnIndex,2] = Value
ENDIF

ENDFUNC
*  wwNameValueCollection :: AddUnique

************************************************************************
* wwNameCollection :: Insert
****************************************
***  Function: Inserts an item into the array at the specified
***            Position.
***    Assume:
***            Position
***              Position to insert it *before*. New item becomes
***              the item at this position. Existing item is shifted down
***            Key
***               Key of the value to insert
****           Value
***              Value to insert
***
***    Return: nothing
************************************************************************
FUNCTION InsertAt(Position,Key,Value)

IF PARAMETERS() = 2
   Value = Key
   Key = TRANSFORM(this.Count)
ENDIF

DIMENSION this.aItems[this.Count + 1,2]

IF AINS(this.aItems,Position) = 1 
   this.aItems[Position,1] = Key
   this.aItems[Position,2] = Value
   this.Count = this.Count + 1
ENDIF

ENDFUNC
*  wwCollection :: Insert

************************************************************************
* wwNameValueCollection :: Item
****************************************
***  Function: Returns an item out of the collection
***    Assume:
***      Pass: Key  -  numeric index or Key String value
***    Return: value or .NULL. if not found
************************************************************************
FUNCTION Item(Key)

IF VARTYPE(Key) = "N"
   RETURN this.aItems[Key,2]
ELSE
   lnElement = ASCAN(this.aItems,Key,1,this.Count,1,7) && Case insensitive/exact on
   IF lnElement = 0
      RETURN null
   ENDIF

   RETURN this.aItems[lnElement+1]
ENDIF

ENDFUNC

FUNCTION GetKey(Index)
   RETURN THIS.aItems[Index,1]
ENDFUNC

FUNCTION GetIndex(Key)
LOCAL lnElement
   lnElement = ASCAN(this.aItems,Key,1,this.Count,1,7)  && Case insensitive/exact on
   IF lnElement > 0
      RETURN (lnElement + 1)/2
   ENDIF
   RETURN 0
ENDFUNC

************************************************************************
* wwNameValueCollection :: Remove
****************************************
***  Function:
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION Remove(Key)
LOCAL lnRow
   IF VARTYPE(Key) = "N"
      ADEL(this.aItems,key)
   ELSE
      lnRow = this.GetIndex(Key)
      IF lnRow = 0
         RETURN
      ENDIF

      ADEL(this.aItems,lnRow)
   ENDIF
   THIS.Count = THIS.Count - 1
ENDFUNC

************************************************************************
* wwNameValueCollection :: Clear
****************************************
***  Function:
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION Clear()

THIS.Count = 0
THIS.aItems = .f.

ENDFUNC
*  wwCollection :: Clear


************************************************************************
* wwNameValueCollection :: ToAttributeString
****************************************
***  Function: Loops through name value pairs and creates attribute
***            strings
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION ToAttributeString()
LOCAL lnX, lcOutput
lcOutput = ""

FOR lnX = 1 TO THIS.Count
   lcOutput = lcOutput + this.aItems[lnX,1] + [="] + this.aItems[lnX,2] + [" ]
ENDFOR 

RETURN lcOutput
ENDFUNC
*  wwNameValueCollection :: ToAttributeString

FUNCTION Dispose
THIS.aItems=null
ENDFUNC

FUNCTION Destroy
THIS.aItems=null
ENDFUNC

ENDDEFINE

*************************************************************
DEFINE CLASS wwStack AS wwCollection
*************************************************************
*: Author: Rick Strahl
*:         (c) West Wind Technologies, 2005
*:Contact: http://www.west-wind.com
*:Created: 08/20/2005
*************************************************************
#IF .F.
*:Help Documentation
*:Topic:
Class wwStack

*:Description:

*:Example:

*:Remarks:

*:SeeAlso:


*:ENDHELP
#ENDIF

*** Custom Properties
nStackPointer = 0

*** Stock Properties
************************************************************************
* wwStack :: Push
****************************************
***  Function:
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION Push(lvValue)
THIS.Add(lvValue)
ENDFUNC
*  wwStack :: Push

************************************************************************
* wwStack :: Pop
****************************************
***  Function: Pops an item off the stack
***    Assume:
***      Pass:
***    Return: value of the last item on the stack. Null if stack is empty
************************************************************************
FUNCTION Pop()
LOCAL lvValue

IF THIS.Count < 1
   RETURN null
ENDIF

lvValue = THIS.aItems[THIS.Count]
THIS.Remove(THIS.Count)

RETURN lvValue
ENDFUNC
*  wwStack :: Pop

************************************************************************
* wwStack :: Peek
****************************************
***  Function: Returns the last item without popping it off the stack
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION Peek()
LOCAL lvValue

IF THIS.Count < 1
   RETURN null
ENDIF

lvValue = THIS.aItems[THIS.Count]

RETURN lvValue
ENDFUNC
*  wwStack :: Peek

*** Hide Other Collection methods
PROTECTED FUNCTION Add(lvValue)
DODEFAULT(lvValue)
ENDFUNC


PROTECTED FUNCTION Remove(lnIndex)
DODEFAULT(lnIndex)
ENDFUNC

ENDDEFINE
*EOC wwStack 



*** wwBusiness Related Collections

*************************************************************
DEFINE CLASS wwValidationError AS Custom
*************************************************************
*: Author: Rick Strahl
*:         (c) West Wind Technologies, 2005
*:Contact: http://www.west-wind.com
*:Created: 11/16/2005
*************************************************************
*** Custom Properties

*** Stock Properties

*** The Error Message for the validation Error
cMessage  = ""

*** Optional name of the object it applies to
cObjectName = ""

ENDDEFINE

*************************************************************
DEFINE CLASS wwValidationErrors AS wwCollection
*************************************************************
*: Author: Rick Strahl
*:         (c) West Wind Technologies, 2005
*:Contact: http://www.west-wind.com
*:Created: 11/16/2005
*************************************************************


************************************************************************
* wwValidationErrors :: ToString
****************************************
***  Function: Turns the Validation Errors into a string
***    Assume:
***      Pass:
***    Return:
************************************************************************
FUNCTION ToString()
LOCAL lcOutput, lnX

lcOutput = ""
FOR lnX = 1 TO this.Count
   IF lnX < this.Count
      lcOutput = lcOutput + this.aItems[lnX].cMessage + CRLF
   ELSE
      lcOutput = lcOutput + this.aItems[lnX].cMessage 
   ENDIF   
ENDFOR

RETURN lcOutput
ENDFUNC

ENDDEFINE
