/**
 * Unisource Andromeda v. 2.0
 * 
 * Copyright 2007 by High-Touch Communications Inc.
 * 
 * 
 * This software was developed internally by High-Touch Communications Inc.
 * for Unisource. In no event shall this source code be published.
 */
 
/**
* Extension methods for simple data types (e.g. strings, arrays, objects)
*/

Array.prototype.firstMatch = function(predicate){
	return Lambda.first(this, predicate);
};

Array.prototype.lastMatch = function(predicate) {
	return Lambda.last(this, predicate);
}
/*
Array.prototype.select = function(valueFunction) {
	return Lambda.select(this, valueFunction);
}
*/
Array.prototype.sum = function(valueFunction) {
	return Lambda.sum(this, valueFunction);
}

Array.prototype.toDictionary = function(keyFunction, valueFunction) {
	return Lambda.toDictionary(
		this, 
		keyFunction, 
		valueFunction
	);
}

Array.prototype.findIndexOf = function(item) {
	var index = -1;
	for (var i=0;i<this.length;i++) {
		if (item == this[i]) {
			index = i;
			break;
		}
	}
	return index;
}

Array.prototype.move = function(oldIndex, newIndex) {
	if (oldIndex < newIndex) {
		this._moveUp(
			oldIndex, 
			newIndex
		);
	} else if (oldIndex > newIndex) {
		this._moveDown(
			oldIndex, 
			newIndex
		);		
	}
}

Array.prototype._moveUp = function(oldIndex, newIndex) {
	var movingItem = this[oldIndex];
	for (var i=oldIndex;i<newIndex;i++) {		
		this[i] = this[i+1];
	}
	this[newIndex] = movingItem;
}
Array.prototype._moveDown = function(oldIndex, newIndex) {
	var movingItem = this[oldIndex];
	
	for (var i=oldIndex;i>newIndex;i--) {		
		this[i] = this[i-1];
	}
	this[newIndex] = movingItem;
}



String.prototype.replaceAll = function(values){
	var result = this;
	$H(values).each(
		function(entry) {
			result = result.replace(
				entry.key, 
				entry.value
			);
		}
	)	
	
	return result;
};

String.prototype.pad = function(length, character, where) {
	var paddedString;	
	
	switch(where) {
		case 'left':
			paddedString = this.padLeft(length, character);
			break;
		case 'right':
			paddedString = this.padRight(length, character);
			break;
	}
	
	return paddedString;
}

String.prototype.padLeft = function(length, character) {
	var paddedString = this;
	if (!character) {
		character = ' ';
	}
	while (paddedString.length < length) {
		paddedString = character + paddedString;
	}
	return paddedString;
}

String.prototype.padRight = function(length, character) {
	var paddedString = this;
	if (!character) {
		character = ' ';
	}
	
	while (paddedString.length < length) {
		paddedString += character;
	}
	return paddedString;
}



/**
* Converts a hash-like object to a set of parameters,
* suitable for query strings and HTTP posts, which
* will be translated to an array by PHP
*
* @param string name the name of the parameter
*
* @return object
*/
Hash.prototype.toServerArray = function(name) {
	var hash = this;
	var result =
		Lambda.toDictionary(		
			hash.keys(),
			function(key) {
				return name + '[' + encodeURI(key) + ']';
			},
			
			function(key) {
				return encodeURI(hash.get(key));
			}
		);	
		
	return result;
}

Hash.prototype.toHttpString = function() {
	return $H(this).collect(
		function(entry) {
			return encodeURI(entry.key) + '=' + encodeURI(entry.value)
		}
	).join('&');
}

Hash.fromTuples = function(tuples) {
	return tuples.toDictionary(
		function(element) {return element[0]},		
		function(element) {return element[1]}
		
	);
}



/**
* Combines an array of keys and an array of values
* into an associative
*/
Array.toAssociative = function(keys, values) {
	var associative = {};
	
	for (var i=0, length = keys.length; i < length; i++) {
		associative[keys[i]] = values[i];		
	}
	
	return associative;
}

Array.prototype.removeAll = function(elementToRemove) {
	return 
		$A(this)
			.reject(function(element) {return element == elementToRemove})
			.toArray();
}

Function.prototype.getBody = function() {
    var source = this.toString();
    var firstBrace = source.indexOf('{');
    var lastBrace = source.lastIndexOf('}');
    
    var body = source.substring(firstBrace + 1, lastBrace - 1);
    return body;
}

Array.prototype.union = function(second) {
    var result = this.clone();
    
    second.each(
        function(item) {
            result.push(item);
        }
    );
    
    return result.uniq();
}

Array.prototype.except = function(second) {
    return this.findAll(
        function(element) {
            return !second.member(element);
        }
    );
}

