// Режим дебага моей JS системы
SYSDEBUG=1;

// Абстрактный объкт, для реализаций ООП стиля на JS 
function NS()
{
	// включить отладку для этого объекта
	this.debug=SYSDEBUG;
	
	// присоединить html-объект к системе
	this.a=function (id,name) {this[name]=sys.g(id); if(sys.g(id))sys.g(id).object=this;}
	// присоединить копируемый html-объект к системе
	this.ac=function (id,name) {
		this.a(id,name);
		for(var i=2; str=this.ac.arguments[i]; i++) {
			if (!this["ASSIGN"+str]) {this["ASSIGN"+str]={};} 
			this["ASSIGN"+str][name]=id;
		}
	}
	// скопировать объект, вместе с html-объектами
	this.copyObj=function (what,where,count,new_i,simpleName) {
		var pr="%".repeat(count);
		var n=sys.nodeCopy(what,where,new_i,null,pr);
		var r=new RegExp(pr);
		sys.d(n,1);
		for(var ii in this["ASSIGN"+count]) {
			this.a(this["ASSIGN"+count][ii].replace(r,new_i),ii.replace(r,new_i));
			if (simpleName) this.a(this["ASSIGN"+count][ii].replace(r,new_i),ii.replace(r,""));
		}
		return n;
	}
	// Отладочное сообщение о присоединении html-объекта 
	this.trace_obj=function(str,id,name) {
		if (sys.g(id)) {str="OK "+str+";";} else {str="ERR "+str+";";}
		this.c(str,id+";",name);
	}
	// Вывести отладочное сообщение
	this.c=function(q,w,e) {
		if (this.debug && console && console.log) {
			console.log(q,w,e);
			//if (!("console" in window) || !("firebug" in console)) {if (typeof(w)=="object") {console.dir(w);}}
		}
	}
	// Добавить в объект свойства из массива	
	this.def=function(obj,fi) {
		for(var i in fi) {if (!this["N"+fi[i]]) {this["N"+fi[i]]=obj["N"+fi[i]];}}
	}
}




