var elements; // (new SettignsElements()) присваивается в onBodyStart; SettignsElements объявляется на странице
var createdElements = {};
var dom = {
	ie: navigator.userAgent.indexOf("MSIE") > -1,
	ie6: navigator.userAgent.indexOf("MSIE 6") > -1,
	ie7: navigator.userAgent.indexOf("MSIE 7") > -1,
	ie8: navigator.userAgent.indexOf("MSIE 8") > -1,
	opera: navigator.userAgent.indexOf("Opera") > -1,
	fox: navigator.userAgent.indexOf("Firefox") > -1,
	scrollSpeedInPage: .8,
	get: function(parent, tagName, className, attrHash) {
		// parent - родитель, или массивHTML-элементов или нодесет 
		// tagName - строка
		// className - строка или массив
		// attrHash - объект { name: value }
		var tags, ret;
		if (parent.length) {
			ret = dom.nodesetToArray(parent);
			if (tagName=="*") {
				for (var i=0, l=ret.length, r, ok; i<l; i++) {
					if ( ret[i].nodeType!=1 ) {
						ret.splice(i, 1);
						i--;
						l--;
					}
				}
			} else {
				for (var i=0, l=ret.length, r, ok; i<l; i++) {
					if ( (ret[i].tagName || "").toLowerCase() != tagName.toLowerCase() ) {
						ret.splice(i, 1);
						i--;
						l--;
					}
				}
			}
		} else if (parent.constructor==Array) {
			return [];
		} else {
			ret = dom.nodesetToArray( parent.getElementsByTagName( tagName ) );
		}
		if (className) {
			for (var i=0, l=ret.length, r, ok; i<l; i++) {
				r = ret[i];
				ok = true;
				if (className.constructor == Array) {
					for (var i2=0, l2=className.length, c; ok, i2<l2; i2++) {
						c = className[i2];
						ok = true;
						if ( !dom.hasClass( r, c ) ) ok = false;
					}
				} else if (className) {
					if ( !dom.hasClass( r, className ) ) ok = false;
				}
				if (!ok) {
					ret.splice(i, 1);
					i--;
					l--;
				}
			}
		}
		if (attrHash) {
			for (var i=0, l=ret.length, r, ok; i<l; i++) {
				r = ret[i];
				ok = true;
				for (var attrName in attrHash) {
					if ( !dom.hasAttr(r, attrName, attrHash[attrName]) ) ok = false;
				}
				if (!ok) {
					ret.splice(i, 1);
					i--;
					l--;
				}
			}
		}
		return ret || [];
	},
	precedingSiblings: function(node) {
		var ret = [];
		var cur = node;
		while(cur.previousSibling) ret.push(cur = cur.previousSibling);
		return ret;
	},
	followingSiblings: function(node) {
		var ret = [];
		var cur = node;
		while(cur.nextSibling) ret.push(cur = cur.nextSibling);
		return ret.reverse();
	},
	ancestors: function(node) {
		var ret = [];
		while(node = node.parentNode)
         if (node.nodeType == 1) ret.push(node);
		return ret;
	},
	descendants: function(node, nodeType) {
		var ret = [];
		f(ret, node.firstChild);
		if (typeof(nodeType)=="number") {
			var ret2 = [];
			for (var i=0, l=ret.length; i<l; i++) {
				if (ret[i].nodeType == nodeType) ret2.push(ret[i]);
			}
			return ret2;
		} else {
			return ret;
		}
	 
		function f(arr, cur) {
			arr.push(cur);
			if (cur.firstChild) f(arr, cur.firstChild);
			if (cur.nextSibling) f(arr, cur.nextSibling);
		}
	},
	cr: function(tagName, className, inside, attrHash, propHash, listenersHash) {
		var ret = document.createElement( tagName );
		if (className) ret.className = className;
		if (inside) {
			if ( typeof(inside)=="string" ) {
				ret.innerHTML = inside;
			} else if (inside.constructor == Array) {
				for (var i=0, l=inside.length; i<l; i++) {
					if (inside[i].nodeType) ret.appendChild(inside[i]);
				}
			} else if (inside.nodeType) {
				ret.appendChild(inside);
			}
		}
		if (attrHash) {
			for (var name in attrHash) ret.setAttribute(name, attrHash[name]);
		}
		if (propHash) {
			for (var name in propHash) ret[name] = propHash[name];
		}
		if (listenersHash) {
			dom.addListener(ret, listenersHash);
		}
		return ret;
	},
	rem: function(node) {
		return node.parentNode.removeChild( node );
	},
	clear: function(node) {
		while(node.firstChild) node.removeChild(node.firstChild);
		return node;
	},
	text: function(node) {
		return String(node.textContent || node.innerText);
	},
	nodesetToArray: function(nodeset) {
		var ret = [];
		for (var i=0, l=nodeset.length, r, ok; i<l; i++) {
			ret[i] = nodeset[i];
		};
		return ret;
	},
	nodesetHasNode: function(nodeset, node) {
		for (var i=0, l=nodeset.length, r, ok; i<l; i++) {
			if (node == nodeset[i]) return true;
		};
		return false;
	},
	hasClass: function(node, need) {
		return (new RegExp("(^|\\s)"+ (need || "").toLowerCase().replace(/\-/g, "\\-") +"(\\s|$)")).test( (node.className || "").toLowerCase() );
	},
	hasAttr: function(node, name, need) {
		return (new RegExp("(^|\\s)"+ need +"(\\s|$)")).test( node.getAttribute(name) );
	},
	addClass: function(node, name) {
		if (!dom.hasClass(node, name)) node.className += " " + name;
		return node;
	},
	remClass: function(node, name) {
		node.className = node.className.replace( new RegExp("(^|\\s)"+ name +"(\\s|$)"), " ");
		return node;
	},
	style: function(node, styleName, toInt) {
		if ( !document.defaultView && styleName.indexOf("-")>-1) {
			styleName = styleName.replace(/-top/, "Top");
			styleName = styleName.replace(/-right/, "Right");
			styleName = styleName.replace(/-bottom/, "Bottom");
			styleName = styleName.replace(/-left/, "Left");
		}
		var ret = document.defaultView 
			? document.defaultView.getComputedStyle(node, null).getPropertyValue(styleName)
			: node.runtimeStyle[styleName] || node.style[styleName] || node.currentStyle[styleName];
		if (toInt) ret = parseInt(ret);
		return ret;
	},
	xy: function(node) {
		var x = 0, y = 0;
		while(node.offsetParent) {
			x += node.offsetLeft;
			y += node.offsetTop;
			node = node.offsetParent;
		}
		return [x, y];
	},
	whStyle: function(node, toggleVisibility) {
		if (toggleVisibility) {
			node.style.visibility = "hidden";
			node.style.display = "block";
		}
		if (dom.opera) {
			var ret = ret = [ parseInt(dom.style(node, "width")), parseInt(dom.style(node, "height"))];
			ret[0] -= dom.style(node, "border-left", 1) + dom.style(node, "padding-left", 1) + dom.style(node, "padding-right", 1) + dom.style(node, "border-right", 1);
			ret[1] -= dom.style(node, "border-top", 1) + dom.style(node, "padding-top", 1) + dom.style(node, "padding-bottom", 1) + dom.style(node, "border-bottom", 1);
		} else {
			var ret = [ parseInt(dom.style(node, "width")), parseInt(dom.style(node, "height"))];
		}
		if (toggleVisibility) {
			node.style.display = "none";
			node.style.visibility = "visible";
		}
		return ret;
	},
	addListener: function(node, listeners) {
		if (node==="body") node = document.getElementsByTagName("body")[0];
		if (node.addEventListener) {
			for (var name in listeners) {
				node.addEventListener(name, listeners[name], false);
			}
		} else {
			for (var name in listeners) {
				node.attachEvent("on"+ name, listeners[name]);
			}
		}
	},
	remListener: function(node, listeners) {
		if (node==="body") node = document.getElementsByTagName("body")[0];
		if (node.addEventListener) {
			for (var name in listeners) {
				try {
					node.removeEventListener(name, listeners[name], false);
				} catch(er) { ; }
			}
		} else {
			for (var name in listeners) {
				try {
					node.detachEvent("on"+ name, listeners[name]);
				} catch(er) { ; }
			}
		}
	},
	stopEvent: function(evt) {
		var evt = evt || window.event;
		if (evt.stopPropogandation) evt.stopPropogandation();
		if (evt.preventDefault) evt.preventDefault();
		evt.returnValue = false;
		evt.cancelBubble = true;
		return false;
	},
/*	braceNL: function(ul) {
		var ul = ul || document.getElementById("nl");
		var li = dom.get(ul.childNodes, "li");
		var count = li.length;// li.length -1;
		var lastLi = li[li.length-1];
		if (lastLi.offsetTop != li[0].offsetTop) return; // меню на двух строках
		var x1 = lastLi.offsetLeft + lastLi.offsetWidth;
		var x2 = ul.offsetWidth;
		var d = x2 - x1;
		if (d>0) {
			var dItem = Math.floor(d / count);
			var dItemHalf = Math.floor((d / count) /2);
			for (var i=0, pl, pr; i<count-1; i++) {
				li[i].style.paddingLeft = dom.style(li[i], "padding-left", true) + dItemHalf +"px";
				li[i].style.paddingRight = dom.style(li[i], "padding-right", true) + dItemHalf +"px";
			}
			if (lastLi.offsetTop != li[0].offsetTop) return; // меню на двух строках
			x1 = lastLi.offsetLeft + lastLi.offsetWidth;
			x2 = ul.offsetWidth;
			d = x2 - x1;
			if (d) {
				//lastLi.style.paddingLeft= (parseInt(lastLi.style.paddingLeft) || 0) + d - (dom.fox || dom.ie8 ? 1 : 0 ) +"px";
			}
		}
		if (dom.fox) {
			ul.style.display = "none";
			ul.style.display = "block";
		}
	},

*/

	braceNL: function(ul) {
		var ul = document.getElementById("menu");
		var li = dom.get(ul.childNodes, "a");
		var count = li.length;// li.length -1;
		var lastLi = li[li.length-1];
		if (lastLi.offsetTop != li[0].offsetTop) return; // меню на двух строках
		var x1 = lastLi.offsetLeft + lastLi.offsetWidth;
		var x2 = ul.offsetWidth;
		var d = x2 - x1;
		if (d>0) {
			var dItem = Math.floor(d / count);
			var dItemHalf = Math.floor((d / count) /2);
			li[0].style.paddingRight = dom.style(li[0], "padding-right", true) + dItemHalf +"px";
			for (var i=1, pl, pr; i<count; i++) {
				li[i].style.paddingLeft = dom.style(li[i], "padding-left", true) + dItemHalf +"px";
				li[i].style.paddingRight = dom.style(li[i], "padding-right", true) + dItemHalf +"px";
			}
			if (lastLi.offsetTop != li[0].offsetTop) return; // меню на двух строках
			x1 = lastLi.offsetLeft + lastLi.offsetWidth;
			x2 = ul.offsetWidth;
			d = x2 - x1;
			if (d) {
			//	lastLi.style.paddingLeft = (parseInt(lastLi.style.paddingLeft) || 0) + d - (dom.fox || dom.ie8 ? 1 : 0 ) +"px";
			}
		}
		if (dom.fox) {
			ul.style.display = "none";
			ul.style.display = "block";
		}
	}

	
}

/* defer */
// 0. onBodyStart вызывается инлайновым скриптом или из onDOMContentLoaded

function onBodyStart() {
	dom.braceNL();
}

function onDOMContentLoaded(root) {
	// верстка загружена
	dom.braceNL();// могла не вызваться из HTML 
}

if (typeof(document.readyState)!="undefined") {
	var _timer = setInterval(function() {
		if (/loaded|complete/.test(document.readyState)) {
			clearInterval(_timer);
			delete _timer;
			onDOMContentLoaded();
		}
	}, 10);
} else if (window.addEventListener) {
    window.addEventListener('DOMContentLoaded', onDOMContentLoaded, false);
} else {
	onDOMContentLoaded();
}


/* / defer */

// запрещаем ие6 перезагружать фоновые картинки при a:hover
try{ if (typeof(document.execCommand && !window.XMLHttpRequest)!="undefined") document.execCommand("BackgroundImageCache", false, true) }
catch(er) { }
