/**
 * @author Sergey Chikuyonok (gonarch@design.ru)
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru) 
 */
//if(als == 'undefined')
var als={};

var IE = document.all?true:false;

/**
 * Returns reference to element
 * @param {String, Element} elem
 * @return {Element}
 */
als.getElement=function(elem){
	return (typeof(elem) == 'string') ? document.getElementById(elem) : elem;
}

/**
 * Create new element with specified class and text
 * @param {String} elemName Element name
 * @param {String} [className] Element's class name
 * @param {String} [text] Element's text value
 * @return {Element}
 */
als.createElement=function(elemName, className, text){
	var elem=document.createElement(elemName);
	if(className)
	{
		elem.className=className;
		//if(IE == false) elem.id=className;
	}
	if(text)
		elem.appendChild(document.createTextNode(text));
	return elem;
}

/**
 * Returns height of 1em unit (in pixels)
 * @return {Number}
 */
als.getEmHeight=function(){
	var measurer=document.getElementById('measurer');
	return (measurer) ? measurer.offsetHeight : 0;
}

als.number={
	
	f_thousands_separator: ' ',
	f_fraction_separator: ',',
	
	/**
	 * Parse string into number
	 * @param {String} num String to parse
	 * @return {Number}
	 */
	parse: function(num){
		if(typeof(num) == 'number')
			return num;
		
		var parsed_num=new String(num);
		var re=/^-?\d+(\.\d+)?$/;
		
		parsed_num=parsed_num.replace(/[^\d\.,\-]/g, ''); //remove non-digital symbols 
		parsed_num=parsed_num.replace(/,/, '.'); //replace commas with periods
		
		return (!parsed_num.length || !re.test(parsed_num)) ? null : parseFloat(parsed_num);
	},
	
	/**
	 * Parse string into number and perform simple arithmetic operations
	 * @param {String} num String to parse
	 * @return {Number} 
	 */
	read: function(num){
		if(typeof(num) == 'number')
			return num;
			
		num=new String(num);
		var re=/[\-\+*\/]/g;
		var ops=[];
		var _m;
		while((_m=re.exec(num))){
			ops.push({
				operator: _m[0],
				start: _m.index,
				end: _m.index+_m[0].length
			});
		}
		if(!ops.length){
			return this.parse(num);
		}
		else{
			var expr='', ix=0, len=ops.length, n;
			for(var i=0; i<len; i++){
				n=this.parse(num.substring(ix, ops[i].start));
				if(n != null)
					expr+=n;
				
				expr+=ops[i].operator;
				ix=ops[i].end;
			}
			
			n=this.parse(num.substr(ix));
			if(n != null)
				expr+=n;
			
			try{
				var result=eval(expr);
				return result;
			}
			catch(e){
				return null;
			}
		}
	},
	
	/**
	 * Format number into human-readable string
	 * @param {Number} num Number to format
	 * @param {Number} [round_base] Fraction part length (default: 2)
	 * @return {String}
	 */
	format: function(num, round_base){
		if(typeof(num) == "string") num = num.replace(/([ ]+)/, ''); // если пришла строка с пробелами, удаляем пробелы
		var re=/^(\d+)([\.,](\d+))?$/;
		var _m, fraction_part='', str=new String(num);
		if((_m = str.match(re))){
			var _int=_m[1];
			var _frac=(_m[3]) ? Number('0.'+_m[3]) : 0;
			if(_frac){
				var rf=Math.pow(10, (round_base) ? round_base : 2);
				_frac=Math.round(_frac*rf)/rf;
				if(_frac){
					_frac=String(_frac).replace(/^0\./, '');
					fraction_part=this.f_fraction_separator+_frac;
				}
				else{
					fraction_part='';
				}
			}
			if(Number(_int) < 10000){
				return _int+fraction_part;
			}
			else{
				var new_num='';
				var i;
				for(i=1; i*3<_int.length; i++)
					new_num=this.f_thousands_separator+_int.substring(_int.length - i*3, _int.length - (i-1)*3)+new_num;
				return _int.substr(0, 3 - i*3 + _int.length)+new_num+fraction_part;
			}
		}
		else{
			return str;
		}
	},
	
	/**
	 * Returns right word for number 
	 * @param {Number} num
	 * @param {Array} words
	 * @return {String}
	 */
	right_case: function(num, words){
		var last=Number(String(num).substr(-1));
		var result;
		num%=100;
		if(num >= 5 && num <= 20)
			result=words[2];
		else{
			switch(last){
				case 1:  result=words[0]; break;
				case 2:
				case 3:
				case 4:  result=words[1]; break;
				default: result=words[2]; break;
			}
		}
		
		return result;
	},
	
	/**
	 * Sets value to the nearest side if it not in range
	 * @param {Number} val Number to test
	 * @param {Number} min Minimum range value
	 * @param {Number} max Maximum range value
	 * @return {Number}
	 */
	in_range: function(val, min, max){
		return Math.min(Math.max(val, min), max);
	}
};


/*

	Для генерации текста с последующей вставкой в .innerHTML
	Пример:

	alert(
		html.element.create(
			{
				tag: 'div',
				html: 'text',
				id: 'test',
				title: 'test'
			}
		)
	);

*/
var html = {
	element:
	{
		create: function(o, f)
		{
			var sAttributes = '';
			var sHtml = '';
			for (var x in o)
			{
//				f(x, o[x]);
				if(x != 'html' && x != 'tag') sAttributes += ' ' + x + '="' + o[x] + '"';
				if(x == 'html') sHtml = o[x];
				if(x == 'tag') sTag = o[x];
			}
			return '<' + sTag + (sAttributes ? sAttributes : '') + '>' + sHtml + '</' + sTag + '>';
		}
	}
}

n = {
	format: function(iNum, iComma)
	{
		var sNumber = als.number.format(iNum);
		m = sNumber.match(/,(\d+)/);
		if(m)
			var i = m[1].length;
		else
			var i = 0;
		if(i == 0) sNumber+=',';
		for(i;i<2;i++)
		{
			sNumber+='0';
		}
		return sNumber;
	}
}