/**
 * @author Edgar Grigoryan
 */
var start_date = new Date(); 
function setStartDate(dateText)
{
	var date_arr = dateText.split(".");
	
	start_date = new Date(parseInt(date_arr[2]),parseInt(date_arr[1])-1,parseInt(date_arr[0]));
	
	elem = document.getElementById("months");
	
	if(elem.value)
	_setEndDate(elem,"end_date","day_coount");
}
function _converToDate(date)
{
	var _str = new Array();
	 _str[0] = (date.getDate() < 10  ? "0":"") + date.getDate();
	 _str[1] = (date.getMonth()+1 < 10  ? "0":"") +(date.getMonth()+1)*1; 
	 _str[2] = date.getFullYear();
	
	return  _str.join(".");
}

function _addMonths(date, mC)
{
	
	
	var rdate  = new Date(date.getFullYear(),date.getMonth()+mC,date.getDate());
	return rdate;

}
function _addDays(date, dC)
{
	var rdate  = new Date(date.getFullYear(),date.getMonth(),date.getDate()+dC);
	return rdate;

}

function _getDifferenc(date1,date2)
{
	var _utc1 = Date.UTC(date1.getFullYear(),date1.getMonth(),date1.getDate());
	var _utc2 = Date.UTC(date2.getFullYear(),date2.getMonth(),date2.getDate());
	
	return Math.abs((_utc1 - _utc2) / (24*60*60*1000));
}

function _initDates()
{
 	var toDay = new Date();
 	toDay_str =  _converToDate(toDay);
 	var start_date = document.getElementById("start_date");
	start_date.value = toDay_str;
}

function _setEndDate(elem,end_date,day_coount)
{

	var mc = elem.value;
	mcInt = parseInt(mc);
	if(isNaN(mcInt))
	{
		elem.value = "0";
		
		elem.focus();
		return;
	}
	
	var toDay = start_date;
	
	var _endDate = _addMonths(toDay, mcInt);
	//alert(_endDate.getDay());
	if(! _endDate.getDay())
	{
	_endDate = _addDays(_endDate,1);
	
	}
	
	var _dayCount = _getDifferenc(_endDate,toDay);
	
	var end_date = document.getElementById("end_date");
	var day_coount = document.getElementById("day_coount");
	
	end_date.value = _converToDate(_endDate);
	day_coount.value = _dayCount;
}

function getLoanAmount(total,pre_pay,loan_amount)
{
		var total = document.getElementById(total);
		var pre_pay = document.getElementById(pre_pay);
		var loan_amount = document.getElementById(loan_amount);
		
		var total_val = Number(total.value);
		var pre_pay_val = Number(pre_pay.value);
		
		
		if(isNaN(total_val) || !total_val)
		{
			total.value = "";
			total.focus();
			return;
		}
		
		
		if(isNaN(pre_pay_val) )
		{
			pre_pay.value = 0;
			pre_pay_val = 0;
			//pre_pay.focus();
			//return;
		}
		
		loan_amount.value = total_val-pre_pay_val*total_val/100;
		
}

function checkIsNumeric(elem)
{
 
 var elem_value = Number(elem.value);
 if(isNaN(elem_value))
 {
 	elem.value = '';
	elem.focus()
 }
}



/*
 * 
 * 
 * @param {Date} Bi  	i date
 * @param {Date} Bi1 	i+1 date
 * @param {Number} Gi   "????????? ???????"
 * @param {Number} Di    "??? ??????????"
 * @param {Number} $B$5 ??????? ????????? ????????????
 * @param {Number} $B$4 ????? ??????
 * @param {Number} $B$6 ????? ?????? (?????????)
 * @param {Number} SUM_M "??????? ??????" ??????????
 */
function calcTotal(Bi,Bi1,Gi,Di,$B$5,$B$4,$B$6,SUM_M)
{
	
	
	//alert(Bi+"/"+Bi1+"/"+Gi+"/"+Di+"/"+$B$5+"/"+$B$4+"/"+$B$6+"/"+SUM_M)
	
	
	var X = 0;
	if(!Bi)
	{
		X = 0;
		//alert(1);

	}
	else{
			//alert(2);
			if(!Bi1)
			{
				//alert(3);
				X = $B$4-SUM_M+Gi;
						
			}else
			{
					//alert(4);
					if(Di>0)
					{
						//alert(5);
						X = Di;
						
					}else
					{
							//alert(6);
							var m = $B$5/365*365/1200;
							//alert(m);
							Y = Math.pow((1+m ),$B$6)
							//alert(Y*m);
							X = Y*m /(Y-1)*$B$4+Di;
					}
			}
	}
	
	//alert(X);
	return X;
}

