var animating = false;
var loader_timer;
var csstransitions = Modernizr.csstransitions;
var active_requests = {};

// IE detect
var ieversion = 999;
if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
    ieversion = Number(RegExp.$1);
}

function init_ie_fixes() {
    // run html5 loaded with ajax in ie < 9 through html5shiv
    if(ieversion < 9) {
        $.ajaxSetup({
        	dataFilter: function(data, dataType) {
        		if (typeof innerShiv === 'function' && dataType === 'html') {
        			return innerShiv(data);
        		}
        		else {
        			return data;
        		}
        	}
        });
    }
    if(ieversion < 7) {
        $('#permatabs').css('position', 'absolute');
    }
}

function init_modernizr_alternatives() {

    // no html5 input placeholders
    if(!Modernizr.input.placeholder) {
        $("input").each(function() {
            if($(this).val() == "" && $(this).attr("placeholder") != ""){
                $(this).val($(this).attr("placeholder"));
                $(this).focus(function() {
                    if($(this).val() == $(this).attr("placeholder")) { 
                        $(this).val(""); 
                    }
                }).blur(function() {
                    if($(this).val() == "") {
                        $(this).val($(this).attr("placeholder"));
                    }
                });
            }
        });
    }
    
}

function show_loader(area) {
    loader_timer = setTimeout(function() {
        area.append('<div id=\"loader\"></div>');
        $('#loader', area).stop().animate({'opacity':'1'}, 200);
    }, 300);
}

function hide_loader(area) {
    clearTimeout(loader_timer);
    loader_timer = null;
    $('#loader', area).stop().animate({'opacity':'0'}, 200, function() {
        $(this).remove();
    });
}

