1 // ==========================================================================
  2 // Project:   SproutCore - JavaScript Application Framework
  3 // Copyright: ©2006-2011 Strobe Inc. and contributors.
  4 //            ©2008-2011 Apple Inc. All rights reserved.
  5 // License:   Licensed under MIT license (see license.js)
  6 // ==========================================================================
  7 
  8 SC.mixin( /** @scope SC */ {
  9   /** A zero length range at zero. */
 10   ZERO_RANGE: { start: 0, length: 0 },
 11 
 12   RANGE_NOT_FOUND: { start: 0, length: -1 },
 13 
 14   /** Returns true if the passed index is in the specified range */
 15   valueInRange: function(value, range) {
 16     return (value >= 0) && (value >= range.start) && (value < (range.start + range.length));
 17   },
 18 
 19   /** Returns first value of the range. */
 20   minRange: function(range) { return range.start; },
 21 
 22   /** Returns the first value outside of the range. */
 23   maxRange: function(range) { return (range.length < 0) ? -1 : (range.start + range.length); },
 24 
 25   /** Returns the union of two ranges.  If one range is null, the other
 26    range will be returned.  */
 27   unionRanges: function(r1, r2) {
 28     if ((r1 == null) || (r1.length < 0)) return r2 ;
 29     if ((r2 == null) || (r2.length < 0)) return r1 ;
 30 
 31     var min = Math.min(r1.start, r2.start),
 32         max = Math.max(SC.maxRange(r1), SC.maxRange(r2)) ;
 33     return { start: min, length: max - min } ;
 34   },
 35 
 36   /** Returns the intersection of the two ranges or SC.RANGE_NOT_FOUND */
 37   intersectRanges: function(r1, r2) {
 38     if ((r1 == null) || (r2 == null)) return SC.RANGE_NOT_FOUND ;
 39     if ((r1.length < 0) || (r2.length < 0)) return SC.RANGE_NOT_FOUND;
 40     var min = Math.max(SC.minRange(r1), SC.minRange(r2)),
 41         max = Math.min(SC.maxRange(r1), SC.maxRange(r2)) ;
 42     if (max < min) return SC.RANGE_NOT_FOUND ;
 43     return { start: min, length: max-min };
 44   },
 45 
 46   /** Returns the difference of the two ranges or SC.RANGE_NOT_FOUND */
 47   subtractRanges: function(r1, r2) {
 48     if ((r1 == null) || (r2 == null)) return SC.RANGE_NOT_FOUND ;
 49     if ((r1.length < 0) || (r2.length < 0)) return SC.RANGE_NOT_FOUND;
 50     var max = Math.max(SC.minRange(r1), SC.minRange(r2)),
 51         min = Math.min(SC.maxRange(r1), SC.maxRange(r2)) ;
 52     if (max < min) return SC.RANGE_NOT_FOUND ;
 53     return { start: min, length: max-min };
 54   },
 55 
 56   /** Returns a clone of the range. */
 57   cloneRange: function(r) {
 58     return { start: r.start, length: r.length };
 59   },
 60 
 61   /** Returns true if the two passed ranges are equal.  A null value is
 62     treated like RANGE_NOT_FOUND.
 63   */
 64   rangesEqual: function(r1, r2) {
 65     if (r1===r2) return true ;
 66     if (r1 == null) return r2.length < 0 ;
 67     if (r2 == null) return r1.length < 0 ;
 68     return (r1.start == r2.start) && (r1.length == r2.length) ;
 69   }
 70 
 71 });
 72