(function(){

// our namespace
if(!window.BNM) { window['BNM'] = {} }

function isCompatible(other) {
  if(other === false
	|| !Array.prototype.push
	|| !Object.hasOwnProperty
	|| !document.getElementById
	|| !document.getElementsByTagName
	) {
	return false;
  }
  return true;
};
window['BNM']['isCompatible'] = isCompatible;

function $() { 
  var elements = new Array();
  
  for (var i=0;i<arguments.length;i++) {
    var element = arguments[i];
    
    // assume the argument is an ID
    if (typeof(element) == 'string') {
      element = document.getElementById(element);
    }
    
    // if only one return immediately
    if (arguments.length === 1) {
      return element;
    }
    // else add to array and...
    elements.push(element);
  }
  // return array
  return elements;
};
window['BNM']['$'] = $;

function addEvent(node, type, listener) { 

  if(!isCompatible()) { return false; }  // compatible or not?
  if(!(node = $(node))) { return false; }  // actual node or not?

  if(node.addEventListener) {
    node.addEventListener(type,listener,false);
    return true;
  } else if(node.attachEvent) {
    node['e'+type+listener] = listener;
    node[type+listener] = function() {
      node['e'+type+listener](window.event);
    }
    node.attachEvent('on'+type,node[type+listener]);
    return true;
  }
  return false; // too f'n old
};
window['BNM']['addEvent'] = addEvent;

function removeEvent(node, type, listener) { 
  if(!(node = $(node))) { return false; }
  
  if(node.removeEventListener) {
    node.removeEventListener(node,listener,false);
    return true;
  } else if(node.detachEvent) {
    node.detachEvent('on'+type,node[type+listener]);
    node[type+listener] = null;
    return true;
  }
  return false; // too f'n old
};
window['BNM']['removeEvent'] = removeEvent;

function getElementsByClassName(className, tag, parent) { 
  parent = parent || document;
  if(!(parent = $(parent))) { return false; }
  
  var allTags = (tag == "*" && parent.all) ? parent.all : parent.getElementsByTagName(tag);
  var matchingElms = new Array();
  
  // regEx to check classname
  className = className.replace(/\-/g, "\\-");
  var regex = new RegEx("(^|\\s)" + className + "(\\s|$)");
  
  var element;
  for(var i=0;i<allTags.length;i++) {
    element = allTags[i];
    if(regex.test(element.className)) {
      mathingElements.push(element);
    }
  }
  // Return any matching elements
  return matchingElements;
};
window['BNM']['getElementsByClassName'] = getElementsByClassName;

function toggleDisplay(node, value) { 
  if(!(node = $(node))) { return false; }
  
  if(node.style.display != 'none') {
    node.style.display = 'none';
  } else {
    node.style.display = value || '';
  }
  return true;
};
window['BNM']['toggleDisplay'] = toggleDisplay;

function insertAfter(node, refNode) { 
  if(!(node = $(node))) { return false; }
  if(!(refNode = $(refNode))) { return false; }
  return refNode.parentNode.insertBerfore(node, refNode.nextSibling);
};
window['BNM']['insertAfter'] = insertAfter;

function removeChildern(parent) { 
  if(!(parent = $(parent))) { return false; }
  
  // While they is a child remove it
  while(parent.firstChild) {
    parent.firstChild.parentNode.removeChild(parent.firstChild);
  }
  
  // return parent again so you can chain the methods
  return parent;
};
window['BNM']['removeChildern'] = removeChildern;

function prependChild(parent, newChild) { 
  if(!(parent = $(parent))) { return false; }
  if(!(newChild = $(newChild))) { return false; }
  
  if(parent.firstChild) {
    // there is already a child so insert it before the first one
    parent.insertBefore(newChild,parent.firstChild);
  } else {
    parent.appendChild(newChild);
  }
  // return parent again so you can chain them
  return parent;
};
window['BNM']['prependChild'] = prependChild;

function bindFunction(obj, func) {
  return function() {
    func.apply(obj,arguments);
  }
}
window['BNM']['bindFunction'] = bindFunction;

function getBrowserDimensions() {
	var de = document.documentElement;
	return {
		'width': (
			window.innerWidth
			|| (de && de.clientWidth)
			|| document.body.clientWidth),
		'height': (
			window.innerHeight
			|| (de && de.clientHeight)
			|| document.body.clientHeight)
	}
}
window['BNM']['getBrowserDimensions'] = getBrowserDimensions;

function walkElementsLinear(func,node) {
	var root = node || window.document;
	var nodes = root.getElementsByTagName('*');
	for(var i=0;i<nodes.length;i++) {
		func.call(nodes[i]);
	}
}
window['BNM']['walkElementsLinear'] = walkElementsLinear;

function walkDOMRecursive(func,node,depth,returnedFromParent) {
	var root = node || window.document;
	var returnedFromParent = func.call(root,depth++,returnedFromParent);
	var node = root.firstChild;
	while(node) {
		walkDOMRecursive(func,node,depth,returnedFromParent);
		node = node.nextSibling;
	}
}
window['BNM']['walkDOMRecursive'] = walkDOMRecursive;

/* convert word-word to wordWord... super useful... */
function camelize(s) {
	return s.replace(/-(\w)/g,function (strMatch, p1) {
		return p1.toUpperCase();
	});
}
window['BNM']['camelize'] = camelize;
	
window['BNM']['node'] = {
		ELEMENT_NODE : 1,
		ATTRIBUTE_NODE : 2,
		TEXT_NODE : 3,
		CDATA_SECTION_NODE : 4,
		ENTITY_REFERENCE_NODE : 5,
		ENTITY_NODE : 6,
		PROCESSING_INSTRUCTION_NODE : 7,
		COMMENT_NODE : 8,
		DOCUMENT_NODE : 9,
		DOCUMENT_TYPE_NODE : 10,
		DOCUMENT_FRAGMENT_NODE : 11,
		NOTATION_NODE : 12
};

})();  // end of fake ECMA Script namespace....


/* Rev up the String Object prototype...... */

// repeat a string
if(!String.repeat) {
	String.prototype.repeat = function(l) {
		return new Array(l+1).join(this);
	}
}

// removing trailing and leading whitespace
if(!String.trim) {
	String.prototype.trim = function() {
		return this.replace(/^\s+|\s+$/g,'');
	}
}