function init_slideshow_carousel(container_selector) {
        
    // elements
    var carousel = $(container_selector);
    var inner = $(container_selector + " .carousel-inner");
    
    // counters and sums
    var current_item = 0;
    var items = $(".carousel-item", inner);
    var items_loaded = 0;
    var item_width = $(".carousel-item:first", inner).outerWidth(true); // width including margins
    var inner_width = ((items.length + 1) * item_width) + 100; // +1 to make a nice nest ready for possible clone item at end; +100 for some breathing space
    
    // slides n fades
    var inert_opacity = 0.5;
    var loaded_fade_speed = 750;
    var slide_speed = 1500;
    var slide_interval = 8000;
    var timer;
    
    // hide carousel until load
    $(inner).fadeTo(0, 0);
    
    // set width of inner to accommodate all items
    $(inner).css("width", inner_width + "px");
    
    // start carousel when loaded
    if(ieversion < 999) {
        $(inner).fadeTo(loaded_fade_speed, 1, function() {
            timer = setTimeout(function() { 
                advance_carousel(); 
            }, slide_interval);
        });
    } else {
        
        // preload frame and images inside frame
        
        var preloaders = [];
        
        var frame_src =  $(".carousel-item:first span.frame", inner).css("background-image");
        if(frame_src) {
            frame_src = frame_src.replace(/"/g,"").replace(/url\(|\)$/ig, "");
            var frame_preloader = new Image();
            frame_preloader.src = $(".carousel-item:first span.frame", inner).css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
            preloaders.push(frame_preloader);
        }
        
        $("img", items).each(function() {
            var detail_image_preloader = new Image();
            detail_image_preloader.src = $(this).attr("src");
            preloaders.push(detail_image_preloader);
        });
        
        var preloaders_loaded = 0;
        
        $(preloaders).each(function() {
            $(this).load(function() {
                preloaders_loaded++;
                if(preloaders_loaded == preloaders.length) {
                    $(inner).fadeTo(loaded_fade_speed, 1, function() {
                        timer = setTimeout(function() { 
                            advance_carousel(); 
                        }, slide_interval);
                    });
                }
            });
        });
    }
    
    // prepare carousel to be cosmicically infinite
    // clone first element to end of line
    $(container_selector + " .carousel-item:first-child").clone().appendTo(container_selector + " .carousel-inner");
    
    function advance_carousel() {
        
        if(typeof timer != "undefined") {
            clearTimeout(timer);
        }
        
        // dip opacity during scroll
        $(carousel).fadeTo(slide_speed/2, inert_opacity, "easeOutQuint").fadeTo(slide_speed/2, 1, "easeInQuint");
        
        // scroll
        $(inner).animate({"left": (-(current_item + 1) * item_width) + "px"}, slide_speed, "easeInOutQuart", function() {

            current_item++;
            
            // if we land on the clone, reset position. nobody wants to see dem nasty clones
            if(current_item == items.length) {
                current_item = 0;
                setTimeout(function() {
                    $(inner).css({"left": 0});
                }, 100);
            }
            
            timer = setTimeout(function() { 
                advance_carousel(); 
            }, slide_interval);
            
        });
        
    }
    
}


function init_detail_carousel() {
    
    // elements
    var carousel = $("#detail-carousel");
    
    if(!carousel.length) {
        return;
    }
    
    var inner = $("#detail-carousel .carousel-inner");
    
    // counters and sums
    var current_page = 0;
    var items = $(".carousel-item", inner);
    var pages = Math.ceil(items.length / 5);
    var items_loaded = 0;
    var item_width = $(".carousel-item:first", inner).outerWidth(true); // width including margins
    var inner_width = (items.length * item_width) + 100; // +100 for some breathing space
    var animating_detail_carousel = false;
    
    // slides n fades
    var loaded_fade_speed = 750;
    var slide_speed = 1000;
    var control_fade_speed = 250;
    
    // hide carousel until load
    $(inner).fadeTo(0, 0);
    $("#detail-main-image").fadeTo(0, 0);
    
    // set width of inner to accommodate all items
    $(inner).css("width", inner_width + "px");
        
    function move_carousel(direction) {
        
        if(animating_detail_carousel) {
            return;
        } else {
            animating_detail_carousel = true;
        }
        
        if(direction == "next") {
            var new_left = -(current_page + 1) * item_width * 5;
            current_page++;
        } else {
            var new_left = -(current_page - 1) * item_width * 5;
            current_page--;
        }
        
        if(current_page == 0) {
            $(".prev").fadeOut(control_fade_speed);
            $(".next").fadeIn(control_fade_speed);
        } else if(current_page == pages - 1) {
            $(".next").fadeOut(control_fade_speed);
            $(".prev").fadeIn(control_fade_speed);
        } else {
            $(".prev, .next").fadeIn(control_fade_speed);
        }
        
        // scroll
        $(inner).animate({"left": new_left + "px"}, slide_speed, "easeInOutQuint", function() {
            
            animating_detail_carousel = false;
            
        });
        
    }
    
    // add scroll buttons
    if(pages > 1) {
        $(carousel).append('<a href="#" class="prev pngfix"></a><a href="#" class="next pngfix"></a>');
        $(".prev").click(function(event) {
            event.preventDefault();
            move_carousel('prev');
        }).hide();
        $(".next").click(function(event) {
            event.preventDefault();
            move_carousel("next");
        });
    }
    
    // add click behaviour
    $(items).each(function() {
        $(this).click(function(event) {
            event.preventDefault();
            var t = $(this);
            
            if ($("#detail-main-image img").attr("src") == t.attr("href"))
                return;
            
            if(ieversion < 9) {
                $("#detail-main-image img").attr("src", t.attr("href"));
            } else {
                $("#detail-main-image").stop(true).fadeTo(500, 0, function() {
                    var preloader = new Image();
                    $(preloader).load(function() {
                        $("#detail-main-image img").attr("src", preloader.src).load(function() {
                            $("#detail-main-image").fadeTo(500, 1);
                        });
                    });
                    preloader.src = t.attr("href");
                });
            }
        });
    });
    
    // show carousel when loaded
    if(ieversion < 999) {
        $(inner).fadeTo(loaded_fade_speed, 1);
        $("#detail-main-image").fadeTo(loaded_fade_speed, 1);
    } else {
        $("img", items).each(function() {
            $(this).attr("data-src", $(this).attr("src")).attr("src", "#");
            $(this).attr("src", $(this).attr("data-src"));
        
            $(this).load(function() {
                items_loaded++;
                if(items_loaded == items.length) {
                    $(inner).fadeTo(loaded_fade_speed, 1);
                }
            });
        });
        
        
        // make sure frame and image inside are both loaded 
        var preloaders = [];
        
        var frame_preloader = new Image();
        frame_preloader.src = $("#detail-main-image span.frame").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
        preloaders.push(frame_preloader);
        
        var detail_image_preloader = new Image();
        detail_image_preloader.src = $("#detail-main-image img").attr("src");
        preloaders.push(detail_image_preloader);
        
        var preloaders_loaded = 0;
        
        $(preloaders).each(function() {
            $(this).load(function() {
                preloaders_loaded++;
                if(preloaders_loaded == preloaders.length) {
                    $("#detail-main-image").fadeTo(loaded_fade_speed, 1);
                }
            });
        });
        
    }
    
}


function detail_map() {

    var geocoder;
    var map;
    var map_el = document.getElementById("detail-map");
    var postcode = map_el.getAttribute("data-postcode");
    var address = map_el.getAttribute("data-address");
    var country = map_el.getAttribute("data-country");
    
    function initialize() {
        geocoder = new google.maps.Geocoder();
        var myOptions = {
            zoom: 15,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            mapTypeControl: false,
            streetViewControl: false
        };
        map = new google.maps.Map(map_el, myOptions);
    }

    function geocode_address(address_str, give_up_if_fails) {
        geocoder.geocode( {'address': address_str}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                map.setCenter(results[0].geometry.location);
                var marker = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location
                });
            } else {
                //console.log("Geocode for <" + address_str + "> was not successful for the following reason: " + status);
                
                // geocode for address_line_1 + postcode failed. try again with just the postcode, then give up if that fails too.
                if(give_up_if_fails) {
                    $(map_el).remove();
                    return;
                } else {
                    geocode_address(postcode + " " + country, true);
                }
            }
        });
    }

    initialize();
    
    var initial_address_str = postcode + " " + country;
    if(address) {
        initial_address_str = address + " " + initial_address_str;
    }
    geocode_address(initial_address_str);

}

