(function ($) {
    $(window).load(function(){
        var pathname = location.pathname,
            cart = $('#cart'),
            process = $('#cart-process'),
            state_input = $('input.state', cart),
            state_CA = $('select.CA', cart),
            state_US = $('select.US', cart),
            state_label = $('#state-label', cart),
            country = $('#country', cart);
        // {{{ misc
        // $('#myFlash').height($('#fContent').height());
        if ($('div.full').length) {
            $('img.rule').attr('src', '/images/rule-854.png');
        }
        var text_fields = $('input:text, input:password');
        text_fields.css({ 
            'color': '#AAA', 
            'border': '1px solid #85ADAB', 
            'margin' : '0px 7px 0px 0px', 
            'padding' : '2px 0px 2px 3px'
        });
        $('input:text, input:password', cart)
            .css({
                'color': '#444', 
                'margin': '4px 0px 0px 0px'
            });
        text_fields.focus(function () {
            var el = $(this);
            if (!el.closest('#cart').length) {
                el.val('');
                el.css('color', '#444');
            }
        });
        $('input').css('visibility', 'visible');
        $('#blog .commentlist .comment div').each(function () {
            var el = $(this);
            var attr_id = el.attr('id');
            if (attr_id.search('div-comment') != -1) {
                el.css('margin-bottom', '20px');
                el.after('<img class="blog_rule" src="/images/rule-dash.png"/>');
            }
        });
        $('#blog #sidebar .authors li')
            .each(function(){
                var el = $(this);
                $('a', el)
                    .click(function(){
                        $('.popup', el)
                            .each(function(){
                                var popup = $(this);
                                $('.close', popup)
                                    .click(function(){
                                        popup.hide();
                                    });
                            })
                            .show();
                    });
            });

        // }}}
        // {{{ styled dropdowns
        $('select').each(function(i){
            var el = $(this);
            if (el.hasClass('normal'))
            {
                return;
            }
            var dropdown = $('<ul class="dropdown"></ul>');
            dropdown.css('z-index', 1000-(i*10));
            var list_items = $('<ul class="items"></ul>').hide();
            el.children().each(function () {
                var option = $(this);
                if (option.val() == '')
                {
                    var item = $('<li class="inactive">'+option.text()+'</li>');
                    item.click(function(e){
                        var li = $(this);
                        if (li.hasClass('inactive'))
                        {
                            li
                            .addClass('active')
                            .removeClass('inactive')
                            .children().show();
                        }
                        else
                        {
                            li
                            .addClass('inactive')
                            .removeClass('active')
                            .children().hide();
                        }
                    });
                    dropdown.prepend(item);
                }
                else
                {
                    var item = $('<li>'+option.text()+'</li>');
                    item.data('name', el.attr('name'));
                    item.data('value', option.val());
                    item.click(function () {
                        var el_option = $(this);
                        switch (el_option.data('name'))
                        {
                            case 'blog':
                                location = el_option.data('value');
                            break;
                            case 'patterns':
                                location.pathname = '/patterns/'+el_option.data('value');
                            break;
                            case 'yarn':
                                location.pathname = '/patterns/filter/yarn/'+el_option.data('value');
                            break;
                            case 'yarns':
                                location.pathname = '/yarns/'+el_option.data('value');
                            break;
                            case 'experience':
                                location.pathname = '/patterns/filter/experience/'+el_option.data('value');
                            break;
                            case 'type':
                                location.pathname = '/patterns/filter/type/'+el_option.data('value');
                            break;
                            case 'sort':
                                if (el_option.data('value') == 'featured')
                                {
                                    location.pathname = '/patterns/';
                                }
                                else
                                {
                                    location.pathname = '/patterns/sort/'+el_option.data('value');
                                }
                            break;
                        }
                    });
                    list_items.append(item);
                }
            });
            list_items.append('<li class="bottom">&nbsp;</li>');
            /*
            list_items.wrap('<li/>')
            dropdown.append(list_items);
            */
            $('> li:first', dropdown).append(list_items);
            dropdown.mouseleave(function () {
                $('> .active', this).click();
            });
            el.replaceWith(dropdown);
        });
        
        // }}}
        // {{{ pattern pagination
        paginator('search_results', 'content');
        if ($(document).data('pattern_items') != undefined)
        {
            paginator('pattern', 'patterns');
        }
        
        // }}}
        // {{{ product pagination
        paginator('search_results', 'content');
        if ($(document).data('product_items') != undefined)
        {
            paginator('product', 'products');
        }
        
        // }}}
        // {{{ yarn color switch
        var yarn = $('#yarn > .column_wide');
        if (yarn.html() != null)
        {
            var color_detail = $('> .color_detail', yarn);
            var colors = $('> .colors', yarn);
            $('img', colors).each(function(i){
                $(this).hover(
                    function () {
                        var img_detail = $('> img', color_detail).eq(i);
                        if (!img_detail.hasClass('active'))
                        {
                            $('> img:visible', color_detail).removeClass('active').fadeOut();
                            img_detail.addClass('active').fadeIn();
                        }
                    },
                    function () {}
                );
            });
            $(document).data('yarn_color') != undefined
                ? $('img', colors).eq($(document).data('yarn_color')).mouseover()
                : $('img:first', colors).mouseover();
        }
        
        // }}}
        // {{{ browse more patterns
        var more_patterns = $('#more_patterns');
        if (more_patterns.html() != null)
        {
            if (pathname.search('yarns') !== -1)
            {
                $('#yarn > .column_wide').append(more_patterns.show()).append('<div style="clear:both;" />');
            }
            else if (pathname.search('patterns'))
            {
                $('#pattern > .column_wide > .first_column').append(more_patterns.show());
            }
            else
            {
                return false;
            }
            adjust_background();

            var mp_controls = $('div.control', more_patterns),
                mp_port = $('> div.viewer > div.port', more_patterns),
                mp_list = $('> ul', mp_port),
                mp_items = $('> li', mp_list),
                mp_items_length = mp_items.length;

            // get true width of mp_list
            if (mp_items_length)
            {
                var item = mp_items.eq(0),
                    width = item.width(),
                    margin = item.css('margin-right');
                margin = margin === undefined ? 0 : parseInt(margin.substring(0, margin.length - 2));
                mp_list
                    .data('shift_width', width + margin)
                    .data('image_width', width)
                    .data('true_width', (width * mp_items_length) + (margin * (mp_items_length - 1)));
            }
            else
            {
                return;
            }

            mp_controls.click(function ()  {
                var el = $(this),
                    margin = mp_list.attr('margin-left'),
                    full_width = mp_list.data('true_width'),
                    shift_width = mp_list.data('shift_width');
                margin = margin === undefined ? 0 : parseInt(margin.substring(0, margin.length - 2));

                // know when to stop scrolling
                if (el.hasClass('control_right'))
                {
                    var mp_port_width = mp_port.width();
                    if (Math.abs(margin) >= full_width - mp_port_width)
                    {
                        return;
                    }
                    var new_margin = margin + (full_width - mp_port_width) <= mp_list.data('image_width')
                        ? mp_port_width - full_width
                        : margin - shift_width;
                }
                else if (el.hasClass('control_left'))
                {
                    if (margin === 0)
                    {
                        return;
                    }
                    var new_margin = Math.abs(margin) <= shift_width 
                        ? 0 
                        : margin + shift_width;
                }

                mp_list.animate(
                    {
                        marginLeft: new_margin + 'px'
                    },
                    200,
                    'linear',
                    function ()  {
                        mp_list.attr('margin-left', new_margin + 'px');
                    }
                );
            });
        }

        // }}}
        // {{{ view more images
        $('#view_more_images > ul > li').click(function () {
            var img = $('> img', $(this));
            img.closest('.first_column').children('img').attr('src', img.attr('src'));
        });
        /*
        $('#content .view_more').click(function(e){
            e.preventDefault();
            var vm_images = $('#view_more_images'),
                large_view = $('> .large_view', vm_images);
            vm_images.show();
            $('> ul > li', vm_images).click(function () {
                large_view.children('img').remove();
                large_view.append($(this).children('img').clone());
            });
            $('> ul > li:first', vm_images).click();
            $('> div > a.close', vm_images).click(function(e){
                e.preventDefault();
                vm_images.hide();
            });
        });
        */

        // }}}
        // {{{ share this
        /*
        var share_this = SHARETHIS.addEntry({
            title:document.title,
            url:document.URL
            },
            {button:false}
        );
        $('a.share_this').each(function(i){
            share_this.attachButton(this);
        });
        */
        // }}}
        // {{{ google maps
        $('#address').keyup(function(e) {
            if(e.keyCode == 13)
            {
                $(this).next('input').trigger('click');
            }
        });
        $('#get_markers').click(function(e){
            var geocoder = new GClientGeocoder();
            e.preventDefault();
            if ($(document).data('address') == undefined)
            {
                $('#stockist .last_column').append('<div id="map" style="width:293px; height:293px;"></div>');
                create_gmap('map');
                $(window).unload(function () {
                    GUnload();
                });
            }
            $(document).data('address', $('#address').val());
            geocoder.getLocations($(document).data('address'), add_markers);
        });

        // }}}
        process
            .appendTo('body')
            .css({
                left: '0px',
                position: 'fixed',
                top: '0px',
                height: $(window).height(),
                width: $(window).width(),
                zIndex: '999999'
            });
        $('.background', process)
            .css({
                backgroundColor: '#000',
                height: '100%',
                width: '100%'
            })
            .fadeTo(1, 0.5);
        $('.window', process)
            .css({
                backgroundColor: '#FFF',
                height: '182px',
                left: ($(window).width() - 380) / 2 + 'px',
                position: 'absolute',
                textAlign: 'center',
                top: ($(window).height() - 182) / 2 + 'px',
                width: '380px'
            });
        $('.content', process)
            .css({
                padding: '52px 0 0'
            });
        $(window)
            .resize(function () {
                $('.window', process)
                    .css({
                        left: ($(window).width() - 380) / 2 + 'px',
                        top: ($(window).height() - 182) / 2 + 'px'
                    });
                process
                    .css({
                        height: $(window).height(),
                        width: $(window).width()
                    });
            });
        $('#review', cart)
            .submit(function () {
                process.show();
                var el = $(this),
                    ajax_input = $('<input type="hidden" name="ajax" value="1" />'),
                    errors = $('.errors', el),
                    errors_list = $('<ul />');
                el.append(ajax_input);
                // loading screen
                $.post('/cart/process/', el.serialize(), function(data) {
                    if (data.success)
                    {
                        location.href = '/cart/confirm/';
                    }
                    else
                    {
                        // some kind of errors
                        ajax_input.remove();
                        process.hide();
                        for (var key in data.error)
                        {
                            if (key.search('LONGMESSAGE') !== -1)
                            {
                                errors_list.append('<li>' + decodeURIComponent(data.error[key]) + '</li>');
                            }
                        }
                        if (errors_list.children().length)
                        {
                            errors.show();
                            errors.html(errors_list);
                            errors.prepend('<p>Please correct the following errors:</p>');
                            adjust_background();
                        }
                    }
                }, 'json');
                return false;
            });
        $('#checkout', cart)
            .submit(function () {
                var el = $(this),
                    submit = true,
                    email = $('input[name="billing[EMAIL]"]', el),
                    email_confirm = $('input[name="order[email_confirm]"]', el),
                    errors = $('.errors', el),
                    errors_list = $('<ul />');
                $('.required', cart)
                    .each(function () {
                        var el = $(this),
                            backgroundColor = '#FFF',
                            border = '1px solid #85ADAB';
                        if (el.val() == '')
                        {
                            submit = false;
                            border = '1px solid #d35c3b';
                            backgroundColor = '#fdfdd3';
                            errors_list.append('<li>' + el.parent().text() + '</li>');
                        }
                        el.css({
                            border: border,
                            backgroundColor: backgroundColor
                        });
                    });
                if (email.val() !== email_confirm.val())
                {
                    submit = false;
                    errors_list.append('<li>Emails do not match.</li>');
                    email.css('border', '1px solid red');
                    email_confirm.css('border', '1px solid red');
                }
                if (errors_list.children().length)
                {
                    errors.show();
                    errors.html(errors_list);
                    errors.prepend('<p>Please correct the following errors:</p>');
                }
                return submit;
            });
        $('#cvc', cart)
            .each(function () {
                var el = $(this),
                    image = $('<img src="/images/cart/cvc-popup.gif" />'),
                    anchor = $('<a href="javascript:;">(?)</a>');
                image
                    .css({
                        display: 'none',
                        left: '-203px',
                        position: 'absolute',
                        top: '-217px'
                    });
                anchor
                    .hover(function () {
                        image.toggle();
                    }, function () {
                        image.toggle();
                    })
                    .append(image)
                    .css('position', 'relative');
                $('br', el).before(anchor);
            });
        country
            .change(function () {
                var el = $(this);
                if (el.val() == 'US')
                {
                    state_US.show().attr('name', 'billing[STATE]');
                    state_CA.hide().attr('name', 'state');
                    state_input.hide().attr('name', 'state');
                }
                else if (el.val() == 'CA')
                {
                    state_CA.show().attr('name', 'billing[STATE]');
                    state_US.hide().attr('name', 'state');
                    state_input.hide().attr('name', 'state');
                }
                else
                {
                    state_input.show().attr('name', 'billing[STATE]');
                    state_US.hide().attr('name', 'state');
                    state_CA.hide().attr('name', 'state');
                }
            });
        adjust_background();
    });
})(jQuery);

