// __include

// __startExclude

// start fullscreen background
function _fullscreenBackground(fullscreenBackground){
    fullscreenBackground.jbgallery({
        menu: false,
        style: 'zoom',
        caption: false
    });
}

// play some music
function _startBackgroundMusic() {
    
    if ($('#jPlayer').data('status') != 'initialized') {
        
        
     	$('#jPlayer').jPlayer({
     		ready: function () {
     		    // set a file and plays it immediately (relative to including page, not position of JavaScript-File)
     			this.element.jPlayer('setFile', HTTP + 'public/music/greatpaulukka_slideshow.mp3', HTTP + 'public/music/greatpaulukka_slideshow.ogg').jPlayer('play');
     		},
            volume: 50,
            oggSupport: true
     	})
     	// when title finished, play again
     	.jPlayer('onSoundComplete', function() {
     		this.element.jPlayer('play');
     	});

        $('#jPlayer').data('status', 'initialized');
        
    } else {
        
        $('#jPlayer').jPlayer('play');
        
    }
    
}

// kill the band
function _stopBackgroundMusic() {
    
 	$('#jPlayer').jPlayer('stop');    
    
}

// setup navigation
function _setupNavigation() {
    
    /* main */
    // add original width as data to each element
    $('#navMain li a span.navOn, #navMain li a span.navOff').each(function(){
        $(this).data('originalWidth', $(this).css('width'));
    });
    // hide all active elements
    $('#navMain li').each(function(){
        if (!$(this).hasClass('active'))        $('a span.navOn', this).css('width', 0); 
        else                                    $('a span.navOff', this).css('width', 0); 
    });
    // mouseenter and mouseleave of main navigation
    $('#navMain li').children('a').bind('mouseenter', function(event) {
        hoverMainNav(this, 'mouseenter');
    }).bind('mouseleave', function(event) {
        if (!$(this).parent('li').hasClass('active')) {
            hoverMainNav(this, 'mouseleave');
        }
    });

    /* social */
    // set start and end value of background
    $('#navSocial li a').each(function(i){
        $(this).data('startBackgroundPosition', $(this).backgroundPosition());
        $(this).data('endBackgroundPosition', $(this).backgroundPosition().replace(/4px/g, '19px'));
    });
    // mouseenter and mouseout
    $('#navSocial li a').bind('mouseenter', function(){
        hoverSocialNav(this, 'mouseenter');
    }).bind('mouseleave', function(){
        hoverSocialNav(this, 'mouseleave');
    });

    /* subnav */
    // mouseenter and mouseout
    $('.navSub li').bind('mouseenter', function(){
        $(this).stop().find('a').animate({ color: '#ff5025' }, 'fast');	
    }).bind('mouseleave', function(){
        if (!$(this).hasClass('active')) {
            $(this).stop(false,true).find('a').animate({ color: '#fff' }, 'slow');
        }
    });
    
}

// ajaxify links
function _ajaxifyLinks() {

    // ajaxify links (main navigation)
    $('#navMain a.ajax').click(function(event){
        // prevent clicking when active (would hide element)
        if ($(this).parents('li').hasClass('active'))       return false;
        event.preventDefault();
        // remove class and hide active span
        $('#navMain li.active').removeClass('active').find('a').triggerHandler('mouseleave');
        // assign active-class to current element
        $(event.target).closest('li').addClass('active');
        // coming from cart: rel is the same as hash | otherwise to hashchange
        if (window.location.hash.substring(1) == $(this).attr('rel')) {
            $(window).trigger('hashchange');
        } else {
            window.location.hash = $(this).attr('rel');
        }
    });

    // ajaxify links (sub navigation)
    $('.navSub a.ajax').click(function(event){
        event.preventDefault();
        // remove class
        $('.navSub li.active').removeClass('active');
        // remove colors (from hover)
        $('.navSub li a').css('color', '');
        // assign active-class to current element
        $(event.target).closest('li').addClass('active');
        // change hash
        window.location.hash = $(this).attr('rel');
    });
    
}

// manage hashes
function _manageHashes() {
    
    // what to do when hashtag has changed
    $(window).bind('hashchange', function(){
        // get hash without the '#'
        newHash = window.location.hash.substring(1);
        $.get(
            HTTP + newHash + '/',
            {
                type: 'ajax' // tell controller to use the ajax-template
            }, function(data) {
                // trigger google analytics (prevent errors)
                try { _gaq.push(['_trackPageview', newHash])} catch (e) {}
                loadHashContent(data);
            }, 'json'
        );
		
		if (window.location.hash == '' || window.location.hash == '#home') {
			$('#jbgallery-target').attr('src', 'http://www.gnadenlos2010.de/2010/public/images/wintersale.jpg');	
		} else {
			$('#jbgallery-target').attr('src', 'http://www.gnadenlos2010.de/2010/public/images/default_background.jpg');	
		}
		
		
    });

    // initial triggering of the hashchange-events (in case of deeplinks)
    if (window.location.hash != '' && window.location.hash != '#home') {
        $(window).trigger('hashchange');
        // activate chosen menu-item
        var regEx       = /[A-Za-z0-9-]*/;
        var cleanedHash = regEx.exec(window.location.hash.substring(1));
        $('#navMain li.active').removeClass('active').find('a').trigger('mouseleave');
        $('#navMain a.ajax[rel=' + cleanedHash + ']').trigger('mouseenter').closest('li').addClass('active');
	}
    
}

