1 dojo.provide("calitha.collections.arrays");
  2 dojo.require("calitha.collections.IComparator");
  3 dojo.require("calitha.collections.base.Comparator");
  4 dojo.require("calitha.exception.IllegalArgumentException");
  5 
  6 /**
  7  * @name calitha.collections.arrays
  8  * @namespace
  9  * @description The arrays namespace contains a vaiety of convencience methods for arrays.
 10  */
 11 
 12 /**
 13  * @function
 14  * @param array array
 15  * @returns {Array} new array
 16  * @description Copies an array
 17  */
 18 calitha.collections.arrays.copy = function(/**Array*/ array)
 19 {
 20     var result = new Array(array.length);
 21     calitha.collections.arrays.copyRangeToArray(array, 0, array.length, result, 0);
 22     return result;
 23 };
 24 
 25 /**
 26  * @function
 27  * @param array array
 28  * @param fromIndex from index
 29  * @param toIndex to index (not inclusive)
 30  * @param targetIndex target index
 31  * @description Copies a range of elements in an array to another index
 32  */
 33 calitha.collections.arrays.copyRange = function(/**Array*/ array, /**Number*/ fromIndex, /**Number*/ toIndex, /**Number*/ targetIndex)
 34 {
 35     var count = toIndex - fromIndex;
 36     if (targetIndex < fromIndex)
 37     {
 38         for (var i = 0; i < count; i++)
 39         {
 40             array[targetIndex + i] = array[fromIndex + i];
 41         }
 42     }
 43     else if (targetIndex > fromIndex)
 44     {
 45         for (var j = count - 1; j >= 0; j--)
 46         {
 47             array[targetIndex + j] = array[fromIndex + j];
 48         }
 49     }
 50 };
 51 
 52 /**
 53  * @function
 54  * @param source source array
 55  * @param fromIndex from index
 56  * @param toIndex to index (not inclusive)
 57  * @param dest destination array
 58  * @param targetIndex target index in the destination array
 59  * @description Copies a range of elements from one array to another
 60  */
 61 calitha.collections.arrays.copyRangeToArray = function(/**Array*/ source,
 62                                                      /**Number*/ fromIndex,
 63                                                      /**Number*/ toIndex,
 64                                                      /**Array*/ dest,
 65                                                      /**Number*/ targetIndex)
 66 {
 67     var count = toIndex - fromIndex;
 68     for (var i = 0; i < count; i++)
 69     {
 70         dest[targetIndex + i] = source[fromIndex + i];
 71     }
 72 };
 73 
 74 /**
 75  * @function
 76  * @param source source array
 77  * @param fromIndex from index
 78  * @param toIndex to index (not inclusive)
 79  * @param dest destination array
 80  * @param targetIndex target index in the destination array
 81  * @description Inserts a range of elements in another array
 82  */
 83 calitha.collections.arrays.insertRangeToArray = function(/**Array*/ source,
 84                                                          /**Number*/ fromIndex,
 85                                                          /**Number*/ toIndex,
 86                                                          /**Array*/ dest,
 87                                                          /**Number*/ targetIndex)
 88 {
 89     var count = toIndex - fromIndex;
 90     calitha.collections.arrays.copyRange(dest, targetIndex, targetIndex + count, targetIndex + count);
 91     calitha.collections.arrays.copyRangeToArray(source, fromIndex, toIndex, dest, targetIndex);
 92 };
 93 
 94 /**
 95  * @function
 96  * @param array array
 97  * @param comparator optional comparator
 98  * @description Sorts an array according to the specified comparator object or function. If no comparator
 99  * is specified the natural ordering is used, which means that the elements must be IComparable.
100  */
101 calitha.collections.arrays.sort = function(/**Array*/ array, /**(calitha.collections.IComparator|Function)?*/ comparator)
102 {
103     if (comparator == null)
104     {
105         calitha.collections.arrays._sortWithComparable(array);
106     }
107     else if (comparator.isInstanceOf(calitha.collections.IComparator))
108     {
109         calitha.collections.arrays._sortWithComparator(array, comparator);
110     }
111     else if (comparator.isInstanceOf(Function))
112     {
113         var cmp = new calitha.collections.base.Comparator(comparator);
114         calitha.collections.arrays._sortWithComparator(array, cmp);
115     }
116     else
117     {
118         throw new calitha.exception.IllegalArgumentException(Error("Invalid comparator argument"));
119     }
120 };
121 
122 calitha.collections.arrays._sortWithComparable = function(array)
123 {
124     if (array.length > 0)
125     {
126         var item = array[0];
127         if (!calitha.collections.util.isObjectInstanceOf(item, calitha.collections.IComparable))
128         {
129             throw new calitha.exception.IllegalArgumentException(Error("Can only sort IComparable objects"));
130         }
131 
132     }
133     array.sort(function(o1, o2)
134     {
135         return o1.compareTo(o2);
136     });
137 };
138 
139 calitha.collections.arrays._sortWithComparator = function(array, comparator)
140 {
141     array.sort(function(o1, o2)
142     {
143         return comparator.compare(o1, o2);
144     });
145 };
146