var _tagLists = [];
var objectsRated = $H({});
var tagsExtended = false;
var dataSended = false;
var _tagExtendRequest = null;
var favObjects = [];
var favUsers = [];
var delObjects = [];
var preloadImages = ['star_on.gif','star_rated.gif','rated.gif','fav_on.gif','fav_added.gif','clipboard_on.gif','help.gif','info.gif','error.gif','warning.gif','user_on.gif','ajax-loader.gif','close.gif'];
var tagsPanelOptions = ['DobraOcena','OpisGG'];

var txtStrings = {
	tagsHelp: "<strong>Tagi</strong> to po prostu słowa określające dany opis. Może on być np \"miłosny\", \"śmieszny\" itp. :)",
	tagsLayerHelp: "<strong>Tagując</strong> opis określasz go pojedynczymi słowami (<strong>tagami</strong>). Im więcej osób ztaguje opis, tym prawdziwsze są jego tagi. Dzięki tagom można między innymi łatwo wyszukiwać opisy konkretnego typu.<br /><br />Poniższy formularz zawiera dodne już w różny sposób tagi, aby nie trzeba było wpisywać ich recznie."
};

// priv

function _tagsExtend( response, id ) {
	eval( response.responseText );
	// copy user tags to examine tag changes on unload
	tagsPerObjects.user.each(function(r){
		tagsPerObjects.userBefore[ r[0] ] = r[1].slice();
	});
	tagsExtended = true;
	layerTagToggle( id );
}

function buildTagsLists( id ) {
	// already done ?
	if ( _tagLists.indexOf( id ) != -1 ) return;
	// create lists
	var listOfficial = [];
	var listOthers = [];
	var listUserUses = [];
	var listTop = [];

	// get objects
	var objOfficial = $('obj_'+id+'_official_tags');
	var objOthers = $('obj_'+id+'_others_tags');
	var objUserUses = $('obj_'+id+'_user_uses_tags');
	var objTop = $('obj_'+id+'_top_tags');

	// fill lists with tags
	tagsPerObjects.official[ id ].each(function(tag){
		listOfficial.push( [tag[0], tags[ tag[0] ][0], tag[1]] );
	});
	tagsTop.each(function(tag){
		listTop.push( [tag, tags[ tag ][0]] );
	});

	// tags from other users are optional
	if ( tagsPerObjects.others[ id ] )
		tagsPerObjects.others[ id ].each(function(tag){
			listOthers.push( [tag[0], tags[ tag[0] ][0], tag[1]] );
		});

	tagsUserUses.each(function(tag){
		listUserUses.push( [tag, tags[ tag ][0]] );
	});

	// sort everything (except top's)
	listOfficial	= listOfficial.sortBy(	function(tag){	return -tag[2]; } );		// by count
	listOthers		= listOthers.sortBy(	function(tag){	return -tag[2]; } );		// by count
	listUserUses	= listUserUses.sortBy(	function(tag){	return -tag[1]; } );		// by name

	// write lists to theirs objects
	_writeTagList( objOfficial,	listOfficial,	id, true );
	_writeTagList( objUserUses,	listUserUses,	id );
	_writeTagList( objTop,		listTop,		id );

	// maybe no tags from other users except official ones
	if ( listOthers.length )
		_writeTagList( objOthers, listOthers, id, true );
	else
		Element.toggle('obj_'+id+'_other_tags_container');

	// build user list
	_refreshUserTagList( id );

	// remember this
	_tagLists.push( id );
}

function _writeTagList( obj, list, id, showCount ) {
	if ( list.length == 0 )
		return new Insertion.Bottom( obj, 'brak' );
	var html = '';
	list.each(function(tag){
		html = "<a href='#' onclick='addTagToUserList("+id+", "+tag[0]+");return false;'>"+tag[1]+"</a> ";
		html += showCount ? '('+tag[2]+') ' : '';
		new Insertion.Bottom( obj, html );
	//	obj.appendChild($E( {href:'#', onclick:'addTagToUserList('+id+', '+tag[0]+');return false;', innerHTML: tag[1]} ));
	//	obj.appendChild($E( ' ('+tag[2]+')' ));
	});
}

function _refreshUserTagList( id ) {
	var list = [];
	var obj = $('obj_'+id+'_user_tags');

	if ( tagsPerObjects.user[ id ] && tagsPerObjects.user[ id ].length ) {
		tagsPerObjects.user[ id ].each(function(tag){
			list.push( [tag, tags[ tag ][0]] );
		}.bind(list));
		obj.innerHTML = '';
	} else {
		obj.innerHTML = "<span class='i'>brak...</span>";
		return;
	}

	list = list.sortBy(function(tag,i){ return tag[1]; });

	list.each(function(tag){
		new Insertion.Bottom( obj, tag[1]+"&nbsp;(<a href='#' onclick='removeTagFromList("+id+", "+tag[0]+");return false;'>&laquo;</a>) " );
	/*	obj.appendChild($E( tag[1] ));
		obj.appendChild($E( '&nbsp;(' ));
		obj.appendChild($E( {href:'#', onclick:'removeTagFromList('+id+', '+tag[0]+');return false;', innerHTML: '&laquo;'} ));
		obj.appendChild($E( ')' ));*/
	});
}

/*************************/
/*          GUI          */
/*************************/