// handle new content
function loadHashContent(data) {
    
    // only display returns that doen't contain <body> (then the link pointed to nowhere & the index returns the front page)
    if (data.newContent.match(/<body>/gi) == null) {

        // change site-title
        document.title = data.title;

        // remove scrollbar
        $('.jScrollPaneTrackTop, .jScrollPaneTrackBottom').remove();
        $('#content').jScrollPaneRemove();
        
        // clean bumper
        $('#bumper').html('');
        // clear video
        $('#flashContent').html('');
        
        // route collection-content differently
        if (data.collectionTemplate == true) {
            
          //  GndlsVideos.launch(GndlsVideos.spot);
            
            // fadeout content
            var selector = '#contentHolder, #cartWrapper';
            var count = $(selector).length;
            $(selector).fadeOut('fast', function(){
                if (!--count) {
                    $('#collectionWrapper').html(data.newContent);
                    // hide hidden elements
                    $('#collectionWrapper .hidden').hide();
                    $('#collectionWrapper').fadeIn('fast');
                    GndlsCollection.initCollectionOnly();
                }
            });

        } else {

            // fadeout contentHolder & collectionWrapper
            var selector = '#contentHolder, #collectionWrapper, #cartWrapper';
            var count = $(selector).length;
            $(selector).fadeOut('fast', function(){
                if (!--count) {
                    $('#content').html(data.newContent).closest('#contentHolder').fadeIn('fast', function(){
                        // add scrollbar
                        addScrollbar();
                    });
                }
            });
   
        }
        
        // show subnavigigation
        showSubnavigation(data.L1);

        // forward and backward needs to trigger navigation
        // level1
        var normallyActiveElement = $('a.ajax[rel=' + data.L1 + ']').parents('li.active'); // finds nothing in case of forward / backward
        if (normallyActiveElement.length == 0) {
            $('#navMain li.active').removeClass('active').find('a').trigger('mouseout');
            $('a.ajax[rel=' + data.L1 + ']').trigger('mouseenter').closest('li').addClass('active');
        }
        // level2 (the solution for activating the first element is ugly; not variable if element is referenced or not)
        if (data.L2.length > 0) {
            var normallyActiveElement = $('a.ajax[rel=' + data.L2 + ']').parents('li.active'); // finds nothing in case of forward / backward
            if (normallyActiveElement.length == 0) {
                $('.navSub li.active').removeClass('active');
                $('a.ajax[rel=' + data.L1 + '/' + data.L2 + ']').parent('li').addClass('active');
            }
        } else {
            $('.navSub li').removeClass('active');
            $('.navSub li:first').addClass('active');
        }
    }
    
}

// hover-animation of main nav elements
function hoverMainNav(element, event) {

    // simpleConsole('blub');

    var navOnWidth  = $('span.navOn', element).data('originalWidth');
    var navOffWidth = $('span.navOff', element).data('originalWidth');

    if (event == 'mouseenter') {
        // immediatly stop any animation, we need to expand the element
        $('span.navOn', element).stop();
        $('span.navOff', element).stop();
        // expand and reduce elements
        $('span.navOn', element).animate({width: navOnWidth}, 500);
        $('span.navOff', element).animate({left: navOffWidth,width: 0}, 500);
    } else if (event == 'mouseleave') {
        // timeout makes sure the expanding animation goes one for a few more milliseconds
        window.setTimeout(function(){
            // after timeout, stop animation
            $('span.navOn', element).stop();
            $('span.navOff', element).stop();
            // reduce elements to default value
            $('span.navOn', element).animate({width: 0}, 500);
            $('span.navOff', element).animate({left: 0,width: navOffWidth}, 500);
        }, 100);
    }
    
}

// hover-animation of social nav elements
function hoverSocialNav(element, event) {
    if (event == 'mouseenter') {
        // immediatly stop any animation, we need to expand the element
        $(element).stop();
        // move background
        $(element).animate({backgroundPosition: $(element).data('endBackgroundPosition')}, 250);
    } else if (event == 'mouseleave') {
        // timeout makes sure the expanding animation goes one for a few more milliseconds
        window.setTimeout(function(){
            // after timeout, stop animation
            $(element).stop();
            // move background
            $(element).animate({backgroundPosition: $(element).data('startBackgroundPosition')}, 250);
        }, 100);
    }
}

// custom scrollbar
function addScrollbar() {
    
    $('#content').jScrollPane({
            scrollbarWidth: 3,
            dragMinHeight: 20,
            dragMaxHeight: 40,
            topCapHeight: 4,
            bottomCapHeight: 4
        });
    
    // add dashes on top and bottom (only if scrollbar has been placed)
    if ($('.jScrollPaneTrack').length > 0) {

        $('.jScrollPaneTrack').after($('<div class="jScrollPaneTrackTop"></div>').css({
            top: (parseInt($('.jScrollPaneTrack').css('top')) - 3) + 'px'
        }));
        $('.jScrollPaneTrack').after($('<div class="jScrollPaneTrackBottom"></div>').css({
            top: (parseInt($('.jScrollPaneTrack').css('top')) + parseInt($('.jScrollPaneTrack').css('height')) + 3) + 'px'
        }));
        
    }
    
}

