//autocomplete
;(function($){$.fn.extend({autocomplete:function(urlOrData,options){var isUrl=typeof urlOrData=="string";options=$.extend({},$.Autocompleter.defaults,{url:isUrl?urlOrData:null,data:isUrl?null:urlOrData,delay:isUrl?$.Autocompleter.defaults.delay:10,max:options&&!options.scroll?10:150},options);options.highlight=options.highlight||function(value){return value;};options.formatMatch=options.formatMatch||options.formatItem;return this.each(function(){new $.Autocompleter(this,options);});},result:function(handler){return this.bind("result",handler);},search:function(handler){return this.trigger("search",[handler]);},flushCache:function(){return this.trigger("flushCache");},setOptions:function(options){return this.trigger("setOptions",[options]);},unautocomplete:function(){return this.trigger("unautocomplete");}});$.Autocompleter=function(input,options){var KEY={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var $input=$(input).attr("autocomplete","off").addClass(options.inputClass);var timeout;var previousValue="";var cache=$.Autocompleter.Cache(options);var hasFocus=0;var lastKeyPressCode;var config={mouseDownOnSelect:false};var select=$.Autocompleter.Select(options,input,selectCurrent,config);var blockSubmit;$.browser.opera&&$(input.form).bind("submit.autocomplete",function(){if(blockSubmit){blockSubmit=false;return false;}});$input.bind(($.browser.opera?"keypress":"keydown")+".autocomplete",function(event){hasFocus=1;lastKeyPressCode=event.keyCode;switch(event.keyCode){case KEY.UP:event.preventDefault();if(select.visible()){select.prev();}else{onChange(0,true);}break;case KEY.DOWN:event.preventDefault();if(select.visible()){select.next();}else{onChange(0,true);}break;case KEY.PAGEUP:event.preventDefault();if(select.visible()){select.pageUp();}else{onChange(0,true);}break;case KEY.PAGEDOWN:event.preventDefault();if(select.visible()){select.pageDown();}else{onChange(0,true);}break;case options.multiple&&$.trim(options.multipleSeparator)==","&&KEY.COMMA:case KEY.TAB:case KEY.RETURN:if(selectCurrent()){event.preventDefault();blockSubmit=true;return false;}break;case KEY.ESC:select.hide();break;default:clearTimeout(timeout);timeout=setTimeout(onChange,options.delay);break;}}).focus(function(){hasFocus++;}).blur(function(){hasFocus=0;if(!config.mouseDownOnSelect){hideResults();}}).click(function(){if(hasFocus++>1&&!select.visible()){onChange(0,true);}}).bind("search",function(){var fn=(arguments.length>1)?arguments[1]:null;function findValueCallback(q,data){var result;if(data&&data.length){for(var i=0;i<data.length;i++){if(data[i].result.toLowerCase()==q.toLowerCase()){result=data[i];break;}}}if(typeof fn=="function")fn(result);else $input.trigger("result",result&&[result.data,result.value]);}$.each(trimWords($input.val()),function(i,value){request(value,findValueCallback,findValueCallback);});}).bind("flushCache",function(){cache.flush();}).bind("setOptions",function(){$.extend(options,arguments[1]);if("data"in arguments[1])cache.populate();}).bind("unautocomplete",function(){select.unbind();$input.unbind();$(input.form).unbind(".autocomplete");});function selectCurrent(){var selected=select.selected();if(!selected)return false;var v=selected.result;previousValue=v;if(options.multiple){var words=trimWords($input.val());if(words.length>1){var seperator=options.multipleSeparator.length;var cursorAt=$(input).selection().start;var wordAt,progress=0;$.each(words,function(i,word){progress+=word.length;if(cursorAt<=progress){wordAt=i;return false;}progress+=seperator;});words[wordAt]=v;v=words.join(options.multipleSeparator);}v+=options.multipleSeparator;}$input.val(v);hideResultsNow();$input.trigger("result",[selected.data,selected.value]);return true;}function onChange(crap,skipPrevCheck){if(lastKeyPressCode==KEY.DEL){select.hide();return;}var currentValue=$input.val();if(!skipPrevCheck&&currentValue==previousValue)return;previousValue=currentValue;currentValue=lastWord(currentValue);if(currentValue.length>=options.minChars){$input.addClass(options.loadingClass);if(!options.matchCase)currentValue=currentValue.toLowerCase();request(currentValue,receiveData,hideResultsNow);}else{stopLoading();select.hide();}};function trimWords(value){if(!value)return[""];if(!options.multiple)return[$.trim(value)];return $.map(value.split(options.multipleSeparator),function(word){return $.trim(value).length?$.trim(word):null;});}function lastWord(value){if(!options.multiple)return value;var words=trimWords(value);if(words.length==1)return words[0];var cursorAt=$(input).selection().start;if(cursorAt==value.length){words=trimWords(value)}else{words=trimWords(value.replace(value.substring(cursorAt),""));}return words[words.length-1];}function autoFill(q,sValue){if(options.autoFill&&(lastWord($input.val()).toLowerCase()==q.toLowerCase())&&lastKeyPressCode!=KEY.BACKSPACE){$input.val($input.val()+sValue.substring(lastWord(previousValue).length));$(input).selection(previousValue.length,previousValue.length+sValue.length);}};function hideResults(){clearTimeout(timeout);timeout=setTimeout(hideResultsNow,200);};function hideResultsNow(){var wasVisible=select.visible();select.hide();clearTimeout(timeout);stopLoading();if(options.mustMatch){$input.search(function(result){if(!result){if(options.multiple){var words=trimWords($input.val()).slice(0,-1);$input.val(words.join(options.multipleSeparator)+(words.length?options.multipleSeparator:""));}else{$input.val("");$input.trigger("result",null);}}});}};function receiveData(q,data){if(data&&data.length&&hasFocus){stopLoading();select.display(data,q);autoFill(q,data[0].value);select.show();}else{hideResultsNow();}};function request(term,success,failure){if(!options.matchCase)term=term.toLowerCase();var data=cache.load(term);if(data&&data.length){success(term,data);}else if((typeof options.url=="string")&&(options.url.length>0)){var extraParams={timestamp:+new Date()};$.each(options.extraParams,function(key,param){extraParams[key]=typeof param=="function"?param():param;});$.ajax({mode:"abort",port:"autocomplete"+input.name,dataType:options.dataType,url:options.url,data:$.extend({q:lastWord(term),limit:options.max},extraParams),success:function(data){var parsed=options.parse&&options.parse(data)||parse(data);cache.add(term,parsed);success(term,parsed);}});}else{select.emptyList();failure(term);}};function parse(data){var parsed=[];var rows=data.split("\n");for(var i=0;i<rows.length;i++){var row=$.trim(rows[i]);if(row){row=row.split("|");parsed[parsed.length]={data:row,value:row[0],result:options.formatResult&&options.formatResult(row,row[0])||row[0]};}}return parsed;};function stopLoading(){$input.removeClass(options.loadingClass);};};$.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(row){return row[0];},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(value,term){return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>");},scroll:true};$.Autocompleter.Cache=function(options){var data={};var length=0;function matchSubset(s,sub){if(!options.matchCase)s=s.toLowerCase();var i=s.indexOf(sub);if(options.matchContains=="word"){i=s.toLowerCase().search("\\b"+sub.toLowerCase());}if(i==-1)return false;return i==0||options.matchContains;};function add(q,value){if(length>options.cacheLength){flush();}if(!data[q]){length++;}data[q]=value;}function populate(){if(!options.data)return false;var stMatchSets={},nullData=0;if(!options.url)options.cacheLength=1;stMatchSets[""]=[];for(var i=0,ol=options.data.length;i<ol;i++){var rawValue=options.data[i];rawValue=(typeof rawValue=="string")?[rawValue]:rawValue;var value=options.formatMatch(rawValue,i+1,options.data.length);if(value===false)continue;var firstChar=value.charAt(0).toLowerCase();if(!stMatchSets[firstChar])stMatchSets[firstChar]=[];var row={value:value,data:rawValue,result:options.formatResult&&options.formatResult(rawValue)||value};stMatchSets[firstChar].push(row);if(nullData++<options.max){stMatchSets[""].push(row);}};$.each(stMatchSets,function(i,value){options.cacheLength++;add(i,value);});}setTimeout(populate,25);function flush(){data={};length=0;}return{flush:flush,add:add,populate:populate,load:function(q){if(!options.cacheLength||!length)return null;if(!options.url&&options.matchContains){var csub=[];for(var k in data){if(k.length>0){var c=data[k];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub.push(x);}});}}return csub;}else
if(data[q]){return data[q];}else if(options.matchSubset){for(var i=q.length-1;i>=options.minChars;i--){var c=data[q.substr(0,i)];if(c){var csub=[];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub[csub.length]=x;}});return csub;}}}return null;}};};$.Autocompleter.Select=function(options,input,select,config){var CLASSES={ACTIVE:"ac_over"};var listItems,active=-1,data,term="",needsInit=true,element,list;function init(){if(!needsInit)return;element=$("<div/>").hide().addClass(options.resultsClass).css("position","absolute").appendTo(document.body);list=$("<ul/>").appendTo(element).mouseover(function(event){if(target(event).nodeName&&target(event).nodeName.toUpperCase()=='LI'){active=$("li",list).removeClass(CLASSES.ACTIVE).index(target(event));$(target(event)).addClass(CLASSES.ACTIVE);}}).click(function(event){$(target(event)).addClass(CLASSES.ACTIVE);select();input.focus();return false;}).mousedown(function(){config.mouseDownOnSelect=true;}).mouseup(function(){config.mouseDownOnSelect=false;});if(options.width>0)element.css("width",options.width);needsInit=false;}function target(event){var element=event.target;while(element&&element.tagName!="LI")element=element.parentNode;if(!element)return[];return element;}function moveSelect(step){listItems.slice(active,active+1).removeClass(CLASSES.ACTIVE);movePosition(step);var activeItem=listItems.slice(active,active+1).addClass(CLASSES.ACTIVE);if(options.scroll){var offset=0;listItems.slice(0,active).each(function(){offset+=this.offsetHeight;});if((offset+activeItem[0].offsetHeight-list.scrollTop())>list[0].clientHeight){list.scrollTop(offset+activeItem[0].offsetHeight-list.innerHeight());}else if(offset<list.scrollTop()){list.scrollTop(offset);}}};function movePosition(step){active+=step;if(active<0){active=listItems.size()-1;}else if(active>=listItems.size()){active=0;}}function limitNumberOfItems(available){return options.max&&options.max<available?options.max:available;}function fillList(){list.empty();var max=limitNumberOfItems(data.length);for(var i=0;i<max;i++){if(!data[i])continue;var formatted=options.formatItem(data[i].data,i+1,max,data[i].value,term);if(formatted===false)continue;var li=$("<li/>").html(options.highlight(formatted,term)).addClass(i%2==0?"ac_even":"ac_odd").appendTo(list)[0];$.data(li,"ac_data",data[i]);}listItems=list.find("li");if(options.selectFirst){listItems.slice(0,1).addClass(CLASSES.ACTIVE);active=0;}if($.fn.bgiframe)list.bgiframe();}return{display:function(d,q){init();data=d;term=q;fillList();},next:function(){moveSelect(1);},prev:function(){moveSelect(-1);},pageUp:function(){if(active!=0&&active-8<0){moveSelect(-active);}else{moveSelect(-8);}},pageDown:function(){if(active!=listItems.size()-1&&active+8>listItems.size()){moveSelect(listItems.size()-1-active);}else{moveSelect(8);}},hide:function(){element&&element.hide();listItems&&listItems.removeClass(CLASSES.ACTIVE);active=-1;},visible:function(){return element&&element.is(":visible");},current:function(){return this.visible()&&(listItems.filter("."+CLASSES.ACTIVE)[0]||options.selectFirst&&listItems[0]);},show:function(){var offset=$(input).offset();element.css({width:typeof options.width=="string"||options.width>0?options.width:$(input).width(),top:offset.top+input.offsetHeight,left:offset.left}).show();if(options.scroll){list.scrollTop(0);if($.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var listHeight=0;listItems.each(function(){listHeight+=this.offsetHeight;});}}},selected:function(){var selected=listItems&&listItems.filter("."+CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);return selected&&selected.length&&$.data(selected[0],"ac_data");},emptyList:function(){list&&list.empty();},unbind:function(){element&&element.remove();}};};$.fn.selection=function(start,end){if(start!==undefined){return this.each(function(){if(this.createTextRange){var selRange=this.createTextRange();if(end===undefined||start==end){selRange.move("character",start);selRange.select();}else{selRange.collapse(true);selRange.moveStart("character",start);selRange.moveEnd("character",end);selRange.select();}}else if(this.setSelectionRange){this.setSelectionRange(start,end);}else if(this.selectionStart){this.selectionStart=start;this.selectionEnd=end;}});}var field=this[0];if(field.createTextRange){var range=document.selection.createRange(),orig=field.value,teststring="<->",textLength=range.text.length;range.text=teststring;var caretAt=field.value.indexOf(teststring);field.value=orig;this.selection(caretAt,caretAt+textLength);return{start:caretAt,end:caretAt+textLength}}else if(field.selectionStart!==undefined){return{start:field.selectionStart,end:field.selectionEnd}}};})(jQuery);