// pass callback as string.
function init_google_maps(callback) {
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = "http://maps.google.co.uk/maps/api/js?sensor=false&callback=" + callback;
	document.body.appendChild(script);
}


function init_custom_select() {
    // put span behind every select element for custom style
    // select opacity set to 0 = still clickable
    // unsupported browsers jus get OS default field
    if(!$.browser.opera && !($.browser.msie && $.browser.version < 8)) {
        $("select:not(.field-customised)").each(function() {
            var title = $(this).attr('title');
            if(typeof $('option:selected', this) != "undefined") title = $('option:selected', this).text();
            $(this)
            .addClass("field-customised")
            .wrap("<div style=\"position:relative\" />")
            .css({'z-index':10,'opacity':0,'-khtml-appearance':'none'})
            .after('<span class="custom-select">' + title + '</span>')
            .change(function() {
                val = $('option:selected',this).text();
                $(this).next("span").text(val);
            })
            .next("span").css({'width':$(this).outerWidth()});
        });
    }
}

// also styles radios
// - radios need to be the child of a form to work correctly here
// unsupported browsers jus get OS default field
function init_custom_checkbox() {
    
    if(!$.browser.opera && !($.browser.msie && $.browser.version < 8)) {
        
        function toggle_input_checked(the_input) {
            var is_radio = $(the_input).is("[type='radio']");
            var is_checked = $(the_input).attr("checked");
            
            if(is_radio && is_checked) {
                // don't alter the value of an already checked radio button
                return;
            } else if(is_radio && !is_checked) {
                // uncheck other radios
                var radio_name = $(the_input).attr("name");
                $(the_input).parents("form").find("input[type='radio']").filter("[name='" + radio_name + "']").each(function() {
                    $(this).removeAttr("checked");
                });
            } 

            // update the value
            var new_value = !is_checked;
            $(the_input).attr("checked", new_value);
            $(the_input).change();
        }
        function update_custom_appearance(the_input) {
            var is_checked = $(the_input).attr("checked");
            var is_radio = $(the_input).is("[type='radio']");
            
            // style the input's span to match the input value
            if(is_checked) {
                $(the_input).next("span").addClass("checked");
                $(the_input).siblings("label:first").addClass("highlight");
            } else {
                $(the_input).next("span").removeClass("checked");
                $(the_input).siblings("label:first").removeClass("highlight");
            }
            
            // if radio, update other radios of same name to be unchecked
            if(is_radio) {
                var radio_name = $(the_input).attr("name");
                $(the_input).parents("form").find("input[type='radio']").filter("[name='" + radio_name + "']").each(function() {
                    if(!$(this).attr("checked")) {
                        $(this).next("span").removeClass("checked");
                        $(this).siblings("label:first").removeClass("highlight");
                    }
                });
            }
            
        }
        
        $("input[type='checkbox'], input[type='radio']").not(".field-customised").each(function() {
            $(this)
            .addClass("field-customised")
            .hide()
            .after('<span class="custom-checkbox"></span>')
            .next("span")
            .click(function() {
                
                // clicking span = update input value and span style to match
                toggle_input_checked($(this).prev("input"));
                update_custom_appearance($(this).prev("input"));
                
            }).prev("input").change(function() {
                
                // changing input = just update span style to match
                update_custom_appearance($(this));
                
            });
            
            // update span style for each element in case of inital setting on page load
            update_custom_appearance($(this));
            
        });
    }
}

function init_form_buttons() {
    $(".submit").livequery('click', function() {
        $(this).parents("form").submit();
    });
}


