/**
* Simple Javascript eXtension - 1.0
* (c) 2011 - 2015 Steve L. Nyemba, steve@the-phi.com
* License GPL version 3.0
* 
* Implementation of miscellaneous utilities commonly used, These functions are reusable and simple:
* jx.utils.vector				extracts a vector from an array of objects (or a matrix)
* jx.utils.keys					extract keys from an associative array
* jx.utils.unique				returns unique objects in an array, including array of objects (provided an key function)
*
* jx.utils.patterns:
* 		Implementation of design patterns defined by the GOF http://en.wikipedia.org/wiki/Software_design_pattern
* jx.utils.patterns.visitor		The visitor design pattern
* jx.utils.patterns.iterator	The iterator design pattern
* jx.utils.patterns.observer 	The observer design pattern
*
* @TODO:
*	- Find a way to alias jx.utils
*/

if(!jx){
	var jx = {} ;
}

jx.utils={} ;

/**
* Extract an array from an array of associative arrays (map), 
* This function can also perform a sort of join provided a set of keys (good for building a matrix)
* @param key	key or column of the associative array
* @param array	an array or associative arrays i.e [{}]
*/
jx.utils.vector=function(key,rec){
	var vector = [] ;
	var value;
	for(var i=0; i < rec.length; i++){
//		value = rec[i][key] ;	
//                if(key.constructor == String){
//                    vector.push( value ) ;
//                }else
                if(key.constructor == Array){
                    value = []
                    for(ii in key){
                        value.push(rec[i][key[ii]])
                    }
                    
                }else{
                    value = rec[i][key] ;	
                }
            vector.push( value ) ;
	}
	return vector ;

}//-- end jx.utils.vector(key,rec) 

/**
* Extract keys from an associative array
* @param rec	associative array
*/
jx.utils.keys=function(rec){	
	return Object.keys(rec) ;
}//-- end jx.utils.keys
jx.utils.values = function(rec){
	var r = []
    for(id in rec){
    	var value  = rec[id]
        r.push(value)
    }
  
  return r
}
/**
 * This function will returnt he unique elements of a list
 * @param list  list of elements (duplicates are expected)
 */
jx.utils.unique = function (list,getKey){
    var obj = {}
    for(var i=0; i < list.length; i++){
    	if(list[i].constructor == Object && getKey != null){
		var key = getKey(list[i]) ;
		obj[key]  = list[i] ;

	}else{
		obj[list[i]]= 1 ;
	}
    }
    if(getKey == null){
	    return jx.utils.keys(obj);
    }else{
    	//
	// This will return the unique list of objects, provided the user has given a key extraction function
	// The key extraction function is analogous to the equal operator in C++
	//
    	return jx.utils.patterns.visitor(jx.utils.keys(obj),function(id){
		return obj[id] ;
	})
    }
}
jx.utils.join = function(x,y){
	if(x.length != y.length){
		return [] 
	}else{
		var rec = x ;
		for(var i in rec){
			//
			//@TODO: Consider the case we are adding to a matrix
			//
			rec[i] = [x[i],y[i]]
		}
		return rec ;
	}
}
jx.utils.size = function(id){
	if(id.match(/window|screen/i)){
		var width = window.innerWidth
		|| document.documentElement.clientWidth
		|| document.body.clientWidth;	
		var height = window.innerHeight
		|| document.body.clientHeight;
	}else if(jx.dom.exists(id)){
		var element = jx.dom.get.instance(id)
		var width = element.clientWdith
		var height = element.clientHeight
	}
	return {width:width,height:height}
	
}
/**
 * Implementation of a few standard design patterns. Their use is user/dependent
 * For more information on how/when to use a design pattern please use google/wikipedia ;-)
 */
jx.utils.patterns = {}
jx.utils.patterns.visitor = function(list,pointer){
	var rlist = [] ;
    for(var i=0; i < list.length; i++){       
        value = pointer(list[i]) ;
		if(value != null){
			rlist.push(value) ;
		}
    }
    return (rlist.length > 0)?rlist:[];
}
/**
 * Implementation of an iterator design pattern: i.e we use a sequence of objects and call a given method on them
 * This is a basic iterator design pattern 
 */
jx.utils.patterns.iterator = function(list,pointer){
    for(var i=0; i < list.length; i++){
        list[i][pointer]();
    }
}
/**
 * This is an implementation of an observer design pattern, the obervers will just have to call notify on the subject
 * The observers' role is to render some stuff on the ui, having said this, this design pattern is suited for ui & asynchronous tasks
 * @param lobservers	list of observers
 * @param init			pointer to be called on each observer to trigger it
 */
jx.utils.patterns.observer = function(lobservers,init){
	var p = {} ;	//-- specification of the subject
	p.index = 0;
	p.nodes = lobservers ;
	p.pointer = init;
	p.notify = function(){
		//
		// This function is designed to be called by the observers
		//
		if( this.index < this.nodes.length){
			this.start() ;
		}
	}
	p.start = function(){
		var observer = this.nodes[this.index];
		try{
			++this.index;
			if(this.pointer.constructor == String){
				observer[this.pointer](this) ;	
			}else{
				this.pointer(observer);
				this.notify() ;
			}
			
			
			
		}catch(e){
			//
			// if an exception was thrown, chances are were unable to increment and call notify
			// In the spirit of "The show must go on", we will make the notify call here for the failed observer
			//
			++this.index ;
			this.notify();
			
		}
		
	}
	//
	// let's fire the design pattern
	//
	p.start() ;
	return p
}

/**
* Apply a function to an array (visitor-like design pattern)
* @param fn	casting function on the vector or array of data
* @param list	array of numeric data (hopefully)
* @return 	array containing casted type
*/
jx.utils.cast = jx.utils.patterns.visitor ;