// show subnavigation
function showSubnavigation(navElement) {
    var subNavID = 'navSub' + navElement.substr(0, 1).toUpperCase() + navElement.substr(1);
    hideSubNav(subNavID);
    if ($('#' + subNavID + ' li').length > 0) {
        $('#' + subNavID + ' li a').each(function(index){
            $(this).delay((index + 1) * 100).animate({
                textIndent: 0
            }, 300);
        });
    }
}

// hide subnavigatio (via text-indent)
function hideSubNav(activeSubNavID) {
    if (typeof(activeSubNavID) == 'undefined')  activeSubNavID = '_____'
    $('.navSub li a').each(function(){
        // hide only subnavs that are not the current
        if ($(this).parents('#' + activeSubNavID).length == 0) {
            $(this).css('textIndent', '-100px');
        }
    });
}

// start gallery
function startGallery() {


    $('.hiddenOnGallery').fadeOut('slow', function(){
        GndlsVideos.launch(GndlsVideos.slideshow);
        $('.galleryControls').show('slow');
    });


    /*
    // fetch backgrounds
    $.get(
        HTTP + 'gallery/',
        {
            gallery: 'true'
        }, function(data) {

            var $element = $('<ul id="backgroundImages"></ul>');
            
            for(var i = data.length - 1; i >= 0; --i) {
                
                $element.append('<li><a title="" alt="" href="' + IMG + 'backgrounds/' + data[i] + '"></a></li>');

            }
            
            fullscreenBackground.jbgallery("destroy");

            $('#defaultBackground').remove();
            $('#jbgallery-api').append($element);
            $('.hiddenOnGallery').fadeOut('slow', function(){
                $('.galleryControls').show('slow');
            });

            _fullscreenBackground(fullscreenBackground);
            _startBackgroundMusic();
            // start autoplay
            window.setTimeout(function(){
                $('#gCPlayStop').triggerHandler('click');
            }, 4000);

        }, 'json'
        
    );
    */
    
}

// stopGallery
function stopGallery() {
    
    $('#flashContent').html('');

    $('.galleryControls').fadeOut('slow', function(){
        $('.hiddenOnGallery').show('slow');
    });

    /*
    $('#backgroundImages').remove();
    $('#jbgallery-api').append('<ul id="defaultBackground"><li><a title="" alt="" href="' + IMG + 'default_background.jpg"></a></li></ul>');

    $('.galleryControls').fadeOut('slow', function(){
        $('.hiddenOnGallery').show('slow');
    });

    fullscreenBackground.jbgallery("destroy");
    _fullscreenBackground(fullscreenBackground);
    _stopBackgroundMusic();
    */
    
}