// permatabs
// add .pop-open to a permatab overlay panel to have it open on page load
function init_permatabs() {
    
    //set the events up
    
    var close_speed = 500;
    
    // toggle dem panels
    $("#permatabs a.toggle").livequery('click', function() {
        
        $("#permatabs a.toggle").removeClass("active");
        
        // target panel is closed, other panels may be open
        if($(this).next(".overlay-panel:visible").length == 0) {

            var panel = $(this).next(".overlay-panel");

            // close other panels
            $("#permatabs .overlay-panel").hide();
            
            // absolute positioning used for ie6 - scroll to top
            if(ieversion <= 7) {
                $("html, body").scrollTop(0);
            }
            
            $(panel).show();
            $(this).addClass("active");
            
            // make sure panel does not go off bottom of screen
            if(parseInt(panel.position().top) + parseInt(panel.outerHeight()) >= $(window).height()) {
                panel.css({top:Math.max(0, $(window).height() - panel.outerHeight())});
            } else {
                panel.css({top:$(this).position().top});
            }

        } else {
            // target panel is open and user is clicking to close   
            $("#permatabs .overlay-panel").fadeOut(close_speed);
        }
        
    });
    
    $("#permatabs a.close").livequery('click', function() {
        $(this).parents(".overlay-panel").prev(".toggle").click();
    });
    
    // must be visible on document ready in order to initialise custom scrollbars
    // hence the dance between visibility:hidden and display:none to avoid unsightly flash of permatab!
    $("#permatabs .overlay-panel").livequery(function(){
        var t = $(this);
        
        t.hide().css({visibility:"visible"});
        if (t.hasClass('pop-open'))
        {
            t.prev("a.toggle").click();
        }
        
        if (t.hasClass('fade-out'))
        {
            setTimeout(function(){
                if (t.is(':visible') && $('input:focus', t).length == 0)
                {
                    t.prev("a.toggle").click();
                }
            }, 3000);
        }
    });
    
    var panels = ['my_account', 'my_shortlist'];
    //get the html content
    $.each(panels, function(i, p){
        $.ajax({
            url: base_url+'account/'+p+'/',
            type: 'POST',
            dataType: 'html',
            data: {
                referer: window.location.href,
                subsite: subsite,
                subsite_url: subsite_url
            },
            success: function(data)
            {
                data = $(data);
                switch (p)
                {
                    case 'my_account':
                        init_account(data);
                        break;
                    case 'my_shortlist':
                        init_shortlist(data);
                        break;
                }
            }
        });
    });
    
}

function init_account(data)
{
    $("#permatabs").prepend(data);
    $("form", data).each(function(i, v){
        init_form_validation($(v));
    });
    //try and fill in some forms
    var edit_form = $('#account-edit');
    if (edit_form.length > 0)
    {
        var name = $('input[name=first_name]', edit_form).val()+' '+$('input[name=last_name]', edit_form).val(),
            email = $('input[name=email_address]', edit_form).val();
            
        $('input[name=name]').livequery(function(){
            if ( ! $(this).val())
                $(this).val(name);
        });
        $('input[name=email_from]').livequery(function(){
            if ( ! $(this).val())
                $(this).val(email);
        });
    }
}

