function array_join(sDelimiter, iStartIndex, iEndIndex){
	if(!sDelimiter) sDelimiter=', ';
	
	if(!iStartIndex) iStartIndex=0;
	else iStartIndex=Math.max(0, iStartIndex);
	
	if(!iEndIndex) iEndIndex=this.length-1;
	else iEndIndex=Math.min(iEndIndex, this.length-1)
	
	var sReturn='';
	for(var i=iStartIndex; i<iEndIndex; i++)
		sReturn+=this[i]+sDelimiter;
	
	if(this[iEndIndex]) sReturn+=this[iEndIndex];
	return sReturn;
}

Array.prototype.add=function(Value){
	this[this.length]=Value;
}

Array.prototype.inArray=function(sValue){
	for(var i=0; i<this.length; i++){
		if(this[i]==sValue) return true;
	}
	return false;
}

Number.prototype.between=function(iStart, iEnd, bNoInclude){
	var iVal=this.valueOf();
	if(bNoInclude)
		return ( iVal > iStart && iVal < iEnd );
	else
		return ( iVal >= iStart && iVal <= iEnd );
}

Array.prototype.join=array_join;
Object.prototype.join=array_join; // это чтоб на arguments работало

function ValueObject(sLabel, Value){
	this.label=sLabel;
	this.value=Value;
}

ValueObject.prototype.getLabel=function(){
	return this.label;
}

ValueObject.prototype.getValue=function(){
	return this.value;
}

function CUObject(){}
CUObject.prototype.sKeyDelimiter='-';
CUObject.prototype.bIsIndexed=false;
//CUObject.prototype.aValues=[];
CUObject.prototype.add=function(sLabel, Value){
	/*
	arguments[0] - название элемента
	arguments[1] - его значение
	arguments[2...n] - ключ
	*/
	
	if(this.bIsIndexed){
		if(!this.aValues) this.aValues=[];
		this.aValues[this.aValues.length]=new ValueObject(sLabel, Value);
	}
	else{
		var sKey=arguments.join(this.sKeyDelimiter, 2);
		if(!this[sKey]) this[sKey]=[];
		this[sKey][this[sKey].length]=new ValueObject(sLabel, Value);
	}
}

CUObject.prototype.get=function(){ // возвращает массив значений
	var aResult;
	if(this.bIsIndexed){
		aResult=this.aValues;
	}
	else{
		var sKey=arguments.join(this.sKeyDelimiter);
		if(!(aResult=this[sKey]))
			aResult=[];
	}
	return aResult;
}

CUObject.prototype.getItem=function(iIndex){ //возвращает объект класса ValueObject по индексу iIndex
	var Args=arguments;
	var aData=this.get.apply(this, [arguments.join(this.sKeyDelimiter, 1)]);
	var oResult;
	if(!(oResult=aData[Number(iIndex)]))
		oResult=new ValueObject('',0);
	return oResult;
}

CUObject.prototype.getValue=function(){ //аналогичен getItem(), только сразу достает value объекта
	var oResult;
	if(oResult=this.getItem.apply(this, arguments))
		return oResult.getValue();	
	else
		//alert('error ');
		return null;
}

function CUObjectIx(){}
CUObjectIx.prototype=new CUObject();
//CUObjectIx.prototype.aValues=[];
CUObjectIx.prototype.bIsIndexed=true;
CUObjectIx.prototype.length=function(){
	return this.aValues.length;
};

//=========================//

function getFieldType(oObj){
	var sType=(oObj.type) ? oObj.type : oObj[0].type;
	if(sType.indexOf('select') != -1)
		sType='select';
	return sType;
}

function getSelected(obj, bAutoConvert){
	var sType=(obj.type) ? obj.type : obj[0].type;
	//var sType=getFieldType(obj);
	var ReturnVal=null;
	switch(sType){
		case 'radio':
			for(var i=0; i<obj.length; i++){
				//if(obj[i].disabled) return 1;
				if(obj[i].checked){
					ReturnVal=(obj[i].disabled) ? 1 : obj[i].value;
					break;
				}
			}
			break;
		case 'select-one':
			if(obj.selectedIndex != -1) ReturnVal=obj[obj.selectedIndex].value;
			if(obj.disabled){ReturnVal=1;}
			break;
		case 'checkbox':
			if(obj.checked) ReturnVal=obj.value;
			if(obj.disabled) ReturnVal=1;
	}
	if(ReturnVal != null && bAutoConvert !=1)
		ReturnVal=parseInt(ReturnVal);
	return ReturnVal;
}

