/**
 * @namespace GA_project
 * @sdoc ga.sdoc
 * @id GA
 */
typeof GA == 'undefined' && (GA = {})
/** @id GA.eventWatcherClass */
GA.eventWatcherClass = function(eventType, nodeClassName, onInMethodName, onOutMethodName) {
  //если нет параметров выходим.
  if (!eventType || !nodeClassName) return;
  var s,
  eventWatcherParams = {
    'onIn': onInMethodName || false,
    'onOut': onOutMethodName || false
  };
  this.watchedEvents = {};
  if (nodeClassName.constructor == RegExp) {
    eventWatcherParams.classReg = nodeClassName
  } else {
    s  = '(?:\\s|^)'+nodeClassName+'(?:\\s|$)';
    eventWatcherParams.classReg = new RegExp(s);
    if (typeof eventWatcherParams.classReg.compile != 'undefined') {
      eventWatcherParams.classReg.compile(s)
    }
  }
  eventType.constructor != Array && (eventType = [eventType]);
  for (var i = eventType.length; i--; ) {
    this.watchedEvents[eventType[i]] = 
      this.methodIntoEventProcessing('eventProcessing', eventType[i], document, eventWatcherParams)
  }
}
GA.eventWatcherClass.removeEventProcessing = document.addEventListener ?
  function(sEvent, handler, oNode) {
    oNode.removeEventListener(sEvent, handler, false)
  }:
  function(sEvent, handler, oNode){
    oNode.detachEvent('on'+sEvent, handler)
  }
GA.eventWatcherClass.prototype = {
  'eventProcessing': function(oNode, pos, e, eventWatcherParams) {
    var initialNode = oNode;
    do {
      if (/*this.*/eventWatcherParams.classReg.test(oNode.className)) {
        // событие произошло на узле с заданным классом.
        return /*this.*/eventWatcherParams.onIn ?
          this[/*this.*/eventWatcherParams.onIn](oNode, pos, e):
          null
      }
    } while (oNode = oNode.parentNode);
    // событие произошло вне узла с заданным классом.
    return /*this.*/eventWatcherParams.onOut?
      this[/*this.*/eventWatcherParams.onOut](initialNode, pos, e):
      null
  },
  'methodIntoEventProcessing': document.addEventListener ?
  function(methodName, sEvent, oNode, oParams) {
    var handler = (
      function(obj, methodName, oParams) {
        return function(e) {
          obj[methodName](e.target, {'x': e.pageX, 'y': e.pageY}, e, oParams) === false && e.preventDefault()
        }
      }
    )(this, methodName, oParams || null);
    oNode.addEventListener( sEvent, handler, false );
    return handler
  }:
  function(methodName, sEvent, oNode, oParams) {
    var handler = (
      function(obj, methodName, oParams) {
        return function() {
          var e = window.event,
          r = {
            'x': e.clientX + document.documentElement.scrollLeft ,
            'y': e.clientY + document.documentElement.scrollTop
          };
          if (document.body) {
            r.x += document.body.scrollLeft;
            r.y += document.body.scrollTop
          }
          e.srcElement &&
          obj[methodName](e.srcElement, r, e, oParams) === false &&
            (e.returnValue = false)
        }
      }
    )(this, methodName, oParams || null);
    oNode.attachEvent('on'+sEvent, handler);
    return handler
  }
}
