/** extension.js
 * @autor: janne louw
 * @date: 30-11-2005
 *
 * @description: prototype extensions
 */

/** String.substrUpto
 * returns substring starting after argument string
 */
String.prototype.substrAfter = function (string) {
   return this.substr(this.indexOf(string) + string.length);
}

/** String.substrUpto
 * returns substring up to the argument string
 */
String.prototype.substrUpto = function (string) {
   return this.substr(0 , this.indexOf(string) );
}

/** String.trim
 * removes leading and trailing whitespace characters
 */
String.prototype.trim = function () {
   return this.replace(/^\s+|\s+$/g,'');
}

/** Number.round
 * rounds the number to the nearest whole number. If a precision is defined 
 *    that number of decimals is used. A negative number means that the number 
 *    is rounded to the nearest power of ten of the absolute value of precision.
 */
Number.prototype.round = function (intPrecision) {
   intPrecision = ( isNaN(parseInt(intPrecision)) ? 0 : parseInt(intPrecision) );
   var intPower = Math.pow(10, intPrecision);
   return Math.round(this.valueOf() * intPower) / intPower;
}
/** Number.floor
 * floor the number to the whole number. If a precision is defined that number 
 * of decimals is used. A negative number means that the number is floored to the 
 * power of ten of the absolute value of precision.
 */
Number.prototype.floor = function (intPrecision) {
   intPrecision = ( isNaN(parseInt(intPrecision)) ? 0 : parseInt(intPrecision) );
   var intPower = Math.pow(10, intPrecision);
   return Math.floor(this.valueOf() * intPower) / intPower;
}
/** Number.precision
 * returns the precision of the least significant digit of number.
 * precision is the floored -10log of the digit: .1-.9 is 1, 1-9 is 0, 1-9 * 10 is -1;
 */
Number.prototype.precision = function () {
   var numRemainder;
   var numTolerance = Math.pow(10, (-15 + (Math.log(this.valueOf()) / Math.LN10 ).round() ));
   var intPrecision = 0;
   var numPower = 1;
   numRemainder = this.valueOf() % numPower;
   if (numRemainder == 0 ) {
      do {
         --intPrecision;
         numPower *= 10;
         numRemainder = this.valueOf() % numPower;
      } while ( numRemainder == 0 && this.valueOf() >= numPower );
      ++intPrecision;
   }
   else {
      while (numRemainder > numTolerance && numPower - numRemainder > numTolerance) {
         numPower = numPower / 10;
         ++intPrecision;
         numRemainder = this.valueOf() % numPower;
      }
   }
   return intPrecision;
}

Number.prototype.intRange = function(min, max) {
   if (isNaN( this.valueOf() )) return min;
   if (isUndefined(max)) return Math.max( min, this.valueOf().floor() );
   return Math.max( min, Math.min(max, this.valueOf().floor()) );
};

Number.prototype.floatRange = function(min, max) {
   if (isNaN( this.valueOf )) return min;
   if (isUndefined(max)) return Math.max( min, this.valueOf() );
   return Math.max( min, Math.min(max, this.valueOf()) );
};

/** Date.equals
 * returns true if the argument date has the same value
 */
Date.prototype.equals = function (date) {
   if (typeof date != 'object' || ! ( date instanceof Date ) ) {
      return false;
   }
   return !( this.valueOf() > date || this.valueOf() < date );
}
/** Date.round
 * Sets the time to midnight
 */
Date.prototype.round = function () {
   this.setHours(0);
   this.setMinutes(0);
   this.setSeconds(0);
   this.setMilliseconds(0);
   return this;
}
/** Date.copy
 * returns a new instance with the same time
 */
Date.prototype.copy = function () {
   return new Date(this.getTime());
}
/** Date.daysInMonth
 * returns the number of days in the month
 */
Date.prototype.daysInMonth = function () {
   var i, dateLoop;
   for (i = 31; i >= 28; --i) {
      dateLoop = this.copy();
      dateLoop.setDate(i);
      if (dateLoop.getDate() == i) {
         return i;
      }
   }
   return 0;
}
/** Date.getDayOfWeek
 * returns the number of the day of the week starting monday = 0;
 */
Date.prototype.getDayOfWeek = function() {
   return (this.getDay() + 6) % 7;
}
/** Array.add
 * custom 'push' method that works in IE 5.2 Mac
 */
Array.prototype.add = function (value) {
   this[ this.length ] = value;
}