// {{{ function adjust_background()
function adjust_background()
{
    var content = $('#content'),
        container = $('#container'),
        bkgs = $('> .background_image', container),
        num_bkgs = $('> .background_image:visible', container).length,
        bkg_height = 100;
    if (content.html() == null)
    {
        content = $('#splash');
    }
    content.css('height', '');
    var content_height = content.outerHeight();
    if ((content_height % bkg_height) != 0)
    {
        content.height(content_height + (bkg_height - (content_height % bkg_height)));
    }
    var difference = (content.outerHeight() / bkg_height) - num_bkgs;
    for (var i = 0; difference < i; i--)
    {
        var bkg = $(bkgs.get(bkgs.length+(i-1)));
        bkg.remove();
    }
    for (var i = 0; i < difference; i++)
    {
        container
            .append(
                $(bkgs.get(Math.floor(Math.random()*bkgs.length)))
                    .clone()
                    .removeClass('hidden')
            );
    }
    container.height($('#main').outerHeight() + 200);
}

// }}}
// {{{ function add_markers(response)
function add_markers(response)
{
    var status_code = response.Status.code;
    if (status_code == 200)
    {
        google_map.clearOverlays();
        var data = response.Placemark[0];
        var distance = $('#radius').val();
        if (!(distance > 0))
        {
            distance = 250;
        }
        $.getJSON('/store_locator/results/', { distance: distance, 'point[]': [data.Point.coordinates[1], data.Point.coordinates[0]] }, function (db_data) {
            var store_list = $('#stockist ul.store_list');
            $('#stockist_pagination').remove();
            store_list.html('');
            $('#stockist > .column_wide > .results').text('Results for "'+$(document).data('address')+'"');
            if (db_data.success)
            {
                var num_items = 4;
                var page = 1;
                var pages = (db_data.items.length / num_items);
                $.each(db_data.items, function (i, item) {
                    var point = new GLatLng(item.latitude, item.longitude);
                    var store = item.Name;
                    var opts = { title: store.name, clickable: true };
                    var marker = new GMarker(point, opts);
                    google_map.addOverlay(marker);
                    marker.bindInfoWindowHtml("<span style='color: blue;'>" + store.name + '</span><br />' + item.address);
                    var store_html = '<li class="marker page_'+page;
                    if ((i+1) > num_items)
                    {
                        store_html += ' hidden';
                    }
                    store_html += '"><div class="store"><h2>'+store.name+'</h2><p>'+item.address;
                    if (item.phone != '')
                    {
                        store_html += '<br />'+item.phone;
                    }
                    if (store.website != '')
                    {
                        store_html += '<br /><a href="'+store.website+'" target="_blank">'+store.website+'</a>';
                    }
                    store_html += '</p></div></li>';
                    var store_obj = $(store_html);
                    store_obj.click(function () {
                        if (!$(this).hasClass('active'))
                        {
                            store_obj.siblings().removeClass('active');
                            store_obj.addClass('active');
                            google_map.panTo(point);
                            GEvent.trigger(marker, 'click');
                        }
                    });
                    if (i == 0)
                    {
                        google_map.setCenter(point, 15);
                        store_obj.trigger('click');
                        store_list.html(store_obj);
                    }
                    else
                    {
                        store_list.append(store_obj);
                    }
                    if ((i+1) % num_items == 0)
                    {
                        page++; 
                    }
                });
                if (pages > 1)
                {
                    var pag_html = '<div id="stockist_pagination"><img src="/images/rule-598.png" /><span>Page: </span><ul class="cleared">';
                    for (var j=0; j<pages; j++)
                    {
                        pag_html += j === 0 ? '<li class="active">' : '<li>';
                        pag_html += j+1;
                        pag_html += '</li>';
                    }
                    pag_html += '</ul></div>';
                    store_list.after(pag_html);
                    paginator('stockist', 'store_list');
                }
                adjust_background();
            }
        });
    }
    else
    {
        alert('Invalid Address');
    }
}

// }}}
// {{{ function paginator(div_id, list_class)
function paginator(div_id, list_class)
{
    var item_list = $('#'+div_id+' > .column_wide ul.'+list_class);
    var pagination = $('#'+div_id+'_pagination');
    var pagination_list = $('> ul', pagination);
    var pagination_p = $('> p', pagination);
    pagination_p.click(function () {
        $(this).fadeOut('slow', function () {
            pagination_list.fadeIn('slow');
            $('> li:first', pagination_list).removeClass('active').click();
        });
    });
    $('> li', pagination_list).click(function () {
        var el = $(this);
        if (!el.hasClass('active'))
        {
            if (el.hasClass('view_all'))
            {
                pagination_list.fadeOut('slow', function () {
                    pagination_p.fadeIn('slow');
                    $('li:hidden', item_list).fadeIn('slow');
                    adjust_background();
                });
                return false;
            }
            el.addClass('active');
            el.siblings().removeClass('active');
            var visible_items = $('li:visible', item_list);
            visible_items.fadeOut('slow', function () {
                $('li.page_'+el.text(), item_list).fadeIn('slow');
                if ($(this).html() == visible_items.eq(visible_items.length-1).html())
                {
                    adjust_background();
                }
            });
        }
    });
}

// }}}