/*

"???????	 ???????"		:date		
"????? ?????"			:dayCount	
"??? ??????????"			:otherPay
"????? ???????"			:tail
"??????? ??????"			:loanPay
"????????? ???????"		:precents
???????? ???????			:totalPay

*/

function on_maninCalc()
{
	
	var _form = document.getElementById('_maninCalc');
	var errors = 0;
	for( var i = 0 ; i < _form.elements.length; i++)
	{
		var elem = _form.elements[i];
		if(elem.type == 'text')
		elem.className ='inputC';
		val = Number(elem.value);
		
		if(!elem.readOnly   && elem.type == 'text' &&  (isNaN(val)|| !val))
		{
			if(elem.id == 'pre_pay' || elem.id == 'inshurens' || elem.id == 'other')
			{
				elem.value  = 0;
			}else{
			errors++;
			elem.className ='err';
			}
		};
	};
	if(errors)
	return;
	
	var _months = document.getElementById('months');
	var _loan_pay = document.getElementById('loan_pay');
	var _precent = document.getElementById('precent');
	var _inshurens = document.getElementById('inshurens');
	var _other = document.getElementById('other');
	
	var V_months = Number(_months.value);
	var V_loan_pay = Number(_loan_pay.value);
	var V_precent = Number(_precent.value);
	var V_inshurens = Number(_inshurens.value);
	var V_other = Number(_other.value);
	
	
	var _today =start_date;
	
	
	
	var _loanArray = new Array(_months+3);





	var _firstRow = {
						date:_today,
						dayCount:0,
						otherPay:0,
						tail:0,
						loanPay:0,
						precents:0,
						totalPay:(-1)*V_loan_pay
		};
	_loanArray[0] = _firstRow;

	var _firstRow = {
						date:_today,
						dayCount:0,
						otherPay:V_inshurens+V_other,
						tail:V_loan_pay,
						loanPay:0,
						precents:0,
						totalPay:V_inshurens+V_other
					};
	_loanArray[1] = _firstRow;
	
	

	var _loanPayed = 0;
	var _loanPay = 0;
	for(var i = 2 ; i < V_months+2; i++)
	{
		
			
			var _newDate = _addMonths(_today,i-1);
			
			if(i+1 < V_months+2)
			var _next = _addMonths(_newDate,1);
			else
			_next = 0;
			
			if( _next && !_next.getDay())
			{
				_next = _addDays(_next,1);
			}
			
			if(_newDate.getDay() == 6)
			{
				_newDate = _addDays(_newDate,1);
			}
			
			
			var _otherPay = 0;
			
			var _deyDif = _getDifferenc(_newDate,_loanArray[i-1].date);
			
			var _tail = _loanArray[i-1].tail-_loanArray[i-1].loanPay;
			
			var ___precents = _deyDif*((_tail*V_precent)/100)/365;
			
			var $B$5 = V_precent;
			var $B$6  = V_months;
			var $B$4 = V_loan_pay;
			var I = _otherPay;
		
			totalPay = calcTotal(_newDate, _next , ___precents , _otherPay ,$B$5 ,$B$4 ,$B$6 ,_loanPayed );
			
			_loanPay = _otherPay > 0 ? 0:totalPay -___precents- _otherPay;
			
			var _base = (1+V_precent/12);
			_loanPayed += _loanPay;
			

			var $B$5 = V_precent;
			var $B$6  = V_months;
			var $B$4 = V_loan_pay;
			var I = _otherPay;



			

			var _firstRow = 
						{
				         date:_newDate,
						 dayCount:_deyDif,
						 otherPay:_otherPay,
						 tail:_tail,
						 loanPay:_loanPay,
						 precents:___precents,
						 totalPay:totalPay
						 };
			_loanArray[i] = _firstRow;
			
			

	}
	
	var _table = document.getElementById("_grid");
	
	while (_table.rows.length > 1) 
	{
     _table.deleteRow(1);
	}
	
	var _XIRDATES  = new Array(_loanArray.length);
	var _XIRVALUES = new Array(_loanArray.length);
	var total_percents = 0;
	var total_loan  = 0;
	for(var i = 0; i < _loanArray.length; i++)
	{
		_XIRDATES[i] 
		var _row = _table.insertRow(-1);
		//var Cell_0 = _row.insertCell(-1);
		var Cell_1 = _row.insertCell(-1);
		var Cell_2 = _row.insertCell(-1);
		var Cell_3 = _row.insertCell(-1);
		var Cell_4 = _row.insertCell(-1);
		var Cell_5 = _row.insertCell(-1);
		var Cell_6 = _row.insertCell(-1);
		var Cell_7 = _row.insertCell(-1);
		_className = 'even';
		if (_row.rowIndex % 2)
		{
			_className = 'odd';
		}
/*
"???????	 ???????"		:date		
"????? ?????"			:dayCount	
"??? ??????????"			:otherPay
"????? ???????"			:tail
"??????? ??????"			:loanPay
"????????? ???????"		:precents
???????? ???????			:totalPay
*/
		Cell_1.innerHTML = _converToDate(_loanArray[i].date);
		Cell_2.innerHTML = _loanArray[i].dayCount;
		Cell_3.innerHTML =number_format( _loanArray[i].otherPay.toFixed(2),2,"."," ");
		Cell_4.innerHTML = number_format(_loanArray[i].tail.toFixed(2),2,"."," ");
		Cell_5.innerHTML = number_format(_loanArray[i].loanPay.toFixed(2),2,"."," ");
		Cell_6.innerHTML = number_format(_loanArray[i].precents.toFixed(2),2,"."," ");
		Cell_7.innerHTML = number_format(_loanArray[i].totalPay,2,"."," ");
		//Cell_0.innerHTML = _row.rowIndex;
		_XIRDATES[i] = _loanArray[i].date;
		_XIRVALUES[i] = _loanArray[i].totalPay; 
		
		 total_percents += _loanArray[i].precents;
		
    	 total_loan  += _loanArray[i].loanPay;
		Cell_1.className = _className;
		Cell_1.className = 'date '+_className;
		Cell_2.className = 'number '+_className;
		Cell_3.className = 'number '+_className;
		Cell_4.className = 'number '+_className;
		Cell_5.className = 'number '+_className;
		Cell_6.className = 'number '+_className;
		Cell_7.className = 'number '+_className;
										
	}
	
	document.getElementById("total_percents").innerHTML = number_format(total_percents,2,"."," " );
	document.getElementById("total_loan").innerHTML = number_format(total_loan,2,"."," " );
	
	
		
	// XIRR(_XIRVALUES,_XIRDATES,0.1);
	var _xirr1 = XIRR2(_XIRVALUES,_XIRDATES,0.01)*100;
	
	document.getElementById("xiirPR").innerHTML = _xirr1.toFixed(2);
	//resizeIframe('calc_fr');
	//alert(_loanArray);
}
/**
 * Formats the number according to the format string; adherses to the american number standard where a comma is inserted after every 3 digits.
 *  note: there should be only 1 contiguous number in the format, where a number consists of digits, period, and commas
 *        any other characters can be wrapped around this number, including $, %, or text
 *        examples (123456.789):
 *          0? - (123456) show only digits, no precision
 *          0.00? - (123456.78) show only digits, 2 precision
 *          0.0000? - (123456.7890) show only digits, 4 precision
 *          0,000? - (123,456) show comma and digits, no precision
 *          0,000.00? - (123,456.78) show comma and digits, 2 precision
 *          0,0.00? - (123,456.78) shortcut method, show comma and digits, 2 precision
 *
 * @method format
 * @param format {string} the way you would like to format this text
 * @return {string} the formatted number
 * @public
 */