function init_shortlist(data)
{
    $("#permatabs").append(data);
    
    //update scrollbars whenever visible
    $('#shortlist-items:visible', data).livequery(function(){
        var jsp = $(this).data('jsp');
        if (jsp)
            jsp.reinitialise();
    });
    
    //check this page is added to shortlist
    var listing_id = $('#listing-id').val(),
        add_button = $('#add-to-shortlist');
        
    if (listing_id)
    {
        $('input.listing-id', data).each(function(){
            var val = $(this).val();
            if (val == listing_id)
            {
                add_button.text('Added to Shortlist');
            }
        });
    }
    
    //add to shortlist button
    add_button.click(function(){
        var toggle = $('a.toggle.shortlist');
            
        //do the ajax call in the background
        $.ajax({
            url: base_url+'account/add_to_shortlist/',
            type: 'POST',
            dataType: 'json',
            data: {
                subsite: subsite,
                subsite_url: subsite_url,
                listing_id: listing_id
            },
            success: function(data)
            {
                if (data.item)
                {
                    var item = $(data.item),
                        item_name = $('.name', item).text().toLowerCase(),
                        index = -1,
                        current_items = $('#shortlist-items li');
                        
                    //update the counts
                    $('.shortlist-count').text(data.count);
                    
                    //find a place to put it
                    current_items.each(function(i, v){
                        var li = $(this),
                            name = $('.name', li).text().toLowerCase();
                        
                        if (item_name < name)
                        {
                            index = i;
                            return false;
                        }
                    });
                    
                    if (index == -1)
                    {
                        $('#shortlist-items ul').append(item);
                    }
                    else
                    {
                        item.insertBefore(current_items.filter(':eq('+index+')'));
                    }
                    
                    current_items.removeClass('last').removeClass('clear');
                    $('#shortlist-items li:nth-child(4n)').each(function(){
                        var item = $(this);
                        item.addClass('last');
                        item.next().addClass('clear');
                    });
                    
                    item.hide();
                    item.fadeIn(500);
                    
                    //update scrollbars
                    var jsp = $('#shortlist-items').data('jsp');
                    if (jsp)
                        jsp.reinitialise();
                }
            }
        });
        
        //now disguise the delay with smoke and mirrors...
        
        //open the shortlist
        if ( ! toggle.hasClass('active'))
        {
            toggle.click();
        }
        //change the button text      
        add_button.text('Added to Shortlist');
    });
        
    //remove from shortlist
    $('.delete-shortlist-item').livequery('click', function(){
        var item = $(this).parents('li'),
            item_id = $('input.listing-id', item).val();
            
        if (item_id)
        {
            $.ajax({
                url: base_url+'account/remove_from_shortlist/',
                type: 'POST',
                data: {
                    subsite: subsite,
                    listing_id: item_id
                },
                dataType: 'json',
                success: function(data)
                {
                    if (data)
                    {
                        $('.shortlist-count').text(data.count);
                    }
                }
            });
        
            if (item_id == listing_id)
            {
                add_button.text('Add to Shortlist');
            }

            item.fadeOut(500, function(){
                item.remove();
                $('#shortlist-items li').removeClass('last').removeClass('clear');
                $('#shortlist-items li:nth-child(4n)').each(function(){
                    var item = $(this);
                    item.addClass('last');
                    item.next().addClass('clear');
                });
            });

            //update scrollbars
            var jsp = $('#shortlist-items').data('jsp');
            if (jsp)
                jsp.reinitialise();
        }
    });
}

// overlay panels
// add .pop-open to an overlay panel to have it open on page load
function init_overlay_panels() {
    
    var close_speed = 400,
        background_speed = 600,
        background_opacity = 0.4,
        background_height = "100%",
        overlay_counter = -1,
        captcha_counter = -1,
        positioning_method = "fixed";
    
    // overlay background
    $("body").append('<div id="overlay-background" />');
    if(ieversion < 7) {
        background_height = $(document).height();
        positioning_method = "absolute";
    }
    $("#overlay-background").css({background:"#000", width:"100%", height:background_height, position:positioning_method, left:"0", top:"0", zIndex:499}).hide().click(function() {
        // close overlay and panels on background click
        $(".overlay-panel").not(function() {
            // but don't close permatab panels as they have special case functions
            return $(this).parents("#permatabs").length;
        }).fadeOut(close_speed);
        $(this).fadeOut(close_speed);
    });
    
    function open_panel(panel) {
        // bind press escape to close panel
        $(document).keyup(function(e) {
            if (e.keyCode == 27) {$('.close', panel).click();}   // esc
        });
        panel.show();

        // absolute positioning used for ie6 - scroll to top
        if(ieversion <= 6) 
        {
            $("html, body").scrollTop(0);
        }

        //init recaptcha
        var captcha_wrapper = $('.captcha-wrapper', panel);
        if (captcha_wrapper.length)
        {
            Recaptcha.create(recaptcha_public_key, captcha_wrapper[0], {
                theme: 'white'
            });
        }
        $("#overlay-background").fadeTo(background_speed, background_opacity);
    }
    function close_panel(panel) {
        $(document).unbind('keyup');
        panel.fadeOut(close_speed, function(){
            //destroy recaptcha
            var captcha_wrapper = $('.captcha-wrapper', panel);
            if (captcha_wrapper.length)
            {
                Recaptcha.destroy();
            }
        });
        $("#overlay-background").fadeOut(close_speed);
    }
    
    
    
    var overlays = ['shortlist_send'];
    if ($('.detail-actions').length)
    {
        overlays.push('listing_send');
        overlays.push('listing_enquiry');
    }
    //get the html content
    $.each(overlays, function(i, p){
        $.ajax({
            url: base_url+'overlays/'+p+'/',
            dataType: 'html',
            data: {
                referer: window.location.href,
                subsite: subsite,
                subsite_url: subsite_url
            },
            success: function(panel)
            {
                // insert into DOM asap for ie6
                panel = $(panel);
                $('body').append(panel);
                panel = $('body .overlay-panel:last');
                
                $("form", panel).each(function(i, v){
                    init_form_validation($(v));
                });

                var panel_id = panel.attr('id');
                if ( ! panel_id)
                {
                    overlay_counter++
                    panel_id = 'overlay_panel_'+overlay_counter;
                    panel.attr('id', panel_id);
                }
                
                var opener_selector = panel.attr("data-opener-selector");
                
                if (opener_selector)
                {
                    $(opener_selector).livequery('click', function(){
                        if (panel.is(":visible"))
                        {
                            close_panel(panel);
                        }
                        else
                        {
                            open_panel(panel);
                        }
                    });
                }
                $(".close", panel).click(function(){
                    close_panel(panel);
                });

                // must be visible on document ready in order to initialise custom scrollbars, custom select boxes etc
                // hence the dance between visibility:hidden and display:none to avoid unsightly flash of panel
                setTimeout(function(){
                    panel.hide().css({visibility:"visible"});
                    if (panel.hasClass("pop-open"))
                    {
                        open_panel(panel);
                    }
                }, 0);
                
                if (ieversion < 7) 
                {
                    panel.css("position", "absolute");
                }
                
                switch (p)
                {
                    case 'listing_enquiry':
                        $('.listing-name', panel).text($('.main h1').first().text());
                    case 'listing_send':
                        var input = $('<input type="hidden" name="listing_id" />');
                        input.val($('#listing-id').val());
                        $('form', panel).append(input);
                        
                        /*if ($('.message', panel).length)
                        {
                            track_listing_interaction(p);
                        }*/
                        
                        break;
                }
            }
        });
    });
    
    $(".overlay-panel").livequery(function(){
        var t = $(this);
        
        $('.message', t).delay(2000).slideUp(500, function(){
            $(this).remove();
        });
        
        if (t.parents('#permatabs').length)
            return;
        
        if (t.hasClass('fade-out'))
        {
            setTimeout(function(){
                if (t.is(':visible') && $('input:focus', t).length == 0)
                {
                    close_panel(t);
                }
            }, 3000);
        }
    });
}