/* object for collection */
var GndlsCollection = {
    delayPageTurn: 100,                         // delay of hiding each product when turning the page
    ajaxTarget: HTTP + 'kollektion/',           // target for all ajax requests

    /* initialization wrappers */

    // wrapper for all intializations => call on page load
    init: function() {
        this.initPagination();                      // pagination of collection overview
        this.initMouseover();                       // mouseover of collectin overview
        this.initProductChange();                   // bind link for showing details of one product
        this.initShowCart();                        // bind button for showing the cart
        this.initProductDetailsFunctions();         // bind functions in product details (side-link, retina-zoom and color chooser & add to cart)
        window.setTimeout(function(){
            GndlsCollection.updateCartOverview();   // update cart overview after some time (to prevent problems with xml)
        }, 500);
    },
    // wrapper for collection-specific intializations => call after loading collection
    initCollectionOnly: function() {
        this.initPagination();                      // pagination of collection overview
        this.initMouseover();                       // mouseover of collectin overview
        this.initProductChange();                   // bind link for showing details of one product
        this.initProductDetailsFunctions();         // bind functions in product details (side-link, retina-zoom and color chooser & add to cart)
    },
    // wrapper for functions of product details => call when new details are loaded
    initProductDetailsFunctions: function(){
        this.initChangeSideLink();                  // switch side of image
        this.initRetinaZoom();                      // init retina-zoom of image
        this.initSizeColorChooser();                // init chooser of size and color and add-to-cart-link
    },

    /* product overview */

    // bind page-turning
    initPagination: function() {
        $('#collectionOverviewPagination a').click(function(){
            if (!$(this).hasClass('active')) {
                var pageIndex = parseInt($(this).attr('rel'));
                GndlsCollection.hideCurrentPage();
                GndlsCollection.showNextPage(pageIndex);
                // change class of link to active and remove previous active link
                $('#collectionOverviewPagination a.active').removeClass('active');
                $(this).addClass('active');
            }
            return false;
        });
    },
    // bind hover of previews
    initMouseover: function() {
        
        $('#collectionOverview a').mouseenter(function(){
            $('div.productActive', this).stop(true, true).fadeIn('fast');
        }).mouseleave(function(){
            if (!$(this).hasClass('active')) {
                $('div.productActive', this).stop(true, true).fadeOut('fast');
            }
        });
        
    },
    // bind clicking on preview (changing product)
    initProductChange: function() {
        $('#collectionOverview a').click(function(){
            // only links that are not active
            if (!$(this).hasClass('active')) {
                // remove active class from all other links
                $('#collectionOverview a.active').each(function(){
                    $(this).removeClass('active');
                    $('div.productActive', this).fadeOut('fast');
                });
                $(this).addClass('active');
                // trigger google analytics (prevent errors)
                try { _gaq.push(['_trackPageview', 'product: ' + $(this).attr('rel')])} catch (e) {}
                GndlsCollection.changeProduct($(this).attr('rel'));
                // I'm not changing hashes here; this would trigger normal hashchange-event and result in double loading; deep links are not so important here and search-engines get it anyway
            }
            return false;
        });
    },
    // bind backside-link
    initChangeSideLink: function() {
        $('#productLinkChangeSide a').click(function(){
            var newImage = $('#productImageHolder img:hidden').attr('src');
            // swap images
            $('#productImageHolder img:visible').fadeOut('slow');
            $('#productImageHolder img:hidden').fadeIn('slow');
            // change image of retinaZoom
            $('#retina').css('backgroundImage', 'url(' + newImage + ')');
            // change caption of link
            $('#productLinkChangeSide a span:visible').fadeOut('fast', function(){
                $('#productLinkChangeSide a span:hidden').not(this).fadeIn('fast');
            });
            return false;
        });
    },
    // show next page
    showNextPage: function(pageIndex) {

        // first hide all products in next page
        $('#collectionOverview > li:eq(' + pageIndex + ') ul li').hide();
        // then display page
        $('#collectionOverview > li:eq(' + pageIndex + ')').show(function(){
            $('ul li', this).each(function(i){
                var delayFadeIn = (GndlsCollection.delayPageTurn * 2) + (GndlsCollection.delayPageTurn * (i + 1));
                $(this).delay(delayFadeIn).fadeIn('slow');
                if ($('a', this).hasClass('active')) {
                    $('div.productActive', this).delay(delayFadeIn).fadeIn('slow');
                }
                if ($('a', this).hasClass('soldOut')) {
                    $('div.productSoldOut', this).delay(delayFadeIn).fadeIn('slow');
                }
            });
        });
        
    },
    // hide current page of pagination (with more distinguished animation)
    hideCurrentPage: function() {
        
        var finishCount     = $('#collectionOverview > li:visible ul li').length;           // when 0 start fading in
        var delayCount      = 1;                                                            // used for incremental delay
        
        $('#collectionOverview > li:visible ul li a img').each(function(){
            // fade out with incremental offset
            var delayFadeOut = GndlsCollection.delayPageTurn * delayCount;
            delayCount++; // increase delay of next image
            // fade out overlay
            $(this).parent().find('div').delay(delayFadeOut).fadeOut('slow');
            // fade out image
            $(this).delay(delayFadeOut).fadeOut('slow', function(){
                // finishCount--;
                if (--finishCount == 0) {
                    // hide old page completely (instead of just hiding the images)
                    $(this).closest('ul').parent().hide(function(){
                        // show images inside lis again
                        $(this).find('img:hidden').show();                        
                    });
                }
            });
        });
        
    },
    // change product-details
    changeProduct: function(rel) {
        // get hash without the '#'
        newHash = rel.substring(1);
        // show loading-div
        $('#collectionDetailsLoading').fadeIn('slow', function(){
            // make request
            $.get(
                HTTP + newHash + '/',
                {
                    type: 'ajaxSingleProduct' // tell controller to use the ajax-template for a single product
                }, function(data) {
                    // insert data (simple overwrite) & hide hidden elements 
                    $('#collectionDetailsHolder').show().html(data.newContent).find('.hidden').hide();
                    // initialize functions of details
                    GndlsCollection.initProductDetailsFunctions();
                    // hide loader again
                    $('#collectionDetailsLoading').fadeOut('slow');
                }, 'json'
            );
        });
    },

    /* product details */

    // bind retina zoom for image (credits: http://tutorialzine.com/2010/06/apple-like-retina-effect-jquery-css/)
    initRetinaZoom: function() {
        if ($('#productImageHolder').length == 1) {
            // the variables
        	var left	            = 0,
        		top		            = 0,
        		sizes	            = { retina: { width: 160, height: 160 }, productImageHolder:{ width: 237, height: 217 } },
        		productImageHolder	= $('#productImageHolder'),
        		offset	            = { left: productImageHolder.offset().left, top: productImageHolder.offset().top },
        		retina	            = $('#retina');
            // binding the events
        	productImageHolder.mousemove(function(e){
                // mouse-position
        		left = (e.pageX-offset.left);
        		top = (e.pageY-offset.top);
                // Fixes a bug where the retina div is not shown
        		if (retina.is(':not(:animated):hidden'))        productImageHolder.trigger('mouseenter');
                // if we are out of the bondaries of the productImageHolder screenshot, hide the retina div
        		if (left < 0 || top < 0 || left > sizes.productImageHolder.width || top > sizes.productImageHolder.height) {
        			if(!retina.is(':animated'))         productImageHolder.trigger('mouseleave');
        			return false;
        		}
                // position of retina and offset of background
        		var retinaLeft          = left - sizes.retina.width/2;                      // position of retina is: half width / height of retina further to the left / top from mouse position
        		var retinaTop           = top - sizes.retina.height/2;
        		var backgroundLeft      = 3.66 * left * -1;                                 // what are the 3.66? => mouse position runs from 0 to 237; background-offset has to range vom 0 to 868 (with - half rentina) in the same time => 868 / 237
        		var backgroundTop       = (top * -3.6313) + (40 - (top * 0.184332));        // see above, but start 40px further up, which are incrementally decreased as mouse moves down
        		// setting the css
        		retina.css({
        			left				: retinaLeft,
        			top					: retinaTop,
        			backgroundPosition	: backgroundLeft +'px ' + backgroundTop + 'px'
        		});
        	}).mouseleave(function(){
                retina.stop(true,true).fadeOut('fast');
        	}).mouseenter(function(){
                retina.stop(true,true).fadeIn('fast');
        	});
        }
    },
    // initialize the size and color choosers
    initSizeColorChooser: function() {
        /* choose size */
        $('#productSizes a').click(function(){
            var size = $(this).attr('rel');
            var sizeName = $(this).attr('id');
            // hide other indicators and color lists
            $('#productSizes a.chosen').removeClass('chosen').find('span.chosenIndicator').hide();
            $('#chooseSizeFirst').hide();
            $('ul.productColors').not('#size_' + size).hide();
            // update summary
            GndlsCollection.updateChosenSize(sizeName, size)
            GndlsCollection.updateChosenColor('', '');
            // show this indicator and color-list
            $(this).addClass('chosen').find('span.chosenIndicator').show();
            $('ul#size_' + size).show(function(){
                // pre-choose color if there only is one
                var colorCount = $(this).find('a').length;
                if (colorCount == 1) {
                    $(this).find('a:first').triggerHandler('click');
                }
            }).find('a.chosen').removeClass('chosen').find('span.chosenIndicator').hide();
            return false;
        });
        /* choose color */
        $('.productColors a').click(function(){
            var colorValue = $(this).attr('rel');
            var colorName = $(this).text();
            // hide ofther indicators
            $('.productColors:visible a.chosen').removeClass('chosen').find('span.chosenIndicator').hide();
            // add chose indicator
            $(this).addClass('chosen').find('span.chosenIndicator').show();
            // update summary
            GndlsCollection.updateChosenColor(colorName, colorValue);
            return false;
        });
        /* submit form */
        $("#chosenProductSubmit").click(function(event){
            GndlsCollection.addToCart();
            return false;
        });    
    },
    // update the summary with the chosen size
    updateChosenSize: function(sizeName, size) {
        $('#noneChosen:visible').hide();
        $('#chosenSize').html(sizeName);
        $('#sizeID').attr('value', size);
    },
    // update the summary with the chosen color
    updateChosenColor: function(colorName, colorValue) {
        $('#noneChosen:visible').hide();
        // add comma if there was a value (instead of deleting)
        if (colorName.length > 0)   displayName = ', ' + colorName;
        else                        displayName = '';
        // change values
        $('#chosenColor').html(displayName);
        $('#colorID').attr('value', colorValue);
    },
    // add product to cart
    addToCart: function() {
        var productID   = $('#productIDID').attr('value'),
            size        = $('#sizeID').attr('value'),
            color       = $('#colorID').attr('value');
        if (productID.length == 0 || size.length == 0 || color.length == 0) {
            GndlsCollection.displayMessage('.errorDisplay', 'Bitte wähle zuerst eine Größe und dann eine Farbe aus.');
            return false;
        }
    	$.post(
            GndlsCollection.ajaxTarget,
            {
    			addToCart: "true",
    			productID: productID,
    			size: size,
    			color: color
    	    },
        	function(data){
                // show error or output content
                if (data.result == 'error') {
                    GndlsCollection.displayMessage(data.message);
                } else {
                    GndlsCollection.updateCartOverview(true);
                }
            }, "json"
        );
        
    },

    /* display / update cart or cartOverview */

    // update the cart overview (just price and quantity)
    updateCartOverview: function(highlight) {
        if (highlight == true) {
            var original = $('#cartOverviewLeft').css('backgroundColor');
            var to = $('#toCart').css('backgroundColor');
            // prevent multiple highlights
            if (!$('#cartOverviewLeft').is(':animated')) {
                $('#cartOverviewLeft').pulse({
                    backgroundColor: ['#FF491F', '#000000']
                }, 1000, 1);
            }
        }
    	$.get(
            GndlsCollection.ajaxTarget,
            {
    			cartOverview: "true"
    	    },
        	function(data){
                // show error or output content
                if (data.result == 'error') {
                    $('#cartOverviewCount, #cartOverviewSum').html('Fehler!');
                } else {
                    $('#cartOverviewCount').html(data.count);
                    $('#cartOverviewSum').html(data.sum);
                }
            }, "json"
        );
    },

    /* cart-functions */

    // bind show cart-content
    initShowCart: function() {
        $('#toCart').click(function(){
            // do nothing if cart is already displayed
            if ($('#cartWrapper').is(':visible'))    return false;
            GndlsCart.hideEverythingButCart(function(){
                GndlsCart.showCart();
            });
            return false;
        });
    },

    /* helpers */

    // explode parameters of function-buttons in cart
    explodeParameters: function($eventTarget) {
        
        return $eventTarget.attr('rel').split(',');
        
    },
    // same as gnadenlosShowCurrency() in PHP-helpers
    formatCurrency: function(number) {
        return 'EUR ' + number_format(number, 2, ',', '.');
    },
    // display message (show element, add text, fade out after a while)
    displayMessage: function(selector, message) {
        $error = $(selector)
        $error.html(message);
        if ($error.is(':hidden')) {
            $error.slideDown();
        }
        window.setTimeout(function(){
            $error.slideUp();
        }, 7000);
    }

}