function is_finite(val) {
    // http://kevin.vanzonneveld.net
    // +   original by: Onno Marsman
    // *     example 1: is_finite(Infinity);
    // *     returns 1: false
    // *     example 2: is_finite(-Infinity);
    // *     returns 2: false
    // *     example 3: is_finite(0);
    // *     returns 3: true
 
    var warningType = '';
 
    if (val===Infinity || val===-Infinity) {
        return false;
    }
 
    //Some warnings for maximum PHP compatibility
    if (typeof val=='object') {
        warningType = (val instanceof Array ? 'array' : 'object');
    } else if (typeof val=='string' && !val.match(/^[\+\-]?\d/)) {
        //simulate PHP's behaviour: '-9a' doesn't give a warning, but 'a9' does.
        warningType = 'string';
    }
    if (warningType) {
        throw new Error('Warning: is_finite() expects parameter 1 to be double, '+warningType+' given');
    }
 
    return true;
}
var  FINANCIAL_ACCURACY= 1.0e-6;
var FINANCIAL_MAX_ITERATIONS =200;

var FINANCIAL_SECS_PER_DAY = 24 * 60 * 60;
var FINANCIAL_HALF_SEC = 0.5 / FINANCIAL_SECS_PER_DAY;
function is_array( mixed_var ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Legaev Andrey
    // +   bugfixed by: Cord
    // +   bugfixed by: Manish
    // +   improved by: Onno Marsman
    // %        note 1: In php.js, javascript objects are like php associative arrays, thus JavaScript objects will also
    // %        note 1: return true
    // *     example 1: is_array(['Kevin', 'van', 'Zonneveld']);
    // *     returns 1: true
    // *     example 2: is_array('Kevin van Zonneveld');
    // *     returns 2: false
    // *     example 3: is_array({0: 'Kevin', 1: 'van', 2: 'Zonneveld'});
    // *     returns 3: true
    // *     example 4: is_array(function tmp_a(){this.name = 'Kevin'});
    // *     returns 4: false
 
    var key = '';
 
    if (!mixed_var) {
        return false;
    }
 
    if (typeof mixed_var === 'object') {
 
        if (mixed_var.hasOwnProperty) {
            for (key in mixed_var) {
                // Checks whether the object has the specified property
                // if not, we figure it's not an object in the sense of a php-associative-array.
                if (false === mixed_var.hasOwnProperty(key)) {
                    return false;
                }
            }
        }
 
        // Uncomment to enable strict JavsScript-proof type checking
        // This will not support PHP associative arrays (JavaScript objects), however
        // Read discussion at: http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_is_array/
        //
        //  if (mixed_var.propertyIsEnumerable('length') || typeof mixed_var.length !== 'number') {
        //      return false;
        //  }
 
        return true;
    }
 
    return false;
}
function XNPV($rate, $values, $dates)
	{
	//	if ((!is_array($values)) || (!is_array($dates))) return 0;
		if ($values.length != $dates.length) return 0;
		
		$xnpv = 0;
		//alert($values.length);
		for ($i = 0; $i < $values.length; $i++)
		{
			$xnpv += $values[$i] / Math.pow(1 + $rate, _getDifferenc( $dates[0], $dates[$i]) / 365);
		}
		return (is_finite($xnpv) ? $xnpv: 0);
	}
	