function layerToggle( id ) {
	if (! $F('useEffects') )
		return Element.toggle( id );
	window.attachEvent && ! window.opera
	?	$(id).visible()	// IE
		? Effect.SlideUp( id, {duration: 0.5} )
		: Effect.SlideDown( id, {duration: 0.5} )
	:	$(id).visible()	// rest of the world
		? Effect.Fade( id, {duration: 0.3} )
		: Effect.Appear( id, {duration: 0.5} );
}
/*
TODO: przebudowac to na indexy slowne
obj[1] - object data array
obj[1][0]: txt

obj[1][1][0]: mid
obj[1][1][1]: author

obj[1][2][0]: ratting
obj[1][2][1]: votes

obj[1][3]: queue [0|1|2]

obj[1][4]: count_taggers

obj[1][5]: count_favs
*/
function writeObjects( options ) {
	var def_options = $H({
		author: true,
		favObject: true,
		favUser: true,
		ratting: true,
		tagLayer: true,
		tags: true,
		showQueue: false,
		cssClass: null
	});
	// load default options
	if ( typeof options == 'undefined' ) options = def_options;
	else def_options.each(function(op) {
			if ( typeof options[ op[0] ] == 'undefined' ) options[ op[0] ] = def_options[ op[0] ];
		});
	// parse the template...
	var template = TrimPath.parseDOMTemplate('obj_template');
	// prepare template data
	var data = {
		homeURL:	homeURL,
		z:			objects.keys().length+1,	// decrementing z-index
		favType:	favType,	// add or del fav icon
		txt:		'',	// tmp string used for txt filtering
		stars:		'',	// tmp string used for vote-stars creation
		cssClass:	'',	// class name for main txt
		URLobject:	'',
		URLauthor:	'',
		tags:		'', // tags list
		del:		null,	// del button visible
		own:		null,	// visitior is the object author
		count_taggers:		null,	// amount of users that have tagged this object
		obj:		null,	// object ;)
		options:	options
	};

	if ( action == 'w-kolejce' ) {
		options.showQueue = true;
		options.ratting = false;
		options.tags = false;
		options.favObject = false;
	}

	var adSwith = Math.ceil( Math.random() * objects.keys().length ) -1;

	var HTML, HTMLwork = ''; var toWalk = [];
	objectsOrder.each(function(objID){
		var obj = [ objID, objects[ objID ] ];
		// obj[0] == id; obj[1] == object data array
		data.obj = obj;
		// author ?
		if ( mid != 0 && mid == obj[1][1][0] ) {
			data.cssClass = 'lineColor2';
			data.own = true;
			data.del = true;
		} else {
			data.cssClass = 'lineColor1';
			data.del = false;
			data.own = false;
		}
		// css class forced
		if ( options.cssClass ) data.cssClass = options.cssClass;
		// decrement z-index
		data.z--;
		// filter object txt content
		data.txt = filter( obj[1][0] );
		// build links
		data.URLobject = url([ ['_','opis'], ['__',obj[0]] ]);
		if ( obj[1][1][0] == 0 ) {
			obj[1][1][1] = 'nieznany';
			data.URLauthor = '';
		} else data.URLauthor = url([ ['_','osoba,'+obj[1][1][0]] ]);
	//	for ( s=1; s<=5; s++ ) {
		if ( options.ratting ) data.stars = rattingGetStars( obj[0], obj[1][2][0] );

	//	new Insertion.Bottom( target, template.process( data ) );
		if ( options.tags ) data.tags = _writeObjectTags( obj[0] );
		HTMLwork += template.process( data );
	//	if ( options.ratting ) rattingWalkOff( obj[0] );
	//	if ( options.ratting ) toWalk.push( obj[0] );

		// swap temp HTML vars to place ads between them
		if ( adSwith-- == 0 ) {
			HTML = HTMLwork;
			HTMLwork = '';
		}
	});
	$('objects').innerHTML = HTML;
	$('objects2').innerHTML = HTMLwork;

	// make the start shine ;)
	toWalk.each(function(id){
		rattingWalkOff( id );
	});
}

// TODO: zapisywanie do innerHTML za jednym razem wszystkiego ?
function _writeObjectTags( id ) {
	var list = [];
	var similar = [];
//	var obj = $('obj_'+id+'_tags');
	// fill lists with tags
	if ( tagsShow == 'official' ) {
		tagsPerObjects.official[ id ].each(function(tag){
			// tag[0]: id, tag[1]: count
			list.push( [tag[0], tags[ tag[0] ][0], tag[1]] );
		});
		// sort by count
		list = list.sortBy( function(tag){ return tag[2]; } );
	} else if ( tagsShow == 'user' ) {
		tagsPerObjects.user[ id ].each(function(tag){
			// tag: id
			list.push( [tag, tags[ tag ][0]] );
		});
		// sort by name
		list = list.sortBy( function(tag){ return tag[1]; } );
	} else if ( tagsShow == 'others' ) {
		tagsPerObjects.others[ id ].each(function(tag){
			// tag[0]: id, tag[1]: count
			list.push( [tag[0], tags[ tag[0] ][0], tag[1]] );
		});
		// sort by name
		list = list.sortBy( function(tag){ return tag[1]; } );
	} else alert('ERROR');
	if ( list.length == 0 ) {
	//	obj.innerHTML += 'brak';
		return 'brak';
	}
	var tmp = '';
	list.each(function(tag){
		tmp += "<a href='"+url( [ ['_','spis'], ['tagi',tag[1] ] ] )+"'>"+tag[1]+"</a> ";
		if ( tag.length == 3 ) tmp += "("+tag[2]+") ";
	});
	// sort by name if needed
	if ( tagsShow != 'user' ) list = list.sortBy( function(tag){ return tag[1]; } );
	list.each(function(tag){
		similar.push( tag[1] );
	});

//	obj.innerHTML += tmp+" <a class='noLinkBorder' href='"+url( [ ['_','spis'], ['tagi',similar.toString() ] ] )+"' title='Podobne opisy'>...</a>";
	return tmp+" <a class='noLinkBorder' href='"+url( [ ['_','spis'], ['tagi',similar.toString() ] ] )+"' title='Podobne opisy'>...</a>";
}