var GndlsCart = {
    ajaxTarget: HTTP + 'kollektion/',           // target for all ajax requests
    stepCSSValues: { open: { width: 237, padding: 31 }, closed: { width: 31, padding: 19 } },
    // wrapper for initializing the final display of cart and its functions: increase, decrease, delete => call this after the cart-steps are requested via ajax
    initCartSteps: function() {
        this.initDeleteProduct();                   // delete complete product from listing
        this.initIncreaseQuantity();                // add "one" to quantity
        this.initDecreaseQuantity();                // subtract "one" to quantity, delete if only one there
        this.initStepBackButtons();                 // init buttons to go back one or two steps
        this.initPaymentButtons();                  // binds the function (mirror value to step three) to buttons for payment methods
        this.initProceedButtonOne();                // check payment and move to next step
        this.initFormMirroring();                   // mirror address to step 3
        this.initProceedButtonTwo();                // check address and move to step three
        this.initChangeButtons('#cartSummary');     // init change-buttons on summary (in hole summary, instead of just the listings-summary when this gets updated)
        this.initFinalPurchase();                   // init the final "bestellung abschicken"-button
    },

    /* display cart / cart-overview */

    // hide content and collection-content
    hideEverythingButCart: function(f) {
        // deactivate navigation
        $('#navMain li.active').removeClass('active').find('a').trigger('mouseout');
        hideSubNav();
        // hide everything
        var count = $('#contentHolder, #collectionWrapper').length;
        $('#contentHolder, #collectionWrapper').fadeOut('fast', function(){
            // callback after last fadeOut
            if (!--count) {
                if (typeof f == "function")     f();  
            }
        });
    },
    // show cart wrapper (and step one)
    showCart: function() {
        // clear flash
        $('#flashContent').html('');
        // remove all styles of steps (in case the were shown previously)
        $('.cartStep').removeAttr('style');
        $('.cartStep, #cartThankYou').not('#cartListings').hide();
        // empty cart listings
        $('#cartListings').html('');
        $('#cartWrapper').fadeIn('slow', function(){
            // trigger google analytics (prevent errors)
            try { _gaq.push(['_trackPageview', 'showCart'])} catch (e) {}
            GndlsCart.showCartListings();
        });
    },
    // show the listing of the cart (with 'choose payment'-segment)
    showCartListings: function() {
        $.get(
            GndlsCart.ajaxTarget,
            {
                cartListings: 'true'
            },
            function(data){
                if (data.match(/<body>/gi) == null) {
                    $('#cartListings').html(data).find('.hidden').hide();
                    // bind functions to buttons
                    GndlsCart.initCartSteps();
                    // add pretty radio buttons
                    $('input:radio').uniform();
                }
            }, "text"
        );
    },
    // get listing for summary
    showCartListingsSummary: function() {
        $.get(
            GndlsCart.ajaxTarget,
            {
                cartListings: 'true',
                summary: 'true'
            },
            function(data){
                if (data.match(/<body>/gi) == null) {
                    $('#cartSummaryListings').html(data);
                    // bind "change"-event to the button in summary listing
                    GndlsCart.initChangeButtons('#cartSummaryListings');                    
                }
            }, "text"
        );
    },

    /* update cart */

    // update summary (total price) of detailed cart-listing (or delete cart-display if it's empty)
    updateCartListingsSummary: function(data) {
        // cart is empty: remove cart-display and show message
        if (data.listingsArray == false) {
            $('#cartListings *').not('#cartEmpty').remove();
            $('#cartEmpty').show();
        }
        // update summary
        else {
            $('#cartListings .totalPrice').html(GndlsCollection.formatCurrency(data.listingsArray.totalPrice));
            $('#cartListings .shipping').html(GndlsCollection.formatCurrency(data.listingsArray.shipping));
            $('#cartListings .totalPriceWithShipping').html(GndlsCollection.formatCurrency(data.listingsArray.totalPriceWithShipping));
        }
    },
    // update singe listing (single product) in cart
    updateSingleListing: function($eventTarget, data) {
        $eventTarget.closest('tr').find('.productQuantity').html(data.quantity);
        $eventTarget.closest('tr').find('.productSum').html(GndlsCollection.formatCurrency(data.sum));
    },

    /* general functions */
    
    // bind function to 'stepBack'-buttons
    initStepBackButtons: function() {
        $('.cartStepBack').click(function(){
            var index = $('.cartStepBack').index($(this));
            GndlsCart.goToStep(index);
            return false;
        });
    },
    // change displayed step (show next)
    finishStep: function(index, f) {
        // find current step
        $currentStep = $('.cartStep:eq(' + index +')');
        // fadeOut content (except for 'back'-button)
        var count = $currentStep.find('*').not('.cartStepBack').length;
        $currentStep.find('*').not('.cartStepBack').fadeOut(function(){
            // after all finished close step and display back
            if (!--count) {
                $currentStep.animate({
                    width: GndlsCart.stepCSSValues.closed.width,
                    paddingLeft: GndlsCart.stepCSSValues.closed.padding,
                    paddingRight: GndlsCart.stepCSSValues.closed.padding
                }, function(){
                    // show 'back'-button
                    $currentStep.find('.cartStepBack').fadeIn();
                    // hide back-button and hidden elements in next step
                    $('.cartStep:eq(' + (index + 1) + ') .cartStepBack, .cartStep:eq(' + (index + 1) + ') .hidden').hide();
                    // show next step
                    $('.cartStep:eq(' + (index + 1) + ')').fadeIn(function(){
                        // show everything except for back-button
                        $(this).find('*').not('.cartStepBack, .hidden').fadeIn();
                        // do callback
                        if (typeof f == "function")     f();  
                    });
                });
            }
        });
    },
    // go to specific step and hide all others (function is attached to back-buttons)
    goToStep: function(index) {
        count = $('.cartStep:gt(' + index + ')').length;
        // hide all following steps
        $('.cartStep:gt(' + index + ')').fadeOut(function(){
            // resize to original width and show content except normally hidden elements
            $(this).css({
                width: GndlsCart.stepCSSValues.open.width,
                paddingLeft: GndlsCart.stepCSSValues.open.padding,
                paddingRight: GndlsCart.stepCSSValues.open.padding
            }).find(':hidden').not('.hidden').show().closest('.cartStep').find('.hidden').hide();
            // proceed after all are hidden
            if (!--count) {
                // hide back-button
                $('.cartStep:eq(' + index + ')').find('.cartStepBack').fadeOut(function(){
                    // resize target step
                    $(this).closest('.cartStep').animate({
                        width: GndlsCart.stepCSSValues.open.width,
                        paddingLeft: GndlsCart.stepCSSValues.open.padding,
                        paddingRight: GndlsCart.stepCSSValues.open.padding
                    }, function(){
                        // show everything except for back-button
                        $(this).find('*').not('.cartStepBack, .hidden').fadeIn();
                    });
                });
            }
        })
    },

    /* functions of cart-listing (step 1) */

    // bind delete function to buttons
    initDeleteProduct: function() {
        $('a.deleteProduct').click(function(event){
            Confirm.inline('#cartListings .errorDisplay', 'Willst du das Produkt wirklich aus dem Warenkorb entfernen?', function(){
                // save target
                var $eventTarget = $(event.target);
                // explode parameters
                var parameters = GndlsCollection.explodeParameters($eventTarget);
                // send post
                $.post(
                    GndlsCollection.ajaxTarget,
                    {
                        deleteProduct: 'true',
                        productID: parameters[0],
                        size: parameters[1],
                        color: parameters[2]
                    },
                    function(data){
                        if (data.result == 'error') {
                            GndlsCollection.displayMessage('#cartListings .errorDisplay', data.message);
                        } else {
                            $eventTarget.closest('tr').remove();
                            GndlsCollection.updateCartOverview();
                            GndlsCart.updateCartListingsSummary(data);
                        }
                    }, "json"
                );
            });
            return false;
        });
    },
    // bind increase quantity-function to buttons
    initIncreaseQuantity: function() {
        $('a.increaseQuantity').click(function(event){
            // save target
            var $eventTarget = $(event.target);
            // explode parameters
            var parameters = GndlsCollection.explodeParameters($eventTarget);
            // send post
            $.post(
                GndlsCollection.ajaxTarget,
                {
                    increaseQuantity: 'true',
                    productID: parameters[0],
                    size: parameters[1],
                    color: parameters[2]
                },
                function(data){
                    if (data.result == 'error') {
                        GndlsCollection.displayMessage('#cartListings .errorDisplay', data.message);
                    } else {
                        GndlsCart.updateSingleListing($eventTarget, data.updatedListing);
                        GndlsCollection.updateCartOverview();
                        GndlsCart.updateCartListingsSummary(data);
                    }
                }, "json"
            );
            return false;
        });
    },
    // bind decrease quantity-function to buttons
    initDecreaseQuantity: function() {
        $('a.decreaseQuantity').click(function(event){
            // save target
            var $eventTarget = $(event.target);
            // only one left? => trigger delete
            if (parseInt($eventTarget.closest('tr').find('.productQuantity').html()) == 1){
                $eventTarget.closest('tr').find('.deleteProduct').triggerHandler('click');
                // stop processing
                return false;
            }
            // explode parameters
            var parameters = GndlsCollection.explodeParameters($eventTarget);
            // send post
            $.post(
                GndlsCollection.ajaxTarget,
                {
                    decreaseQuantity: 'true',
                    productID: parameters[0],
                    size: parameters[1],
                    color: parameters[2]
                },
                function(data){
                    if (data.result == 'error') {
                        GndlsCollection.displayMessage('#cartListings .errorDisplay', data.message);
                    } else {
                        GndlsCart.updateSingleListing($eventTarget, data.updatedListing);
                        GndlsCollection.updateCartOverview();
                        GndlsCart.updateCartListingsSummary(data);
                    }
                }, "json"
            );
            return false;
        });
    },
    // bind payment-button
    initPaymentButtons: function() {
        $('#paymentMethodForm input[type="radio"]').change(function(){
            if ($('input[value="prePayment"]').is(':checked')) {
                $('#paymentMethod').html('per Vorkasse');
            } else {
                $('#paymentMethod').html('mit PayPal');
            }
        });
    },
    // bind proceed-button
    initProceedButtonOne: function() {
        $('#cartStepOneProceed').click(function(){
            if (!GndlsCart.checkPayment()) {
                GndlsCollection.displayMessage('#cartListings .errorDisplay', 'Bitte wähle eine Zahlungsart aus.');
                return false;
            }
            GndlsCart.finishStep(0, function(){
                // set focus to first input field of form
                $('#cartAddressForm input:first').focus();
            });
            return false;
        });
    },
    // check if one of the paymentButtons is checked
    checkPayment: function() {
        return $('#paymentMethodForm input[type="radio"]:checked').length == 1;
    },
    
    /* functions of address (step 2) */
    
    // init button of second step (address) & check form before proceed
    initProceedButtonTwo: function() {
        // disable normal messages
        jQuery.validator.messages.required = "";
        jQuery.validator.messages.email = "";
        // initialize validation
        $('#cartAddressForm').validate({meta: 'validate'});
        // bind proceeding
        $('#cartStepTwoProceed').unbind('click').click(function(){
            // form is not valid
            if (!$('#cartAddressForm').valid()) {
                // eMail wrong or omitted field?
                if (!$('#eMail').valid())       var message = 'Bitte gib eine gültige eMail-Adresse an.';
                else                            var message = 'Bitte fülle alle Felder aus.';
                // display message
                GndlsCollection.displayMessage('#cartAddress .errorDisplay', message);
                // just for safety
                return false;
            }
            GndlsCart.finishStep(1);
            // update cart-display
            GndlsCart.showCartListingsSummary();
            return false;
        });
    },
    // mirror address form to summary
    initFormMirroring: function() {
        $('#cartAddressForm input').keyup(function(){
            $('#target' + ucfirst($(this).attr('id'))).html($(this).attr('value').toLowerCase());
        });
    },

    /* functions of summary (step 3) */

    // bind buy-button – THIS IS THE PURCHASE
    initFinalPurchase: function() {
        $('#cartStepThreeProceed').click(function(){
            // check approval of consents
            if (!GndlsCart.checkConsents()) {
                GndlsCollection.displayMessage('#cartSummary .errorDisplay', 'Bitte bestätige unsere Bedingungen.');
                return false;
            }
            // serialize the two needed forms (address and payment)
            var serializedPurchase = $('#cartAddressForm').serialize() + '&' + $('#paymentMethodForm').serialize();
            // send post
            $.post(
                GndlsCollection.ajaxTarget,
                serializedPurchase,
                function(data){
                    if (data.result == 'error') {
                        GndlsCollection.displayMessage('#cartSummary .errorDisplay', data.message);
                    } else {
                        // url? => paypal
                        if (typeof(data.returnValue) != 'undefined' && data.returnValue != null && data.returnValue.length > 7) {
                            window.location.href = data.returnValue;
                        } else {
                            GndlsCollection.updateCartOverview();
                            GndlsCart.thankYou();
                        }
                    }
                }, "json"
            );
            return false;
        });
    },
    // bind change-buttons
    initChangeButtons: function(el) {
        $('.cartChangeButton', el).click(function(){
            var index = parseInt($(this).attr('rel'));
            GndlsCart.goToStep(index);
            return false;
        });
    },
    // check consents
    checkConsents: function() {
        return $('#consentsForm input[type="checkbox"]').length == $('#consentsForm input:checked').length;
    },
    // display thank you-message
    thankYou: function() {
        // hide all steps
        var selector = '.cartStep';
        count = $(selector).length;
        $(selector).fadeOut(function(){
            // show thank you-note
            if (!--count) {
                $('#cartThankYou').fadeIn('slow');
                GndlsVideos.launch(GndlsVideos.kiss);
            }
        });        
    }
    
}