function XIRR($values, $dates, $guess )
{
	
	var __xx = new Array();
	
	
	

	var _jsonValues =json_encode($values);
	var dates = datesToPHPTime($dates);
	var _jsonDate = json_encode(dates);
	
	
	var URL = '/scripts/XIRR.php?chk='+Math.random()*1000;
	new Ajax.Request(URL, {
	
	  method: 'post',
	  postBody:  'values='+_jsonValues+'&dates='+ _jsonDate,
	
	  onSuccess: function(transport) {
	_xirr = transport.responseText*100;
		document.getElementById("__xiirPR").innerHTML =_xirr;
	
		//alert(transport.responseText)
	  },
	  onFailure:function()
	  {
		  $('"__xiirPR"').innerHTML=this.responseText;
		}

	  
	
	});


	
		//document.getElementById("__XIRR").innerHTML = _xir.toFixed(2);
}
function datesToPHPTime(_datesArray)
{
	try{
	var phpTime = new Array(_datesArray.length);
	for(var i = 0 , lim = _datesArray.length; i <lim;i++ )
	{
		phpTime[i] = mktime(0,0,0,_datesArray[i].getMonth(),_datesArray[i].getDate(),_datesArray[i].getFullYear());
	}
	
	return phpTime;
	}catch(e){alert(e.message)}
}

