////////////////////////////////
/* -- Create Observer References -- */
/*  Note: each observer only listens to a given event type. When an event fires, 'Observables' 
    notify (or use) only those observers who have signed up for the given event.
    Ex. a form input (observable) fires a 'focus' event. The event is passed on to a containing div (observer) which in turn changes its own background color.
*/


function JMakeObserverRelationshipsUtil(){};

/**
*Create 'one to many' observer references between an element (observable) and another element (observer)
*One observer is watching many observables WITHIN ANY given container
* @author Hans Brough
* @member JMakeObserverRelationshipsUtil
* @param {Object} _ObserverCache        cache of element(s) (many) which potentially watch another element
* @param {Object} _ObservableCache      cache of element(s) (one) which are each assigned many observers
* @param {Object} _ObservableElem       dom element that will serve as the thing being observed
* @param {Array}  _observableTypeArgs   set of arguments that help find a given type of observable
* @param {String} eventType             name of event fired by observable and listend for by observers
* @param {Object} _container            dom element in which to start searching for elements that match description of observers in which we are interested
* @return                               returns nothing. adds observers to Observable.
*/
JMakeObserverRelationshipsUtil.relateOneToMany = function(_ObserverCache,_ObservableCache,_ObservableElem,_observingTypeArgs,eventType,_container){
  //Grab refs to all observable elems in a given element and format for ingest
  var _obslist = [];
  var _observingElemsInContainer = getElemIdsByTypeAndAttributeValue(_observingTypeArgs[0],_observingTypeArgs[1],_observingTypeArgs[2],_container);
  //create/format single observer entry and add to master list of observer relationships to ingest
  for(var x=0;x<_observingElemsInContainer.length;x++){
    var _currObsElemId = _observingElemsInContainer[x];
    var _obsEntry = [_ObservableElem.id,_ObserverCache.elements[_currObsElemId],eventType];
    _obslist.push(_obsEntry);
  }
    
  //Store the observer relationship(s). As user interacts with page these references are looked up and potentially acted upon in some way.
  _ObservableCache.ingestObservers(_obslist);
  return;
}  

/*  ----- 
  Create 'one to many' observer references between an element (observable) and another element (observer)
  One observer is watching many observables WITHIN ITSELF only
  this mapping ultimately helps in notifying an observer element that one of their observables has fired a focus event
  "_observableTypeArgs" = set of arguments that help find a given type of observable
----- */
JMakeObserverRelationshipsUtil.relateOneToManyWithSameEvent = function(_ObserverCache,_ObservableCache,_observableTypeArgs,eventType){
  //Grab refs to all observable elems in each container and format for ingest
  var _obslist = [];
  for(var elem in _ObserverCache.elements){
    var _observableElemsInContainer = getElemIdsByTypeAndAttributeValue(_observableTypeArgs[0],_observableTypeArgs[1],_observableTypeArgs[2],_ObserverCache.elements[elem]);
    //create/format single observer entry and add to master list of observer relationships to ingest
    for(var x=0;x<_observableElemsInContainer.length;x++){
      var _obsEntry = [_observableElemsInContainer[x],_ObserverCache.elements[elem],eventType];
      _obslist.push(_obsEntry);
    }
  }   
  
  //Store the observer relationship(s). As user interacts with page these references are looked up and potentially acted upon in some way.
  _ObservableCache.ingestObservers(_obslist);
  return;
}  

//Associate an observer with several observables within a given containing element
JMakeObserverRelationshipsUtil.relateOneToManyInContainer = function(_Observer,_ObservableCache,_observableTypeArgs,eventType,_container){
  //Grab refs to all observable elems in each container and format for ingest
  var _obslist = [];
    var _observableElemsInContainer = getElemIdsByTypeAndAttributeValue(_observableTypeArgs[0],_observableTypeArgs[1],_observableTypeArgs[2],_container);
    //create/format single observer entry and add to master list of observer relationships to ingest
    for(var x=0;x<_observableElemsInContainer.length;x++){
      var _obsEntry = [_observableElemsInContainer[x],_Observer,eventType];
      _obslist.push(_obsEntry);
    }
  
  //Store the observer relationship(s). As user interacts with page these references are looked up and potentially acted upon in some way.
  _ObservableCache.ingestObservers(_obslist);
  return;
}  


/* -----
  Create 'one to one' observer references between elements.
  Example:Each form input has an observing <p> element in which to display messages.
----- */
JMakeObserverRelationshipsUtil.relateOneToOneWithDiffEvents = function(_ObserverCache,_ObservableCache,_observerTypeArgs){
  //Grab refs to all observer elems that match atrribute name/values we are seeking
  var _obslist = [];
  var _matchingObserverElems = getElemIdsByAttributeName(_observerTypeArgs[0],_observerTypeArgs[1],null);
  //create/format single observer entry and add to master list of observer relationships to ingest
  for(var x=0;x<_matchingObserverElems.length;x++){
    var _observableId = _ObserverCache.elements[_matchingObserverElems[x]].getAttribute(_observerTypeArgs[0]);
    var _observer = _ObserverCache.elements[_matchingObserverElems[x]];
    var _observerEvents = _ObserverCache.elements[_matchingObserverElems[x]].getAttribute('j_event');
    if(_observerEvents){
      var _observerEventList = _observerEvents.split(" ");
      for(var z=0;z<_observerEventList.length;z++){
       	//entry in the form of [id of thing to observe, object ref to thing doing the observing,the event name]
	 var _obsEntry = [_observableId,_observer,_observerEventList[z]];
        _obslist.push(_obsEntry);
      }
    }
  }  
  
  //Store the observer relationship(s). As user interacts with page these references are looked up and potentially acted upon in some way.
  _ObservableCache.ingestObservers(_obslist);
  return;

}

/* -----
  Create 'many to one' observer reference where all observables are INSIDE the observer unless
  the optional _container argument is passed to specify a different element from which to search within
  Example: many input elements observe one form.
----- */
JMakeObserverRelationshipsUtil.relateManyToOneWithDiffEvents = function(_ObserverCache,_Observable,_observerTypeArgs,_container){
  var _containingElement = (_container)?_container:_Observable;
  //Grab refs to all observable elems that match atrribute name/values we are seeking
  var _obslist = [];
  var _matchingObserverElems = getElemIdsByTypeAndAttributeValue(_observerTypeArgs[0],_observerTypeArgs[1],_observerTypeArgs[2],_containingElement)
  //create/format single observer entry and add to master list of observer relationships to ingest
    for(var x=0;x<_matchingObserverElems.length;x++){
      var _currentObserver = _ObserverCache.elements[_matchingObserverElems[x]];
      var _observerEvents = (_currentObserver==undefined)?false:_currentObserver.getAttribute('j_event');
      //do only if observer has event(s)
      if(_observerEvents){
        //this can be a space delimited list of event types
        var _observerEventList = _observerEvents.split(" ");
        for(var z=0;z<_observerEventList.length;z++){
          //entry in the form of [id of thing to observe, object ref to thing doing the observing,the event name]
          var _obsEntry = [_Observable.id,_currentObserver,_observerEventList[z]];
          _obslist.push(_obsEntry);
        }
      }
    }
  
  //Store the observer relationship(s). As user interacts with page these references are looked up and potentially acted upon in some way.
  _ObserverCache.ingestObservers(_obslist);
  return;

}

  