//fonteffect
(function($){var FE={};FE.divcounter=0;FE.tabpos=["","0001021020212212","00010203041020304041424344142434","000102030405061020304050606162636465162636465666"];$.fn.FontEffect=function(o){var d=$.extend({outline:false,outlineColor1:"",outlineColor2:"",outlineWeight:2,proportional:false,hideText:false,debug:false},o);this.not(".JQFE").each(function(){if(!d.outline){d.outline=true;};if(d.outline){if(d.outlineColor1==""&&d.outlineColor2==""){d.outlineColor1=pickcontrast($(this).css("color"));};if(d.outlineColor2=="")d.outlineColor2=d.outlineColor1;};var userdisplay=$(this).css("display");var userposition=$(this).css("position");$(this).css({display:"inline",position:((userposition=="absolute")?"absolute":"relative")});var h=$(this).height();var w=$(this).width()*1.04;var W=w+"px";var H=h+"px";var t=$(this).html();$(this).data("options",d).addClass("JQFE").css({width:W,height:H,display:userdisplay,position:(($(this).css("position")!="absolute")?"relative":"absolute"),zoom:1});var MyContainer=$("<div></div>").css({width:W,height:H,position:"relative"});MyContainer.append($("<div class='JQFEText'>"+t+"</div>").css({display:d.hideText?"none":"inline",width:W,height:H,position:"relative",zIndex:100}));var alldivsup=$("<div></div>").css({width:W,height:H,left:"0px",position:"absolute",top:parseInt($(this).css("paddingTop"))*0+"px",zIndex:110});var alldivsdown=$(alldivsup).clone().css({zIndex:90});FE.divounter+=4;$(this).html("");if(d.outline){var totdiv=(d.outlineWeight)*8;var to=FE.tabpos[d.outlineWeight];for(i=0;i<totdiv;i++){appo=$("<div class='JQFEOutline'>"+t+"</div>").css({position:"absolute",top:(to.charAt(i*2)-d.outlineWeight)+"px",left:(to.charAt(i*2+1)-d.outlineWeight)+"px",width:W,color:((i<totdiv/2+d.outlineWeight)?d.outlineColor1:d.outlineColor2),zIndex:((i>totdiv-totdiv/3)?20:30)});FE.divounter+=i;alldivsdown.append(appo);};};MyContainer.append(alldivsdown);MyContainer.append(alldivsup);$(this).append(MyContainer);});function hex2rgb(hexcolor){hexcolor=hexcolor.substring(1);if(hexcolor.length==3)hexcolor=hexcolor.charAt(0)+hexcolor.charAt(0)+hexcolor.charAt(1)+hexcolor.charAt(1)+hexcolor.charAt(2)+hexcolor.charAt(2);var rgbcolor="rgb("+parseInt(hexcolor.substring(0,2),16)+", "+parseInt(hexcolor.substring(2,4),16)+", "+parseInt(hexcolor.substring(4,6),16)+")";return(rgbcolor);};function chkColorString(col){return(/(#([0-9A-Fa-f]{3,6})\b)|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\))/.test(col));};function pickcontrast(col){if(chkColorString(col)){col=col.toUpperCase();if(col.charAt(0)=="#")col=hex2rgb(col);var appo=col.substring(4,col.length-1).split(", ");var g=255-parseInt(appo[0]);var b=255-parseInt(appo[1]);var r=255-parseInt(appo[2]);col="rgb("+r+", "+g+", "+b+")";};return(col);};return this;};$.fn.changeOptionsFE=function(newoptions){if(this){var oldoptions=$(this).data("options")||{};$.extend(oldoptions,newoptions);$(this).data("options",oldoptions);};};$.fn.redrawFE=function(newoptions){if(this){if(newoptions)$(this).changeOptionsFE(newoptions);$(this).removeFE();$(this).FontEffect($(this).data("options"));};};$.fn.removeFE=function(removeoptions){if(this&&$(this).hasClass("JQFE")){var t=$(this).find("div[class='JQFEText']").html();$(this).removeClass("JQFE");if(removeoptions)$(this).data("options",{});$(this).find("div[class^='JQFE']").remove();$(this).html(t);};};})(jQuery);Number.prototype.pxToEm=String.prototype.pxToEm=function(settings){settings=$.extend({scope:'body',reverse:false},settings);var pxVal=(this=='')?0:parseFloat(this);var scopeVal;var getWindowWidth=function(){var de=document.documentElement;return self.innerWidth||(de&&de.clientWidth)||document.body.clientWidth;};if(settings.scope=='body'&&$.browser.msie&&(parseFloat($('body').css('font-size'))/getWindowWidth()).toFixed(1)>0.0){var calcFontSize=function(){return(parseFloat($('body').css('font-size'))/getWindowWidth()).toFixed(3)*16;};scopeVal=calcFontSize();}
else{scopeVal=parseFloat($(settings.scope).css("font-size"));};var result=(settings.reverse==true)?(pxVal*scopeVal).toFixed(2)+'px':(pxVal/scopeVal).toFixed(2)+'em';return result;};

//elastic textarea
(function(jQuery){$.fn.extend({elastic:function(){var mimics=['paddingTop','paddingRight','paddingBottom','paddingLeft','fontSize','lineHeight','fontFamily','width','fontWeight'];return this.each(function(){if(this.type!='textarea'){return false}var $textarea=$(this),$twin=$('<div></div>').css({'position':'absolute','display':'none','word-wrap':'break-word'}),lineHeight=parseInt($textarea.css('line-height'),10)||parseInt($textarea.css('font-size'),'10'),minheight=parseInt($textarea.css('height'),10)||lineHeight*3,maxheight=parseInt($textarea.css('max-height'),10)||Number.MAX_VALUE,goalheight=0,i=0;if(maxheight<0){maxheight=Number.MAX_VALUE}$twin.appendTo($textarea.parent());var i=mimics.length;while(i--){$twin.css(mimics[i].toString(),$textarea.css(mimics[i].toString()))}function setHeightAndOverflow(height,overflow){curratedHeight=Math.floor(parseInt(height,10));if($textarea.height()!=curratedHeight){$textarea.css({'height':curratedHeight+'px','overflow':overflow})}}function update(){var textareaContent=$textarea.val().replace(/&/g,'&amp;').replace(/  /g,'&nbsp;').replace(/<|>/g,'&gt;').replace(/\n/g,'<br>');var twinContent=$twin.html();if(textareaContent+'&nbsp;'!=twinContent){$twin.html(textareaContent+'&nbsp;');if(Math.abs($twin.height()+lineHeight-$textarea.height())>3){var goalheight=$twin.height()+lineHeight;if(goalheight>=maxheight){setHeightAndOverflow(maxheight,'auto')}else if(goalheight<=minheight){setHeightAndOverflow(minheight,'hidden')}else{setHeightAndOverflow(goalheight,'hidden')}}}}$textarea.css({'overflow':'hidden'});$textarea.keyup(function(){update()});$textarea.live('input paste',function(e){setTimeout(update,250)});update()})}})})(jQuery);

$.cookie=function(a,b,c){if(arguments.length>1&&(b===null||typeof b!=="object")){c=$.extend({},c);if(b===null){c.expires=-1}if(typeof c.expires==="number"){var d=c.expires,e=c.expires=new Date;e.setDate(e.getDate()+d)}return document.cookie=[encodeURIComponent(a),"=",c.raw?String(b):encodeURIComponent(String(b)),c.expires?"; expires="+c.expires.toUTCString():"",c.path?"; path="+c.path:"",c.domain?"; domain="+c.domain:"",c.secure?"; secure":""].join("")}c=b||{};var f,g=c.raw?function(a){return a}:decodeURIComponent;return(f=(new RegExp("(?:^|; )"+encodeURIComponent(a)+"=([^;]*)")).exec(document.cookie))?g(f[1]):null}
$.fn.labelOver=function(a){return this.each(function(){var b=$(this),c=b.attr("for");if(c){var d=$("#"+c);this.hide=function(){b.css({textIndent:-1e4})};this.show=function(){if(d.val()==""){b.css({textIndent:0})}};d.focus(this.hide);d.blur(this.show);b.addClass(a).click(function(){d.focus()});if(d.val()!=""){this.hide()}}})}

function log(x){
	$('#log').show().append('<p>'+x+'</p>');
}

function validate(form, url){
    var status=false, data=form.serialize();
    $.ajax({
        data:data, url:url, type:'POST', dataType:'json', async:false, traditional:true,
        success: function(data, textStatus){
            status = data.valid;
            if(!status){
                var get_form_error_position = function(key){
                    key = key || '__all__';
                    if(key == '__all__'){var filter = ':first';}
					                else{var filter = ':first[id^=id_' + key.replace('__all__', '') + ']';}
                    return form.find(":input:visible:not(:button)").filter(filter).parent();
                };
                $('ul.errorlist').remove();
                $('.error').removeClass('error');
                $.each(data.errors, function(key, val){
					if(key=='id_town_0'){key='id_town_txt';}
                    $('#'+key).addClass('error').after('<ul class="errorlist"><li>'+val+'</li></ul>');
                });
                $('.error:first').focus();
				$('.error').blur(function(){
					var e=$(this);
					if(e.val()){ 
						e.removeClass('error');
						e.next('.errorlist').remove();
					}
				});
                $('.submit button').html('Save ad');
            }
        },
        error: function(XHR, textStatus, errorThrown){ status = true; }
    });
    return status;
}

function lazy_script(src){
    var po = document.createElement('script');po.async = true;po.src = src;
    var s = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(po, s);
}

function sort_towns(){
	// sort towns alphabetically
	var sortable = $('.sortable');
	sortable.prepend('<li class="header"><a href="#" class="a_z">A-Z</a> &nbsp; <a href="#" class="pop active">Popular towns</a></li>');
	sortable.find('li').not('.header').each(function(i){
		$(this).attr('order', i);
	});
	var a_z = function(a){ return $(a).text().toUpperCase(); }
	var pop = function(a){ return parseInt($(a).attr('order')); }
	var ol = function(extract, clicked){
		sortable.find('a').removeClass('active');
		$(clicked).addClass('active');
		var items = sortable.children('li').not('.header').get();
		items.sort(function(a, b) {
			var cA = extract(a);
			var cB = extract(b);
			return (cA < cB) ? -1 : (cA > cB) ? 1 : 0;
		})
		$.each(items, function(idx, itm) { sortable.append(itm); });
	}
	$('.a_z').click(function(){ol(a_z, this)});
	$('.pop').click(function(){ol(pop, this)});
}

$.fn.fix_radios = function(){
	if(navigator.userAgent.match(/(iPhone|iPod|iPad)/)){
		$('.op label').click(function(){
			var el = $(this).find('input').attr('for');
			if ($('#'+el+'[type=radio], #'+el+'[type=checkbox]').attr('selected', !$('#'+el).attr('selected'))) {
				return;
			} else {
				$('#'+el)[0].focus();
			}
		});
	}
	// Thanks to Dominis @ evilstreak.co.uk/blog/fixing-change-events-on-radios
	function focus(){
		// if this isn't checked then no option is yet selected. bail
		if(!this.checked) return;

		// if this wasn't already checked, manually fire a change event
		if(!this.was_checked){
			$(this).change();
		}
	}
	function change(e){
		// shortcut if already checked to stop IE firing again
		if(this.was_checked){
			e.stopImmediatePropagation();
			return;
		}
		// reset all the was_checked properties
		$("input[name="+this.name+"]").each(function(){
			this.was_checked = this.checked;
		});
	}
	// attach the handlers and return so chaining works
	return this.focus(focus).change(change);
}

function form_buttons(){
	// Radio buttons (with and without None defaults) & sets of checkboxes
	// Click the label to select a radio button within, highlight selected label
	$("input[type=radio]").fix_radios();
	var s = 'selected';
	var radios = $('.op :radio');
	var radio_na = $('.op :radio[value=""]').parent();
	var checkboxes = $('.op :checkbox');
	var fields = $(radios).add(checkboxes);
	var hide = {'position':'absolute','left':'-9999px'};
	fields.css(hide);
	radio_na.css(hide).addClass('na');
	$('.op :checked').parent().addClass(s);
	fields.parent().parent().find('label:not(.na):first').addClass('L');
	fields.parent().parent().find('label:not(.na):last').addClass('R');
	$('.L.R').addClass('LR').removeClass('L').removeClass('R');
	fields.change(function(){
		fields.each(function(){
			$(this).parent().toggleClass(s, $(this).is(':checked'));
		});
	});
	// Click selected radio again to reset to "n/a",
	radios.parent().click(function(e){
		e.stopPropagation(); // event would fire twice otherwise
		e.preventDefault();
		var l = $(this);
		var c = l.find('input')[0];
		var na = $('input[name="'+c.name+'"][value=""]')[0];
		if(c.checked){
			l.removeClass(s);
			na.checked = true;
			na.blur();
			na.focus();
		} else {
			l.addClass(s);
			c.checked = true;
			c.blur();
			c.focus();
		}
	});
	$('label:has(img)').css('padding-top','0');
}

function features(){
	bool = function(x){
		var path = '[name="'+x+'"]';
		var choice = $(path), radio = $(path + ':checked');
		if(radio[0]){ choice = radio;}
		return Boolean(parseInt(choice.val()));
	}
	var w = bool('whole'), o = bool('offered');
	if (o) { $('.wanted' ).hide(); $('.offered').fadeIn('slow'); }
	  else { $('.offered').hide(); $('.wanted' ).fadeIn('slow'); }
	if (w) { $('.room'   ).hide(); $('.whole'  ).fadeIn('slow'); }
	  else { $('.whole'  ).hide(); $('.room'   ).fadeIn('slow'); }
	$('.op .about'		).toggle(!w || !o);
	$('.op .preferences').toggle(!w ||  o);
	$('.op .bills'		).toggle(!w &&  o);
	$('.p_type' 		).toggle( w ||  o);
}

function predictive(field){
	$("#id_"+field+"_txt").autocomplete(
			"/autocomplete-"+field,
			{width: 330, selectFirst: true, autoFill: false, minChars: 1, max: 20}
		).result(function(event, data, formatted){
			$("#id_"+field+"_key").val(data[1]);
			$("#id_"+field+"_typ").val(data[2]);
		}).attr("autocomplete","off");
}

function process(data){
	$('#offered .count').text(data.offered_count);
	$('#wanted .count').text(data.wanted_count);
	$('#offered ul').html(data.offered);
	$('#wanted ul').html(data.wanted);
	$('.pagination').html(data.paginate);
	try{ Map.pins(loc_x, loc_y, data.pins, 14, 8); } catch(err){}; // offline dev
}

function link_thumbs(){
    $('#res li').not('#sh li').find('i').each(function(){
		var i = $(this);
	    var href = i.next().find('a').attr('href');
	    i.append($("<a href='" + href + "'></a>"));
    });
}

$(function(){
	var timeout;
	var requests=[];
	$('input#id_q,#sidebar input').change(function(){
		clearTimeout(timeout);
		timeout = setTimeout(function(){
			var query = $('form#search :input[value][name!="q_txt"]').serialize();
			var url = '/search?' + query.replace('&radius=5'      , '')
			                            .replace('&min_price=50'  , '')
			                            .replace('&max_price=1200', '')
			                            .replace('&min_age=16'    , '')
			                            .replace('&max_age=99'    , '');
			if(history.pushState){
				window.history.pushState('', 'Search', url);
			}
			else {
				$.cookie('back_url', url, {path: '/', expires: 365});
			}
			$('.ac_input').addClass('ac_loading');
			for(var i = 0; i < requests.length; i++){
			    requests[i].abort();
			}
			requests.push(
				$.ajax({
					type: 'GET',
					url: '/api',
				    dataType: 'jsonp',
				    jsonp: false, // we'll just use hardcoded name
				    jsonpCallback: 'process',
					data: query,
					cache: true,
					success: function(){
						link_thumbs();
						$('.ac_input').removeClass('ac_loading');
					},
					error: function(jqXHR, textStatus, errorThrown){
						// console.log(jqXHR);
						// console.log('#1. ' + textStatus);
						// consloe.log('#2. ' + errorThrown);
					}
				}));
		}, 500);
	});
	if(!history.pushState){
		var back_url = $.cookie('back_url');
		if(back_url){
			$('.back').attr('href', back_url);
			$.cookie('back_url', null);
		}
	}
	
	// TODO test
	//var ms = $('link[title="mobile"]');
	//$('.desktop').click(function(){
	//	ms.attr('disabled', true);
	//	$.cookie('desktop', 'Y', {path: '/', expires: 365});
	//	return false;
	//});
	//if($.cookie('desktop') === 'Y'){
	//	ms.attr('disabled', true);
	//}
	
	$('.script').show();
	$('label#eg, #up li label').css({'display':'block'}).labelOver('over');
	var s = $('#s');
	$('#s input').focus(function(){
		s.addClass('active');
	}).blur(function(){
		s.removeClass('active');
	});
	predictive('q');
	predictive('town');
	link_thumbs();
	features();
	$('[name="offered"], [name="whole"]').change(function(){
		features();
	});
	
	sort_towns();
	form_buttons();
	
    $('.fileinputs').prepend('<div class="fileupload"><input type="text" value="Click to upload photo…"></div>');
	var fileinputs = $('#up input[type=file]');
	fileinputs.addClass('file hidden');
	fileinputs.change(function(){
		var input = $(this);
		var path = input.val().replace('C:\\fakepath\\', '');
		input.parents('.fileinputs').find('input[type=text]').val(path);
	});
	
	$('.errorlist').prev('input, textarea, select').addClass('error');
	$("input[name='package']").change(function(){
		$('#packages label').removeClass('selected');
		var input = $(this);
		var i = input.next('i');
		var note = $('.package-note span');
		input.parent().addClass('selected');
		if(i.hasClass('monthly')){
			var val = i.attr('class').replace('monthly ','');
			note.text('of £' + val + '0');
		} else {
			note.text('');
		}
	});

	$("#homepage .auth input[type='text']:first").focus();
	$("#signup #id_email").blur(function(){
		var username = $('#id_username');
		if(!username.val()){
			var alias = $('#id_email').val().split('@')[0];
			username.val(alias);
		}
	});
	$("#uk #london a, #uk b").FontEffect({outline:true});
	$("#uk").removeClass('noscript');
	var top = 'top',
	    close = $('#uk .close'),
		region = $('#uk b'),
		ul = $('#uk ul');
	region.click(function(){
		var b = $(this);
		if(b.hasClass(top)){
			b.parent('li').find('ul').slideUp(400, function() {
				region.removeClass(top);
			});
			close.remove();
		} else {
			ul.hide();
			region.removeClass(top);
			close.remove();
			b.parent('li').find('ul').slideDown();
			b.addClass(top);
			b.parent('li').find('ul li:first').append('<a href="#close" class="close"><img src="/i/i/n.png" alt=""></a>');
		}
	});
	close.live('click', function(){
		ul.hide();
		region.removeClass(top);
		close.remove();
	});
	
	var msg = $("#fmessage");
	function feedback(){
		var a = msg.val(),
			status = $("#fstatus");
		if(a){
			status.show();
			status.html("Sending…");
			$("#fsubmit button").attr("disabled", "disabled").addClass("disabled").removeClass("default").blur();
			$.ajax({
				type: "POST", url: "/feedback", data: {
					fmessage: a,
					femail: $("#femail").val()
				},
				error: function(b, d, c){
					status.html("Whoops! We're experiencing some technical hiccups. If you're not too frustrated by this, please email us at hello@flatmaterooms.co.uk instead.");
				},
				success: function(b, c){
					status.html("Success! Thanks for taking the time to write.");
				}
			});
		}
	}
	$(".placeholder").val("Send us your suggestions, love letters. Tell us about issues…");
	var test = msg.val();
	msg.bind('click focus', function(){
		if(msg.val() == test){
			msg.removeClass("placeholder").val("");
			$("#fsubmit").show();
		}
	});
	$("#f form").submit(function(){
		feedback();
		return false;
	});
	$('.tolower').click(function(){
		var desc = $('#id_description');
		desc.val(desc.val().toLowerCase());
		$("#caps").hide();
	});
	$("#postcode").blur(function(){
		showAddress($('#street').value(), $('#main_search').value());
		return false;
	});
	$('#id_body').css({'min-height':'50px'}).elastic();
	
	// ie6 radio border, png transparency and hover fixes
	if($.browser.msie && parseInt($.browser.version, 10) == 6){
		$('input[type="checkbox"],input[type="radio"]').css({'border':'0','background':'none'});
		var f = function(src){return "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+ src +"', sizing='scale');"}
		$('.badge').attr("style", "background-image:none;" + f('/i/fire.png'));
		$('.i, #post .geocoded img').each(function(){
			var i = $(this);
			var style = i.attr("style");
			i.attr("style", f(i.attr('src')) + style);
			i.attr('src', '/i/blank.gif');
		});
		$('.subnav li').hover(
			function(){
				$(this).find('ul').show();
			},
			function(){
				$(this).find('ul').hide();
			}
		);
		$('.nav div').hover(
			function(){
				$(this).addClass('hover');
			},
			function(){
				$(this).removeClass('hover');
			}
		);
	}

});

var Map = {
	load: function(){
		var script = document.createElement("script");
		var host = 'http://maps';
		if(window.location.protocol == 'https:'){
		    host = 'https://maps-api-ssl';
		}
		script.src = host + '.google.com/maps/api/js?sensor=false&callback=map';
		document.body.appendChild(script);
	},

	sendto: function(marker, link){
		google.maps.event.addListener(marker, 'click', function(){
			window.location = link;
			return true;
		});
	},

	pin: function(map,coords,no,title,draggable){
		var sprite = '/i/m21.png';
		if(no == 0){
			sprite = '/i/m.png';
			no = 1;
		}
		if(no < 22){
			var shadow = new google.maps.MarkerImage('/i/m-s.png', new google.maps.Size(40, 34), new google.maps.Point(0, 0), new google.maps.Point(11, 34));
			var shape = {coord: [0, 0, 28, 26], type: 'rect'};
			var image = new google.maps.MarkerImage(sprite, new google.maps.Size(22, 34), new google.maps.Point(0, no * 34 - 34), new google.maps.Point(11, 34));
		} else {
			var shape = {coord: [3, 3, 3], type: 'circle'};
			var image = new google.maps.MarkerImage('/i/m-dot.png', new google.maps.Size(6,6), new google.maps.Point(0,0), new google.maps.Point(3,3));
		}
		var pin = new google.maps.Marker({
			position: coords,
			map: map,
			shadow: shadow,
			icon: image,
			shape: shape,
			title: title,
			draggable: draggable
		});
		return pin;
	},

	pins: function(lat, lon, locations, min_zoom, max_zoom){
		var opts = {
			zoom: min_zoom,
			center: new google.maps.LatLng(lat, lon),
			mapTypeControl: false,
			mapTypeId: google.maps.MapTypeId.ROADMAP,
			scrollwheel: false,
			streetViewControl: false,
			navigationControlOptions: {
				style: google.maps.NavigationControlStyle.SMALL
			}
		}
		var map = new google.maps.Map(document.getElementById("pins-map"), opts);
		try{
				var bounds = new google.maps.LatLngBounds();
				for (var i = 0; i < locations.length; i++){
					var location = locations[i];
					var coords = new google.maps.LatLng(location[1], location[2]);
					var marker = Map.pin(map, coords, i+1, location[0], false);
					Map.sendto(marker, location[3]);
					bounds.extend(coords);
					map.fitBounds(bounds);
				}
				google.maps.event.addListener(map, 'zoom_changed', function(){
					if (map.getZoom() > min_zoom) map.setZoom(min_zoom);
					if (map.getZoom() < max_zoom) map.setZoom(max_zoom);
				});
		}
		catch(err){}; // IE7 can fail here, that's ok
	},

	streetview: function(lat, lon){
		var coords = new google.maps.LatLng(lat, lon);
		var opts = {
			zoom: 18,
			center: coords,
			mapTypeControl: false,
			mapTypeId: google.maps.MapTypeId.HYBRID,
			scrollwheel: false,
			navigationControlOptions: {
				style: google.maps.NavigationControlStyle.SMALL
			}
		};
		var map = new google.maps.Map(document.getElementById("map"), opts);
		var marker = Map.pin(map,coords,0,'',false);
		marker.setMap(map);

		var sv = new google.maps.StreetViewService();
		sv.getPanoramaByLocation(coords, 50, processSVData);

		function processSVData(data, status){
			if(status == google.maps.StreetViewStatus.OK){
				var panoramaOptions = {
					position: coords,
					navigationControl: false,
					addressControl: false,
					scrollwheel: false
				};
				var panorama = new google.maps.StreetViewPanorama(document.getElementById("streetview"),panoramaOptions);
				map.setStreetView(panorama);
				function refreshPanoPov(){
					var markerPos = marker.getPosition(); 
					var panoPos = panorama.getPosition(); 
					if(markerPos && panoPos){
						var markerLat = markerPos.lat() / 180 * Math.PI; 
						var markerLon = markerPos.lng() / 180 * Math.PI; 
						var panoLat = panoPos.lat() / 180 * Math.PI; 
						var panoLon = panoPos.lng() / 180 * Math.PI; 
						var y = Math.sin(markerLon-panoLon)*Math.cos(markerLat); 
						var x = Math.cos(panoLat)*Math.sin(markerLat)-Math.sin(panoLat)*Math.cos(markerLat)*Math.cos(markerLon-panoLon); 
						var brng = Math.atan2(y, x) / Math.PI * 180; 
						var pov = panorama.getPov(); 
						pov.heading = brng; 
						panorama.setPov(pov); 
					}
				}
				google.maps.event.addListener(marker, 'position_changed', refreshPanoPov); 
				google.maps.event.addListener(panorama, 'position_changed', refreshPanoPov); 
			} else {
				$('#streetview').hide();
			}
		}
	},

	geocode: function(ID, detail){
		// given the element, listen for changes in value
		// on change set lat, lon hidden fields, update marker position and center
		var el = $(ID);
		el.blur(function(){
			// always geocode using postcode if available
			// this would need full address for l10n
			var postcode = $('#id_postcode').val();
			if(postcode=='' || postcode==undefined){
				var address = el.val();
			} else {
				var address = postcode.replace(' ', '');
				detail = true;
			}
			var geocoder = new google.maps.Geocoder();
			geocoder.geocode({'address': address, 'region': 'uk'}, function(results, status){
			  if (status == google.maps.GeocoderStatus.OK){
				var lat = results[0].geometry.location.lat().toFixed(6);
				var lon = results[0].geometry.location.lng().toFixed(6);
				$('#id_coords_0').val(lat)
				$('#id_coords_1').val(lon);
				Map.edit(lat, lon, detail);
			  }
			});
		});
	},

	edit: function(lat, lon, detail){
		if(lat!='0' && lon!='0'){
			$('.geocoded').show();
		} else {
			$('.geocoded').hide();
			return false;
		}
		var coords = new google.maps.LatLng(lat, lon);
		zoom = 14; 
		if(detail){ zoom = 18; }
		var opts = {
			zoom: zoom,
			center: coords,
			mapTypeControl: false,
			scrollwheel: false,
			streetViewControl: false,
			mapTypeId: google.maps.MapTypeId.HYBRID
		};
		var map = new google.maps.Map(document.getElementById("map"), opts);
		var marker = Map.pin(map,coords,0,'Drag to move pin',true);
		marker.setMap(map);
		google.maps.event.addListener(marker, 'drag', function(){
			$('#id_coords_0').val(marker.getPosition().lat().toFixed(6));
			$('#id_coords_1').val(marker.getPosition().lng().toFixed(6));
		});
	}
}
