var npFocusRotation = (function() {

    var _DisplayTime = 5000;
    var _intervalId = [];
    var _CurrentId;

    function _rotate(Id) {

        //stop rotation if submenu container is not visible
        if (!($("#SubMenu" + Id).is(":visible"))) {
            _stop();
            return;
        }

        var cur = $("#SubMenu" + Id + " .focus .item:visible");
        if (cur.is(":last-child")) {
            cur.fadeOut(500, function() {
                // run the loop function again when time is up, in this case 5 seconds
                $("#SubMenu" + Id + " .focus .item:first-child").fadeIn(500, function() {
                    _intervalId.push(setTimeout("npFocusRotation.rotate(" + Id + ")", _DisplayTime));
                });
            });
        }
        else {
            cur.fadeOut(500, function() {
                // run the loop function again when time is up, in this case 5 seconds
                cur.next().fadeIn(500, function() {
                    _intervalId.push(setTimeout("npFocusRotation.rotate(" + Id + ")", _DisplayTime));
                });
            });
        }
    }

    function _stop() {
        for (var i = 0; i < _intervalId.length; i++) {
            clearTimeout(_intervalId[i]);
            _intervalId.splice(i, 1);
        }
        _CurrentId = null;
    }

    return {

        go: function(Id) {
            if (Id != _CurrentId) {
                _stop();
                _CurrentId = Id;
                _intervalId.push(setTimeout("npFocusRotation.rotate(" + Id + ")", _DisplayTime));
            }
        },
        rotate: function(Id) {
            _rotate(Id);
        },
        stop: function() {
            _stop();
        }
    }
})();

//Rotation
var npImgRotation = (function() {

    var _DisplayTime = 7000;
    var _intervalId = [];
    var _CurrentId;

    function _goTo(id) {
        var ImgId = "img-" + id;
        var BtnId = "imgbtn-" + id;

        if ($("#Scene .ImageRotation img").is(":visible")) {
            $("#Scene .ImageRotation img:visible").fadeOut("fast", function() {
                $("#" + ImgId).fadeIn("fast");
            });
        } else {
            $("#" + ImgId).fadeIn("fast");
        }
        //clear button
        $("#Scene .active").removeClass();
        //set button
        $("#" + BtnId).addClass("active");
    }

    function _Rotate() {
        var tmpId;
        var cur = $("#Scene ul li.active");
        
        if (cur.is(":last-child")) {
            tmpId = $("#Scene ul li:first").find(".data .imgid").text();
            _goTo(tmpId);
            _intervalId.push(setTimeout("npImgRotation.Rotate()", _DisplayTime));
        }
        else {
            tmpId = cur.next().find(".data .imgid").text();
            _goTo(tmpId);
            _intervalId.push(setTimeout("npImgRotation.Rotate()", _DisplayTime));
        }
    }

    function _Init() {
        $("#Scene .ImageRotation ul").fadeIn("fast");
        $("#Scene .ImageRotation ul li:last-child").addClass("active");
        _Rotate();

    }

    function _stop() {
        for (var i = 0; i < _intervalId.length; i++) {
            clearTimeout(_intervalId[i]);
            _intervalId.splice(i, 1);
        }
        _CurrentId = null;
    }

    return {

        goTo: function(id) {
            _goTo(id);
        },
        Init: function() {
            _Init();
        },
        Rotate: function() {
            _Rotate();
        }
    }
})();

//Link rotation
var npLinkRotation = (function () {
    var _ContainerClassName = "LinkRotation";

    //*** Private

    function _findContainer(Node) {
        return $(Node).closest("." + _ContainerClassName).get(0);
    }

    function _goPrevious(CurrentNode) {
        var $CurrentNode = $(CurrentNode);

        if (!($CurrentNode.is(":first-child"))) {
            $CurrentNode.removeClass("active").fadeOut("fast");
            $CurrentNode.prev(".item").addClass("active").fadeIn("fast");
        }
    }

    function _goNext(CurrentNode) {
        var $CurrentNode = $(CurrentNode);

        if (!($CurrentNode.is(":last-child"))) {
            $CurrentNode.removeClass("active").fadeOut("fast");
            $CurrentNode.next(".item").addClass("active").fadeIn("fast");
        }
    }

    function _findCurrentNode(Node) {
        var ParentNode = _findContainer(Node);
        return $(ParentNode).find(".items .active").get(0);
    }

    function _rotate(strContainerId) {
        var CurrentNode = $("#" + strContainerId).find(".items .active").get(0);
    }

    //*** Public    
    return {
        goPrevious: function (Node) {
            _goPrevious(_findCurrentNode(Node));
        },
        goNext: function (Node) {
            _goNext(_findCurrentNode(Node));
        }

    }
})()