var desc_html = false;
function init_search_controls() {
    $("#search-summary").hide();
    $("#toggle-search-options").click(function() {
        if($(this).hasClass("close")) {
            
            // compile search summary
            var summary = "";
            if($("#search-refine #keyword").val() != "" && $("#search-refine #keyword").val() != $("#search-refine #keyword").attr("placeholder")) {
                summary += $("#search-refine #keyword").val() + ". ";
            }
            $("#search-refine #search-options input:checked").each(function() {
                summary += $(this).parents("li").find("label").text() + ". ";
            });
            if(summary != "") {
                $("#search-summary .update").text(summary);
            } else {
                $("#search-summary .update").text("No options selected");
            }
            
            $("#search-instruction").hide();
            $("#search-summary").show();
            
            $("#search-options").slideUp(200);
            
            $(this).removeClass("close").addClass("open").html("Open");
        } else {
            $("#search-instruction").show();
            $("#search-summary").hide();
            
            $("#search-options").slideDown(200);

            $(this).removeClass("open").addClass("close").html("Close");
        }
        
    });
    
    if($("#search-options").hasClass("closed")) {
        $("#toggle-search-options").click();
    }
    
    $('input:checkbox').change(function(){
        refine_search();
    });
    
    $('#search-refine-form').submit(function(e){
        refine_search();
        e.preventDefault();
        return false;
    });
    
    desc_html = $($('#search-results .section-desc').html());
}

function refine_search()
{
    var url = base_url+'search/refine/',
        data = $('#search-refine-form').serialize(),
        keyword_value = $('#keyword').val();
        
    if (active_requests[url])
    {
        active_requests[url].abort();
        active_requests[url] = false;
    }
    var results_list = $('#search-results-list'),
        desc_holder = $('#search-results .section-desc');
        
    desc_holder.html('Searching...');

    if (keyword_value)
    {
        $('#search-summary .update').html(keyword_value+'.').show();
    }
    else
    {
        $('#search-summary .update').hide();
    }
        
    results_list.height(results_list.height());
    $('.search-result-item').animate({opacity: 0}, 500);
    
    active_requests[url] = $.ajax({
        url: url,
        dataType: 'json',
        type: 'post',
        data: data,
        success: function(data)
        {
            active_requests[url] = false;
            $('.highlight', desc_html).html(data.count+' Result'+(data.count == 1 ? '' : 's'));
            desc_holder.html(desc_html);
            results_list.html(data.html);
            results_list.height('auto');
            sequence_results();
        }
    });
}

function sequence_results()
{
    $('.search-result-item').each(function(i, v){
        $(v).css({opacity:0}).delay(i*100).animate({opacity: 1}, 500);
    });
}