// builds most popular tags list
function writeTagsPanel( panelTags, checkedTags ) {
	var tagsPanel = $('tagsPanelTagsList');
	if (! tagsPanel ) return;
	var checked = '';
	var checkedAll = true;
	var panelTagsTxts = [];
	var tmp = '', tb = '';
	panelTags.each(function(tagID){
		if ( checkedTags.indexOf( tagID ) != -1 ) {
			checked = "checked='checked'";
			bold = 'tb';
		} else {
			checked = '';
			bold = '';
		}
		// tag[0]: txt, tag[1]: count, tag[2]: count users
		tag = tags[ tagID ];
		panelTagsTxts.push( tag[0] );
		if ( tag.length == 3 )
			tmp += "\
				<div>\
					<label class='tagPanelTag fadeSrc fadeFor_tag_"+ tagID +" "+ bold +"' for='tag_"+tagID+"' title='Obecny w "+tag[1]+" opisach, użyty przez "+tag[2]+" użytkowników' onclick=\"$('tagsPanelWhat_tags').checked=true;toggleDiv('tagsPanelTags_div',1);\" "+checked+">\
						<input type='checkbox' name='tag_"+tagID+"' class='fadeMe' id='tag_"+tagID+"' value='1' "+checked+" /> "+tag[0]+" (<strong>"+tag[1]+"</strong>/"+tag[2]+")\
					</label>\
				</div>";
		else
			tmp += "\
				<div>\
					<label class='tagPanelTag fadeSrc fadeFor_tag_"+ tagID +" "+ bold +"' for='tag_"+tagID+"' title='Obecny w "+tag[1]+" opisach' onclick=\"$('tagsPanelWhat_tags').checked=true;toggleDiv('tagsPanelTags_div',1);\" "+checked+">\
						<input type='checkbox' name='tag_"+tagID+"' class='fadeMe' id='tag_"+tagID+"' value='1' "+checked+" /> "+tag[0]+" (<strong>"+tag[1]+"</strong>)\
					</label>\
				</div>";

		if ( checked ) checkedAll = false;
/*		
		Event.observe( $( 'tag_'+tagID ), 'click', function(){
			$('tagsPanelAll').checked = false; 
		});
*/
	});
	tagsPanel.innerHTML = tmp;
	var search_phrase = $('search_phrase');
	if (! search_phrase.value && checkedAll ) $('tagsPanelWhat_all').checked = true;
	// stip selected tags from input
	else if ( search_phrase.value ) {
		var tmp = getTagsFromString( search_phrase.value );
		search_phrase.value = '';
		tmp.each(function(tag){
			if ( panelTagsTxts.indexOf( tag ) == -1 )
				search_phrase.value += tag+' ';
		});
	}
}

/*************************/
/*     FORM SUBMITS      */
/*************************/

function searchSubmit() {
	var URL = [];
	// TODO sprawdzanie czy w ogole ktos cos wyszukuje i jakis komunikat o bledzie
	if ( $('search_tags_users').checked ) 
		URL.push( ['opcje', 'WszystkieTagi'] );
	if ( $('search_bools').checked ) {
		URL.push( ['_', 'szukaj'] );
		URL.push( ['__', encodeURIComponent( $F('search_tags') ) ] );
	} else {
		URL.push( ['_','spis'] );
		URL.push( ['tagi', getTagsFromString( $F('search_tags'), ',' ) ] );
	}
	location.href = url( URL, true );
	return false;
}

function tagsPanelFormSubmit( page ) {
	var optionsURL = [];
	if ( $('tagsPanelWhat_all').checked ) {
		var urlParams = [ ['_', action] ];
	} else {
		var submitTags = [];
		var nodes = $('tagsPanelForm').getElementsByTagName('input');
		var tmpID = '';
		$A( nodes ).each(function( node ){
			// gets tag name from tags array
			if ( node.id.substr(0,4) == 'tag_' && node.checked )
				submitTags.push( tags[ node.id.substr(4) ][0] );
		});
		if ( $F('search_phrase').strip().toLowerCase() != 'wpisz poszukiwane tagi' ) {
			getTagsFromString( $F('search_phrase') ).each(function( tag ){
				if ( submitTags.indexOf( tag ) == -1 )
					submitTags.push( tag );
			});
		}
		// sort by name
		submitTags = submitTags.sortBy(	function(tagStr){ return tagStr; } );
		// form variable
		if ( submitTags.toString() ) {
			var urlParams = [ ['_',action], ['tagi', submitTags.toString()] ];
			if ( $('tagsPanelTags_users') && $('tagsPanelTags_users').checked )
				optionsURL.push('WszystkieTagi');
			else if ( $('tagsPanelTags_my') && $('tagsPanelTags_my').checked )
				optionsURL.push('MojeTagi');
		} else
			// no tags selected, back to 'all' version
			var urlParams = [ ['_',action] ];
	}
	tagsPanelOptions.each(function( op ){
		if ( $(op) && $F(op) ) optionsURL.push( op );
	});
	if ( optionsURL.length > 0 ) urlParams.push( ['opcje', optionsURL.toString()] );
	if ( action_page ) urlParams.push( ['__', action_page] );
	if ( window.sort_page ) urlParams.push( ['od', sort_page] );
	document.location = url( urlParams, true );
//	console.log( url( urlParams, true ) );	
	return false;
}

