/**
 * 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.
 */
 
/**
* A collection of functions that can be performed on lambda-style functions
*/
Lambda = {
	/**
	* Returns the first element that satisfies
	* a predicate
	*
	* @param Array 		sequence   a sequence of items
	* @param Function   predicate  a function accepting a single
	*		element of the sequence as an argument and returning
	*		a Boolean
	*
	* @return mixed
	*/
	first : function(sequence, predicate) {
		var item = null;
		for (var i = 0, length = sequence.length ; i < length; i++) {
			if (predicate(sequence[i])) {
				item = sequence[i];
				break;
			}
		}	
		return item;
	},
	
	/**
	* Returns the last element that satisfies
	* a predicate
	*
	* @param Array 		sequence   a sequence of items
	* @param Function   predicate  a function accepting a single
	*		element of the sequence as an argument and returning
	*		a Boolean
	*
	* @return mixed
	*/
	last : function(sequence, predicate) {
		var item = null;
		for (var i = sequence.length - 1; i >= 0; i--) {
			if (predicate(sequence[i])) {
				item = sequence[i];
				break;
			}
		}	
		return item;
	},	
	
	/**
	* Returns all elements in a sequence that satisfy a predicate
	*
	* @param Array 		sequence   a sequence of items
	* @param Function   predicate  a function accepting a single
	*		element of the sequence as an argument and returning
	*		a Boolean
	*
	* @return Array
	*/
	all : function(sequence, predicate) {
		var items = [];
		
		for (var i=0,length = sequence.length; i<length; i++) {
			if (predicate(sequence[i])) {
				items.push(sequence[i]);
			}
		}
		
		return items;
	},
	
	/**
	* Applies valueFunction to each element of the array and
	* returns an array of results (similar to LINQ's Select)
	*
	* @return Array
	*/
	select: function(sequence, valueFunction) {
		var length = sequence.length;
		var result = new Array(length);
		
		for (var i=0; i < length; i++) {
			result[i] = valueFunction(sequence[i]);
		}
		
		return result;
	},
	
	/**
	* Finds the sum of elements in a sequence, using valueFunction to
	* obtain the value of each element
	*
	* @return Number
	*/
	sum : function(sequence, valueFunction) {
		var sum = 0.0;
		if (!valueFunction) {
			valueFunction = function(item) {return item };
		}
		for (var i=0, length = sequence.length; i < length; i++) {
			sum += valueFunction(sequence[i]);
		}
		
		return sum;
	},
	
	toDictionary : function(sequence, keyFunction, valueFunction) {
		var dictionary = {};
		
		if (valueFunction == null) {
			valueFunction = function(item) {return item; }
		};
		
		for (var i = 0, length = sequence.length; i < length ; i++) {
			var original = sequence[i]
			dictionary[keyFunction(original)] =
				valueFunction(original);
		}
		
		return $H(dictionary);
	}
	
};