function mktime() {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: baris ozdil
    // +      input by: gabriel paderni 
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: FGFEmperor
    // +      input by: Yannoo
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: jakes
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Marc Palau
    // *     example 1: mktime(14, 10, 2, 2, 1, 2008);
    // *     returns 1: 1201871402
    // *     example 2: mktime(0, 0, 0, 0, 1, 2008);
    // *     returns 2: 1196463600
    // *     example 3: make = mktime();
    // *     example 3: td = new Date();
    // *     example 3: real = Math.floor(td.getTime()/1000);
    // *     example 3: diff = (real - make);
    // *     results 3: diff < 5
    // *     example 4: mktime(0, 0, 0, 13, 1, 1997)
    // *     returns 4: 883609200
    // *     example 5: mktime(0, 0, 0, 1, 1, 1998)
    // *     returns 5: 883609200
    // *     example 6: mktime(0, 0, 0, 1, 1, 98)
    // *     returns 6: 883609200
    
    var no, ma = 0, mb = 0, i = 0, d = new Date(), argv = arguments, argc = argv.length;
 
    if (argc > 0){
        d.setHours(0,0,0); d.setDate(1); d.setMonth(1); d.setYear(1972);
    }
 
    var dateManip = {
        0: function(tt){ return d.setHours(tt); },
        1: function(tt){ return d.setMinutes(tt); },
        2: function(tt){ var set = d.setSeconds(tt); mb = d.getDate() - 1; return set; },
        3: function(tt){ var set = d.setMonth(parseInt(tt)-1); ma = d.getFullYear() - 1972; return set; },
        4: function(tt){ return d.setDate(tt+mb); },
        5: function(tt){ return d.setYear(tt+ma); }
    };
    
    for( i = 0; i < argc; i++ ){
        no = parseInt(argv[i]*1);
        if (isNaN(no)) {
            return false;
        } else {
            // arg is number, let's manipulate date object
            if(!dateManip[i](no)){
                // failed
                return false;
            }
        }
    }
 
    return Math.floor(d.getTime()/1000);
}
function json_encode(mixed_val) {
    // http://kevin.vanzonneveld.net
    // +      original by: Public Domain (http://www.json.org/json2.js)
    // + reimplemented by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: json_encode(['e', {pluribus: 'unum'}]);
    // *     returns 1: '[\n    "e",\n    {\n    "pluribus": "unum"\n}\n]'
 
    /*
        http://www.JSON.org/json2.js
        2008-11-19
        Public Domain.
        NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
        See http://www.JSON.org/js.html
    */
    
    var indent;
    var value = mixed_val;
    var i;
 
    var quote = function (string) {
        var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
        var meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };
 
        escapable.lastIndex = 0;
        return escapable.test(string) ?
        '"' + string.replace(escapable, function (a) {
            var c = meta[a];
            return typeof c === 'string' ? c :
            '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
        }) + '"' :
        '"' + string + '"';
    }
 
    var str = function(key, holder) {
        var gap = '';
        var indent = '    ';
        var i = 0;          // The loop counter.
        var k = '';          // The member key.
        var v = '';          // The member value.
        var length = 0;
        var mind = gap;
        var partial = [];
        var value = holder[key];
 
        // If the value has a toJSON method, call it to obtain a replacement value.
        if (value && typeof value === 'object' &&
            typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }
        
        // What happens next depends on the value's type.
        switch (typeof value) {
            case 'string':
                return quote(value);
 
            case 'number':
                // JSON numbers must be finite. Encode non-finite numbers as null.
                return isFinite(value) ? String(value) : 'null';
 
            case 'boolean':
            case 'null':
                // If the value is a boolean or null, convert it to a string. Note:
                // typeof null does not produce 'null'. The case is included here in
                // the remote chance that this gets fixed someday.
 
                return String(value);
 
            case 'object':
                // If the type is 'object', we might be dealing with an object or an array or
                // null.
                // Due to a specification blunder in ECMAScript, typeof null is 'object',
                // so watch out for that case.
                if (!value) {
                    return 'null';
                }
 
                // Make an array to hold the partial results of stringifying this object value.
                gap += indent;
                partial = [];
 
                // Is the value an array?
                if (Object.prototype.toString.apply(value) === '[object Array]') {
                    // The value is an array. Stringify every element. Use null as a placeholder
                    // for non-JSON values.
 
                    length = value.length;
                    for (i = 0; i < length; i += 1) {
                        partial[i] = str(i, value) || 'null';
                    }
 
                    // Join all of the elements together, separated with commas, and wrap them in
                    // brackets.
                    v = partial.length === 0 ? '[]' :
                    gap ? '[\n' + gap +
                    partial.join(',\n' + gap) + '\n' +
                    mind + ']' :
                    '[' + partial.join(',') + ']';
                    gap = mind;
                    return v;
                }
 
                // Iterate through all of the keys in the object.
                for (k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
 
                // Join all of the member texts together, separated with commas,
                // and wrap them in braces.
                v = partial.length === 0 ? '{}' :
                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                mind + '}' : '{' + partial.join(',') + '}';
                gap = mind;
                return v;
        }
    };
 
    // Make a fake root object containing our value under the key of ''.
    // Return the result of stringifying the value.
    return str('', {
        '': value
    });
}
function XIRR2($values,$dates, $guess )
	{
		
		


	//	if ((!is_array($values)) && (!is_array($dates))) return -1;
		if ($values.length != $dates.length) return -2;
		
		// create an initial bracket, with a root somewhere between bot and top
		$x1 = 0.0;
		$x2 = $guess;
		$f1 = XNPV($x1, $values, $dates);
		$f2 = XNPV($x2, $values, $dates);
		for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; $i++)
		{
			if (($f1 * $f2) < 0) break;
			if (Math.abs($f1) < Math.abs($f2)) {
				$f1 = XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates);
			} else {
				$f2 = XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates);
			}
		}
		if (($f1 * $f2) > 0) return -3;
		
		$f = XNPV($x1, $values, $dates);
		if ($f < 0.0) {
			$rtb = $x1;
			$dx = $x2 - $x1;
		} else {
			$rtb = $x2;
			$dx = $x1 - $x2;
		}
		
		for ($i = 0;  $i < FINANCIAL_MAX_ITERATIONS; $i++)
		{
			$dx *= 0.5;
			$x_mid = $rtb + $dx;
			$f_mid = XNPV($x_mid, $values, $dates);
			if ($f_mid <= 0) $rtb = $x_mid;
			if (( Math.abs($f_mid) < FINANCIAL_ACCURACY) || ( Math.abs($dx) < FINANCIAL_ACCURACY)) return $x_mid;
		}
		return -4;
	}
	