/*************************/
/*   TAGS MANIPULATION   */
/*************************/

function addTagToUserList( id, tagId ) {
	if (! tagsPerObjects.user[ id ] )
		tagsPerObjects.user[ id ] = [];
	if ( tagsPerObjects.user[ id ].indexOf( tagId ) == -1 ) {
		tagsPerObjects.user[ id ].push( tagId );
		_refreshUserTagList( id );
	}
}

function removeTagFromList( id, tagId ) {
	if ( tagsPerObjects.user[ id ].indexOf( tagId ) != -1 ) {
		tagsPerObjects.user[ id ] = tagsPerObjects.user[ id ].without( tagId );
		_refreshUserTagList( id );
	}
}

/*************************/
/* OBJECT EVENT HANDLERS */
/*************************/

function layerTagToggle( id, event ) {
	if ( mid == 0 ) return layerContext( event, 'layerError',
		"Musisz być <a href='"+ url([ ['_', 'loguj'] ]) +"' class='b'>zalogowany</a>, aby móc tagować opisy.",
		5000);
	// TODO: budowanie requesta na url();
	if (! tagsExtended ) {
		if ( _tagExtendRequest !== null ) return;
		var params = 'action=ajax&tagsShow='+tagsShow+'&code=fetch_extra_tags&ids='+objects.keys().toString()+'&tags='+$H(tags).keys().toString();
		_tagExtendRequest = new Ajax.Request( homeURL,{
			parameters: params,
			onSuccess: function(response){ _tagsExtend(response,id); },
			onException: function(ajax,exception){ alert("URL:\n"+homeURL+'?'+params+"\nAJAX exception:\n"+dump( exception ) ); }
		});
		return;
	}
	buildTagsLists(id);
	var layer = 'obj_'+id+'_tag_layer';
	// position: relative vs floats problem...
	var xy = Position.cumulativeOffset( $('obj_'+id+'_txt') );
	Element.setStyle( layer, { top: (xy[1]+40)+'px', left: xy[0]+'px' } );

	if (! $F('useEffects') ) return Element.toggle( layer );
	$(layer).visible()
		? Effect.DropOut( layer )
		: Effect.Grow( layer, {duration: 0.5} );
}

function favUser( event, mid, removeThisDiv ) {
	if ( favUsers.indexOf( mid ) != -1 ) return;
	if ( mid == 0 ) return layerContext( event, 'layerError',
		"Musisz być <a href='"+ url([ ['_', 'loguj'] ]) +"' class='b'>zalogowany</a>, aby móc wybrać użytkownika do ulubionych.",
		5000);
	if ( favUserType != 'add' && ! confirm("Czy na pewno chcesz usunąć tego użytkownika z ulubionych ?") )
		return;
	favUsers.push( mid );
	var img = $('obj_'+mid+'_fav_user');
	if ( img ) img.alt = '';
	if ( favUserType == 'add' ) {
		if ( img ) swapImg( 'obj_'+mid+'_fav_user', img.src.replace(/fav_(on|off)/, 'fav_added' ) );
		if ( $F('showTips') ) layerContext( event, 'layerInfo', 'Wybrano u?ytkownika do ulubionych.');
	} else {
		if ( img ) swapImg( 'obj_'+mid+'_fav_user', img.src.replace(/favNot_(on|off)/, 'favNot_del' ) );
		if ( $F('showTips') ) layerContext( event, 'layerInfo', 'Usuni?to u?ytkownika z ulubionych.');
	}
	if ( removeThisDiv ) removeDiv( removeThisDiv );
}
// TODO: implementacja w szablonie
function favObject( event, id, removeObject, openTagLayer /* true */ ) {
	if ( favObjects.indexOf( id ) != -1 ) return;
//	if ( typeof openTagLayer == 'undefined' ) openTagLayer = true;
	if ( mid == 0 ) return layerContext( event, 'layerError',
		"Musisz być <a href='"+ url([ ['_', 'loguj'] ]) +"' class='b'>zalogowany</a>, aby móc dodać opis do ulubionych.",
		5000);
	if ( favType != 'add' && ! confirm("Czy na pewno chcesz usunąć ten opis z ulubionych ?") )
		return;
	var img = $('obj_'+id+'_fav');
	img.alt = '';
	if ( favType == 'add' ) {
		var time = swapImg( 'obj_'+id+'_fav', img.src.replace(/fav_(on|off)/, 'fav_added' ) );
		if ( $F('showTips') ) layerContext( event, 'layerInfo', 'Dodano opis do ulubionych.');
	} else {
		var time = swapImg( 'obj_'+id+'_fav', img.src.replace(/favNot_(on|off)/, 'favNot_del' ) );
		if ( $F('showTips') ) layerContext( event, 'layerInfo', 'Usuni?to opis z ulubionych.');
	}
	favObjects.push( id );
	if ( openTagLayer && favType == 'add' ) setTimeout('layerTagToggle( '+id+' );', time);
	if ( removeObject ) removeDiv( 'obj_'+id );
}

