/*
 * жалкая попытка навести порядок, а именно -  рантайм. кто вздумает писать
 * свое - будет покаран лично мной.
 * */
function fl_json_decode(u_json){
	var t_object = false;
	eval('t_object='+u_json+';');
	return t_object;
}


function count(mixed_var, mode) {
    // Count the number of elements in a variable (usually an array)
    //
    // version: 1103.1210
    // discuss at: http://phpjs.org/functions/count
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Waldo Malqui Silva
    // +   bugfixed by: Soren Hansen
    // +      input by: merabi
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Olivier Louvignes (http://mg-crea.com/)
    // *     example 1: count([[0,0],[0,-4]], 'COUNT_RECURSIVE');
    // *     returns 1: 6
    // *     example 2: count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE');
    // *     returns 2: 6
    var key, cnt = 0;

    if (mixed_var === null || typeof mixed_var === 'undefined') {
        return 0;
    } else if (mixed_var.constructor !== Array && mixed_var.constructor !== Object) {
        return 1;
    }

    if (mode === 'COUNT_RECURSIVE') {
        mode = 1;
    }
    if (mode != 1) {
        mode = 0;
    }

    for (key in mixed_var) {
        if (mixed_var.hasOwnProperty(key)) {
            cnt++;
            if (mode == 1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object)) {
                cnt += this.count(mixed_var[key], 1);
            }
        }
    }

    return cnt;
}


function Toggle(nodeid){
	var node = document.getElementById(nodeid);
	if (node) {
	  switch (node.style.display){
		case('block'):
			node.style.display = 'none';
			break;
		case('none'):
		  node.style.display = 'block';
		  break;
		default:
		  node.style.display = 'block';
		  break;
	  }
	}
}

/* спижжено с phpjs */

