function slideSwitch() {
    var $active = $('#slideshow DIV.active');
    if ( $active.length == 0 ) $active = $('#slideshow DIV:last');

    // use this to pull the divs in the order they appear in the markup
    var $next =  $active.next().length ? $active.next() : $('#slideshow DIV:first');

    // uncomment below to pull the divs randomly
    var $sibs  = $active.siblings();
    var rndNum = Math.floor(Math.random() * $sibs.length );
    var $next  = $( $sibs[ rndNum ] );

    $active.addClass('last-active');

    $next.css({opacity: 0.0})
        .addClass('active')
        .animate({opacity: 1.0}, 1000, function() {
            $active.removeClass('active last-active');
        });
}

$(document).ready(function() {

    $(function() {
        setInterval( "slideSwitch()", 5000 );
    });

    function scrollTo(element) {
        var offset = element.offset();
        var confirmTop    = offset.top;
        $('html,body').animate({scrollTop: element.offset().top}, 500);
    }

    function make_wizard() {
        $("form.wizard").each(function() {
            var form = $(this);
            var pages = form.find('.wizard_page');
            pages.hide();
            
            var buttons = form.find('.buttons');
            var originalButtons = buttons.find(":input");
            
            var nextButton = $('<button class="next">Next &gt;</button>');
            buttons.append(nextButton);
            
            var prevButton = $('<button class="prev">&lt; Prev</button>');
            buttons.prepend(prevButton);
            
            var currentPage = 0;
            
            // see if there's a page that's marked as having errors
            pages.each(function(i) {
                if ( $(this).hasClass('error_page') && currentPage == 0 ) {
                    currentPage = i;
                }
            });
            
            function showPage(i) {
                pages.hide().filter(':eq('+i+')').fadeIn('slow');
                if ( i == (pages.size()-1) ) {
                    // when it's the last page we'll hide the next
                    // button and show the originalButtons
                    originalButtons.show();
                    nextButton.hide();
                }
                else {
                    originalButtons.hide();
                    nextButton.show();
                }
                
                if ( i == 0 ) {
                    prevButton.hide();
                }
                else {
                    prevButton.show();
                }
            }
            
            function gotoNextPage() {
                if ( currentPage < pages.size() ) {
                    currentPage++;
                    showPage(currentPage);
                }
            }
            
            function ajax_validate(event, callback) {
                var page = $(pages.get(currentPage));
                if ( page.hasClass('ajax_validate') ) {
                    // stop other handlers running
                    event.preventDefault();
                    event.stopImmediatePropagation();
                    
                    var loading = $('<img src="/static/images/loading_icon.gif" />')
                    nextButton.attr('disabled', 'disabled');
                    originalButtons.attr('disabled', 'disabled');
                    originalButtons.before(loading);
                    
                    var page_id = page.attr('id');
                    var inputs = page.find(':input');
                    
                    var url = form.attr('action') + 'ajax-validate/' + page_id + '/';
                    
                    $.ajax({
                        url: url,
                        data: inputs.serialize(),
                        dataType: 'json',
                        success: function (data) {
                            // remove previous errors
                            page.find('ul.errorlist').remove();
                            var was_error = false;
                            for ( var key in data ) {
                                was_error = true;
                                var ul = $('<ul class="errorlist"></ul>').hide();
                                for ( var i = 0; i < data[key].length; i++ ) {
                                    var error = data[key][i];
                                    ul.append($('<li></li>').text(error));
                                }
                                if ( key.match(/__all__$/) ) {
                                    // error for the entire form
                                    page.find("table").before(ul)
                                }
                                else {
                                    // error for a field
                                    page.find(':input[name='+key+']:first').parents('td:first').prepend(ul);
                                }
                                ul.fadeIn();
                            }
                            
                            if ( !was_error) {
                                callback();
                            }
                            else {
                                scrollTo(page.find('ul.errorlist:first'));
                            }
                        },
                        complete: function() {
                            nextButton.removeAttr('disabled');
                            originalButtons.removeAttr('disabled');
                            loading.remove();
                        }
                    });
                    
                }
            }
            
            nextButton.click(function(event) { ajax_validate(event, gotoNextPage); });
            
            // this only runs if we aren't validating via ajax
            nextButton.click(function(event) {
                event.preventDefault();
                gotoNextPage();
            });
            
            prevButton.click(function(event) {
                event.preventDefault();
                if ( currentPage > 0 ) {
                    currentPage--;
                    showPage(currentPage);
                }
            });
            
            form.keypress(function (event) {
                if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
                    event.preventDefault();
                    form.submit();
                }
            });

            
            form.submit(function(event) {
                // only submit form, when we're on the last
                // page
                if ( currentPage == (pages.size()-1) ) {
                    ajax_validate(event, 
                        function() {
                            form.unbind('submit');
                            form.submit();
                        });
                }
                else {
                    event.preventDefault();
                    nextButton.click();
                }
            });
            
            showPage(currentPage);
            
        });
    }

    function extended_search(form) {
        form.find('.extended_search')
                .click(function(event) {
                    $(this).remove();
                    form.find('.search_drop_down.extended').removeClass("extended");
                    event.preventDefault();
                })
    }
    
    

    function create_tabs() {
        $(".tobe_tabbed").each(function() {
            create_tabs_from_element($(this));
        });
        
        make_tab_menu();
    }
    
    function create_tabs_from_element(element) {
        var tabs = $("<ul></ul>");
        
        // find only immediate child divs
        var visible = 0;
        var children = element.find(" > div").addClass('tab');
        
        // work out which tab to show
        children.each(function(i) {
            if ( window.location.hash && ('#' + $(this).attr('id')) == window.location.hash ) {
                visible = i;
            }
            else if ( $(this).hasClass('default_tab') ) {
                visible = i;
            }
        });
        
        children.each(function(i) {
            create_tab(tabs, children, $(this), visible == i, $(this).attr('id'));
        });
        
        element.addClass("tabbed");
        element.prepend($("<div class='tabs'></div>").append(tabs));
        
        ensure_tabs_minimum_height(children);
    }
    
    function create_tab(tabs,all_children,child,visible,name) {
        var title = child.find("h2:first").remove().text();
        var tab_link = $("<a href='#'></a>").append(document.createTextNode(title));
        if ( name ) {
            tab_link = tab_link.attr('href','#'+name);
        }
        var tab = $("<li></li>").append(tab_link);
        tabs.append(tab);
        
        if ( !visible ) {
            child.hide();
        }
        else {
            tab_link.addClass("selected");
        }
        
        tab_link.click(function(event) {
            event.preventDefault();
            
            if ( !tab_link.hasClass("selected") ) {
                tabs.find("a").removeClass("selected");
                all_children.hide();
                tab_link.addClass("selected");
                child.show();
                // see if the child contains a googmap
                var map = child.find("div.map_canvas");
                if ( map.size() > 0 && !map.hasClass("map_reloaded") ) {
                    var id = map.attr("id");
                    window.goog_maps[id]();
                    map.addClass("map_reloaded");
                }
            }
            
        });
    }
    
    function ensure_tabs_minimum_height(children) {
        var max_height = 0;
        
        children.each(function() {
            max_height = Math.max(max_height, $(this).height());
        });
        
        children.css('minHeight', max_height+'px');
    }
    
    function make_tab_menu() {
        /* when there are too many tabs to show in available space */
        $('.tabbed .tabs').each(function() {
            var tabs = $(this);
            var tabs_left = tabs.offset().left;
            var tabs_right = tabs_left + tabs.width();
            
            var overlapping_tabs = [];
            tabs.find('li').each(function() { 
                var tab = $(this);
                var left = tab.offset().left;
                var right = left + tab.width();
                
                if ( right > (tabs_right-10) ) {
                    overlapping_tabs.push(tab);
                    tab.remove();
                }
            });
            
            if ( overlapping_tabs.length > 0 ) {
                var menu_link = $('<li><a title="Show more tabs" href="#">&hellip;</a></li>');
                var menu = $('<ul class="tab_menu"></ul>');
                for ( var i = 0; i < overlapping_tabs.length; i++ ) {
                    menu.append(overlapping_tabs[i]);
                }
                menu.hide().css('position', 'absolute').addClass('hidden');
                $("body").append(menu);
                
                tabs.find('ul').append(menu_link);
                menu_link
                    .find('a')
                    .click(function(event) {
                        if ( menu.hasClass('hidden') ) {
                            var menu_top = menu_link.offset().top + menu_link.height();
                            var menu_left = menu_link.offset().left;
                            
                            menu.css({ top: menu_top, left: menu_left}).removeClass('hidden').show();
                        }
                        else {
                            menu.addClass('hidden').hide();
                        }
                        
                        event.preventDefault();
                    });
                
            }
        });
    }
    
    function attach_rating_form(form) {
        form.find(':submit').hide();
        form.find('.star_rating_editable').click(function() {
            form.submit();
        });
        
        form.submit(function(event) {
            // submit the form via ajax
            // we don't really care about the result
            // we'll just assume it worked and hide
            // the "saving..." message
            event.preventDefault();
            var saving = $('<span> saving...</span>');
            form.find('.star_rating').after(saving);
            $.ajax({
                url: form.attr('action'),
                type: 'POST',
                data: form.serialize(),
                complete: function() {
                    saving.remove();
                }
            });
        });
    }
    
    function create_star_ratings() {
        $(".reviews form .rating select, .product_comments .rating select").each(function() {
            create_star_rating($(this));
        });
        
        // now find all rating_forms and make them auto-post
        $('form.rating_form').each(function() {
            attach_rating_form($(this));
        });
    }
    function create_star_rating(element) {
        // replace select field with a javascript run
        // hidden field and couple of divs
        var field_name=element.attr('name');
        var hidden_field=
            $("<input type='hidden' value='' />")
            .attr('name', field_name);
        
        var rating_div=
            $("<div class='star_rating star_rating_editable' title='click to change rating'><div class='stars'></div></div>").append(hidden_field);
        
        function set_rating(rating,element) {
            element.find('input[name='+field_name+']').attr('value',rating);
            element.find(".stars").width((rating*element.width())/5);
        }
        
        rating_div.click(function(e) {
            var x = e.pageX - $(this).offset().left;
            var rating = Math.ceil(5.0*(x/$(this).width()));
            set_rating(rating,$(this));
        });
        
        var current_rating = element.attr('value');
        
        element.replaceWith(rating_div)
        
        set_rating(current_rating,rating_div);
    }
    
    function random_id() {
        var id = [];
        for ( var i = 0; i < 10; i++ ) {
            id.push(String.fromCharCode(97 + Math.round(Math.random() * 25)));
        }
        return id.join("");
    }
    
    function add_carousel(element) {
        /*var button_id = random_id();
        element.find('.carousel').before("<button id='next"+button_id+"' class='prevButton'><span>&lt;</span></button>");
        element.find('.carousel').after("<button id='prev"+button_id+"' class='nextButton'><span>&gt;</span></button>");
        element.find('.carousel').jCarouselLite(
            { btnPrev: '#next'+button_id,
              btnNext: '#prev'+button_id,
              circular: false,
              visible: 5
            }
        );*/
        
        var carousel = element.find('.carousel');
        
        var left = 0;
        
        function scroll_carousel(next) {
            var ul = carousel.children('ul');
            
            var carousel_left = carousel.offset().left;
            var carousel_right = carousel_left + carousel.width();
            
            var dx = 0;
            if ( next ) {
                ul.find('> li').each(function() {
                    if ( !dx ) {
                        var li = $(this);
                        var li_right = li.offset().left + li.width();
                        if ( li_right > carousel_right ) {
                            dx = (carousel_right - li_right);
                        }
                    }
                });
            }
            else {
                ul.find('> li').each(function() {
                    var li = $(this);
                    var li_left = li.offset().left;
                    if ( li_left < carousel_left ) {
                        dx = (carousel_left - li_left);
                    }
                });
            }
            
            if ( dx ) {
                left += dx;
                ul.stop().animate({marginLeft: left+"px"});
            }
            
            return;
            var total_width = 0;
            var positions = [];
            
            ul.find('> li').each(function() { 
                var width = $(this).width();
                positions.push(total_width);
                total_width += width;
            });
            
            if ( next ) {
                current++;
            }
            else {
                current--;
            }
            
            current = Math.max(0, Math.min(current, positions.length-1));
            
            var margin = -positions[current];
            ul.stop().animate({marginLeft: margin+"px"});
        }
        
        element.find('.carousel').before(
            $("<button class='prevButton'><span>&lt;</span></button>")
                .click(function(event) {
                    scroll_carousel(false);
                    event.preventDefault();
                })
        );
        element.find('.carousel')
            .after($("<button class='nextButton'><span>&gt;</span></button>")
                .click(function(event) {
                    scroll_carousel(true);
                    event.preventDefault();
                })
            );
        
    }
    
    $('.products_carousel').each(function() {
        add_carousel($(this));
    });
    
    function extract_popup(data) {
        data = $("<div />").append(data.replace(/<script(.|\s)*?\/script>/g, ""));
        return data.find("div.popup").removeClass("popup");
    }

    function install_form(dialog, data) {
        // ensure we post the form via ajax and keep the results
        // inside the popup
        
        dialog.find("form").unbind();
        var popup = $("<div class='popup'></div>").append(extract_popup(data));
        dialog.replaceWith(popup);
        process_forms(popup.find("form"));
        
        popup.find("form").submit(function(event) {
            var form = $(this);
            $.ajax({
                url: form.attr("action"),
                type: "POST",
                data: form.serialize(),
                success: function(data) {
                    if ( data ) {
                        install_form(popup, data);
                    }
                },
                complete: function(xhr,status) {
                    // see if we need to do a redirect
                    var location = xhr.getResponseHeader('X-Javascript-Location');
                    if ( location ) {
                        window.location = location;
                    }
                }
            });
            event.preventDefault();
        });
    }
    
    function enable_popup(element, url_attr, event_type) {
        element.bind(event_type, function(event) {
            var dialog = $("<div>Loading...</div>");
            dialog.modal({position: ['50px',null]});
            
            var url = element.attr(url_attr)
            var form_data = element.serialize()
            
            $.ajax({
                url: url,
                type: "GET",
                data: form_data,
                success: function(data) {
                    install_form(dialog, data);
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    dialog.replaceWith("<div>Error Loading</div>");
                    window.location=url;
                }
            });
            
            event.preventDefault();
        });
    }
    
    function process_forms(forms) {
        forms.find('select').each(
            function(i) {
                // grey text in select boxes, when empty value selected
                var select = $(this);
                select.change(
                    function() {
                        if ( select.val() ) {
                            select.removeClass("hint");
                        }
                        else {
                            select.addClass("hint");
                        }
                    }
                ).change();
            }
        );
        
        // find hidden labels on forms for input boxes
        // and show label value in input box (grayed out)
        forms.find('label:hidden').each(
            function(i) {
                var label = $(this);
                var forID = label.attr("for");
                var input = $('#'+forID);
                if ( input.attr('type') == 'text' ) {
                    var labelText = label.text();
                    labelText = labelText.replace(/:$/, '');
                    
                    input.blur(
                        function() {
                            if ( !input.val() ) {
                                input.addClass("hint");
                                input.val(labelText);
                            }
                        }
                    ).focus(
                        function() {
                            if ( input.hasClass("hint") ) {
                                input.removeClass("hint");
                                input.val("");
                            }
                        }
                    ).blur();
                }
            }
        );
        
        forms.submit(function() {
            // remove value from input fields that have the "hint" class
            $(this).find("input.hint").val("");
            return true;
        });
    }
    
    //MB - welcome popup
    //$("#welcome").modal({position: ["15%","25%"]});

    $('a.popup').each(function() {
        enable_popup($(this), 'href', 'click');
    });
    
    $('form.popup').each(function() {
        enable_popup($(this), 'action', 'submit');
    });
    
    
    $('.product_search_form form.hide_extended').each(function() {
        extended_search($(this));
    });
    
    process_forms($("form"));
    
    // add read more links
    $('#right_col .side_widget .accordian div.article').each(function(i, elem) {
        var url = $(elem).find('h2 a').attr('href');
        if ( url ) {
            var link = $("<div class='read_more_link'><a href=''>Read more &gt;</a></div>").find('a').attr('href', url).end();
            $(elem).find('div.summary').append(link);
        }
    });
    $('#right_col .side_widget .accordian').accordion({header: 'h2'});
    
    
    create_star_ratings();
    create_tabs();
    
    function update_actions(old_actions, new_actions) {
        old_actions.find('a').unbind();
        old_actions.replaceWith(new_actions);
        attach_actions();
    }
    
    $('a.print').click(function(event) {
        window.print();
        event.preventDefault();
    });
    
    $('a.bookmark').click(function(event) {
        var url = $(this).attr('href');
        $(this).parent('li').addClass('loading');
        $.ajax({
            url: url,
            complete: function(xhr) {
                var location = xhr.getResponseHeader('X-Javascript-Location');
                if ( location ) {
                    window.location = location;
                }
                else {
                    window.location.reload();
                }
            }
        });
        event.preventDefault();
    });
    
    function preload_image(url) {
        $("<img />").attr("src", url);
    }
    preload_image('/static/images/loading_icon.gif');

    make_wizard();
    
    /** add this bookmarking service **/
    $('li.share a').click(function(event) {
        event.preventDefault();
        addthis_sendto();
    })
    .hover(function() {
            addthis_open(this, '', '[URL]', '[TITLE]');
        },
        addthis_close
    );
    
    // ensure that stockist search form clears designer/category fields
    // when one changed
    function attach_to_stockist_form() {
        var stockist_category = $('.stockist_search_form form :input[name=category]');
        var stockist_designer = $('.stockist_search_form form :input[name=designer]');
        stockist_designer.change(function() {
            if ( stockist_designer.val() ) {
                stockist_category.val("");
                stockist_category.change();
            }
        });
        stockist_category.change(function() {
            if ( stockist_category.val() ) {
                stockist_designer.val("");
                stockist_designer.change();
            }
        });
    };
    attach_to_stockist_form();

    $('form.comment_form').submit(function(event) {
        var textarea = $(this).find(':input[name=comment]');
        if ( !textarea.val() ) {
            event.preventDefault();
            $(this).find('ul.errorlist').remove();
            textarea.before("<ul class='errorlist'><li>This field is required</li></ul>");
        }
    });
    
    
});