function loadImagesOnScroll()
{

	var lastElementTop = $(document.body).select(".previewBlock").last().cumulativeOffset().top;	
	var viewportHeight = document.viewport.getHeight();
	var viewportOffset = document.viewport.getScrollOffsets().top;
	

	
	if(viewportHeight >= lastElementTop || viewportHeight == 0)
	{
		viewportHeight = 700;
	}
	
	viewportOffset += viewportHeight;	
	
	if(lastElementTop - viewportOffset <= viewportHeight / 2)
	{
		if($('lastImage'))
		{
			return;
		}
		
		var imagesCount = $(document.body).select(".previewBlock").size();
		var lastImg = $(document.body).select(".previewBlock").last();
	
		if(document.loading == imagesCount)
		{
			return;
		}
	
		document.loading = imagesCount;
	
		var location = document.location.href.replace(/(#|\?).*$/g, '');
	
		if(document.find)
		{
			var tofind = document.find;
		}
		else
		{
			var tofind = '';
		}
	
		new Ajax.Request(
			location+'/images',
			{
				method: 'get',
				parameters: {'nolayout': 1, 'find': tofind, 'offset': imagesCount},
				onSuccess:
				function(transport)
				{
					lastImg.insert({after: transport.responseText});
					document.loading = '';
					anchor({'offset': imagesCount});
				}
			}
		);
	}
}














incrementalFind = function(element)
{
	var me = this;
	this.blockClass = null;
	this.incrementalForm = null;
	this.currentValue = null;
	this.isBlurred = true;
	this.init = function()
	{

		me.findTimeout = null;
		
		if(me.blockClass == null)
		{
			me.blockClass = ".previewBlock";
		}
		
		if(me.incrementalForm == null)
		{
			me.incrementalForm = "incrementalForm";
		}		
	
		$(me.incrementalForm).observe('submit', function(event)
		{		
			return preventDefaultEvent(event);
		});
		
		me.element = $(element);
		me.element.observe('keyup', me.onFindChanged);
		me.element.observe('focus', me.focusField);
		me.element.observe('blur', me.blurField);	
		
		me.blurField();


		var dochash = document.location.hash.replace(/^#/, '');

		if(me.element.value && !me.isBlurred)
		{
			document.location.replace("#"+element.value);
			me.findOnType();
			me.element.focus();
			me.element.selectionStart = element.value.length;		
		}
		else
		if(dochash)
		{
			me.element.value = dochash; 
			me.isBlurred = false;
			me.findOnType();
			me.element.focus();
			me.element.selectionStart = me.element.value.length;
		}
		
		me.eraseId = me.element.identify()+"_erase";
		
		if(element.value && !me.isBlurred)
		{
			me.showErase();
		}
	}

	this.showErase = function()
	{

		if(!$(me.eraseId))
		{
			me.element.insert({after:" <span id='"+me.eraseId+"' style='font-size: 20px; position: absolute; top: -5px; margin-left: -25px; color: black; cursor: hand;'>&#x232B;</span>"});
			$(me.eraseId).observe('click', function(){me.element.value = ''; me.blurField(); me.onFindChanged()});
		}
		
		$(me.eraseId).show();
	}
	
	this.hideErase = function()
	{
		$(me.eraseId).hide();
	}
	
	this.onFindChanged = function(event)
	{	
		var element = me.element;
	
		if(me.isBlurred)
		{
			element.value = '';
		}
	
		if(element.value)
		{	
			me.showErase();
		}
		else
		{
			me.hideErase();
		}
		
	
		clearTimeout(me.findTimeout);
	
		me.findTimeout = setTimeout(function()
		{ 
			if(element.value)
			{
				document.location.replace("#"+element.value);
			}
			else
			{
				document.location.replace("#");
			}
			
			me.findOnType();
		}, 
		500);
		
		if(event)
		{
			return preventDefaultEvent(event);
		}
	}
	
	
	this.findOnType = function()
	{
		var string = document.location.hash.replace(/^#/, '');
		

		
		if(string == me.currentValue)
		{
			return;
		}


		
		if(!string)	string = '';
		
		me.currentValue = string;
	
		var location = document.location.href.replace(/(#|\?).*$/g, '');
		
		new Ajax.Request(location+'/find',
		{
			method: 'get',
			parameters: {'nolayout': 1, 'find': string},
			onSuccess: function(transport)
			{
				if(transport.responseText.isJSON())
				{
					var names = transport.responseText.evalJSON();
					

					$(document.body).select(me.blockClass).each(function(block)
					{
						if(names && names.indexOf(block.identify()) != -1)
						{
							if(!block.visible())
							{
								block.show();
							}
						}
						else
						{
							block.hide();
						}
					}
					
					);
				}
				
				
				/*if(string)
				{
					string = ', '+string;		
				}
				$('examp').update(string);*/
			}
		}
		);
	}	
	
	me.focusField = function()
	{

		if(me.isBlurred)
		{
			me.element.value = '';
		}
		
		me.isBlurred = false;
		me.element.removeClassName('blurredSearch');		
	}
	
	me.blurField = function()
	{
		if(!me.element.value)
		{
			me.isBlurred = true;
			me.element.addClassName('blurredSearch');
			me.element.value = 'Поиск';
		}
	}
	

	
	me.init();

}










function debug(text)
{
	if($('outx'))
	{
		$('outx').remove();
	}
	
	$(document.body).insert({after: "<div style='position: fixed; top: 0; left: 0; background: black; color: white;' id='outx'>"+text+"</div>"});	
}







function anchor(params)
{
	var uri = {};

	var matches = document.location.href.match(/#(.*)$/);
	if(matches)
	{
		var uri = matches[1].toString().toQueryParams();
	}



	if(params)
	{
		$H(params).each(function(param)
		{
			if(param.key && param.value != '')	
			{
				uri[param.key] = param.value;	
			}
			else
			{
				delete uri[param.key];
			}
		})
	}

	
	if(uri.size > 1)
	{
		$H(uri).each(function(param)
		{
			if(!param.value)	
			{
				delete uri[param.key];
			}
		});
	}



		window.location.replace('#'+$H(uri).toQueryString());

	return uri;	
}













inplaceEdit = function(element, url, defaultValue, options)
{
	var me = this;

	me.input = null;
	me.editing = null;

	me.editingId = "editing";
	me.inputId = "editingInput";

	if(options)
	{
		me.options = options;
	}
	else
	{
		me.options = {};
	}

	me.element = $(element);

	if(me.element.empty())
	{
		me.value = '';
	}
	else
	{
		me.value = me.element.innerHTML;	
	}
	me.url = url;
	
	if(!defaultValue)
	{
		defaultValue = "click to edit";
	}
	
	me.defaultValue = '<i class="defaultValue">'+defaultValue+'</i>';
	
	me.isDefaultValue = function()
	{
		return me.element.select('i').length > 0;
	}
	
	
	me.endEdit = function()
	{

	
		me.input.hide();
		me.value = me.input.value;
		
		me.element.show();
		
		$(document.body).stopObserving('click', me.onBodyClick);
	}
	
	me.onBodyClick = function(event)
	{
		var element = event.element();
		
		if(element.identify() == me.input.identify() || element.identify() == me.element.identify())
		{
			return null;
		}
		
		$(document.body).stopObserving('click', me.onBodyClick);		

		me.endEdit();		
	}	
	
	me.save = function(event)
	{
		var input = me.input;		
		var url = me.url;
		var elementId;
		
		if(me.options.fieldName)
		{
			elementId = me.options.fieldName;
		}
		else
		{
			elementId = me.element.identify().toString();
		}
		
		
		
		var params = {'nolayout': 1};
		

		params[elementId] = input.value;

		new Ajax.Request(url,
		{
			method: 'post',
			parameters: params,
			onSuccess: function(transport)
			{


				var json = transport.responseText.evalJSON();

				var newValue = json[elementId];


								
				me.endEdit();
				

				
				me.element.update(newValue);
				
				me.value = newValue;

				if(elementId == 'title')
				{
					document.title = newValue;
				}
								

				me.setDefaultElementValue();
			}
		}
		
		)
	}
	
	me.startEdit = function()
	{
		var element = me.element;
		
		/*if($(me.editingId))
		{
			$(me.editingId).remove();
		}*/
		if($(me.inputId))
		{
			$(me.inputId).remove();
		}
		//&nbsp;<span style="position: relative; right: 30px" onclick=\'alert("foo")\'>ok</span>
		//element.insert({after: '<div id="'+me.editingId+'"><input type="text" id="'+me.inputId+'" value="" class="inplace" /></div>'});
		element.insert({after: '<input type="text" id="'+me.inputId+'" value="" class="inplace" style="position: absolute; display: block"/>'});
		
		me.input = $(me.inputId);
		me.editing = $(me.editingId);
		
		
		if(!me.isDefaultValue())
		{
			me.input.value = me.element.innerHTML;
		}
		
		
		me.input.focus();
		me.input.select();
		me.input.clonePosition(element);
		
		var fs = element.getStyle('font-size');
		//debug(fontSize);
		me.input.setStyle({fontSize: fs});

	
		
		//element.hide();
			
		me.input.observe('keydown', function(event)
		{
			if(event.keyCode == 13)
			{
				me.save();
			}
			else if(event.keyCode == 27)
			{
				me.endEdit();
			}
		});

		setTimeout(function(){$(document.body).observe('click', me.onBodyClick)}, 100);
			
	}
	
	me.onClick = function(event)
	{
		if(!event.ctrlKey && !event.shiftKey && !event.altKey)
		{
			me.startEdit()
		}
	}

	me.setDefaultElementValue = function()
	{
		if(me.element.empty())
		{
			me.element.innerHTML = me.defaultValue;
		}
	}

	me.element.observe('click', me.onClick);	

	me.element.addClassName('editable');
	me.setDefaultElementValue();
}


function navigate (event)
{
//	debug(event.keyCode);
//event.keyCode == 74 || 
//event.keyCode == 75 || 
	if((event.ctrlKey && event.keyCode == 39))
	{
		var link = $('nextLink');
	}
	else
	if((event.ctrlKey && event.keyCode == 37))
	{
		var link = $('prevLink');
	}



	if (link && link.href) 
		document.location = link.href;


}



Element.addMethods({
	lazyload: function(element, options)
	{
		/**
		What does it do?
			It delays loading of images in (long) pages. Images below the fold (far down in the
			page) wonât be loaded before the user scrolls down. This is exact opposite of image
			preloading. With long pages containing heavy image content end user result is the
			same. Page feels snappier. Browser is in ready state after loading visible images.
			No need to wait for n pictures to load.
			
		From Wikipedia:
			Lazy loading is a design pattern commonly used in computer programming to defer
			initialization of an object until the point at which it is needed. It can contribute
			to efficiency in the programâs operation if properly and appropriately used.
		
		Inspired by:
			http://www.appelsiini.net/2007/9/lazy-load-images-jquery-plugin
			
		Requires:
			Prototype.js version 1.6.0_rc0 or later
			A page with lots of big images below the fold (optional)
		*/
		
		function $restore()
		{
			// this function restores the original image source; called when above the fold
			if ( true === $(element).hasAttribute('_src') )
			{
				$(element).writeAttribute({ src: $(element).readAttribute('_src') });
			}
		}
		function $scroll()
		{
			// this function returns the amount the page is scrolled vertically
			var scroll_y = self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
			return parseInt(scroll_y);
		}
		function $height()
		{
			// this function returns the height of the viewport
			var window_height = window.innerHeight || document.documentElement.clientHeight;
			return parseInt(window_height);
		}
		var element     = $(element);
		var options     = Object.extend({
			threshold   : 0,
			placeholder : '/images/grey.gif',
			event       : 'scroll',
			frequency   : 0.1
		}, options || {});

		var offset      = $(element).cumulativeOffset()[1];
		var activate_on = (offset - options.threshold) - $height();

		var old_source  = $(element).readAttribute('src');
		var new_source  = options.placeholder;

		$(element)
			.writeAttribute({ src :  new_source })
			.writeAttribute({ '_src' :  old_source });
		
		if ( 'scroll' === options.event )
		{
			new PeriodicalExecuter(function($executor)
			{
				if ( activate_on <= $scroll() )
				{
					$restore(); $executor.stop();
				}
			}, options.frequency);
		}
		else
		{
			$(element).observe(options.event, function(event)
			{
				$restore(); $(element).stopObserving();
			});
		}

		return $(element);
	}
});



function preventDefaultEvent(event)
{
	if(event.preventDefault)
	{			
		event.preventDefault();
	}
	else if(event.returnValue)
	{ 
		event.returnValue = false;
	}
	
	return false;		
}




















function elementDistance(element1, element2)
{
	var e1 = element1.positionedOffset();
	var e2 = element2.positionedOffset();
	
	var distanceX = Math.abs(e1.left - e2.left); 
	var distanceY = Math.abs(e1.top - e2.top); 

	return Math.sqrt( distanceX*distanceX + distanceY*distanceY );	
}

function getNearElements(elements, elementToFind)
{
	var elements2 = elements.clone();
	var offset = elementToFind.positionedOffset();
	var out = {};
	
	var sorted = elements2.sort(function(a,b)
	{
		var distanceA = elementDistance(elementToFind, a);
		var distanceB = elementDistance(elementToFind, b);
		
		return distanceA - distanceB;
	});
	
	for(var i=1; i<5; i++)
	{
		var el = sorted[i];
		
		
		if(el)
		{
			var eloffset = el.positionedOffset();	
			if((eloffset.top > offset.top) && (eloffset.left == offset.left) && !out.down)
			{
				out.down = el;
			}
			else if((eloffset.top < offset.top) && (eloffset.left == offset.left) && !out.up)
			{
				out.up = el;
			}
			else if((eloffset.left < offset.left) && (eloffset.top == offset.top) && !out.left)
			{
				out.left = el;
			}
			else if((eloffset.left > offset.left) && (eloffset.top == offset.top) && !out.right)
			{
				out.right = el;
			}
		}
	}
	
	return out;
}





function omnumber(number, titles)
{
    var absnum = Math.abs(number);var cases = [2,0,1,1,1,2];
    return number+" "+ titles[(absnum%100>4&&absnum%100<20)?2:cases[Math.min(absnum%10,5)]];
}






var keywordEditor = function(container)
{
	me = this;
	
	me.container = $(container);
	me.keywords = {};
	me.commonKeywords = [];
	me.additionalKeywords = [];
	me.elements = [];
	
	
	me.setElements = function(elements)
	{
	
		me.elements = elements;
		
		
	
		me.keywords = {};
		
		var names = '';
		var flatKeywords = [];
		for(i in me.elements)
		{
			var element = me.elements[i];
			
			var name = element.identify().replace(/^image_/, '');
			
			var keywords = $(name+'_keywords').innerHTML; 
			
			if(keywords)// && !me.isDefaultValue())
			{
				var keysArray = keywords.split(' ').uniq();
				
				if(!keysArray)
				{
					keysArray = [];
				}
				
				me.keywords[name] = keysArray;
				flatKeywords.push(keysArray);
				
			}
			else
			{
				me.keywords[name] = [];
			}
		}


		var newkeys = flatKeywords.flatten().uniq();
		
		
		
		me.commonKeywords = [];
		me.additionalKeywords = [];

		newkeys.each(function(keyToCheck)
		{
			if(keyToCheck.match(/^[\s\n]*$/)) return;
			
			var isCommon = true;
			
			for(i in me.keywords)
			{
				var keysArray = me.keywords[i];
				
				var index = keysArray.indexOf(keyToCheck);
				if(index == -1)
				{
					isCommon = false;
					
					break;
				}
			}
			
			if(isCommon)
			{
				me.commonKeywords.push(keyToCheck);
				
			}
			else
			{
				me.additionalKeywords.push(keyToCheck);
			}
			
		});

		for(i in me.commonKeywords)
		{
			var commonKeyword = me.commonKeywords[i];
			
			for(j in me.keywords)
			{
				var keysArray = me.keywords[j];
				
				var index = keysArray.indexOf(commonKeyword);
				
				if(index != -1)
				{
					keysArray[index] = null;
				}
			}
		}

		
		$('keywordsText').value = me.commonKeywords.join(" ");		
		
		var keysToAddText = '';
		
		if(me.additionalKeywords.length)
		{
			keysToAddText = "<span class='newkeyword'>"+me.additionalKeywords.join("</span><span class='newkeyword'>")+'</span>';
		}
		
		$('keywordsToAdd').update(keysToAddText);
	}

	$('saveKeywords').observe('click', function(event)
	{
		

		var newCommon = $('keywordsText').value.split(' ').uniq();
		var params = {};
		for(i in me.elements)
		{
			var element = me.elements[i];
			
			var name = element.identify().replace(/^image_/, '');
			//var url = element.select('a').first().href+'/save';
			
			
			var keysToSave = [me.keywords[name],newCommon].flatten().uniq().join(' ');
			
			keysToSave = keysToSave.replace(/^\s+/, '').replace(/\s+/, ' ').replace(/\s+$/,'');
			//alert([name, keysToSave]);
			
			$(name+'_keywords').innerHTML = keysToSave;
			
			params[name] = keysToSave;
		}
		
		params['nolayout'] = 1;
		
		new Ajax.Request(document.location+'keywords',
		{
			method: 'post',
			parameters: params,
			onSuccess: function(transport)
			{
				//debug(transport.responseText);
			}
		});
		
		
	});
	
	$('keywordsToAdd').observe('click', function(event)
	{
		var element = event.element();
		
		if(element.hasClassName('newkeyword'))
		{
			$('keywordsText').value += ' '+element.innerHTML;
			$('keywordsText').focus();
			
			element.hide();
		}
	});

}


