/*
    Require:
    - jquery library
    - jquery ui library
    <!-- Script -->
    <script language="javascript" type="text/javascript">
        $(function() {
            $("#<id>").rotating_banners();
        });
    </script>

    Edit Mode Requirement:
    <!-- Html -->
    <div id="<id>" class="bannerContainer" style="display:none;">
        <div id="TK0" class="icreateToken"></div>
    </div>
    <div id="<id>Edit" class="bannerContainer">
        <div class="bannerEdit">
            <div class="bannerImage">
                <div id="TK1" class="icreateToken"></div>
            </div>
            <div class="bannerText">
                <div id="TK2" class="icreateToken"></div>
            </div>
            <div class="bannerCaption">
                <div id="TK3" class="icreateToken"></div>
            </div>
        </div>
    </div>

    Normal Mode Requirement:
    <!-- Html -->
    <div id="<id>" class="bannerContainer">
        <div class="banner default">
            <div class="bannerImage">
                <!-- Image Content -->
            </div>
            <div class="bannerText">
                <!-- Text Content -->
            </div>
            <div class="bannerCaption">
                <!-- Text Content -->
            </div>
        </div>
        <div class="banner">
            <div class="bannerImage">
                <!-- Image Content -->
            </div>
            <div class="bannerText">
                <!-- Text Content -->
            </div>
            <div class="bannerCaption">
                <!-- Text Content -->
            </div>
        </div>
    </div>
*/
(function($){

	$.fn.rotating_banners = function(p) {

		var p=p||{};
		
		var alertMsg = { "maxAllowableBannersReach" : "You've reach the maximum allowable banners.",
		    "noBannerToEdit" : "There's no banner to edit.",
		    "bannerSuccessfullyDeleted" : "Banner successfully deleted.",
		    "confirmBannerDeletion" : "Are you sure that you want to delete?",
		    "noBannerToDelete" : "There's no banner to delete.",
		    "bannerSuccessfullyUpdated" : "Banner successfully updated.",
		    "bannerSuccessfullyAdded" : "Banner successfully added."
		    };

		var _timerLength = p && (p.timerLength != null) ? p.timerLength : 5000,
		    _enableTimer = p && (p.enableTimer != null) ? p.enableTimer : true,
		    _transitionLength = p && (p.transitionLength != null) ? p.transitionLength : 1000,
		    _transitionType = p && (p.transitionType != null) ? p.transitionType : "fade",
		    _bannerClass = p && (p.bannerClass != null) ? p.bannerClass : "banner",
		    _tokenClasses = p && (p.tokenClasses != null) ? p.tokenClasses : [ "bannerImage", "bannerText", "bannerCaption" ],
		    _navButtonClass = p && (p.navButtonClass != null) ? p.navButtonClass : "navButton",
		    _navButtonsOnly = p && (p.navButtonsOnly != null) ? p.navButtonsOnly : false,
		    _editElement = p && (p.editElement != null) ? p.editElement : $(this).attr("id") + "Edit",
		    _icreateTokenClass = p && (p.icreateTokenClass != null) ? p.icreateTokenClass : "icreateToken",
		    _maxBanners = p && (p.maxBanners != null) ? p.maxBanners : 10,
		    _alertMsg = p && (p.alertMsg != null) ? p.alertMsg : alertMsg;

        var enableEdit = $(this).children("div." + _icreateTokenClass).length > 0;
 
        if ((enableEdit && $("#" + _editElement).length > 0) || (!enableEdit)) {
		var bannerContainer = enableEdit ? $("#" + _editElement) : $(this),
		    editContainer = bannerContainer.children(".bannerEdit:first"),
		    icreateContainer = enableEdit ? $(this).children("div." + _icreateTokenClass) : "",
		    blankContainer = editContainer.clone().removeClass(_bannerClass + "Edit");

		if (enableEdit) {
		    bannerContainer.append(icreateContainer.children("." + _bannerClass).clone());
		    $(this).hide();
		    $(bannerContainer).show();
		    blankContainer.children("div").each(function() {
			    $(this).empty();
		    });
		}
		// DOM elements
		var banners = bannerContainer.children("." + _bannerClass),
		    anchorTag = $(document.createElement("a")).attr("href", "#"),
		    navLeft = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "NavLeft").append(anchorTag.clone().attr("title", "Previous Banner").append("Previous")).addClass("bannerNavLeft"),
		    navButtonsContainer = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "NavButtons").addClass("bannerNavButtons"),
		    navRight = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "NavRight").append(anchorTag.clone().attr("title", "Next Banner").append("Next")).addClass("bannerNavRight"),
		    navContainer = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "Nav").addClass("bannerNav"),
		    ctrContainer = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "Controls").addClass("bannerControls");

		// instance variables
		var timerIndex,
		    previousIndex = 0,
		    currentIndex = 0,
		    maxIndex,
		    navText = "Go to ",
		    isEditMode = false;

		if ((banners.length > 0) || (enableEdit)) {
//		    $(this).css("background-image", "none");
		    _initialize()
		}
        }
        else {
        	alert("Error - unable to find '" + _editElement + "' tag, please provide an edit tag or correct the tag id.");
        }
        
        function _initialize() {
            maxIndex = banners.length - 1;

            if (banners.length > 0) {
                // default to first image if no default image is set
                if (bannerContainer.children(".default").length <= 0) {
                    bannerContainer.children("." + _bannerClass + ":first").addClass("default");
                }

                // built navigation buttons
                banners.each(function(index) {
                    var navButtonTitle = navText + $(this).css( { "position": "absolute", "top": "0", "left": "0" } ).children(":first").children("img:first").attr("alt");
                    var navButton = $(anchorTag.clone().attr("title", navButtonTitle).append(index + 1).wrap("<div class='" + _navButtonClass + "'></div>").parent());
                    if ($(this).hasClass("default")) {
                        if ($(this).is(":hidden")) {
                            $(this).show();
                        }
                        navButton.children("a").addClass("selected");
                        previousIndex = index;
                        currentIndex = index;
                    }
                    navButton.click(function(event) {
                        event.preventDefault();
                        this.index = index;
                        _navButtonClick(this);
                    });
                    navButtonsContainer.append(navButton);
                });

                if (_navButtonsOnly) {
                    bannerContainer.prepend(navContainer.append(navButtonsContainer));
                    navButtonsContainer.children("." + _navButtonClass + ":first").addClass("first");
                    navButtonsContainer.children("." + _navButtonClass + ":last").addClass("last");

                    // set navContainer width
                    navContainer.width(navButtonsContainer.children(":first").outerWidth() * banners.length);
                }
                else {
                    // bind onclick events
                    navLeft.click(function(event) {
                        event.preventDefault();
                        _navLeftClick(this);
                    });
                    navRight.click(function(event) {
                        event.preventDefault();
                        _navRightClick(this);
                    });
                    bannerContainer.prepend(navContainer.append(navButtonsContainer).prepend(navLeft).append(navRight));

                    // set navContainer width
                    navContainer.width(navButtonsContainer.parent().children(":first").outerWidth() + (navButtonsContainer.children(":first").outerWidth() * banners.length) + navButtonsContainer.parent().children(":last").outerWidth());
                }

                // start timer
                startTimer();
            }
            
            if (enableEdit) {
                // built edit controls
                var addControl = $(document.createElement("div")).addClass("NormalMode").append(anchorTag.clone().attr("title", "Add Banner").append("Add")),
                    editControl = $(document.createElement("div")).addClass("NormalMode").append(anchorTag.clone().attr("title", "Edit Banner").append("Edit")),
                    deleteControl = $(document.createElement("div")).addClass("NormalMode").append(anchorTag.clone().attr("title", "Delete Banner").append("Delete")).addClass("last"),
                    saveControl = $(document.createElement("div")).addClass("EditMode").append(anchorTag.clone().attr("title", "Save Banner").append("Save")).hide(),
                    cancelControl = $(document.createElement("div")).addClass("EditMode").append(anchorTag.clone().attr("title", "Cancel Banner").append("Cancel")).addClass("last").hide();

                // bind onclick events
                addControl.click(function(event) {
                    event.preventDefault();
                    _addClick(this);
                });
                editControl.click(function(event) {
                    event.preventDefault();
                    _editClick(this);
                });
                deleteControl.click(function(event) {
                    event.preventDefault();
                    _deleteClick(this);
                });
                saveControl.click(function(event) {
                    event.preventDefault();
                    _saveClick(this);
                });
                cancelControl.click(function(event) {
                    event.preventDefault();
                    _cancelClick(this);
                });
                ctrContainer.append(addControl).append(editControl).append(deleteControl).append(saveControl).append(cancelControl);
                bannerContainer.prepend(ctrContainer);
            }
        }
        
        function resetElements() {
            $(navContainer).remove();
            $(ctrContainer).remove();
            bannerContainer.children("." + _bannerClass).each(function() { $(this).remove() } );
            bannerContainer.append(icreateContainer.children("." + _bannerClass).clone());

            banners = bannerContainer.children("." + _bannerClass),
		        anchorTag = $(document.createElement("a")).attr("href", "#"),
		        navLeft = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "NavLeft").append(anchorTag.clone().attr("title", "Previous Banner").append("Previous")).addClass("bannerNavLeft"),
		        navButtonsContainer = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "NavButtons").addClass("bannerNavButtons"),
		        navRight = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "NavRight").append(anchorTag.clone().attr("title", "Next Banner").append("Next")).addClass("bannerNavRight"),
		        navContainer = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "Nav").addClass("bannerNav"),
		        ctrContainer = $(document.createElement("div")).attr("id", bannerContainer.attr("id") + "Controls").addClass("bannerControls");
        }

        function _addClick(button) {
            if (banners.length < _maxBanners) {
                stopTimer();
                $(navContainer).hide();
                $(ctrContainer).children(".NormalMode").each(function() { $(this).hide(); });
                isEditMode = false;

                // clear edit container
                $.each(_tokenClasses, function() {
                    $(editContainer).children("." + this).children("." + _icreateTokenClass).empty();
                });

                // animate transition
                if (banners.length > 0) {
                    $(banners[currentIndex]).stop(true, true).hide("slide", {direction: "left"}, _transitionLength);
                    $(editContainer).stop(true, true).show("slide", {direction: "right"}, _transitionLength, function() {
                        $(ctrContainer).children(".EditMode").each(function() { $(this).show(); });
                    });
                }
                else {
                $(editContainer).stop(true, true).show();
                $(ctrContainer).children(".EditMode").each(function() { $(this).show(); });
                }
            }
            else {
                alert(_alertMsg["maxAllowableBannersReach"] ? _alertMsg["maxAllowableBannersReach"] : alertMsg["maxAllowableBannersReach"]);
            }
        }

        function _editClick(button) {
            if (banners.length > 0) {
                stopTimer();
                $(navContainer).hide();
                $(ctrContainer).children(".NormalMode").each(function() { $(this).hide(); });
                isEditMode = true;

                // set current banner to edit container
                $.each(_tokenClasses, function() {
                    $(editContainer).children("." + this).children("." + _icreateTokenClass).empty().append($(banners[currentIndex]).children("." + this).html());
                });

                // animate transition
                $(banners[currentIndex]).stop(true, true).hide("slide", {direction: "left"}, _transitionLength);
                $(editContainer).stop(true, true).show("slide", {direction: "right"}, _transitionLength, function() {
                    $(ctrContainer).children(".EditMode").each(function() { $(this).show(); });
                });
            }
            else {
                alert(_alertMsg["noBannerToEdit"] ? _alertMsg["noBannerToEdit"] : alertMsg["noBannerToEdit"]);
            }
        }

        function _deleteClick(button) {
            if ($(icreateContainer).children("." + _bannerClass).length > 0) {
                if (confirm(_alertMsg["confirmBannerDeletion"] ? _alertMsg["confirmBannerDeletion"] : alertMsg["confirmBannerDeletion"])) {
                    var index = currentIndex - 1;
                    if (index < 0) {
                        index = maxIndex;
                    }

                    $(icreateContainer).children(".default").removeClass("default");
                    $(icreateContainer.children("." + _bannerClass)[index]).addClass("default");
                    $(icreateContainer.children("." + _bannerClass)[currentIndex]).remove();

                    resetElements();
                    _initialize();
                    
                    alert(_alertMsg["bannerSuccessfullyDeleted"] ? _alertMsg["bannerSuccessfullyDeleted"] : alertMsg["bannerSuccessfullyDeleted"]);
                }
            }
            else {
                alert(_alertMsg["noBannerToDelete"] ? _alertMsg["noBannerToDelete"] : alertMsg["noBannerToDelete"]);
            }
        }

        function _saveClick(button) {
            var template = $(blankContainer).clone().addClass(_bannerClass).addClass("default");
            $.each(_tokenClasses, function() {
                template.children("." + this).append(editContainer.children("." + this).children("." + _icreateTokenClass).html());
            });
            
            $(icreateContainer).children(".default").removeClass("default");
            if (isEditMode) {
                $.each(_tokenClasses, function() {
                    $(icreateContainer.children("." + _bannerClass)[currentIndex]).children("." + this).empty().append(template.children("." + this).html());
                });
                $(icreateContainer.children("." + _bannerClass)[currentIndex]).addClass("default");
            }
            else if ($(icreateContainer).children("." + _bannerClass).length > 0) {
                $(icreateContainer.children("." + _bannerClass)[currentIndex]).after(template.wrap("<div></div>").parent().html());
            }
            else {
                $(icreateContainer).empty();
                $(icreateContainer).append(template.wrap("<div></div>").parent().html());
            }
            $.each(_tokenClasses, function() {
                editContainer.children("." + this).children("." + _icreateTokenClass).empty();
            });
            $(editContainer).hide();

            resetElements();
            _initialize();
            
            if (isEditMode) {
                alert(_alertMsg["bannerSuccessfullyUpdated"] ? _alertMsg["bannerSuccessfullyUpdated"] : alertMsg["bannerSuccessfullyUpdated"]);
            }
            else {
                alert(_alertMsg["bannerSuccessfullyAdded"] ? _alertMsg["bannerSuccessfullyAdded"] : alertMsg["bannerSuccessfullyAdded"]);
            }
        }

        function _cancelClick(button) {
            $(ctrContainer).children(".EditMode").each(function() { $(this).hide(); });
            $(editContainer).stop(true, true).hide("slide", {direction: "right"}, _transitionLength);
            if (banners.length > 0 ) {
                $(banners[currentIndex]).stop(true, true).show("slide", {direction: "left"}, _transitionLength, function() {
                    $(navContainer).show();
                    $(ctrContainer).children(".NormalMode").each(function() { $(this).show(); });
                    startTimer();
                });
            }
            else {
                $(navContainer).show();
                $(ctrContainer).children(".NormalMode").each(function() { $(this).show(); });
                startTimer();
            }
        }

        function _navLeftClick(button) {
            previousIndex = currentIndex;
            currentIndex--;
            if (currentIndex < 0) {
                currentIndex = maxIndex < 0 ? 0 : maxIndex;
            }
            toggleBanner(true);
        }

        function _navButtonClick(button) {
            previousIndex = currentIndex;
            currentIndex = button.index;
            toggleBanner();
        }

        function _navRightClick(button) {
            previousIndex = currentIndex;
            currentIndex++;
            if (currentIndex > maxIndex) {
                currentIndex = 0;
            }
            toggleBanner(false);
        }

        function _timerHandler() {
            previousIndex = currentIndex;
            currentIndex++;
            if (currentIndex > maxIndex) {
                currentIndex = 0;
            }
            toggleBanner(false);
        }
        
        function toggleBanner(reverse) {
            if (previousIndex != currentIndex) {
                // stop any reqired controls
                stopControls();

    	        // set selected nav button
	            var navButtons = $(navButtonsContainer.children("." + _navButtonClass));
	            $(navButtons[previousIndex]).children("a").removeClass("selected");
	            $(navButtons[currentIndex]).children("a").addClass("selected");
	            
                // animate rotating banner
	            if (_transitionType == "slide") {
	                reverse = reverse != null ? reverse : previousIndex > currentIndex;
	                $(banners[previousIndex]).stop(true, true).hide("slide", {direction: reverse ? "right" : "left"}, _transitionLength);
	                $(banners[currentIndex]).stop(true, true).show("slide", {direction: reverse ? "left" : "right"}, _transitionLength, startControls);
	            }
	            else {
	                $(banners[previousIndex]).stop(true, true).fadeOut(_transitionLength * 2);
	                $(banners[currentIndex]).stop(true, true).fadeIn(_transitionLength, startControls);
	            }
	        }
        }
        
        function stopControls() {
            stopTimer();
            if (enableEdit) {
                // hide edit controls
                $(ctrContainer).hide();
            }
        }
        
        function startControls() {
            startTimer();
            if (enableEdit) {
                // show edit controls
                $(ctrContainer).show();
            }
            $(banners[previousIndex]).removeClass("default");
            $(banners[currentIndex]).addClass("default");
        }
        
        function stopTimer() {
            if ((_enableTimer) && (!enableEdit)) {
                // stop timer
                clearTimeout(timerIndex);
            }
        }
        
        function startTimer() {
            if ((_enableTimer) && (!enableEdit) && (banners.length > 0)) {
                // reset timer
                timerIndex = setTimeout(_timerHandler, _timerLength);
            }
        }
	};

})(jQuery);