function favImg( id, state ) {
	var img = $('obj_'+id+'_fav');
	if ( favType == 'add' ) {
		if ( img.src.indexOf('fav_added') != -1 ) return;
		swapImg( 'obj_'+id+'_fav', img.src.replace(/fav_(on|off)/, 'fav_'+state) );
	} else {
		if ( img.src.indexOf('favNot_del') != -1 ) return;
		swapImg( 'obj_'+id+'_fav', img.src.replace(/favNot_(on|off)/, 'favNot_'+state) );
	}
}

function removeDiv( id, effect ) {
	if ( $F('useEffects') ) {
		if ( typeof effect == 'string' ) {
			if (! $(id).id ) {
				$(id).id = 'dasd313212dasdas3';
				eval("Effect."+effect+"('dasd313212dasdas3');");
				$(id).id = '';
			} else eval("Effect."+effect+"('"+$(id).id+"');");
		} else Effect.Fade( id );
	} else $(id).toggle();
}

function toggleDiv( id, explicit ) {
	// explicit: 1 - show; 0 - hide
	if ( typeof explicit != 'undefined' ) {
		if (! explicit && $(id).visible() ) {
			if ( $F('useEffects') ) Effect.Fade( id, { duration: 0.5 } );
			else $(id).hide();
		} else if ( explicit && ! $(id).visible() ) {
			if ( $F('useEffects') ) Effect.Appear( id, { duration: 0.5 } );
			else $(id).show();
		}
	} else if ( $F('useEffects') ) {
		if ( $(id).visible() ) Effect.Fade( id, { duration: 0.5 } );
		else Effect.Appear( id, { duration: 0.5 } );
	} else $(id).toggle();
}

function delObject( event, id ) {
	if (! confirm("Czy na pewno chcesz usun?? ten opis ?") ) return;
	delObjects.push( id );
	if ( $('obj_'+id) ) removeDiv('obj_'+id);
	else document.location = url([ ['_','osoba,'+mid], ['__','opisy'] ]);
}

function objectClip( event, id ) {
	var txt = unsafe_value( $('obj_'+id+'_txt').innerHTML );
	if (! clipboard( txt ) )  return layerContext( event, 'layerError',
		"Niestety kopiowanie opisu do schowka <strong>nie działa</strong> na twojej przeglądarce.<br />Przepraszamy...",
		5000);
	var img = Event.element( event );
	if ( img.alt ) img.alt = '';
	if ( $F('showTips') )
		layerContext( event, 'layerInfo', 'Skopiowano opis do schowka.<br />Możesz go wkleić naciskając <strong>CTRL+V</strong>.');
}

function swapImgSrc( idOrObj, part1, part2 ) {
	var obj = $( idOrObj );
	if (! obj ) return;
	swapImg( obj.id, replace( obj.src, part1, part2 ) );
}

function swapImg( id, newURL ) {
	// FF only effect
	if ( $('useEffects' ) && $F('useEffects') && ! isIE() && ! isOpera() ) {
		Effect.Fade( id, {
			duration: 0.15, to: 0.5, queue: { scope: id }
		});
		setTimeout("$('"+id+"').src = '"+newURL+"'", 150);
		Effect.Appear( id, {
			duration: 0.15, to: 1, queue: { scope: id, position: 'end' }
		});
		setTimeout("$('"+id+"').src = '"+newURL+"'", 150);
		/*
		Effect.FadeImg(id, newURL, {
			duration: 1.20, queue: { scope: id, position: 'end' }});
		*/
		return 0.30;
    } else {
		$(id).src = newURL;
		return 0;
	}
}

/*************************/
/*    CONTEXT LAYERS     */
/*************************/

// TODO zrobic delay na 2 sek
function inputTagsTip(event) {
	if (! $F('showTips') ) return;
/*	layerContext(event,'layerTip',
		"Rozdzielaj tagi spacjami. Jeśli chcesz łączyć słowa (np nazwy własne) korzystaj z <strong>podkreślenia</strong> np <strong class='i'>chuck_norris</strong>.");
	Event.observe( Event.element( event ), 'mouseout', _inputTagsTip );*/
}

function _inputTagsTip( event ) {
	Event.stopObserving( Event.element( event ), 'mouseout', _inputTagsTip );
	if ( $F('useEffects') )
		Effect.Fade('layerTip', { duration: 0.5, queue: { scope: 'layerTip', position: 'end', limit:2 } } );
	else
		Element.toggle('layerTip');
}

var _rejectInfoShown = false;
function rejectObjectInfo( event ) {
	if (! Event.element( event ).checked || _rejectInfoShown ) return;
	_rejectInfoShown = true;
	layerContext(event,'layerWarning',
		"Zaznaczając ten przycisk moż?esz przyczynić się do usunięcia opisu z bazy. Dokonując wyboru weź pod uwage, że nawet jeśli dla Ciebie opis jest nieprzydatny, to może być wartościowy dla innych użytkowników.",11000);
}

function layerContext( event, layer, txt, timeout ) {
	var timeout = timeout ? timeout : 2000;

	$(layer).getElementsByTagName('p')[0].innerHTML = txt;
	Element.setStyle( layer, $H({
		left: (Event.pointerX( event )+20)+'px',
		top: (Event.pointerY( event )+20)+'px'
	}));
	if ( $F('useEffects') ) {
		Effect.Appear( layer, { duration: 0.5, queue: { scope: layer, position: 'end', limit:2 } } );
		if ( layer != 'layerTip' )
			setTimeout("if ( $('"+layer+"').visible() ) Effect.Puff('"+layer+"', { duration: 0.5, queue: { scope: '"+layer+"', position: 'end', limit:2 } } );",timeout);
	} else {
		Element.toggle( layer );
		if ( layer != 'layerTip' )
			setTimeout("if ( $('"+layer+"').visible() ) Element.toggle('"+layer+"');",timeout);
	}
}