function init_directory_scrolling() {
    
    var scrollElement = $("html, body");
    var disable_scroll = function() {return false;}
    var is_scrolling = false;
    var scroll_offset = 132;
    
    $(".scrollfix").css({position: "absolute"});
    
    // get initial position of container to float
    var scrollfix_offset = $(".scrollfix").offset().top;
    
    // hide back to top link until needed
    $(".back-to-top").hide();
    
    // reset to top - required for firefox
    scrollElement.scrollTop(0);
    
    // pad out the space underneath .scrollfix
    $(".scrollfix").each(function() {
        $(this).after("<div data-existential-reason=\"to pad out the space underneath .scrollfix\" style=\"height: " + $(this).outerHeight(true) + "px\" />");
    });

    // smooth scrolling to internal links with .smooth-scroll
    $("a.smooth-scroll[href^='#']").click(function(event) {
        event.preventDefault();
    
        if(is_scrolling) {
            return false;
        }

        is_scrolling = true;
    
        var $link = $(this),
        target = this.hash,
        $target = $(target);
        
        var new_scrollTop;
        if(target == '#top') {
            new_scrollTop = 0;
        } else {
            new_scrollTop = $target.offset().top - scroll_offset;
        }
        
        $(window).bind('mousewheel', disable_scroll);
    
        scrollElement.stop().animate({'scrollTop': new_scrollTop}, 1000, 'easeInOutQuad', function() {
            is_scrolling = false;
            $(window).unbind('mousewheel', disable_scroll);
        
            if(typeof $link.attr("data-do-not-activate") == "undefined") {
                $(".a-z .active").removeClass("active");
                $link.parent().addClass("active");
            }
        });

    });
    
    // make .scrollfix sticky or static
    $(window).scroll(function() {           
        
        // fix or unfix the nav
        var current_scrolltop = $("html").scrollTop() || $("body").scrollTop();
        if(current_scrolltop >= scrollfix_offset) {
            $(".scrollfix").addClass("scrollfix-sticky");
            $(".back-to-top").show();
        } else {
            $(".scrollfix").removeClass("scrollfix-sticky");
            $(".back-to-top").hide();
        }
        
    });
    
    // activate links when scrolled past
    // usings waypoints plugin to avoid problems with scrolling really quick past short sections
    $.waypoints.settings.scrollThrottle = 30;
    $("section.waypoint").waypoint(function(event, direction) {
        $('.a-z .active').removeClass('active');
        $('a[href=#'+$(this).attr('id')+']').parent().addClass('active');
    }, {
       offset: 150 // 150 from top
    });
    
    // refresh the waypoints after images have loaded and pushed them all down
    $(window).load(function() {
        $.waypoints('refresh');
    });

}

function init_tabsets() {
    
    $(".tabset-control").each(function() {
        
        $(this).find("a").each(function(index) {
            
            var target_tab_selector = $(this).attr("href");
            
            // tab does not have a target set
            if(target_tab_selector.indexOf("#") != 0) {
                return;
            }
            
            // hide tab if not the first
            if(index != 0) {
                $(target_tab_selector).hide();
            }
            
            $(this).click(function(event) {
                event.preventDefault();
                
                // activate and deactivate links 
                $(this).parents("ul").find(".active").removeClass("active");
                $(this).parents("li").addClass("active");

                // show target tab
                $(target_tab_selector).show();

                // hide other tabs in this set
                $(this).parents("ul").find("a").not("[href='" + target_tab_selector + "']").each(function() {
                    $($(this).attr("href")).hide();
                });

            });
            
            if($(this).parent().hasClass("active")) {
                $(this).click();
            }
            
        });
    
    });
    
    var hash = window.location.hash;
    if (hash)
    {
        $('a[href='+hash+']').click();
    }
    
}


function init_form_validation(form) {
    function is_email(email) { 
         var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
         return email.match(re)
    }
    function is_empty(value) {
        if($.trim(value) == "") {
            return true;
        } else {
            return false;
        }
    }
    function perform_match(one, two) {
        return one == two;
    }

    function display_error(for_what, message) {
        for_what = $(for_what);
        for_what.addClass("error");
        $("label[for='" + for_what.attr("id") + "']").addClass("error").append("<span class=\"error-message\"> (" + message + ")</span>");
        for_what.siblings(".custom-checkbox").addClass("error");
        for_what.siblings(".custom-select").addClass("error");
        validation_errors++;
    }
    
    if ( ! form)
        form = $("form");

    form.submit(function(event) {
        
        var t = $(this);
        
        validation_errors = 0;

        $("span.error-message", t).remove();
        $(".error", t).removeClass("error");

        // required field
        // give field this attribute: data-validation-required="true"
        $("[data-validation-required]", t).not(".error").each(function() {
            var input = $(this);
            if(input.is(":checkbox")) {
                if(!input.attr("checked")) {
                    display_error(input, "required");
                }
            } else {
                if(is_empty(input.val())) {
                    display_error(input, "required");
                }
            }

        });

        // is valid email
        // give field this attribute: data-validation-email="true"
        $("[data-validation-email]", t).not(".error").each(function() {
            var input = $(this);
            if(!is_email(input.val())) {
                display_error(input, "please check");
            }
        });

        // match against other field
        // give field this attribute: data-validation-match="#css-selector-to-match-against"
        $("[data-validation-match]", t).not(".error").each(function() {
            var input = $(this);
            if(!perform_match(input.val(), $(input.attr("data-validation-match")).val())) {
                display_error(input, "please check");
            }
        });


        if(validation_errors > 0) {
            event.preventDefault();
            return false;
            // focus first error field
            $("input.error:first, textarea.error:first, select.error:first", t).focus();
        }
    });
    
}