function getSelectedIx(oObj){
	var sType=getFieldType(oObj);
	var iIx=-1;
	switch(sType){
		case 'select':
			iIx=oObj.selectedIndex;
			break;
		case 'radio':
			for(var i=0; i<oObj.length; i++){
				if(oObj[i].checked){
					iIx=i;
					break;
				}
			}
			break;
	}
	
	return iIx;
}

function RebuidVariants(oFormItem, aVariants){
	//clear all OPTIONS
	for(var i=oFormItem.options.length; i>=0; i--){
		oFormItem.options[i]=null;
	}
	
	//insert new
	var sLabel, sValue;
	for(var i=0; i<aVariants.length; i++){
		sLabel=aVariants[i].getLabel();
		sValue=aVariants[i].getValue();
		if(sLabel == '') sLabel=sValue;
		oFormItem.options[i]=new Option(sLabel, sValue);
	}
	
	oFormItem.selectedIndex=0;
}


function disableItems(oForm, sItemName, bDisable, iDefaultIndex){
	var oItems = oForm.elements[sItemName];
	for (var i=0; i<oItems.length; i++){
		oItems[i].disabled = (bDisable)? true : false;
	}
	if(bDisable && iDefaultIndex != null){
		oItems[iDefaultIndex].disabled=false;
		oItems[iDefaultIndex].checked=true;
	}
}

function SwapDisabled(oForm, sItemName, bDisable, iDefaultIndex){
	var oRef=oForm[sItemName];
	var sType=(oRef.type) ? oRef.type : oRef[0].type;
	switch(sType){
		case 'radio':
			disableItems(oForm, sItemName, bDisable, iDefaultIndex);
			break;
		default:
			oRef.disabled=(bDisable)? true : false;
	}
}

function LabelDisabler()
{
	var oLabels=document.getElementsByTagName('label');
	var sElementID;
	for(var i=0; i<oLabels.length; i++){
		sElementID=(oLabels[i].attributes) ? oLabels[i].attributes['for'].nodeValue : oLabels[i].getAttribute('for');
		if(sElementID) oLabels[i].className=(document.getElementById(sElementID).disabled) ? 'disabled' : '';
	}
}

function fnIsNaN(iStr){
	return (isNaN(iStr) || iStr == Number.NaN || iStr=='NaN');
}


/* функция смотрит, какой элемент в oObj выбран, и если он disabled - перемещает выделение к ближайшему не-disabled */
function getNearest(oObj, iMoveDir, bAutoAttempt){
	/* iMoveDir: 0 - снизу вверх, 1 - сверху вниз */
	iMoveDir=(iMoveDir)?true:false;
	var bSuccess=false;
	var iSelected;
	
	var sObjType=getFieldType(oObj);
	switch(sObjType){
		case 'select':
			iSelected=getSelectedIx(oObj);
			if(oObj.options[iSelected].disabled){
				if(iMoveDir){
					for(var i=iSelected; i<oObj.options.length; i++){
						if(!oObj.options[i].disabled){
							oObj.options[i].selected=true;
							bSuccess=true;
							break;
						}
					}
				}
				else{
					for(var i=iSelected; i>-1; i--){
						if(!oObj.options[i].disabled){
							oObj.options[i].selected=true;
							bSuccess=true;
							break;
						}
					}
				}
			}
			break;
		case 'radio':
			iSelected=getSelectedIx(oObj);
			if(iSelected > -1 &&  oObj[iSelected].disabled){
				if(iMoveDir){
					for(var i=iSelected; i<oObj.length; i++){
						if(!oObj[i].disabled){
							oObj[i].checked=true;
							bSuccess=true;
							break;
						}
					}
				}
				else{
					for(var i=iSelected; i>-1; i--){
						if(!oObj[i].disabled){
							oObj[i].checked=true;
							bSuccess=true;
							break;
						}
					}
				}
			}
	}
	
	if(!bSuccess && !bAutoAttempt){ //попробуем в обратном направлении
		getNearest(oObj, !iMoveDir, true);
		return;
	}
}

function WriteText(sID, sText, bAppend){
	var oRef;
	if(oRef=document.getElementById(sID)){
		if(bAppend)
			oRef.innerHTML+=sText;
		else
			oRef.innerHTML=sText;
	}
}