/*************************/
/*       AJAX STUFF      */
/*************************/

Ajax.Responders.register({
	// mouse loading
	onCreate: function() {
		if ( document.styleSheets && document.styleSheets[0].addRule )	// IE
			document.styleSheets[0].addRule('*','cursor: wait;');
		else if ( document.styleSheets && document.styleSheets[0].insertRule ) {	// W3C
			css = document.styleSheets[0];
			css.insertRule('* {cursor: wait;}',css.cssRules.length);
		}},
	// mouse back to auto
	onComplete: function() {
		if ( document.styleSheets && document.styleSheets[0].addRule ) {	// IE
			css = document.styleSheets[0];
			css.removeRule( css.rules.length-1 );
		} else if ( document.styleSheets && document.styleSheets[0].insertRule ) {	// W3C
			css = document.styleSheets[0];
			css.deleteRule( css.cssRules.length-1 );
		}}
});

// wysylanie danych zromadzonych podczas wyswietlania strony
function sendData() {
	if ( dataSended == true ) return;
	dataSended = true;
	var query = $H({});
	var tmp = '';
	objectsRated.each(function(obj){
		// 0: id; 1: ratting
		if (! query['rated'] ) query['rated'] = obj[0];
		else query['rated'] += ','+obj[0];
		query[ 'ratting'+obj[0] ] = obj[1];
	});
	if ( favObjects.length ) {
		if ( favType == 'add' )
			query['favObjects'] = favObjects.toString();
		else
			query['favNotObjects'] = favObjects.toString();
	}
	if ( favUsers.length ) {
		if ( favUserType == 'add' )
			query['favUsers'] = favUsers.toString();
		else
			query['favNotUsers'] = favUsers.toString();
	}
	if ( delObjects.length )
		query['delObjects'] = delObjects.toString();

	var reject = [];
	if ( window.tagsPerObjects ) {
		$H( tagsPerObjects.official ).each(function(obj){
			// obj[0]: id, obj[1]: rest...
			if ( $('obj_'+obj[0]+'_reject') && $F('obj_'+obj[0]+'_reject') )
				reject.push( obj[0] );
		});
	}
	if ( reject.length ) query['rejectObjects'] = reject.toString();

	if ( tagsExtended ) {
	//	query['tags'] = [];	// list of object ids
		//query['tagXXXadd'] = [];	// add this tags to id XXX
		//query['tagXXXdel'] = [];	// add this tags for id XXX
		// choosen tags
		var userBeforeIDs = tagsPerObjects.userBefore.keys();
		tagsPerObjects.user.each(function(obj){
			// obj[0]: obj id, obj[1]: tags list
			var change = false;
			var before = tagsPerObjects.userBefore[ obj[0] ];
			if ( userBeforeIDs.indexOf( obj[0] ) == -1 ) {
				// add all
				change = true;
				query['obj'+obj[0]+'add'] = obj[1].toString();
			} else if ( obj[1].length == 0 ) {
				// delete all
				change = true;
				query['obj'+obj[0]+'del'] = tagsPerObjects.userBefore[ obj[0] ].toString();
			} else if ( obj[1].length > 0 && ( obj[1].difference( before ).toString() || before.difference( obj[1] ).toString() ) ) {
				// some changes, find out...
				change = true;
				// needs Array.prototype.difference !
				tmp = obj[1].difference( before);
				if ( tmp != '' ) query['obj'+obj[0]+'add'] = tmp;
				tmp = before.difference( obj[1] );
				if ( tmp != '' ) query['obj'+obj[0]+'del'] = tmp;
			}

			if ( change == true ) {
				if ( query['objs'] ) query['objs'].push( obj[0] );
				else query['objs'] = [ obj[0] ];
			}
		});
		// inputed tags
		var spaceRegExp = / +/;
		objects.each(function(obj){
			// obj[0]: id...
			if ( $F('obj_'+obj[0]+'_new_tags') ) {
			//	query['obj'+obj[0]+'new'] = $F('obj_'+obj[0]+'_new_tags').replace( spaceRegExp, '%20' );
				query['obj'+obj[0]+'new'] = $F('obj_'+obj[0]+'_new_tags');
				if ( query['objs'] ) query['objs'].push( obj[0] );
				else query['objs'] = [ obj[0] ];
			}
		});
	}

	if ( query.keys().length == 0 ) return;
//	query['mid'] = mid;
	query['action'] = 'ajax';
	query['code'] = 'unload';

//	alert( query.toQueryString() );
	var req = new Ajax.Request( homeURL ,{
		postBody: query.toQueryString(),
		onException: function(ajax,exception){ alert("AJAX exception:\n"+dump( exception ) ); },
		asynchronous: false
	});
}

Event.observe( window, 'beforeunload', sendData );
Event.observe( window, 'unload', sendData );

/***************************/
/*       RATTING STUFF     */
/***************************/

var star_off = 'images/star_off.gif';
var star_on = 'images/star_on.gif';
var walkingOnStars = null;	// hehe ;)