function utf8_decode (str_data) {
    var tmp_arr = [],
        i = 0,
        ac = 0,
        c1 = 0,
        c2 = 0,
        c3 = 0;

    str_data += '';

    while (i < str_data.length) {
        c1 = str_data.charCodeAt(i);
        if (c1 < 128) {
            tmp_arr[ac++] = String.fromCharCode(c1);
            i++;
        } else if (c1 > 191 && c1 < 224) {
            c2 = str_data.charCodeAt(i + 1);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = str_data.charCodeAt(i + 1);
            c3 = str_data.charCodeAt(i + 2);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }

    return tmp_arr.join('');
}

function base64_decode (data) {
    var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
        ac = 0,
        dec = "",
        tmp_arr = [];

    if (!data) {
        return data;
    }

    data += '';

    do { // unpack four hexets into three octets using index points in b64
        h1 = b64.indexOf(data.charAt(i++));
        h2 = b64.indexOf(data.charAt(i++));
        h3 = b64.indexOf(data.charAt(i++));
        h4 = b64.indexOf(data.charAt(i++));

        bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;

        o1 = bits >> 16 & 0xff;
        o2 = bits >> 8 & 0xff;
        o3 = bits & 0xff;

        if (h3 == 64) {
            tmp_arr[ac++] = String.fromCharCode(o1);
        } else if (h4 == 64) {
            tmp_arr[ac++] = String.fromCharCode(o1, o2);
        } else {
            tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
        }
    } while (i < data.length);

    dec = tmp_arr.join('');
    dec = this.utf8_decode(dec);

    return dec;
}

function var_export (mixed_expression) {
    var retstr = '',
        iret = '',
        cnt = 0,
        x = [],
        i = 0,
        funcParts = [],
        idtLevel = arguments[2] || 2,
        innerIndent = '',
        outerIndent = '';

    var getFuncName = function (fn) {
        var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
        if (!name) {
            return '(Anonymous)';
        }
        return name[1];
    };

    var _makeIndent = function (idtLevel) {
        return (new Array(idtLevel + 1)).join(' ');
    };

    var __getType = function (inp) {
        var i = 0;
        var match, type = typeof inp;
        if (type === 'object' && inp.constructor && getFuncName(inp.constructor) === 'PHPJS_Resource') {
            return 'resource';
        }
        if (type === 'function') {
            return 'function';
        }
        if (type === 'object' && !inp) {
            return 'null'; // Should this be just null?
        }
        if (type === "object") {
            if (!inp.constructor) {
                return 'object';
            }
            var cons = inp.constructor.toString();
            match = cons.match(/(\w+)\(/);
            if (match) {
                cons = match[1].toLowerCase();
            }
            var types = ["boolean", "number", "string", "array"];
            for (i = 0; i < types.length; i++) {
                if (cons === types[i]) {
                    type = types[i];
                    break;
                }
            }
        }
        return type;
    };
    var type = __getType(mixed_expression);

    if (type === null) {
        retstr = "NULL";
    } else if (type === 'array' || type === 'object') {
        outerIndent = _makeIndent(idtLevel - 2);
        innerIndent = _makeIndent(idtLevel);
        for (i in mixed_expression) {
            var value = this.var_export(mixed_expression[i], true, idtLevel + 2);
            //value = typeof value === 'string' ? value.replace(/</g, '&lt;').replace(/>/g, '&gt;') : value;
            x[cnt++] = innerIndent + i + ' => ' + (__getType(mixed_expression[i]) === 'array' ? '\n' : '') + value;
        }
        iret = x.join(',\n');
        retstr = outerIndent + "array (\n" + iret + '\n' + outerIndent + ')';
    } else if (type === 'function') {
        funcParts = mixed_expression.toString().match(/function .*?\((.*?)\) \{([\s\S]*)\}/);
        retstr = "create_function ('" + funcParts[1] + "', '" + funcParts[2].replace(new RegExp("'", 'g'), "\\'") + "')";
    } else if (type === 'resource') {
        retstr = 'NULL'; // Resources treated as null for var_export
    } else {
        retstr = (typeof(mixed_expression) !== 'string') ? mixed_expression : "'" + mixed_expression.replace(/(["'])/g, "\\$1").replace(/\0/g, "\\0") + "'";
    }

    return retstr;
}

function time() {
    return Math.floor(new Date().getTime() / 1000);
}

function sprintf(){var regex=/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g;var a=arguments,i=0,format=a[i++];var pad=function(str,len,chr,leftJustify){if(!chr){chr=' ';}var padding=(str.length>=len)?'':Array(1+len-str.length>>>0).join(chr);return leftJustify?str+padding:padding+str;};var justify=function(value,prefix,leftJustify,minWidth,zeroPad,customPadChar){var diff=minWidth-value.length;if(diff>0){if(leftJustify||!zeroPad){value=pad(value,minWidth,customPadChar,leftJustify);}else{value=value.slice(0,prefix.length)+pad('',diff,'0',true)+value.slice(prefix.length);}}return value;};var formatBaseX=function(value,base,prefix,leftJustify,minWidth,precision,zeroPad){var number=value>>>0;prefix=prefix&&number&&{'2':'0b','8':'0','16':'0x'}[base]||'';value=prefix+pad(number.toString(base),precision||0,'0',false);return justify(value,prefix,leftJustify,minWidth,zeroPad);};var formatString=function(value,leftJustify,minWidth,precision,zeroPad,customPadChar){if(precision!=null){value=value.slice(0,precision);}return justify(value,'',leftJustify,minWidth,zeroPad,customPadChar);};var doFormat=function(substring,valueIndex,flags,minWidth,_,precision,type){var number;var prefix;var method;var textTransform;var value;if(substring=='%%'){return'%';}var leftJustify=false,positivePrefix='',zeroPad=false,prefixBaseX=false,customPadChar=' ';var flagsl=flags.length;for(var j=0;flags&&j<flagsl;j++){switch(flags.charAt(j)){case' ':positivePrefix=' ';break;case'+':positivePrefix='+';break;case'-':leftJustify=true;break;case"'":customPadChar=flags.charAt(j+1);break;case'0':zeroPad=true;break;case'#':prefixBaseX=true;break;}}if(!minWidth){minWidth=0;}else if(minWidth=='*'){minWidth=+a[i++];}else if(minWidth.charAt(0)=='*'){minWidth=+a[minWidth.slice(1,-1)];}else{minWidth=+minWidth;}if(minWidth<0){minWidth=-minWidth;leftJustify=true;}if(!isFinite(minWidth)){throw new Error('sprintf: (minimum-)width must be finite');}if(!precision){precision='fFeE'.indexOf(type)>-1?6:(type=='d')?0:undefined;}else if(precision=='*'){precision=+a[i++];}else if(precision.charAt(0)=='*'){precision=+a[precision.slice(1,-1)];}else{precision=+precision;}value=valueIndex?a[valueIndex.slice(0,-1)]:a[i++];switch(type){case's':return formatString(String(value),leftJustify,minWidth,precision,zeroPad,customPadChar);case'c':return formatString(String.fromCharCode(+value),leftJustify,minWidth,precision,zeroPad);case'b':return formatBaseX(value,2,prefixBaseX,leftJustify,minWidth,precision,zeroPad);case'o':return formatBaseX(value,8,prefixBaseX,leftJustify,minWidth,precision,zeroPad);case'x':return formatBaseX(value,16,prefixBaseX,leftJustify,minWidth,precision,zeroPad);case'X':return formatBaseX(value,16,prefixBaseX,leftJustify,minWidth,precision,zeroPad).toUpperCase();case'u':return formatBaseX(value,10,prefixBaseX,leftJustify,minWidth,precision,zeroPad);case'i':case'd':number=parseInt(+value,10);prefix=number<0?'-':positivePrefix;value=prefix+pad(String(Math.abs(number)),precision,'0',false);return justify(value,prefix,leftJustify,minWidth,zeroPad);case'e':case'E':case'f':case'F':case'g':case'G':number=+value;prefix=number<0?'-':positivePrefix;method=['toExponential','toFixed','toPrecision']['efg'.indexOf(type.toLowerCase())];textTransform=['toString','toUpperCase']['eEfFgG'.indexOf(type)%2];value=prefix+Math.abs(number)[method](precision);return justify(value,prefix,leftJustify,minWidth,zeroPad)[textTransform]();default:return substring;}};return format.replace(regex,doFormat);}

/**
 * рисует очень красивый временной интервал
 * @version 1.1.0.2011-09-20
 */
function fl_showdate_interval(u_date_stamp, u_parts_separator, u_templates, is_show_parts_always){
	var zsec = u_date_stamp % 60;
	var zmin = (Math.floor(u_date_stamp/60)) % 60;
	var zhur = (Math.floor(u_date_stamp/3600)) % 24;
	var zday = (Math.floor(u_date_stamp/86400)) % 365;
	var zyar = (Math.floor(u_date_stamp/31536000));

	var rzlt=[];
	if(!u_parts_separator){
		u_parts_separator = ', ';
	}

	if(!u_templates){
		u_templates=['%d годов', '%d дней', '%d час', '%d мин', '%d сек'];
	}

	if(u_templates[0] && (zyar > 0 || is_show_parts_always)){
		rzlt.push(sprintf(u_templates[0], zyar));
	}

	if(u_templates[1] && (zday > 0 || is_show_parts_always)){
		rzlt.push(sprintf(u_templates[1], zday));
	}

	if(u_templates[2] && (zhur > 0 || is_show_parts_always)){
		rzlt.push(sprintf(u_templates[2], zhur));
	}

	if(u_templates[3] && (zmin > 0 || is_show_parts_always)){
		rzlt.push(sprintf(u_templates[3], zmin));
	}

	if(u_templates[4] && (zsec > 0 || is_show_parts_always)){
		rzlt.push(sprintf(u_templates[4], zsec));
	}

	var rx = rzlt.join(u_parts_separator);

	return rx != '' ? rx : 'мгновение';
}


/* fln-default.js - руками не трогать */
/* функция для нормального скрытия элементов
 * с анимацией, блекджеком и шлюхами
 * @version 1.0.1.2011-04-23
 */
$.fn.fl_hide = function(cb){
	$(this).animate({
		'height': 'hide',
		'opacity': 'hide'
	},250,cb);

	return $(this);
}

/* и соот-но противоположного действия
 * @version 1.0.1.2011-04-23
 */
$.fn.fl_show = function(cb){
	$(this).animate({
		'height': 'show',
		'opacity': 'show'
	},250,cb);

	return $(this);
}


/* и соот-но еще одно очень нужное действие :)
 * @version 1.0.0.2011-04-25
 */
$.fn.fl_toggle = function(cb){
	$(this).animate({
		'height': 'toggle',
		'opacity': 'toggle'
	},250,cb);

	return $(this);
}

/*
 * выравниваем компонент по центру экрана
 * зависит от свойства display
 * @version 1.0.1.2011-04-27
 */

$.fn.fl_center = function(){
	var u_top=$(this).css('position')=='absolute' ? $(window).scrollTop() : 0;
	var html = document.documentElement;

	//хитрожопый способ получить высоту и ширину окна
	var u_width = (window.innerWidth || html.clientWidth);
	var u_height = (window.innerHeight || html.clientHeight);

	$(this).css({
		'left': ''+Math.round(u_width/2-$(this).width()/2)+'px',
		'top': ''+Math.round(u_top+u_height/2-$(this).height()/2)+'px'
	});

	return $(this);
}


/* функция для единичного захвата элементов. думаю что будет универсальным
 * решением...
 * @version 1.0.0.2011-04-24
 * не работает, блджад
 */
$.fl_hook = function(selector,ident){
	ident=typeof(ident)=='string' ? ident : 'flr_hook';
	//выбираем только нехукнутые элементы
	return $(selector+':not(['+ident+'="1"])').attr(ident,'1');
}


//получение синхронизированорго с сервером времени
$.fl_get_server_time=function(){
	return time()+$.fl_time_difference;
}

//делаем всем заебись
$(function(){

	//fln-deafults. экспонат руками не трогать
	/*
	 * получение координатов мышки
	 * записываются в переменные ниже
	 * @version 1.0.0.2011-04-26
	 */

	$.fl_mouse_x=0;
	$.fl_mouse_y=0;

	$('body').mousemove(function(vi){
		$.fl_mouse_x=vi.pageX;
		$.fl_mouse_y=vi.pageY;
	});

	//есть такая фигня - картинки, по клику на которые надо бы открывать
	//стоящие рядом ссылки. реализумем их с помощью специального стиля
	$('.sfl-link-trigger').click(function(){
		document.location = $(this).next('a').attr('href');
	});

	//а еще, есть такие компоненты, которые надо выравнивать по центру
	//их также реализуем специальным стилем...
	$(window).resize(function(){
		$('.sfl-center-align').fl_center();
	});

	//обработка лабелов для радиобаттонов/чекбоксов - крайне полезная штука
	$('.sfl-radio-label').click(function(){
		$(this).prev('input').click();
	});


	$(window).resize();


	//копипаста, выравнивающая формулогина по клике на сцылге
//	$('a.sfl-authlink:not([fl_compiled="1"])').attr({
//		'onclick': false,
//		'fl_compiled': 1
//	}).click(function(evt){
//		var xpos=this.offsetLeft;
//		var ypos=this.offsetTop;
//
//		var pr=false;
//
//		if(typeof(this.offsetParent)!='undefined'){
//			pr=this.offsetParent;
//		}
//
//		//wtf?
//		while(typeof(pr)!='undefined' && pr){
//			xpos+=pr.offsetLeft;
//			ypos+=pr.offsetTop;
//			pr=pr.offsetParent;
//		}
//
//		ypos+=14;
//
//		if(!$(this).is('.sfl-lfnormalposition')){
//			xpos-=175;
//		}else{
//			xpos-=21;
//			ypos-=152;
//		}
//
//		/* хуйня, но что поделаешь */
//		$('#glogin_form').css({
//			'left': ''+xpos+'px',
//			'top': ''+ypos+'px',
//			'display': 'block',
//			'position': 'absolute'
//		});
//
//		evt.preventDefault();
//		evt.cancelBubble=true;
//	});


	/* влияем на магнитный[е] рейтинг[и] */
	$('.fl-graymagnitbox .fl-gmpad').click(function(){
		$(this).addClass('fl-gmpactive').removeClass('fl-gmpinactive').siblings('.fl-gmpad').removeClass('fl-gmpactive').addClass('fl-gmpinactive');
		$(this).parent('.fl-graymagnitbox').find('.fl-gminbox .fl-mgrcbox:eq('+($(this).index()-1)+')').animate({
			'opacity':'show',
			'height':'show'
		},300).siblings('.fl-mgrcbox').animate({
			'opacity':'hide',
			'height':'hide'
		},300)
	});

	/* оживляем едиты с дефолтным значением */
	$('.sfl-default-edit').focus(function(){
		//если у нас тупо вписан тайтл - значение надо убирать
		if(this.title == this.value){
			this.value = '';
		}
		$(this).css({
			'color': '#000000'
		});
	});

	// продолжаем оживление
	$('.sfl-default-edit').blur(function(){
		//если у нас тупо вписан тайтл лили ничего нет - значение надо установить равное тайтлу
		if(this.value == '' || this.title == this.value){
			this.value = this.title;
			$(this).css({
				'color': '#9a9a9a'
			});
		}else{
			$(this).css({
				'color': '#000000'
			});
		}
	});

	//компилируем теги данных. это уже кажется описано в спецификации
	$('.sfl-data').each(function(){
		this.sfl_data = fl_json_decode($(this).attr('sfl:data'));
	});

	//перерисовываем их
	$('.sfl-default-edit').blur();


	/**
	 * сия чушь ищет нам обьект по селектору и sfl-атрибутам, этакая короче база данных домашней выделки
	 * @version 1.0.0.2011-08-23
	 */

	$.fn.sfl_find = function(u_sfl_filters){
		var is_valid = false;

		//ищем обьекты стандартным селектором
		return $(this).filter(function(){
			is_valid = true;

			//проверяем соотвествие полей
			for(var k_filter_name in u_sfl_filters){
				is_valid &= $(this).attr(k_filter_name) == u_sfl_filters[k_filter_name];
			}

			return is_valid;
		});
	}
});