function toArray(_obj)
{
	var m = new Array(_obj.length);
	
	for(var i = 0 , lim =_obj.length;i < lim;i++ )
	{
		m[i] = _obj[i];
	}
	return m;
}

function number_format( number, decimals, dec_point, thousands_sep ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     bugfix by: Michael White (http://getsprink.com)
    // +     bugfix by: Benjamin Lupton
    // +     bugfix by: Allan Jensen (http://www.winternet.no)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    // +     bugfix by: Howard Yeend
    // +    revised by: Luke Smith (http://lucassmith.name)
    // +     bugfix by: Diogo Resende
    // +     bugfix by: Rival
    // %        note 1: For 1000.55 result with precision 1 in FF/Opera is 1,000.5, but in IE is 1,000.6
    // *     example 1: number_format(1234.56);
    // *     returns 1: '1,235'
    // *     example 2: number_format(1234.56, 2, ',', ' ');
    // *     returns 2: '1 234,56'
    // *     example 3: number_format(1234.5678, 2, '.', '');
    // *     returns 3: '1234.57'
    // *     example 4: number_format(67, 2, ',', '.');
    // *     returns 4: '67,00'
    // *     example 5: number_format(1000);
    // *     returns 5: '1,000'
    // *     example 6: number_format(67.311, 2);
    // *     returns 6: '67.31'
 
    var n = number, prec = decimals;
    n = !isFinite(+n) ? 0 : +n;
    prec = !isFinite(+prec) ? 0 : Math.abs(prec);
    var sep = (typeof thousands_sep == "undefined") ? ',' : thousands_sep;
    var dec = (typeof dec_point == "undefined") ? '.' : dec_point;
 
    var s = (prec > 0) ? n.toFixed(prec) : Math.round(n).toFixed(prec); //fix for IE parseFloat(0.55).toFixed(0) = 0;
 
    var abs = Math.abs(n).toFixed(prec);
    var _, i;
 
    if (abs >= 1000) {
        _ = abs.split(/\D/);
        i = _[0].length % 3 || 3;
 
        _[0] = s.slice(0,i + (n < 0)) +
              _[0].slice(i).replace(/(\d{3})/g, sep+'$1');
 
        s = _.join(dec);
    } else {
        s = s.replace('.', dec);
    }
 
    return s;
}