function rattingWalk( id, i ) {
	if ( objectsRated[ id ] ) return;
	walkingOnStars = id;
	var star = null;
	for ( var s=1; s<=5; s++ ) {
		star = $('obj_'+id+'_star_'+s);
		if ( i < s ) {
			if ( star.src.search(/star_off/) == -1 )
				swapImg( 'obj_'+id+'_star_'+s, homeURL+star_off );
		} else {
			if ( star.src.search(/star_on/) == -1 )
				swapImg( 'obj_'+id+'_star_'+s, homeURL+star_on );
		}
	}
}

function rattingWalkOff( id, event ) {
	if ( objectsRated[ id ] ) return;
	if ( event && ! walkingOnStars ) return;
	if ( event ) {
		var el = Event.element( event );
	/*	if ( el.tagName.toLowerCase() == 'img' || Position.within('obj_'+id+'_stars', Event.pointerX(event), Event.pointerY(event) ) )*/
		if ( el.tagName.toLowerCase() == 'img' || el.id == 'obj_'+id+'_stars' )
			return true;
	}
	walkingOnStars = null;
	for ( var s=1; s<=5; s++ ) {
	/*	$('obj_'+id+'_star_'+s).src = objects[ id ][2][0] < s
			? homeURL+star_off
			: homeURL+'images/star_rated_off.gif';*/
		if ( objects[ id ][2][0] < s ) swapImg('obj_'+id+'_star_'+s, homeURL+star_off );
		else swapImg('obj_'+id+'_star_'+s, homeURL+'images/star_rated_off.gif' );
	}
}

function rattingGetStars( id, ratting ) {
	var stars = ''; var img = '';
	$R(1,5).each(function(s){
		img = ratting < s ? homeURL+star_off : homeURL+'images/star_rated_off.gif';
		stars += "<img src='"+ img +"' id='obj_"+ id +"_star_"+ s +"' alt='"+ s +"' onmouseover='rattingWalk("+ id +","+ s +");' onclick='rate("+ id +","+ s +");' /> ";
	});
	return stars;
}

function rate( id, i ) {
	if ( objectsRated[ id ] ) return;
	walkingOnStars = null;
	objectsRated[ id ] = i;
	var star = null;
	for ( var s=1; s<=5; s++ ) {
		star = $('obj_'+id+'_star_'+s);
		if ( i < s )
			star.src = homeURL+star_off;
		else {
			if ( $('useEffects' ) && $F('useEffects') ) {
				if ( isIE() ) {
					Effect.Fade( star, {
						duration: 0.25, to: 0.1, queue: { scope: 'obj_'+id+'_star_'+s }
						} );
					setTimeout('$("obj_'+id+'_star_'+s+'").src = "'+homeURL+'images/star_rated.gif"', 250);
					Effect.Appear( star, {
						duration: 0.25, queue: { scope: 'obj_'+id+'_star_'+s, position: 'end' }
					});
				} else {
					Effect.Pulsate( star, { duration: 0.5 } );
					setTimeout('$("obj_'+id+'_star_'+s+'").src = "'+homeURL+'images/star_rated.gif"', 250);
				}
			} else
				star.src = homeURL+'images/star_rated.gif';
		}
	}
}

/***************************/
/*	        MISC           */
/***************************/

function isIE() {
	return document.attachEvent && ! window.opera;
}

function isOpera() {
	return window.opera;
}

function dump( obj )
{
	var txt = '';
	for( var i in obj ) {
		txt += i+' = '+obj[i]+"\n";
	}
	return txt;
}

// args: [ [arg1,val1], [arg2,val2] ... ]
function url( args, js ) {
	var uri = '';
	var _ = '';
	args = args.sortBy(function(arg){ return arg[0]; });
	if ( friendlyURLs ) {
		var __ = '';
		args.each(function(arg){
			if ( arg[0] == '_' ) {
				_ = arg[1]+'/';
			} else if ( arg[0] == '__' ) {
				__ = arg[1]+'/';
			} else {
				if ( uri ) uri += '/';
				uri += arg[0]+','+arg[1];
			}
		});
		return homeURL+_+__+uri;
	} else {
		uri = '?';
		args.each(function(arg){
			if ( uri != '?' ) uri += (js?'&':'&amp;');
			if ( arg[0] == '_' ) {
				arg[0] = 'action';
				_ = arg[1]
			} else if ( arg[0] == '__' )
				arg[0] = _;
			uri += arg[0]+'='+arg[1];
		});
		return homeURL+uri;
	}
}

/*
alert( url( [['_','test']] ) )
alert( url( [['_','test2'], ['a','b']] ) )
alert( url( [['_','test3'], ['a','b'], ['__','ccc']] ) )
*/

function getTagsFromString( str, join ) {
	var tags = [];
	var tmp = '';
	str.split(/\s+/).each(function(chunk){
		tmp = _normalizeTag( chunk );
		if ( tmp.length > 2 && tags.indexOf( tmp ) == -1 )
			tags.push( tmp );
	});
	return join ? tags.join( join ) : tags;
}

var _normalizePat = new RegExp('[^a-z_0-9]','ig');
function _normalizeTag( str ) {
	str = filter_swichChars( str, plChars );
	return str.replace( _normalizePat, '' );
}

/***************************/
/*	     TAGS CLOUD        */
/***************************/

function tagsCloudClick( anchor, event ) {
	if (! $('tags_cloud_join') || ! $('tags_cloud_join').checked ) return true;
	var URL = location.href.toString();

	// TODO wycinanie tagow, rozbijanie na tablice i sortowanie alfabetyczne
	if ( friendlyURLs ) 
		URL = URL.replace(/tagi,/, 'tagi,'+ anchor.firstChild.nodeValue +',');
	else URL = URL.replace(/tagi=/, 'tagi='+ anchor.firstChild.nodeValue +',');
	location.href = URL;
	Event.stop( event );
	return false;
}

