/* Array or list sort and reverse */

Load 'Sort_array.rx', 'Sort_*.rx'

SORT_* :
 ARRAY
 LIST
;

*_SORT :
 QUICK
 SHUFFLE
 REVERSE
 NO
;

/* * */

Sort ->
Arg Array : ^&Array

Call ArraySort 'Array' Sort_method
Where Sort_method = SortMethod( Already_ordered, Array._, SORT_ARRAY )
Where Already_ordered = AlreadyOrdered( Array )

Return

/* * */

AlreadyOrdered Sort ->
Arg Array : Array,
  - Counter = 0 ..

Do Counter ++ [ Array.i < Array.( i + 1 ) ]
Where i = 1 to Array._ - 1

Return

/* * */

Sort ->
Arg Src : List : <T>, Dest : &List : T

New : List : [Src] = <> ..

Dest = New
After ListSort Src 'New' Sort_method
Where Sort_method = SortMethod( Already_ordered, Src._, SORT_LIST )
Where Already_ordered = AlreadyOrdered( Src )

Return

/* * */

AlreadyOrdered Sort ->
Arg List : List,
  - Counter = 0 ..

Prev = . ..

Do get Element from List
 Z = Prev = Element
 Counter ++ [ Z && Z < Element ]
;

Return

/* Action selectors */

SortMethod Sort ->
Arg Ordered, Total : Integer, 
    . : SORT_ARRAY

When Total = 0 | Total = 1 then
Return NO_SORT

When Ordered = Total - 1 then
Return NO_SORT

When Ordered = 0 then
Return REVERSE_SORT

Else
Return SHUFFLE_SORT

/* * */

SortMethod Sort ->
Arg Ordered, Total : Integer, 
    . : SORT_LIST

When Total = 0 | Total = 1 then
Return NO_SORT

When Ordered = Total - 1 then
Return NO_SORT

When Ordered = 0 then
Return REVERSE_SORT

Else
Return QUICK_SORT

/* Empty functions */

ArraySort '?', NO_SORT = _
ListSort ?, '?', NO_SORT = _

/* * */

Export Sort