function reveal_secret_emails() {
    
    $(".secret-email").each(function() {
        var container = $(this);
        
        // empty <a> inside the container to allow setting other attributes on it, e.g. classes/ids etc
        var tag = container.find("a");
        var email_address = container.attr("data-email").replace(email_secret_string, "@");
        var subject_line;
        if(container.attr("data-subject")) {
            subject_line = "?subject=" + escape(container.attr("data-subject"));
        }
        tag.attr("href", "mailto:" + escape(email_address) + subject_line)
           .attr("title", "Email " + email_address)
           .html(email_address);
    });
}

function track_event(category, action, label, non_interaction, value)
{
    if (typeof _gaq == 'undefined')
    {
        setTimeout(function(){
            track_event(category, action, label, non_interaction, value);
        }, 100);
        return;
    }
    else
    {
        if (label)
        {
            label = document.location+' - '+label;
        }
        else
        {
            label = document.location;
        }
        _gaq.push(['_trackEvent', category, action, label, value, non_interaction]);
    }
}

function init_detail_events()
{
    $('.detail_website').click(function(){
        track_event('listing', 'external link', $(this).attr('href'), true);
    });
    $('.detail_email').click(function(){
        track_event('listing', 'email link', $(this).attr('href'), true);
    });
}

function init_home_events()
{
    $('.carousel-item a').click(function(){
        track_event('home', 'slideshow click', $(this).attr('href'));
    });
    
    $('.featured-listing').click(function(){
        track_event('home', 'featured click', $(this).attr('href'));
    });
}

function init_splash_events()
{
    $('.carousel-item a').click(function(){
        track_event('splash', 'slideshow click', $(this).attr('href'));
    });
    
    $('.featured-listing').click(function(){
        track_event('splash', 'featured click', $(this).attr('href'));
    });
}

function track_listing_interaction(panel_type)
{
    var action = panel_type.replace('_', ' ');
    track_event('listing', action);
}

$('document').ready(function() {
    
    init_modernizr_alternatives();

    if(ieversion < 999) {
        init_ie_fixes();
    }
    
    // draw customised selects
    if($("select").length) { 
        init_custom_select(); 
    }
    // draw customised selects
    if($("input[type='checkbox'], input[type='radio']").length) { 
        init_custom_checkbox();
    }
    // draw customised form fields in dynamically loaded content
    $("body").ajaxComplete(function() { 
        init_custom_select(); 
        init_custom_checkbox(); 
        if(ieversion < 7) {
            $(".pngfix").supersleight();
        }
    });
    
    init_form_buttons();
    init_form_validation();
    
    // custom scrollbars
    $('.scroll-pane').livequery(function(){
        $(this).jScrollPane({
            // use getContentPane() to update content of scroll area content - http://jscrollpane.kelvinluck.com/api.html#getContentPane
            animateScroll:true,
            hideFocus:true,
            verticalGutter:12
        });
    });
    
    if($(".tabset-control").length) {
        init_tabsets();
    }
    
    if($("#permatabs").length) {
        init_permatabs();
    }
    
    if($(".secret-email").length) {
        reveal_secret_emails();
    }
        
    // prevent default on js control links
    $("a[href='#']").livequery('click', function(event) {
        event.preventDefault();
        return false;
    });

    // Page switch
    var template = $('.main').attr('id');
    switch(template) {
        case "splash":
            init_slideshow_carousel("#splash-carousel");
            init_splash_events();
            break;
        case "home":
            init_slideshow_carousel("#home-carousel");
            init_home_events();
            break;
        case "results":
            init_search_controls();
            break;
        case "detail":
            init_detail_carousel();
            if($("#detail-map").length) {
                init_google_maps("detail_map");
            }
            init_detail_events();
            break;
        case "directory":
            init_directory_scrolling();
            break;
    }
    
    if (template != 'splash')
    {
        init_overlay_panels();
    }

});