/***************************/
/*	      SETTINGS         */
/***************************/

/*function settingsField( el ) {
	if ( el.checked ) setCookie( el.id, 1, 1, '', '.gadu-gadu.info.pl' );
	else setCookie( el.id, -1, 1, '', '.gadu-gadu.info.pl' );
}*/

//function settingsLoad( /* id [, id [...]] */ ) {
/*	$A( arguments ).each(function(id){
		var el = $( id );
		if ( el ) {
			if ( getCookie( id ) == 1 ) el.checked = true;
			else if ( getCookie( id ) == -1 ) el.checked = false;
		}
	});
}*/

/***************************/
/*	     onDOMReady        */
/***************************/

// Help functions
function fadeOff( idOrEvent ) { fade( idOrEvent, true ); }
function fade( idOrEvent, show ) {
	if ( typeof idOrEvent == 'string' ) {
		var el = $( idOrEvent );
		var event = null;
	} else {
		var event = idOrEvent;
		var el = Event.element( event );
	}
	if ( show ) {
		$F('useEffects' ) ? Effect.Appear( el, { duration: 0.2 } ) : Element.setOpacity( el, 1 );
	} else {
	//	if ( event && Position.within( el, Event.pointerX(event), Event.pointerY(event) ) ) return;
		if (! el.hasClassName('fadeMe') ) return;
		$F('useEffects' ) ? Effect.Fade( el, { to: 0.5, duration: 0.2 } ) : Element.setOpacity( el, 0.5 );
	}
}

// CONSTRUCT FADE IMAGES
function constructFades(){
	var faded = [];
	[].concat( $$('label.fadeSrc'), $$('a.fadeSrc') ).each(function(el){
//	$A( document.getElementsByClassName('fadeSrc') ).each(function(el){
		Element.classNames(el).each(function(className){
			if ( className.substr(0,8) == 'fadeFor_' ) {
				var id = className.substr(8);
				Event.observe( el, 'mouseover', function(e){ fadeOff( id ); } );
				Event.observe( el, 'mouseout', function(e){ fade( id ); } );
				faded.push( id );
			}
		});
	});
	[].concat( $$('img.fadeMe'), $$('input.fadeMe'), $$('a.fadeMe'), $$('label.fadeMe') ).each(function(el){
//	$A( document.getElementsByClassName('fadeMe') ).each(function(el){
/*		var fader = false;
		if ( el.id ) {
			$$('.fadeFor_'+el.id).each(function(el){
		//	$A( document.getElementsByClassName('fadeFor_'+el.id) ).each(function(el){
				Event.observe( el, 'mouseover', function(e){ fadeOff( el.id ); } );
				Event.observe( el, 'mouseout', function(e){ fade( el.id ); } );
		//		if ( $F('useEffects' ) )
		//				Event.observe( el, 'click', function(e){
		//				Effect.Pulsate( el.id, { duration: 0.3 } );
		//			});
				fader = true;
			});
		}
		if (! fader ) {
			Event.observe( el, 'mouseover', fadeOff );
			Event.observe( el, 'mouseout', fade );
		}*/
		Element.setOpacity( el, 0.5 );
		// input only
		if ( el.tagName.toLowerCase() == 'input' ) {
			Event.observe( el, 'focus', fadeOff );
			Event.observe( el, 'blur', fade );
		}
		if ( el.id && faded.indexOf( el.id ) != -1 ) return;
		Event.observe( el, 'mouseover', fadeOff );
		Event.observe( el, 'mouseout', fade );
	});
}
if ( window.opera ) Event.observe( window, 'load', constructFades );
else Event.onDOMReady( constructFades );

Event.onDOMReady(
	// PRELOAD IMAGES
	function(){
		preloadImages.each(function(img){
			var tmp = new Image();
			tmp.src = homeURL+'images/'+img;
			tmp = null;
		});
	}
);

Event.observe( window, 'load', function(){
	if (! $('ad_top_img') ) return;
	new PeriodicalExecuter(function(){
		if (! $F('useEffects') ) return;
		Effect.Fade( 'ad_top_img', { duration: 0.2, to: 0.3, queue: { position: 'end', scope: 'ad_top_img' } } );
		Effect.Appear( 'ad_top_img', { duration: 0.6, from: 0.3, queue: { position: 'end', scope: 'ad_top_img' }  } );
	}, 10);
}, false);


/*Event.onDOMReady(
	// CONSTRUCT MENU
	function(){
		function _menuClick( event ) {
			var el = Event.element( event );
			Effect.Pulsate( el, { duration: 0.5 } );
		}
		$$('.windowTabs a').each(function(el){
			Element.setOpacity( el, 0.5 );
			Event.observe( el, 'mouseover', fadeOff );
			Event.observe( el, 'mouseout', fade );
			Event.observe( el, 'click', _menuClick );
		})
	}
);*/
/*Event.onDOMReady(
	// CONSTRUCT MENU
	function(){
		function _menuClick( event ) {
			var el = Event.element( event );
			Effect.Pulsate( el, { duration: 0.5 } );
		}
		$$('.windowTabs a').each(function(el){
			Element.setOpacity( el, 0.5 );
			Event.observe( el, 'mouseover', fadeOff );
			Event.observe( el, 'mouseout', fade );
			Event.observe( el, 'click', _menuClick );
		})
	}
);*/