var fullscreenBackground;

// __endExclude

// jQuery Ready-Handler
$(function() {

    fullscreenBackground = $('#jbgallery-api');

    /* __startExclude */

    $('#galleryControl a').click(function(event){
       event.preventDefault(); 
    });

    // control gallery and sound
    $('#gCNext').click(function(){fullscreenBackground.jbgallery('right');});
    $('#gCPrevious').click(function(){fullscreenBackground.jbgallery('left');});
    $('#gCPrevious').click(function(){fullscreenBackground.jbgallery('left');});
    $('#gCPlayStop').click(function(){
        if ($(this).hasClass('stopped')) {
            fullscreenBackground.jbgallery('stop');
            $(this).removeClass('stopped');
        } else {
            fullscreenBackground.jbgallery('play', 2000);
            $(this).addClass('stopped');
        }
    });
    $('#gCMusicOnOff').click(function(){
        if ($(this).hasClass('paused')) {
            $('#jPlayer').jPlayer('play');
            $(this).removeClass('paused');
        } else {
            $('#jPlayer').jPlayer('pause');
            $(this).addClass('paused');
        }
    });
    
    // start fullscreen background
    _fullscreenBackground(fullscreenBackground);

    /* navigation                                                                                           */
    _setupNavigation();

    // adjust height of content
    $('#contentHolder').css({
       height: $(window).height() * 0.75 
    });

    /* scrollbar                                                                                            */
    addScrollbar();
    
    /* hash-based navigation                                                                                */
    _manageHashes();
    _ajaxifyLinks();
    
    /* start / stop gallery                                                                                 */
    $('#startGallery').live('click', function(event){
        event.preventDefault();
        startGallery();
    });
    $('#gCClose').click(function(event){
        event.preventDefault();
        stopGallery();
    });
    /* show/hide collection                                                                                 */
    $('#collectionClose').live('click', function(event){
        event.preventDefault();
        $('#collectionDetailsHolder').fadeOut('slow');
    });

    /* initialize collection */
    GndlsCollection.init();                         // bind functions to collection

    /* __endExclude */

});