//Link flipper
var npLinkFlipper = (function () {
    //*** Private
    var _ContainerClassName = "LinkFlipper";
    var _Properties = {
        duration: 300, //normal mode animation duration
        introDuration: 800, //duration while playing intro animation
        introWhenToStart: 5000, //time to wait before starting the intro animation
        tmp: [] //tmp storage
    };

    function _setEvents() {
        $("." + _ContainerClassName).find(".name").click(function () {
            if (!$(this).closest("li").hasClass("active")) {
                _Toggle({ CurrentNode: this });
            }
        });
    }

    function _Toggle(JSON) {
        var $PreviousContainer = $(JSON.CurrentNode).closest("." + _ContainerClassName).find("li.active");
        var $CurrentContainer = $(JSON.CurrentNode).closest("li");
        var ItemWidths = {minWidth:0, maxWidth:0};

        ItemWidths.minWidth = $CurrentContainer.width();
        ItemWidths.maxWidth = $PreviousContainer.width();

        $CurrentContainer.addClass("active");
        $PreviousContainer.animate({ width: ItemWidths.minWidth + "px" }, { queue: false, duration: _Properties.duration, step: function (now) {
            //Synchronizing changes to get a smoother animation
            $CurrentContainer.width((ItemWidths.maxWidth - now + ItemWidths.minWidth));
        }
            , complete: function () {
                $PreviousContainer.removeClass("active");
                //callback?
                if (JSON.callback) {
                    JSON.callback($CurrentContainer);
                }
            }
        }).find(".content").animate({ opacity: 0 }, { queue: false, duration: _Properties.duration, complete: function () {
            $(this).css({ "opacity": "1" })
        }
        });

    }

    function _calcActiveWidth(MainNode) {
        var Widths = { maxWidth: 0, minWidth: 0 };
        Widths.minWidth = $(MainNode).find("> li > .name").width();
        Widths.maxWidth = $(MainNode).width() + Widths.minWidth;
        $(MainNode).find("> li").each(function () {
            Widths.maxWidth -= $(this).outerWidth({ margin: true });
        });

        return Widths;
    }

    function _introAnimation(CurrentNode) {
        if ($(CurrentNode).is(":last-child")) {
            _Toggle({ CurrentNode: $(CurrentNode).siblings().get(0) });
            //reset duration
            _Properties.duration = _Properties.tmp["duration"];
            delete _Properties.tmp["duration"];
        } else {
            $(CurrentNode).next().each(function () {
                _Toggle({ CurrentNode: this, callback: _introAnimation });
            });
        }
    }

    function _startIntro(MainNode) {
        $(MainNode).find("> li.active").next().each(function () {
            //set animation duration for the the intro show
            _Properties.tmp["duration"] = _Properties.duration;
            _Properties.duration = _Properties.introDuration;
            //start the show
            _Toggle({ CurrentNode: this, callback: _introAnimation });
        });
    }

    function _init() {
        //set active item and set its width
        $("." + _ContainerClassName).each(function () {
            var MainNode = this;
            var ItemWidths = _calcActiveWidth($(MainNode));
            $(MainNode).find("> .active").width(ItemWidths.maxWidth);
        });
        //set events on all items
        _setEvents();
    }

    //*** Public
    return {
        //inits every LinkFlipper on the page
        init: function () {
            _init();
        },
        //inits and starts an intro animation for a particular LinkFlipper
        startIntro: function (MainNode) {
            _init();
            setTimeout(function () { _startIntro(MainNode) }, _Properties.introWhenToStart);
        }
    }
})();