// Разные полезные функции
function SYSTEM()
{
	var ths=this;
	this.none=function() {;}
	
	// Получить объект консоли
	this.dg=function() {
		if (console) {
			return console;
		} else {
			return {log:none,debug:none,info:none,warn:none,error:none,assert:none,dir:none,dirxml:none,trace:none,group:none,groupCollapsed:none,groupEnd:none,time:none,timeEnd:none,profile:none,profileEnd:none,count:none};
		}
	}
	// Получить rgb характеристики цвета из стринги
	this.create_color = function (color){
		if (color.substr(0,3)=='rgb')
		{
			return color.substr(4,color.length-5).split(',');
		}
		else if (color.length==4)
		{
			var q=color.substr(1,1);
			var w=color.substr(2,1);
			var e=color.substr(3,1);
			return [parseInt(q+''+q, 16),parseInt(w+''+w, 16),parseInt(e+''+e, 16)];
		} else {
			return [parseInt(color.substr(1,2), 16),parseInt(color.substr(3,2), 16),parseInt(color.substr(5,2), 16)];
		}
	};
	

	
	// Создать текстовый нод
	this.textCreate=function(val) {return document.createTextNode(val);}
	// Создать hidden поле
	this.hidCreate=function(nm,v) {n=document.createElement("input");n.type="hidden";n.value=v;n.name=nm;return n;}
	// Создать произвольный тэг
	this.tagCreate=function(a) {if (!a) {a="DIV";} return document.createElement(a);}
	// Преобразовать html в ноды
	this.create=function(html,doc,mode) {var t; doc=doc||document; t=doc.createElement("DIV"); t.innerHTML=html; if (mode) return t; else return t.firstChild;}
	
	
	
	// Удалить нод
	this.remove=function (node) {if (node && node.parentNode) return node.parentNode.removeChild(node);}
	// Удалить сам нод
	this.removeSaveChildren=function (node) {while(node.childNodes[0]) {node.parentNode.insertBefore(node.childNodes[0],node);} this.remove_node(node);} 
	// Удалить всех детей нода
	this.clearNode=function (node) {while(node.firstChild) {node.removeChild(node.firstChild)}}
	
	
	
	// Скопировать нод в другой нод (to) перед before и заменить подстроку format на id в полях: id,name 
	this.nodeCopy=function (node,to,id,before,format) {if (node && to) {nn=this.insert(node.cloneNode(1),to,before); this.node_go_id(nn,id,format); /*if (!this.is_ie) {this.copy_prop_r(nn,node);}*/ return nn;}}
	// Вставить нод в др нод перед его поднодом
	this.insert=function(node,parent,before) {parent=parent||node.parentNode; if (before) {return parent.insertBefore(node,before);} else {return parent.appendChild(node);}}
	// Вставить нод в конец документа
	this.docAppend=function() {return document.body.appendChild(document.createElement("DIV"));}
	
	
	
	// getElementById
	this.g=function (s) {return document.getElementById(s);}
	// обойти всех детей и к каждому применить функцию
	this.go=function (node,f) {if (node.nodeType==1) {f(node); for(var i=0;i<node.childNodes.length;i++) {this.go(node.childNodes[i],f);}}}
	// найти форму в которой мы находимся
	this.getForm=function (n) {return this.parent(n,function(n) {if (n.nodeName=='FORM') {return 1;} return 0;});}
	// ищет парент-нод по заданному критерию (функции)
	this.parent=function (p,f) {while(true) {if (p.nodeName=='BODY' || p.nodeName=='#document') {return false;} else if (f(p)) {return p;} else {p=p.parentNode;}}}
	
	
	// получить уникальный номер, число
	this.uid=function() {this.uidv++; return this.uidv;}
	// получить случайный md5-hex
	this.hex=function() {
		var a=['1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f'];
		var str='';
		for(var i=0;i<32;i++) {str+=a[sys.rand(0,15)];}
		return str;
	}
	// получить случайное целое от до
	this.rand=function(min,max) {return Math.round(Math.random()*(max-min))+min;}
	// соединить 2 объекта (массива) в один
	this.merge=function (o1,o2) {if (!o2) {return o1;}for (var i in o2) {o1[i]=o2[i];} return o1;}
	// текущий timestamp
	this.getTime=function () {return new Date().getTime();}
	// вернуть разность двух времен (timeEnd по умолчанию текущее) в сеундах
	this.getTimeDelta=function (timeBegin, timeEnd) {timeEnd = timeEnd || getTime(); return timeEnd - timeBegin;}

	
	
	// показать или скрыть элемент, при a=-1 - toggle
	this.d=function (node,a) {if (a==1 || (a==-1 && node.style.display=='none')) {node.style.display='';} else {if (node.style.display!='none') {node.style.display='none';}}}
	// проверить скрыт ли элемент
	this.is_d=function(node) {return (node.style.display=='none');}
	// неразрешать выделять элемент
	this.unsel=function(node) {
	  node.style.MozUserSelect = "none";
	  node.style.WebkitUserSelect = "none"; //seems to have no effect
	  node.unselectable = "on";
	  node.onselectstart = function() {return false;};
	}
	// задисаблить элемент, а==-1 - toggle
	this.dis=function (node,a) {if (a==1 || (a==-1 && node.disabled==0)) {node.disabled=1;} else {if (node.disabled!=0) {node.disabled=0;}}}
	// задать полупрозрачность элементу
	this.opac=function(node,opac) {
		node.style.opacity = opac;
		node.style.KhtmlOpacity = opac;
		node.style.filter = 'alpha(opacity=' + opac*100 + ')';
	}
	

	this.fromTextToHTML=function (t) {
		t=t.replace(/\n/ig,"<BR\/>");
		return t;
	}
	// From html to textarea
	this.fromHTMLToText=function (t) {
		t=t.replace(/<BR>/ig,"\n");
		t=t.replace(/<BR\/>/ig,"\n");
		t=t.replace(/<BR \/>/ig,"\n");
		t=t.replace(/&#32;/ig," ");
		t=t.replace(/&nbsp;/ig," ");
		return t;
	}
	// проверить строку на пробельные символы
	this.check_empty=function(val) {
		return val.replace(/[ \x0a\x0d]/g,"");
	}
	// заданный якорь в фокус
	this.moveToAnchor=function (n,how) {
		if (typeof(n)=='string') {var tn=n; n=''; for(var i=0;i<document.anchors.length; i++) {if (document.anchors[i].name==tn) {n=document.anchors[i]; break;}}}
		if (n) {n.scrollIntoView(how);}
	}
	
	
	
	// отформатировать размер
	this.lsize=function(sz) {
		if (sz>1024*1024) {sz=Math.round(sz/(1024*10.24))/100+' Гб';}
		else if (sz>1024) {sz=Math.round(sz/(10.24))/100+' Мб';}
		else if (sz>1) {sz=Math.round(sz)+' Кб';}
		else if (sz<3/1024) {sz=Math.round(sz*1024*8)+' бит';}
		else {sz=Math.round(sz*1024)+' б';}
		return sz;
	}
	// отформатировать падежи
	this.lnumb=function(num,arr) {
		if (num<0) {num=-num;}
		var l=num%10;
		if (num>9 && num<21) {l=9;}
	
		if (l==1) {return arr[0];}
		if (l>1 && l<5) {return arr[1];}
		return arr[2];
	}
	
	
	
	// добавить тегу событие
	this.add_handler=function (obj, ev, func, par) {
		if (!obj.handler_stack) {obj.handler_stack={};}
		if (!obj.handler_stack[ev]) {
	  		obj.handler_stack[ev]=[];
	  		if (obj[ev]) {obj.handler_stack[ev][0]=[obj[ev],null];}
	  		obj[ev]=function (e) {var ret; for (var i=0; i<obj.handler_stack[ev].length; i++) {if (obj.handler_stack[ev][i]==undefined) {obj.handler_stack[ev].splice(i, 1); i--;} else {ret=obj.handler_stack[ev][i][0](e,obj,obj.handler_stack[ev][i][1]);}} return ret;}
	  	}
		obj.handler_stack[ev][obj.handler_stack[ev].length]=[func,par];
	}
	this.ah=this.add_handler;
	// очистить события тэга
	this.clear_handler=function (obj, ev)
	{
		if (obj.handler_stack && obj.handler_stack[ev]) {obj.handler_stack[ev]=[];}
	}
	// удалить у тега событие
	this.remove_handler=function (obj, ev, func) {
		if (obj.handler_stack)
		if (obj.handler_stack[ev]) {
			for (var i=0; i<obj.handler_stack[ev].length; i++) {if (obj.handler_stack[ev][i] && obj.handler_stack[ev][i][0]==func) {obj.handler_stack[ev][i]=undefined; return 0;}}
		}
	}
	

	
	// forms
	// вызывает у выше лежащей формы сабмит
	this.form_submit=function(t) {f=this.parent(t,function (n) {if (n.nodeName=='FORM') {return 1;} else {return 0;}}); if (f.onsubmit) {f.onsubmit(); f.onsubmit=null;} f.submit();} 
	// обнуляет все поля вышележащей формы
	this.form_reset=function(t) {
		f=this.parent(t,function (n) {if (n.nodeName=='FORM') {return 1;} else {return 0;}}); 
		this.go(f,function (n) {if (n.defaultValue!=undefined) {n.value=defaultValue;} if (n.object!=undefined && n.object.defaultValue!=undefined) {n.object.defaultValue();}});
	} 
	
	
	// копирует значение - например число
	this.c=function (a) {return a;}
	// копирует объект
	this.copy=function (o) {var n={}; for (var i in o) {n[i]=o[i];} return n;}
	// рекурсивно копирует массив
	this.copy_r=function (o) {var n={}; for (var i in o) {if (typeof(o[i])=='object') {n[i]=this.copy_r(o[i]);} else {n[i]=o[i];}} return n;}
	
	
	
	// установление браузера
	this.data = [
		{t:'A', what:'Firefox', mean:'FF'},
		{t:'A', what:'MSIE', mean:'IE'},
		{t:'A', what:'Netscape', mean:'NS'},
		{t:'V', what:'Apple', mean:'SF'},
		{t:'A', what:'Gecko', mean:'MZ'},
		{t:'V', what:'KDE', mean:'KN'},
		{t:'V', what:'Mozilla', mean:'NS'}
	];
	for (var i=0;i<this.data.length;i++)	{
		if (this.data[i].t=='A') {this.prop=navigator.userAgent;}
		if (this.data[i].t=='V') {this.prop=navigator.vendor;}
		if (this.prop.indexOf(this.data[i].what) != -1) {this.browser = this.data[i].mean; break;}
		if (window.opera) {this.browser = 'OP'; break;}
		this.browser = 'XZ';
	}
	if (this.browser=='SF') {this.is_safari=1;} else {this.is_safari=0;}
	if (this.browser=='IE') {this.is_ie=1;} else {this.is_ie=0;}
	if (window.opera) {this.is_opera=1;} else {this.is_opera=0;}

	
	
	// private - для uid
	this.uidv=0;

	// private - для nodeCopy, проход по детям и замена id,name
	this.node_go_id=function (node,id,format) {
		if (format!=undefined && id!=undefined) {r=new RegExp(format); this.go(node,function(n) {if (n.id) {n.id=n.id.replace(r,id);} if (n.name) {n.name=n.name.replace(r,id);}});}
		else if (id!=undefined) {this.go(node,function(n) {if (n.id) {n.id+=id;}});}
	}
}
sys=new SYSTEM();
s=sys;





// полезные функции
// есть ли элемент в массиве
Array.prototype.inArray=function (val,arr) {
	for(var i=0;i<arr.length;i++) {
		if (arr[i]==val) {return 1;}
	}
	return 0;
}
// чтобы не путать 0 и NaN
Number.prototype.NaN0=function() { return isNaN(this) ? 0 : this; }
// удаляет с обоих сторон пробелы и символы табуляции
String.prototype.trim=function () {
	var str=this;
	var start=0; 
	var end=str.length-1;
	for(var i=0;i<str.length;i++) {if (str.charCodeAt(i)<33) {start++;} else {break;}}
	for(var i=end;i>=0;i--) {if (str.charCodeAt(i)<33) {end--;} else {break;}}
	return str.substring(start,end+1);
}
// копирует строку подряд "a" раз
String.prototype.repeat=function(a) {
	var str=this.toString();
	var ret="";
	for(var i=0;i<a;i++) {
		ret+=str;
	}
	return ret;
}
// заменяет %,%%,%%%,.. на заданную строку
String.prototype.rep=function(cnt,a) {
	var str=this.toString();
	r=new RegExp("%".repeat(cnt));
	return str.replace(r,a);
}
// если не используется jquery
/*function $(element) {
	if (typeof element == 'string')	var element = document.getElementById(element);
	return element;
}*/


