/* global $ */

/*===========================================================================*/
//
// This is the main JavaScript entry point of the jazzunique website
//

/*
If you want to keep the CSS :hover effect for when JavaScript is not available but remove it when it is available, you could add a class to the body element (or any other element that contains all the hovered items), then declare your :hover rules like this:

body.noJS img:hover { // apply CSS hover effect // }

Then, at the start of your JavaScript simply remove the 'noJS' class, which will disable the basic CSS :hover effect. Then apply the fancy hover effect as described by JohnRiv above.
*/

$.fn.reorder = function() {
    // http://blog.rebeccamurphey.com/2007/12/11/jquery-plugin-randomly-reorder-children-elements/

    // random array sort from
    // http://javascript.about.com/library/blsort2.htm
    function randOrd() { return(Math.round(Math.random())-0.5); }

    return($(this).each(function() {
        var $this = $(this);
        var $children = $this.children();
        var childCount = $children.length;
        if (childCount > 1) {
            $children.remove();
            var indices = new Array();
            for (i=0; i<childCount; i++) { indices[indices.length] = i; }
            indices = indices.sort(randOrd);
            $.each(indices,function(j, k) { $this.append($children.eq(k)); });
        }
    }));
}

$(document).ready(function() {
    jQuery.fn.extend({
        anchorOverlay: function(options) {
            function initOverlay($origAnchor) {
                if (options.speed === undefined) { options.speed = 250; }
                if (options.hoverOver === undefined) { options.hoverOver = function () { }; }
                if (options.hoverOut === undefined) { options.hoverOut = function () { }; }

                $origAnchor.wrap("<div>");
                $origAnchor.parent("div").addClass("ui-anchor-overlay-wrapper")
                                            .prepend("<a></a>");
                var $proxyAnchor = $origAnchor.parent("div").find("a").eq(0);
                $proxyAnchor.addClass("ui-anchor-overlay-proxy")
                            .addClass( $origAnchor.attr("class"))
                            .attr("href", $origAnchor.attr("href"))
                            .attr("title", $origAnchor.attr("title"))
                            .width( $origAnchor.width() )
                            .height( $origAnchor.height() )
                            .click( function() {
                                // Pass the click to the original link
                                $origAnchor.click();
                                return false;
                            })
                            .hover(options.hoverOver, options.hoverOut);
            }

            if ($(this).length > 1) {
                $(this).each( function(i) {
                    // Wrap the anchor with a div
                    initOverlay( $(this) );
                });
            }
            else {
                initOverlay($(this));
            }
        }

        /* Adjusts *ALL* anchors in the page to use the ``pageLoaderClick``
           handler on ``click`` events. The handler is unbound first to
           prevent any doubled events.
         */
        /*
        ajaxifyAnchors: function(pageLoader) {

            function pageLoaderClick(event) {
                // Load the url through the PageLoader
                pageLoader.load( $(this).attr("href") );
                // Prevent default anchor behaviour
                return false;
            }

            function doAjaxifyAnchor($anchor) {
                $anchor
                    .unbind( "click", pageLoaderClick )
                    .bind( "click", pageLoaderClick );
            }

            if ($(this).length > 1) {
                $(this).each( function(i) {
                    doAjaxifyAnchor( $(this) );
                });
            }
            else {
                doAjaxifyAnchor($(this));
            }
        }
        */
    });

    $('.toggle-next').parent().next().hide();
    $('.toggle-next').click(function() {
        $(this).parent().next().slideToggle('fast');
        return false;
    });

    // ------------------------------------------------------------------------
    // JazzuniqueSite class (singleton)
    // ------------------------------------------------------------------------
    function JazzuniqueSite() {
        var this_site = this;
        var hashCnt = 0;
        var $navOverlay = null;

        this.isIE6 = function() {
            if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) === 6) {
                return true;
            } else {
                return false;
            }
        };

        this.pageLoader = new PageLoader({
            pageUrl: document.location.href,
            pageLoaded: function(pageUrl, htmlData, pageClass, bodyClass) {
                this_site.updateNavigation(pageUrl);

                if (pageClass === "pageclass-flatpage" || pageClass === "pageclass-listpage"
                    || pageClass === "pageclass-frontpage" || pageClass === "pageclass-archive") {

                    var $content = $(htmlData).find("#content");
                    $("#content").slideUp("normal", function() {
                        // Set the bodyclass of the page to the new page's class.
                        $("body").attr("class", bodyClass);

                        // Hide the to-be-inserted content
                        $content.hide();
                        // Replace the old with the new content
                        $(this).replaceWith( $content );
                        // and slide down the new content in place
                        if ( $("#content").text().length > 0 ) {
                            $("#content").slideDown("normal", function() {
                                // Class specific actions
                                if (pageClass === "pageclass-listpage") {
                                    //this_site.initContentList();
                                    this_site.initContentListScroller();
                                    this_site.initImageListscroller();
                                    this_site.initListHover();
                                }
                                if (pageClass === "pageclass-archive") {
                                    this_site.initListHover();
                                    this_site.initArchiveContentList();
                                }
                                if (pageClass === "pageclass-frontpage") {
                                    this_site.initFrontpage();
                                }

                                // Page specific actions
                                this_site.initNewsletterForm();
                            });
                        }
                    });
                    this_site.updatePageTitle(htmlData);
                }
            }
        });

        // ----------------------- Priviliged functions ----------------------

        this.init = function() {
            this.initNavigation();
            //this.initContentList();
            this.initContentListScroller();
            this.initImageListscroller();
            this.initListHover();
            //this.initAjaxLoader();
            this.initFrontpage();
            this.initMembersDetailPage();

            this.initNewsletterForm();
        };

        this.initNavigation = function () {
            // Add glow effect to navigation anchors
            $("#nav ul li a").not(".nav-current").hover(
                function () {
                    $(this).animate( { color: "#DC0169" }, 250);
                },
                function () {
                    $(this).animate( { color: "white" }, 150);
                }
            );
        };

        /* Updates the navigation bar to reflect the location of the given
           ``permalink``.
         */
        this.updateNavigation = function(permalink) {
            this.updateNavigationCurrent(permalink);

            // Update the permalink
            $("#page-permalink a").attr("href", permalink);

        };

        this.updatePageTitle = function (htmlData) {
            // Update the page title. Unfortunately it is not possible
            // to select elements in the <head> of the returned data
            // using jQuery. So we have to use plain regex here.
            var pageTitleRe = /<title>(.*)<\/title>/;
            var pageTitleResult = pageTitleRe.exec(htmlData);

            if (pageTitleResult.length === 2) { document.title = pageTitleResult[1]; }
        };

        /* Searches the menu entry identified by the given ``permalink`` and
           makes it the selected entry.

           If the given ``permalink`` does not have a direct match in the
           navigation, the last component of the ``permalink`` is stripped
           away and the search is repeated. This procedure is called
           recursively until a match is found or the ``permalink`` was
           finally stripped to the root "/" url.
         */
        this.updateNavigationCurrent = function(permalink) {
            // Find the nav anchor that matches or starts with the given
            // permalink.
            var $anchor = $("#nav a[href=" + permalink + "]");

            if ($anchor.length === 1) {
                $("#nav .nav-current").removeClass("nav-current");
                $anchor.addClass("nav-current")
                    .parents("ul").slideDown()
                        .prev("div").find("a").addClass("nav-current");
            }
            else if ($anchor.length === 0 && permalink !== "/") {
               // Strip the last component and try again
               var lastSlashIndex = permalink.lastIndexOf("/");
               if (lastSlashIndex === permalink.length-1) {
                    // Slash is the last character.. strip it and search again
                    lastSlashIndex = permalink.lastIndexOf("/", lastSlashIndex-1);
               }
               if (lastSlashIndex !== -1 ) {
                   var new_permalink = permalink.substring(0, lastSlashIndex+1);
                   this_site.updateNavigationCurrent(new_permalink);
               }
            }
            else if ($anchor.length >= 1) {
                var $filteredAnchors = $anchor.not(".ui-anchor-overlay-proxy");
                if ($filteredAnchors.length === 1) {
                    $("#nav .nav-current").removeClass("nav-current");
                    $filteredAnchors.addClass("nav-current")
                           .parents("ul").slideDown()
                                .prev("div").find("a").addClass("nav-current");

                }
                else {
                    // There really are two entries with the same URL!
                    // This only happens with first level entries which default
                    // to their first child... so make both current
                    $("#nav .nav-current").removeClass("nav-current");
                    $filteredAnchors.addClass("nav-current")
                           .parents("ul").slideDown()
                                .prev("div").find("a").addClass("nav-current");
                }
            }
        };

        /*
        this.initAjaxLoader = function() {
            $("#ajaxloader").ajaxStart(function(){
                this_site.$navOverlay
                    .width( $("body").width() )
                    .height( $("body").height() )
                    .show();
                $(this).fadeIn();
            });
            $("#ajaxloader").ajaxStop(function(){
                $(this).fadeOut();
                this_site.$navOverlay.hide();
            });
        };
        */

        this.initContentListScroller = function() {
            if ($("body").hasClass("frontpage")) { return; }

            var height = 549;
//             if ($("body").hasClass("newspage")) { height = 596;}
//             else if ($("body").hasClass("archivepage")) { height = 489;}
//             else { height = 549; }

            if ( $("body").hasClass("archivepage") ) {
                $("ul.contentlist li").each(function(idx, e) {
                    if((idx + 1) % 5 == 0) {
                        $(e).addClass('content-last-in-row');
                    }
                });
                /*
                var itemCount = $("ul.contentlist li").length;
                if (itemCount > 24 ) {
                    $("ul.contentlist").jcarousel({
                        vertical: true,
                        scroll: 1,
                        animation: 300,
                        easing: "easeInOutQuart",
                        size: Math.ceil(itemCount/4),
                        buttonNextHTML: '<a ><span></span></a>',
                        buttonPrevHTML: '<a ><span></span></a>',
                        initCallback: function (carousel, state) {
                            carousel.container.css("height", "auto");
                            carousel.clip.css("height", "auto");
                            carousel.buttonPrev.hide().slideDown("fast");
                            carousel.buttonNext.hide().slideDown("fast");
                            carousel.clip.animate({height: height}, 400);
                            carousel.container.animate({height: height}, 400);
                            carousel.container.css("height", height);
                            carousel.clip.css("height", height);
                        }
                    });
                }*/
            }
            else {
                if(($("body").hasClass("designpage") ||
                    $("body").hasClass("newspage")) &&
                    $(".contentlist li").length > 6) {
                    var qFirst = $.query.get('first');
                    //console.log(qFirst);

                    // Determinate current element carousel position
                    var curPos = 1;
                    $(".contentlist li a").each(function(i) {
                        if ($(this).attr("href") == window.location.pathname) {
                            curPos = i + 1;
                        }
                        return;
                    });

                    // Determinate carousel start position
                    var startPos = qFirst || curPos;
                    //console.log('startPos: ' + startPos);

                    $("ul.contentlist").jcarousel({
                        start: startPos,
                        vertical: true,
                        scroll: 1,
                        animation: 300,
                        easing: "easeInOutQuart",
                        buttonNextHTML: '<a ><span></span></a>',
                        buttonPrevHTML: '<a ><span></span></a>',
                        initCallback: function (carousel, state) {
                            carousel.container.css("height", "auto");
                            carousel.clip.css("height", "auto");
                            carousel.buttonPrev.hide().slideDown("fast");
                            carousel.buttonNext.hide().slideDown("fast");
                            carousel.clip.animate({height: height}, 495);
                            carousel.container.animate({height: height}, 495);
                            carousel.container.css("height", height);
                            carousel.clip.css("height", height);

                            $("ul.contentlist").mousewheel(function(event, delta) {
                                if (delta > 0) {
                                    carousel.prev();
                                    return false;
                                }
                                else if (delta < 0) {
                                    carousel.next();
                                    return false;
                                }
                            });
                        },
                        itemFirstInCallback: function(carousel, item, idx, state) {
                            //console.log('Item #' + idx + ' is now the first item');
                            // Pass current first visible carousel item to query
                            // string to restore the carousel's state
                            $(".contentlist li a").each(function(i) {
                                $(this).attr("href", $(this).attr("href").split('?')[0] + $.query.set("first", idx).toString());
                            });
                        }/*,
                        itemLastInCallback: function(carousel, item, idx, state) {
                            console.log('Item #' + idx + ' is now the last item');
                        }*/
                    });
                }
            }
        };

        this.initImageListscroller = function() {
            // Only show the scroll arrows if there are more than one
            // entries.
            if( $(".imagelist").length ) {
                var imageCount = parseInt($(".imagelist").attr("count"));
                $("#imagelist-pager").show();
                $(".imagelist").find("li").show().end()
                    .jcarousel({
                        vertical: false,
                        scroll: 1,
                        size: imageCount,
                        animation: 350,
                        easing: "easeInOutQuart",
                        itemFirstInCallback: function(carousel, item, idx, state) {
                            $("#imagelist-pager-current").html(idx);
                        }
                    });
            }
        };

        this.initListHover = function() {
            if (this.isIE6()) {}
            else {
                $(".img-overlay").hover(
                    function() {
                        if (!$(this).parent("li").hasClass("current")) {
                            $(this).fadeTo("fast", 0.5);
                        }
                    },
                    function() {
                        if (!$(this).parent("li").hasClass("current")) {
                            $(this).fadeTo("fast", 0.0);
                        }
                    }
                );
            }
        };

        this.initFrontpage = function() {
            if ( !$("body").hasClass("frontpage") ) { return; }
            //$("#content a").ajaxifyAnchors(this_site.pageLoader);

            $(".area-images").reorder();
            // Fade area images
            $(".area-images").cycle({
                fx: 'fade',
                speed: 2500,
                timeout: 6000
            });
        };

        this.initArchiveContentList = function() {
            this.initContentListScroller();

            /*
            $(".contentlist a").click(function() {
                // The slug of the clicked item is stored in the markup
                var slug = $(this).parents(".content").find(".slug").html();
                // Store the URL of the archive page we are on
                var cameFrom = $("#page-permalink a").attr("href");

                // When clicking an archive item, the item shall be shown
                // "in the archive" - the navigation shall NOT change to the
                // category of the item! When the item is display "in the archive"
                // a "back to archive" buttons is displayed beneath. To make it
                // work we need to append something to the origin URL, otherwise
                // the PageLoader.load() method will not load because it is
                // already at the same URL (in the archive). We simple append
                // an anchor index to the URL.
                cameFrom += "#1";

                // Store the URL of the archive item for faking the permalink
                var permalink_url = $(this).attr("href");

                $.get( "/contentdetails/" + slug + "/",
                    function(data) {
                        $("#contentlist-container").slideUp("normal", function() {
                            var $data = $(data);
                            $data.hide();
                            $(this).replaceWith($data);

                            $data.slideDown("normal", function() {
                                this_site.initImageListscroller();

                                // Adjust the permalink
                                $("#page-permalink a").attr("href", permalink_url);

                                // Append a "Back to archive link"
                                $("#contentdetails-container")
                                    .after("<div class='back-to-archive'><a href='#'>&laquo; Zurück zum Archiv</a></div>")
                                    .next("div.back-to-archive").slideDown()
                                        .find("a")
                                        .click( function() {
                                            this_site.pageLoader.load(cameFrom);
                                            return false;
                                        });
                                        //.anchorOverlay();

                                // Update the document title
                                var contentTitle = $data.find("h3").eq(0).html();
                                var newDocumentTitle = "JAZZUNIQUE - ARCHIV - " +  contentTitle;
                                document.title = newDocumentTitle;

                            });
                        });
                    }
                );
                return false;
            });
            */
        };

        this.initNewsletterForm = function() {
            if( $("body").hasClass("newsletterpage") ) {

                var newsletterSubscribeOpts = {
                    submitBtn: $("#newsletter-subscribe-form button"),
                    rules: { email: {required: true, email: true} },
                    messages: { email: "Bitte eine gültige E-Mail Adresse eingeben."},
                    submitHandler: function(form) {
                        $.post(
                            "/newsletter/",
                            { subscribe: true,
                              email: $("#newsletter-subscribe-form input").val() },
                            function (data, textStatus) {
                                $("#newsletter-subscribe-form")
                                    .empty()
                                    .append("<p>Ihre Daten wurden erfolgreich übermittelt.</p>");
                            }
                        );
                    }
                };
                $("#newsletter-subscribe-form").validate(newsletterSubscribeOpts);

                var newsletterUnsubscribeOpts = {
                    submitBtn: $("#newsletter-unsubscribe-form button"),
                    rules: { email: {required: true, email: true} },
                    messages: { email: "Bitte eine gültige E-Mail Adresse eingeben."},
                    submitHandler: function(form) {
                        $.post(
                            "/newsletter/",
                            { unsubscribe: true,
                              email: $("#newsletter-unsubscribe-form input").val() },
                            function (data, textStatus) {
                                $("#newsletter-unsubscribe-form")
                                    .empty()
                                    .append("<p>Ihre Daten wurden erfolgreich übermittelt.</p>");
                            }
                        );
                    }
                };
                $("#newsletter-unsubscribe-form").validate(newsletterUnsubscribeOpts);
            }
        };

        this.initMembersDetailPage = function() {
            if( $("body").hasClass("membersdetailpage") ) {
                $("ul.contentlist li a").lightBox({
                    imageLoading: '/media/js/jquery/jquery-lightbox/images/loading.gif',
                    imageBtnClose:'/media/js/jquery/jquery-lightbox/images/close.gif',
                    imageBtnPrev: '/media/js/jquery/jquery-lightbox/images/prev.gif',
                    imageBtnNext: '/media/js/jquery/jquery-lightbox/images/next.gif'
                });
            }
        };
    }

    /** PageLoader

        The PageLoader class is used as a singleton (this is not a requirment)
        and loads and dispatches pages.
      */
    function PageLoader(options) {
        // Constructor code
        this.options = options;

        this.pageUrl = options.pageUrl;

        // ----------------------- Priviliged functions ----------------------

        /* Loads the page identified by ``pageUrl``.
         */
        this.load = function (pageUrl) {
            // console.log("Loading page: " + pageUrl + "current=" + this.pageUrl);
            var self = this;
            if (pageUrl === undefined) { pageUrl = this.pageUrl; }

            if (pageUrl === this.pageUrl) { return false; }

            $.ajax({url: pageUrl,
                    dataType: "html",   // using "xml" here results in a jQuery parseerror?!
                    success: function (htmlData) {
                        // Determine the 'class' of the loaded page. Is it a
                        // flatpage, a list page or a detail page?

                        // For some magic reasons the #pageclass element must not be the
                        // first child of the body but rather has to be contained in the
                        // "#container" element. This seems like a jQuery bug.
                        var pageClass = $(htmlData).find("#pageclass").text();

                        // The <body>-element is not part of the jquery-wrapped html
                        // data - i dont't understand this! To workaround this problem
                        // we are using a regexp to get the value of the <body> class
                        // attribute of the loaded page.
                        var bodyClassMatch = htmlData.search(/body class="(.*)"/);
                        var bodyClass = (bodyClassMatch != -1) ? RegExp.$1 : "bodyclass not found";

                        switch (pageClass) {
                            case "pageclass-flatpage":
                                // console.log("load(): loaded flatpage..");
                                if (self.options.pageLoaded) {
                                    self.options.pageLoaded(pageUrl, htmlData, pageClass, bodyClass);
                                }
                                break;
                            case "pageclass-listpage":
                                // console.log("load(): loaded listpage..");
                                if (self.options.pageLoaded) {
                                    self.options.pageLoaded(pageUrl, htmlData, pageClass, bodyClass);
                                }
                                break;
                            case "pageclass-detailpage":
                                // console.log("load(): loaded detailpage..");
                                break;
                            default:
                                // console.log("load(): unknown pageclass '" + pageClass + "''");
                                self.options.pageLoaded(pageUrl, htmlData, pageClass, bodyClass);
                                break;
                        }

                        // Store the new page url
                        self.pageUrl = pageUrl;
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                    }
            });
        };
    }
    var juSite = new JazzuniqueSite();
    juSite.init();
});

