﻿/*
* jQuery rg Modal Window
* 
* Version 1.1.3
* 14. January 2011
*
* Copyright:
* Rune Øllgaard Grønkjær
* rune.gronkjaer.dk
*
* Developer
* Rune Øllgaard Grønkjær
* rune@gronkjaer.dk
*
* Created with jQuery v1.4.2
* Tested with jQuery v1.4.2
*
********************************** 
* Incorporated scripts
*
* jQuery Utils by Rune Grønkjær
* http://jscripts.teasolutions.dk/rg.jQuery.utils/rg.jQuery.Utils.min.js
*
********************************** 
* Useage:
*
* //Shows the selected elements as modal popups in front of a background content block
* jQuery('#selector').openModalWindow(settings);
* //Closes the closest modal window
* jQuery('#selector').closeModalWindow();
* // Updates the position of the modal window
* jQuery('#selector').updateModalWindow();
* 
*
********************************** 
* Default settings:
*
* jQuery.modalWindowControl.defaultSettings = {
*   backgroundOpacity: 0.7,
*   backgroundBackground: '#000',
*   noBackground: false,
*   enableModalScroll: true,
*   minDistanceToBrowserEdge: 0,
*   zIndex: 999,
*   animateTime: 500,
*   closeOnBlockClick: true,
*   fixedTop: null,
*   fixedLeft: null,
*   //
*   * All events have the Modal Window Control object passed as the first parameter
*   * The mwc grants access to all of the following:
*   * mwc.settings
*   * mwc.modal
*   * mwc.modalContent
*   * mwc.block
*   * mwc.background
*   //
*   onOpen: function () { },
*   onOpened: function () { },
*   // Important: If you implement this YOU will be responsible for executing the closing procedure by calling the mwc.deconstruct();
*   onClose: null,
*   onClosed: function () { },
*   onModalResize: null,
*   onModalResized: null,
*   appendToSelector: 'body'
* };
*
********************************** 
* Changelog:
*
* * * Version 1.0:
* Created: 22. august 2010
*
* * * Version 1.0.1
* Created: 10. September 2010
* Fixed a miscalculation of the width of the modal content
* Added the tea.utils javascript libarary as a script dependency
*
* * * Version 1.0.2
* Created: 16. September 2010
* Removed some mousewheel code that was too greedy
*
* * * Version 1.1
* Created: 19. September 2010
* Removed some the dependency of the mousewheel plugin. It was not working properly
* Added bootstrap capability to the plugin. This way it 
* can be identified if the plugin have allready been loaded.
* Tea.Utils is now being bootstrapped by it's Id, to verify that
* it has not yet been loaded
*
* * * Version 1.1.1
* Created: 20. September 2010
* Bugfix to the new Bootstrapper system
*
* * * Version 1.1.2
* Created: 11. January 2011
* Added the appendToSelector setting to let the user choose not to append the modal window to body. This is usefull for appending to the .NET form.
*
* * * Version 1.1.3
* Created: 14. January 2011
* Fixed an error that SOMETIMES made Safari not show the modal content.
*
*/
/*
*************************
- TEA NAMESPACE
*************************
*/
if (typeof Tea === 'undefined') { var Tea = {}; }
/*
*************************
- BOOTSTRAP INFORMATION
*************************
*/
if (!Tea.Bootstrap) { Tea.Bootstrap = {}; }
if (!Tea.Bootstrap.registeredFiles) { Tea.Bootstrap.registeredFiles = []; }
if (!Tea.Bootstrap.registeredFiles['29339A13-96B3-4FD0-83B5-4C5D915ED9D2']) { //Bootstrap check START
  Tea.Bootstrap.registeredFiles['29339A13-96B3-4FD0-83B5-4C5D915ED9D2'] = 'http://jscripts.teasolutions.dk/plugins/rg.jQuery.modalWindow/rg.jQuery.ModalWindow.min.js';

  (function (jQuery) {
    /*
    * Constructor for the modalWindowControl class.
    * initiates the modal window.
    */
    jQuery.modalWindowControl = function (modalContent, settings) {

      var mwc = this;
      mwc.init = function () {
        mwc.settings = jQuery.extend({}, jQuery.modalWindowControl.defaultSettings, settings);
        // The onOpen event is fired
        mwc.settings.onOpen(mwc);
        mwc.modalContent = jQuery(modalContent);
        mwc.initialize();
        mwc.fireResizeModal(null, true, true);
        mwc.showModal();
        mwc.resizingTimeout = null;
        jQuery(window).bind('resize', mwc.resizeModalwindow);
      };
      /*
      * initializes the Modal Window
      */
      mwc.initialize = function () {
        /*
        * Inserts a marker after the modal content to remember
        * it's original position
        */
        var marker = jQuery('<hr></hr>').css({ display: 'none' }), baseCss = { left: 0, top: 0, width: '100%', height: '100%' }, absoluteOpacityCss = { position: 'absolute', opacity: 0 };
        mwc.modalContent.data('marker', marker);
        mwc.modalContent.after(marker);
        /*
        * Build the markup for the modal window and the modal background block.
        */
        // Build the block wrapper html element
        mwc.block = jQuery('<div></div>').attr('id', (new Date()).getTime()).addClass('_block').css(baseCss).css({ position: 'fixed', zIndex: mwc.settings.zIndex });
        // Create the modal background block element
        mwc.background = jQuery('<div></div>').css(baseCss).css(absoluteOpacityCss).css({ background: mwc.settings.backgroundBackground });
        // Create the modal window element and append the modal content
        mwc.modal = jQuery('<div></div>').addClass('_block_modal').css(absoluteOpacityCss).append(mwc.modalContent);
        if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) === 6) {
          // Remove the scrollbars in IE6
          jQuery('html').data('savedOverflow', {
            'overflow-x': jQuery('html').css('overflow-x'),
            'overflow-y': jQuery('html').css('overflow-y')
          }).css({
            'overflow-x': 'hidden',
            'overflow-y': 'hidden'
          });
        }
        
        // Append the modal block wrapper to the body of the document
        if (!mwc.settings.noBackground) {
          mwc.block.append(mwc.background);
        }
        mwc.block.append(mwc.modal).appendTo(mwc.settings.appendToSelector);
        mwc.block.data('modalWindowControl', mwc);
        mwc.showHiddenContentElement();
      };
      /*
      * Displays the modal window and the modal background block
      */
      mwc.showModal = function () {
        // Animate the modal window to opacity 1
        mwc.modal.animate({ opacity: 1 }, mwc.settings.animateTime, null, function () {
          // Remove filter attribute to render the fonts correctly in IE
          if (this.style.filter) {
            try { this.style.removeAttribute('filter'); }
            catch (ex) { }
          }
          // Subscribe the modal window close method to the click event
          // of the modal background block.
          if (mwc.settings.closeOnBlockClick) {
            mwc.background.bind('click', function () {
              jQuery(this).closeModalWindow();
            });
          }
          // Fire the onOpened event
          mwc.settings.onOpened(mwc);
        });
        // Animate the modal background block to opacity 1
        mwc.background.animate({ opacity: mwc.settings.backgroundOpacity }, mwc.settings.animateTime);
      };
      /*
      * If the modal content is somehow hidden, this method shows the content.
      * It will save the original settings of the content, to be reenabled
      * when the modal window is closed.
      */
      mwc.showHiddenContentElement = function () {
        // Create an object to contain all default css settings of the modal content.
        var initialModalContentCss = {};
        // Set the modal content to display block and save the old value
        if (mwc.modalContent.css('display') === 'none') {
          initialModalContentCss.display = mwc.modalContent.css('display');
          mwc.modalContent.css('display', 'block');
        }
        // Set the modal content to visibility visible and save the old value
        if (mwc.modalContent.css('visibility') === 'hidden') {
          initialModalContentCss.visibility = mwc.modalContent.css('visibility');
          mwc.modalContent.css('visibility', 'visible');
        }
        // Set the modal content to opacity 1 and save the old value
        if (mwc.modalContent.css('opacity') === '0') {
          initialModalContentCss.backgroundOpacity = mwc.modalContent.css('opacity');
          mwc.modalContent.css('opacity', '1');
          if (mwc.modalContent[0].style.filter) {
            try { mwc.modalContent[0].style.removeAttribute('filter'); }
            catch (ex) { }
          }
        }
        // Set the modal content to position static and 0 and save the old values
        if (mwc.modalContent.css('position') != 'static') {
          initialModalContentCss.position = mwc.modalContent.css('position');
          initialModalContentCss.left = mwc.modalContent.css('left');
          initialModalContentCss.top = mwc.modalContent.css('top');
          initialModalContentCss.right = mwc.modalContent.css('right');
          initialModalContentCss.bottom = mwc.modalContent.css('bottom');
          mwc.modalContent.css({ position: 'static', left: 0, top: 0, right: 0, bottom: 0 });
        }
        // Save the modal contents default css settings in its own data.
        mwc.modalContent.data('initialModalContentCss', initialModalContentCss);
      };

      /*
      * Sets the size and position of the modal window.
      */
      mwc.fireResizeModal = function (modalCss, ignoreStartEvent, noAnimate) {
        if (mwc.settings.onModalResize && !ignoreStartEvent) {
          mwc.settings.onModalResize(mwc);
        } else {
          mwc.resizeModal(modalCss, noAnimate);
        }
      };
      mwc.resizeModal = function (modalCss, noAnimate) {
        if (!modalCss) {
          modalCss = mwc.calculateModalCSS();
        }
        // Modal is animated to it's new size
        mwc.modal.animate(modalCss, noAnimate ? 0 : mwc.settings.animateTime / 2, function () {
          if (mwc.settings.onModalResized) {
            mwc.settings.onModalResized(mwc, noAnimate);
          }
        });
        // IE6 cannot handle position fixed, so instead we use position absolute
        if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) === 6) {
          mwc.block.css({
            position: 'absolute',
            height: jQuery(window).height(),
            top: jQuery('html').scrollTop()
          });
        }
      };
      mwc.calculateModalCSS = function () {
        // Calculate the width's and height's of the modal window
        var modalContentHeight = mwc.modalContent.height() + mwc.modalContent.getCssLengthValue("paddingTop") + mwc.modalContent.getCssLengthValue("paddingBottom") + mwc.modalContent.getCssLengthValue("borderTopWidth") + mwc.modalContent.getCssLengthValue("borderBottomWidth"), //mwc.modalContent.outerHeight(true),
          modalContentWidth = mwc.modalContent.width() + mwc.modalContent.getCssLengthValue("paddingRight") + mwc.modalContent.getCssLengthValue("paddingLeft") + mwc.modalContent.getCssLengthValue("borderRightWidth") + mwc.modalContent.getCssLengthValue("borderLeftWidth"), //there is a bug in webkit that renders outerWidth useless in some situations - mwc.modalContent.outerWidth(true)
          availableViewportHeight = (((window.innerHeight) ? window.innerHeight : jQuery(window).height()) - ((mwc.settings.fixedTop === null) ? 0 : mwc.settings.fixedTop)) - (mwc.settings.minDistanceToBrowserEdge * ((mwc.settings.fixedTop === null) ? 2 : 1)),
          availableViewportWidth = (jQuery(window).width() - ((mwc.settings.fixedLeft === null) ? 0 : mwc.settings.fixedLeft)) - (mwc.settings.minDistanceToBrowserEdge * ((mwc.settings.fixedLeft === null) ? 2 : 1)),
          heightExceeded = (modalContentHeight > availableViewportHeight),
          widthExceeded = (modalContentWidth > availableViewportWidth),
          calculatedModalWidth = ((widthExceeded) ? availableViewportWidth : modalContentWidth),
          calculatedModalHeight = ((heightExceeded) ? availableViewportHeight : modalContentHeight),
          scrollBarCorectionAmount = mwc.getScrollBarWidth();
        if (heightExceeded) {
          calculatedModalWidth = calculatedModalWidth + scrollBarCorectionAmount;
          widthExceeded = calculatedModalWidth > availableViewportWidth;
        }
        if (widthExceeded) {
          calculatedModalWidth = availableViewportWidth;
          if (!heightExceeded) {
            calculatedModalHeight = calculatedModalHeight + scrollBarCorectionAmount;
            heightExceeded = calculatedModalHeight > availableViewportHeight;
            if (heightExceeded) {
              calculatedModalHeight = availableViewportHeight;
            }
          }
        }
        // Create a css object for the modal window
        var modalCss = {
          width: calculatedModalWidth,
          height: calculatedModalHeight,
          left: ((mwc.settings.fixedLeft === null) ? ((widthExceeded) ? mwc.settings.minDistanceToBrowserEdge : '50%') : mwc.settings.fixedLeft),
          top: ((mwc.settings.fixedTop === null) ? ((heightExceeded) ? mwc.settings.minDistanceToBrowserEdge : '50%') : mwc.settings.fixedTop),
          marginLeft: ((mwc.settings.fixedLeft === null && !widthExceeded) ? calculatedModalWidth / 2 * -1 : 0),
          marginTop: ((mwc.settings.fixedTop === null && !heightExceeded) ? calculatedModalHeight / 2 * -1 : 0),
          availableViewportHeight: availableViewportHeight,
          availableViewportWidth: availableViewportWidth
        };
        /*
        * If the height or width of the modal content exeeds that of the
        * modal window the overflow of the modal window is set to auto.
        * This is done to create the scroll posibility to let the user
        * see all content.
        */
        if (mwc.settings.enableModalScroll) {
          mwc.modal.css({ overflow: ((heightExceeded || widthExceeded) ? 'auto' : 'visible') });
        } else {
          mwc.modal.css({ overflow: 'visible' });
        }
        return modalCss;
      };
      mwc.resizeModalwindow = function () {
        clearTimeout(mwc.resizingTimeout);
        mwc.resizingTimeout = setTimeout(function () {
          mwc.fireResizeModal();
          mwc.resizingTimeout = null;
        }, 100);
      };
      /*
      * Deconstructs the modal window.
      * Will reset the location and css settings of the modal content.
      */
      mwc.deconstruct = function () {
        // If IE6 the overflow of the html element must be reset.
        if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) === 6) {
          jQuery('html').css(jQuery('html').data('savedOverflow'));
        }

        // Animate the modal window and modal background block to opacity 0
        mwc.modal.add(mwc.background).animate({ opacity: 0 }, mwc.settings.animateTime, null, function () {
          // Remove filter attribute to render the fonts correctly in IE
          if (this.style.filter) {
            try { this.style.removeAttribute('filter'); }
            catch (ex) { }
          }
          // Move the modal content back to it's marker and reset the contents css.
          mwc.modalContent.data('marker').replaceWith(mwc.modalContent.css(mwc.modalContent.data('initialModalContentCss'))); //flytter indholdet tilbage på sin plads
          // Remove the modal block wich envelopes both modal window and modal background block
          mwc.block.remove();
          if (jQuery(this).is('._block_modal')) {
            // Fire the onClosed event
            mwc.settings.onClosed(mwc);
          }
          jQuery(window).unbind('resize', mwc.resizeModalwindow);
        });
      };
      /*
      * Calculates the width of the browsers scrollbar.
      */
      mwc.getScrollBarWidth = function () {
        if (mwc.scrollbarWidth) {
          return mwc.scrollbarWidth;
        }
        // create a div from wich to calculate the scrollbar width
        var testScrollBar = jQuery('<div><div></div></div>').css({ width: 50, height: 50, overflow: 'scroll', position: 'absolute', top: 0, left: 0 }).appendTo('body');
        testScrollBarWidth = testScrollBar.width() - testScrollBar.children().width();
        testScrollBar.remove();
        mwc.scrollbarWidth = testScrollBarWidth;
        return testScrollBarWidth;
      };
      mwc.init();
    };
    /*
    * Default settings for the module.
    * Is used if the user does not specify the settings
    */
    jQuery.modalWindowControl.defaultSettings = {
      backgroundOpacity: 0.7,
      backgroundBackground: '#000',
      noBackground: false,
      enableModalScroll: true,
      minDistanceToBrowserEdge: 0,
      zIndex: 999,
      animateTime: 500,
      closeOnBlockClick: true,
      fixedTop: null,
      fixedLeft: null,
      /*
      * All events have the Modal Window Control object passed as the first parameter
      * The mwc grants access to all of the following:
      * mwc.settings
      * mwc.modal
      * mwc.modalContent
      * mwc.block
      * mwc.background
      */
      onOpen: function () { },
      onOpened: function () { },
      /*
      * Important: If you implement this YOU will be responsible for executing the closing procedure by calling the mwc.deconstruct();
      */
      onClose: null,
      onClosed: function () { },
      onModalResize: null,
      onModalResized: null,
      appendToSelector: 'body'
    };
    /*
    * Opens a modal window whose content is the selected jQuery element.
    * There can only be one element in the selection. If several items 
    * has to be opened, they must be wrapped in a container
    */
    jQuery.fn.openModalWindow = function (settings) {
      new jQuery.modalWindowControl(this[0], settings); //Will only grab the first element in an possible array of elements
      return this;
    };
    /*
    * Closes a modal window
    * This method can be called on ALL jQuery elements inside the modal window
    */
    jQuery.fn.closeModalWindow = function () {
      var mwc = this.getModalWindowControl();
      if (mwc.settings.onClose) {
        // Fire the onClose event
        mwc.settings.onClose(mwc);
      } else {
        mwc.deconstruct(); //Finds the block and decontructs it
      }
      return this;
    };
    /*
    * Updates the position of the modal window
    */
    jQuery.fn.updateModalWindow = function (modalCss, ignoreStartEvent) {
      this.getModalWindowControl().fireResizeModal(modalCss, ignoreStartEvent); //Finds the block, and updates size and position of the modal window
      return this;
    };
    /*
    * Returns the modalWindowControl object of the modal window we are currently inside
    */
    jQuery.fn.getModalWindowControl = function () {
      return this.closest('._block').data('modalWindowControl');
    };
    /*
    * This plugin depends on the following script files
    */
    jQuery.modalWindowControl.scriptDependencies = [{
      key: '8F384D79-9750-45B8-9DB4-D64050E2BF2B',
      uri: 'http://jscripts.teasolutions.dk/tea.utils/tea.utils.min.js'
    }];
    /*
    * Imports the scriptfiles this plugin depends on
    */
    bootstrapScripts = function () {
      for (var i = 0; i < jQuery.modalWindowControl.scriptDependencies.length; i++) {
        if (!Tea.Bootstrap.registeredFiles[jQuery.modalWindowControl.scriptDependencies[i].key]) {
          jQuery.getScript(jQuery.modalWindowControl.scriptDependencies[i].uri);
        }
      }
    };
    bootstrapScripts();
  })(jQuery);
} //Bootstrap check END