//Accordion
var npAccordion = (function () {
    //*** Private
    var _ContainerClassName = "Accordion";
    var _Properties = {
        duration: 300, //normal mode animation duration
        introDuration: 800, //duration while playing intro animation
        introWhenToStart: 5000, //time to wait before starting the intro animation
        tmp: [] //tmp storage
    };

    function _setEvents() {
        $("." + _ContainerClassName).find(".name").click(function () {
            if (!$(this).closest("li").hasClass("active")) {
                _Toggle({ CurrentNode: this });
            }
        });
    }

    function _Toggle(JSON) {
        var $PreviousContainer = $(JSON.CurrentNode).closest("." + _ContainerClassName).find("li.active");
        var $CurrentContainer = $(JSON.CurrentNode).closest("li");
        var ItemSize = { minHeight: 0, maxWidth: 0 };

        ItemSize.minHeight = $CurrentContainer.height();
        ItemSize.maxHeight = $PreviousContainer.height();

        $CurrentContainer.addClass("active");
        $PreviousContainer.animate({ height: ItemSize.minHeight + "px" }, { queue: false, duration: _Properties.duration, step: function (now) {
            //Synchronizing changes to get a smoother animation
            $CurrentContainer.height((ItemSize.maxHeight - now + ItemSize.minHeight));
        }
            , complete: function () {
                $PreviousContainer.removeClass("active");
                //callback?
                if (JSON.callback) {
                    JSON.callback($CurrentContainer);
                }
            }
        })
        /*.find(".content").animate({ opacity: 0 }, { queue: false, duration: _Properties.duration, complete: function () {
            $(this).css({ "opacity": "1" })
        }
        });*/

    }

    function _calcActiveSize(MainNode) {
        var Size = { maxHeight: 0, minHeight: 0 };
        Size.minHeight = $(MainNode).find("> li > .name").height();
        Size.maxHeight = $(MainNode).height() + Size.minHeight;
        $(MainNode).find("> li").each(function () {
            Size.maxHeight -= $(this).outerWidth({ margin: true });
        });

        return Size;
    }

    function _introAnimation(CurrentNode) {
        if ($(CurrentNode).is(":last-child")) {
            _Toggle({ CurrentNode: $(CurrentNode).siblings().get(0) });
            //reset duration
            _Properties.duration = _Properties.tmp["duration"];
            delete _Properties.tmp["duration"];
        } else {
            $(CurrentNode).next().each(function () {
                _Toggle({ CurrentNode: this, callback: _introAnimation });
            });
        }
    }

    function _startIntro(MainNode) {
        $(MainNode).find("> li.active").next().each(function () {
            //set animation duration for the the intro show
            _Properties.tmp["duration"] = _Properties.duration;
            _Properties.duration = _Properties.introDuration;
            //start the show
            _Toggle({ CurrentNode: this, callback: _introAnimation });
        });
    }

    function _init() {
        //set active item and set its width
        $("." + _ContainerClassName).each(function () {
            var MainNode = this;
            var ItemSize = _calcActiveSize($(MainNode));
            $(MainNode).find("> .active").width(ItemSize.maxWidth);
        });
        //set events on all items
        _setEvents();
    }

    function _createAccordion() {
        //m123
        $(".createAccordion-m123").each(function () {
            _createAccordionM123(this);
        });
    }

    function _createAccordionM123(DataNode) {
        var Accordion = _createTemplate();
        var ItemTemplate = $(Accordion).find("> li:first-child").remove().clone();

        //create items based on the urls found inside the data node
        $(DataNode).find("a").each(function () {
            var URLParams = _getUrlParameters($(this).attr("href"));
            var m123Params = { Id: URLParams["I"], CategoryId: URLParams["C"] };
            var m123HTML = _getM123(m123Params);
            var Item = _createItem(m123HTML);
            $(Accordion).append(Item);
        });
        //replace the data node with the accordion
        $(DataNode).replaceWith(Accordion);


        function _createItem(m123HTML) {
            var Item = $(ItemTemplate).clone();
            $(m123HTML).find(".Detail").each(function () {
                var Detail = this;
                $(Item).find(".name").text($(Detail).find("h1").text());
                $(Item).find(".content").append($(Detail).clone());
            })
            return Item;
        }

        function _getM123(m123Params) {
            //iId, iCategoryId
            var strURL = strApplicationRoot + "modules/module_123/proxy.asp?D=2&C=" + m123Params.CategoryId + "&I=" + m123Params.Id;
            var html = $.ajax({
                url: strURL,
                async: false
            }).responseText;

            return html;
        }
    }

    function _getUrlParameters(URL) {
        //returns a hashed array where param names are keys
        var map = {};
        var parts = URL.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
            map[key] = value;
        });
        return map;
    }


    function _createTemplate() {
        var Accordion = $(document.createElement("ul")).addClass(_ContainerClassName).get(0);
        var Item = document.createElement("li");
        //name
        Item.appendChild($(document.createElement("div")).addClass("name").get(0));
        //content
        Item.appendChild($(document.createElement("div")).addClass("content").get(0));

        Accordion.appendChild(Item);

        return Accordion;
    }

    //*** Public
    return {
        //inits every Accordion on the page
        init: function () {
            _init();
        },
        //inits and starts an intro animation for a particular Accordion
        startIntro: function (MainNode) {
            _init();
            setTimeout(function () { _startIntro(MainNode) }, _Properties.introWhenToStart);
        },
        findAndCreate: function () {
            _createAccordion();
            _init();
        }
    }
})();
