﻿(function ($) {
    var modalObjects = [];
    var overlayerID = 'kjModalOverlay';
    var baseModalID = 'kjModal';

    $.showModal = function (settings) {
        settings = jQuery.extend({
            width: "auto", 				// width of the modal
            height: "auto", 				// height of the modal
            modalColor: "#fff", 			// background color of the modal
            opacity: "0.8", 				// opacity of the overlay layer
            overlayImage: "", 			// background image of the overlay
            overlayColor: "#000", 		// background color of the overlay
            overlayShowSpeed: 500, 		// fade in speed of the overlay layer / modal
            modalShowSpeed: 400, 		// fade in speed of the modal object / modal
            target: "", 					// target html element identifier to be used for the modal's content
            url: "", 					// target url to be loaded using ajax for the modal's content
            parameters: {}, 				// any parameters to be passed for ajax loads
            cache: false, 				// ajax content cache
            onShow: function () { }, 		// function to be executed when a modal is to be displayed
            onComplete: function () { }, 	// function to be executed when modal is fully displayed 
            onSuccess: function () { }, 	// function to be executed upon AJAX data loaded completely
            onError: function () { }, 		// function to be executed upon ajax failure
            clearInputs: true,               // clear all input data on show
            hideMessages: false             // hide all messages
        }, settings);

        return privShowModal(settings, true);
    }   //$.showModal(settings)

    function privShowModal(settings, add) {
        if (add) {
            // execute code for when a modal begins to be displayed.
            settings.onShow();

            // push the settings into modalObjects
            modalObjects.push(settings);
        }   //if

        if (validateData(settings)) {
            if (add) {
                // begin display process
                showOverlayLayer(settings, true);
            }   //if
            else {
                setupModalContent(settings, false)
            }   //else
        }   //if

        // return the new modal's ID
        return baseModalID + modalObjects.length;
    }

    $.captureHtmlPostBack = function (settings) {
        settings = jQuery.extend({
            elem: null              // the elem to being searching for the container from
        }, settings);

        if (settings.elem) {
            var parent = $(settings.elem);

            while (parent && parent.attr('class').indexOf('overlayContainer') == -1) {
                parent = parent.parent();
            }   //while

            if (parent.attr('class').indexOf('overlayContainer') > -1) {
                // create a copy so they don't see the post back flicker
                var width = parent.width();
                var height = parent.height();

                // add a temp div to hold the copy
                $('body').append('<div class="kjTempFlickerHider"></div>');

                // apply the css
                $('.kjTempFlickerHider').css({
                    position: 'absolute',
                    left: '50%',
                    top: '50%',
                    marginLeft: '-' + width / 2 + 'px',
                    marginTop: '-' + height / 2 + 'px',
                    width: width + 'px',
                    height: height + 'px',
                    zIndex: '9999',
                    backgroundColor: '#FFFFFF'
                });

                // inject the html
                $('.kjTempFlickerHider').html(parent.html());
            }   //if

            // add a end request function to remove the flicker container
            Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onHtmlPostBack);
        }   //if
    }

    function onHtmlPostBack() {
        Sys.WebForms.PageRequestManager.getInstance().remove_endRequest(onHtmlPostBack);

        $('.kjTempFlickerHider').remove();
    }

    function showOverlayLayer(modalObject, fade) {
        // make sure the overlay layer isnt already present.
        if (!($('#' + overlayerID).length)) {
            // inject the overlay layer html into the body
            $('body').append('<div id="' + overlayerID + '"><!-- --></div>');
            // set the attributes of the overlay
            $('#' + overlayerID).css({
                position: "absolute",
                zIndex: "9998",
                left: "0",
                top: "0",
                opacity: modalObject.opacity,
                display: "none"
            });

            // set the proper display mode for the overlay
            if (modalObject.overlayImage != '') {
                $('#' + overlayerID).css({ backgroundImage: 'url(' + modalObject.overlayImage + ')' });
            }   //if
            else {
                $('#' + overlayerID).css({ backgroundColor: modalObject.overlayColor });
            }   //else

            //set overlay layer size
            setOverlayLayerSize();

            // fade in overlay layer
            if (fade) {
                $('#' + overlayerID).fadeIn(modalObject.overlayShowSpeed, function () {
                    setupModalContent(modalObject, true)
                });
            }   //if
            else {
                $('#' + overlayerID).css('display', 'block');
            }   //else

            // set double click close
            $('#' + overlayerID).dblclick(function () {
                $.closeModal();
            });
        }   //if
        else {
            // must just be adding a modal
            setupModalContent(modalObject, true);
        }   //else
    }   //showOverlayLayer(settings, bool)

    $.closeModal = function (settings) {
        settings = jQuery.extend({
            width: "auto", 				// width of the modal
            height: "auto", 				// height of the modal
            modalColor: "#fff", 			// background color of the modal
            overlayHideSpeed: 500, 	// fade out speed of the ovelay layer / modal
            modalHideSpeed: 400, 	// fade out speed of the modal object / modal
            parameters: {}, 				// any parameters to be passed for ajax loads
            cache: false, 				// ajax content cache
            onClose: function () { }, 	// function to be executed before the modal is closed EX. function() { alert("It is loaded"); }
            onHide: function () { }, 	// function to be executed after the modal has been closed
            onSuccess: function () { },   // function to be executed upon AJAX data loaded completely
            target: "",                 // target html element identifier to be used for the modal's new content
            url: "",                    // target url to be loaded for the modal's new content
            modalID: ""                 // the ID of the modal to alter or close
        }, settings);

        // fire onClose function
        settings.onClose();

        if (validateCloseData(settings)) {
            if (settings.modalID != '') {
                var modalID = '#' + settings.modalID;
                var modalIndex = settings.modalID.replace(baseModalID, '') - 1;

                if (settings.target != '' || settings.url != '') {
                    // set the height so the box doesnt disappear
                    $(modalID).css('height', $(modalID).height() + 'px');

                    // fade out the content container
                    $(modalID + ' .kjModalContent').fadeOut();

                    // get the new data
                    if (settings.target != '') {
                        var tempID = 'temp' + settings.modalID;
                        $(settings.target).wrap('<div id="' + tempID + '" />');
                        $(settings.target).wrap('<div class="kjModalContent" />');
                        $(settings.target).css('display', 'block');

                        // set the css
                        $('#' + tempID).css({
                            position: "absolute",
                            zIndex: "9999",
                            left: "0",
                            top: "0",
                            width: settings.width,
                            height: settings.height,
                            backgroundColor: settings.modalColor,
                            visibility: 'hidden'
                            //display: 'none'
                        });

                        // change the size of the showing modal to match the new modal
                        $(modalID).animate({
                            height: $('#' + tempID).height() + 'px',
                            width: $('#' + tempID).width() + 'px',
                            left: '50%',
                            top: '50%',
                            marginLeft: '-' + ($('#' + tempID).width()) / 2 + 'px',
                            marginTop: '-' + ($('#' + tempID).height()) / 2 + 'px'
                        }, function () {
                            // move the new modal behind the resized showing modal
                            $('#' + tempID).css({
                                left: '50%',
                                top: '50%',
                                marginLeft: '-' + ($('#' + tempID).width()) / 2 + 'px',
                                marginTop: '-' + ($('#' + tempID).height()) / 2 + 'px',
                                visibility: 'visible',
                                display: 'none'
                            });

                            // fade in new content
                            $('#' + tempID).fadeIn(function () {
                                // remove the old modal
                                $(modalID).remove();

                                // rename the new, showing modal
                                $('#' + tempID).attr('id', settings.modalID);
                            });
                        });
                    }   //if
                    else {
                        //show url
                        $.ajax({
                            url: settings.url,
                            data: settings.parameters,
                            cache: settings.cache,
                            dataType: "html",
                            method: "GET",
                            success: function (data) {
                                settings.onSuccess();

                                // fade out the existing content
                                $(modalID + ' .kjModalContent').fadeOut(function () {
                                    // replace the existing content with the new content
                                    $(modalID + ' .kjModalContent').html(data);

                                    // switch the css from display:none to visibility:hidden
                                    // so we can grab the height and width of the box for resizing
                                    $(modalID + ' .kjModalContent').css({
                                        visibility: 'hidden',
                                        display: 'block'
                                    });

                                    // get the new modal size
                                    var width, height;
                                    if (settings.width != 'auto') {
                                        width = settings.width;
                                    }   //if
                                    else {
                                        width = $(modalID + ' .kjModalContent').width() + 'px';
                                    }   //else

                                    if (settings.height != 'auto') {
                                        height = settings.height;
                                    }   //if
                                    else {
                                        height = $(modalID + ' .kjModalContent').height() + 'px';
                                    }   //else

                                    // resize to fit the new content
                                    $(modalID).animate({
                                        width: width,
                                        height: height,
                                        left: '50%',
                                        top: '50%',
                                        marginLeft: '-' + parseInt(width) / 2 + 'px',
                                        marginTop: '-' + parseInt(height) / 2 + 'px'
                                    }, function () {
                                        // switch the css back
                                        $(modalID + ' .kjModalContent').css({
                                            display: 'none',
                                            visibility: 'visible'
                                        });

                                        // fade in the new content
                                        $(modalID + ' .kjModalContent').fadeIn();
                                    });
                                });
                            }
                            //,error: modalObject.onError()
                        });
                    }   //else
                }   //if
                else    // we are closing a specific modal
                {

                    $(modalID).stop().fadeOut(settings.modalHideSpeed, function () {
                        // get the modal settings
                        settings = modalObjects[modalIndex];

                        // remove the modal from the settings list
                        modalObjects.splice(modalIndex, 1);

                        if (modalObjects.length == 0) {
                            //no more modals left, clear the overlay
                            removeOverlayLayer(true, settings, settings.onHide);
                        }   //if
                        else {
                            repositionModals();
                        }   //else

                        if (settings.target == '') {
                            // from a url, remove
                            $(modalID).remove()
                        }   //if
                        else {
                            // from an on page target, unwrap
                            $contentDiv = $(modalID).children(':first').children(':first');
                            $contentDiv.css('display', 'none');
                            $contentDiv.unwrap().unwrap();
                        }   //else
                        // unwrap it
                    });
                }   //else
            }   //if
            else    //we're closing everything
            {
                // fade out the modal(s)
                for (var i = 0; i < modalObjects.length; i++) {
                    var currModalID = '#' + baseModalID + (i + 1);

                    $(currModalID).fadeOut(settings.modalHideSpeed, function () {
                        if ($(this).prev().attr('id') == 'kjModalOverlay') {
                            //it's content from a url, just remove it
                            $(this).remove();
                        }   //if
                        else {
                            // unwrap the content
                            $(this).find('.kjModalContent div:first').unwrap().unwrap().css('display', 'none');
                        }   //else

                        // remove the overlay layer if it exists
                        if ($('#' + overlayerID).length) {
                            // fade out the overlay layer
                            removeOverlayLayer(true, settings, function () {
                                // remove the overlay from the page's html
                                $('#' + overlayerID).remove();
                                // hack: show the select boxes for ie6 users
                                //showSelects();
                                // execute code after the modal is removed from the html
                                settings.onHide();
                            });
                        }   //if
                    });
                }   //for

                modalObjects = [];
            }   //else

            return this;
        }   //if
    }   //$.closeModal(settings)

    function setupModalContent(modalObject, fade) {
        var modalID = baseModalID + modalObjects.length;

        if (modalObject.target != '') {
            // if it's a on-page target, wrap around it so the bindings stay intact.
            $(modalObject.target).wrap('<div id="' + modalID + '" />');
            $(modalObject.target).wrap('<div class="kjModalContent" />');
            $(modalObject.target).css('display', 'block');

            // show the modal
            displayModal(modalObject, fade, modalID);
        }   //if
        else {
            $.ajax({
                url: modalObject.url,
                data: modalObject.parameters,
                cache: modalObject.cache,
                dataType: "html",
                method: "GET",
                success: function (data) {
                    modalObject.onSuccess();
                    // append to the body since we don't have a div to wrap around
                    $('body').append('<div id="' + modalID + '" style="display:none;"><div id="kjModalContent">' + data + '</div></div>');

                    // show the modal
                    displayModal(modalObject, fade, modalID);
                }
                //,error: modalObject.onError()
            });
        }   //else
    }   //setupModalContent(settings, bool)

    function displayModal(modalObject, fade, modalID) {
        modalID = '#' + modalID;

        // set the attributes of the new modal element
        $(modalID).css({
            position: "absolute",
            zIndex: "9999",
            left: "0",
            top: "0",
            width: modalObject.width,
            height: modalObject.height,
            backgroundColor: modalObject.modalColor,
            display: "none"
        });

        repositionModals(function () {
            if (fade) {
                if (modalObject.clearInputs) {
                    // clear all inputs
                    $(modalID).find('input:text').each(function () {
                        $(this).val('');
                    });

                    $(modalID).find('textarea').each(function () {
                        $(this).val('');
                    });

                    // clear all messages
                    $(modalID).find('.errorMessage').each(function () {
                        $(this).html('');
                    });
                }   //if

                if (modalObject.hideMessages) {
                    $(modalID).find('.message').each(function () {
                        $(this).css('display', 'none');
                    });
                }

                // hide all input error messages
                $(modalID).find('.required').each(function () {
                    $(this).css('display', 'none');
                });

                // fade in the modal element after everything's been repositioned.
                $(modalID).fadeIn(modalObject.modalShowSpeed, function () {
                    // execute the code for the overlay/modal display
                    modalObject.onComplete();
                });
            }   //if
            else {
                // just show the element
                $(modalID).css({
                    display: 'block'
                });

                // destroy the copy if present
                if ($('.kjTempFlickerHider').length > 0) {
                    $('.kjTempFlickerHider').remove();
                }   //if
            }   //else
        });
    }   //displayModal(settings, bool)

    $.repositionModals = function () {
        repositionModals();
    }

    function repositionModals(onCompleteFunction) {
        var leftPosition, topPosition;
        var winWidth = $(document).width();
        var winHeight = $(window).height();
        var margin = 10;

        //get the total width
        var totalWidth = 0;
        for (var i = 0; i < modalObjects.length; i++) {
            if (i > 0) {
                totalWidth += margin;
            }   //if
            totalWidth += $('#' + baseModalID + (i + 1)).width();
        }   //for

        //get the left of the first modal position
        leftPosition = ($(document).width() - totalWidth) / 2;

        var movingElemCount = 0;
        for (var i = 0; i < modalObjects.length; i++) {
            var currModalID = '#' + baseModalID + (i + 1);

            //figure the top position
            topPosition = (document.documentElement.scrollTop || document.body.scrollTop) + (winHeight - $(currModalID).height()) / 2;

            // assign the calculated positions to an array
            var positions = {
                left: leftPosition + 'px',
                top: topPosition + 'px'
            };

            // just in case the margins are set; messes with left positioning
            $(currModalID).css({
                marginLeft: 'auto',
                marginTop: 'auto'
            });

            //move the element
            $(currModalID).stop().animate(
                positions,
                200, function () {
                    movingElemCount++;
                    if (movingElemCount == (modalObjects.length)) {
                        if (onCompleteFunction) {
                            onCompleteFunction();
                        }   //if
                    }
                });

            //subtract from the leftPosition for the next element
            leftPosition += ($(currModalID).width() + margin);
        }   //for
    }   //repositionModals(function)

    function removeOverlayLayer(fade, modalObject, onComplete) {
        if (fade) {
            $("#" + overlayerID).fadeOut(modalObject.overlayHideSpeed, function () {
                onComplete();
            });
        }   //if
        else {
            $('#' + overlayerID).remove();

            if (onComplete) {
                onComplete();
            }   //if
        }   //else
    }   //removeOverlayLayer(bool)

    function setOverlayLayerSize() {
        var overlayWidth = $(window).width();
        var overlayHeight = $(document).height();
        $('#' + overlayerID).height(overlayHeight + "px");
        $('#' + overlayerID).width(overlayWidth + "px");
    } // setOverlayLayerSize()

    function validateData(modalObject) {
        var returnValue = false;

        // if there is valid data to populate the modal, return true
        if ((modalObject.target != "" && $(modalObject.target).length) || (modalObject.url != "")) {
            returnValue = true;
        }
        return returnValue;
    } //validateData(settings)

    function validateCloseData(modalObject) {
        var returnValue = true;
        if ((modalObject.target != '' || modalObject.url != '') && modalObject.modalID == '') {
            returnValue = false;
        }   //if
        return returnValue;
    }   //validateCloseData(settings)

    $(window).resize(function () {
        if (modalObjects.length > 0) {
            // remove the overlay layer so it isn't stretching the document
            removeOverlayLayer(false);
            // re-add the overlay layer
            showOverlayLayer(modalObjects[0]);
            // reposition modals so they are centered again
            repositionModals();
        }   //if
    });

    $(window).scroll(function () {
        if (modalObjects.length > 0) {
            repositionModals();
        }   //if
    });
})(jQuery);
