/* VSM Very Simple Modal 1.0 ==============================================
 * Updated: 15/10/2010
 *
 * Author: Gianluca Buoncompagni
 * URL: http://gianlucabuoncompagni.net
 * Required files: jQuery 1.3+ Core
 * License: MIT License (http://www.opensource.org/licenses/mit-license.php)

 * HOW TO USE
 Open a modal window by calling openModal() with the desired settings on click.

    // search in page for a hidden div with id = modal and opens it
    SCRIPT ------------------
    $('a').click(function(){
        $(this).openModal();
    });

    // opens the #remoteDiv content found in ajax.html page, with a custom overlay color, a preload spinner and an additional close button. A callback function is triggered when the modal gets closed.
    SCRIPT -----------------------------
    $('a').click(function(){
        $(this).openModal({
            ovColor: #fff,
            extPage: 'ajax.html',
            target: '#remoteDiv',
            spinner: 'img/preloader.gif',
            addClose: '#closeButton',
            callback: function(){
                alert('Modal closed!')
            }
        });
    });

    // settings can be given to link attributes href and /or rel
    HTML -------------------------
    <a href="#test">Open</a>  // opens #test found in page
    <a href="test.html">Open</a> // opens #default found in remote page test.html
    <a href="test2.php" rel="#externalContent">Open</a> // opens #externalContent found in remote page test2.php
    SCRIPT -----------------------
    $('a').click(function(){
        $(this).openModal(); // opens different contents based on link attributes
    });

    // modal window can be opened on page load by assigning it to a DOM element (ie. html, body, etc.)
    SCRIPT -----------------------
    $('body').openModal({
        extPage:'test_remote.html',
        target:'#settings'
    });


 * DEFAULT SETTINGS:
 * ovColor        // Overlay color (default: '#000')
 * ovOpacity      // Transparency level (default: '0.5')
 * target     // DOM element to be loaded as modal content (default: '#modal')
 * closeOnOverlay   // Clicking on overlay div closes the modal (default: true)

 * OPTIONAL SETTINGS:
 * extPage           // External page to be opened by remote call
 * spinner     // Preload image with path relative to document
 * addClose     // DOM element to be used as additional close trigger
 * prepend     // Hook to function to be called before opening modal
 * callback        // Hook to function to be called once the content has been loaded
 * onModalClose   // Hook to function to be called once the modal has been closed
 * ========================================================================= */

(function ($) {
  $.fn.openModal = function (sets) {
    settings = jQuery.extend({
      ovColor: '#000',
      ovOpacity: '0.5',
      defaultTarget: '#modal',
      target: '',
      extPage: '',
      spinner: '',
      addClose: '',
      prepend: '',
      callback: '',
      onModalClose: '',
      closeOnOverlay: true
    },
    sets);

    // IE detect
    var ie6 = $.browser.msie && parseInt($.browser.version) == 6 && typeof window['XMLHttpRequest'] != "object";

    return this.each(function (event) {

      if (event != undefined) {
        if (event.preventDefault) {
          event.preventDefault()
        } else {
          event.returnValue = false;
        };
      };

      // INIT OVERLAY -------------------------------------------
      var href = $(this).attr('href');
      var rel = $(this).attr('rel');
      var bodyHeight = $('body').outerHeight();
      var viewportHeight = $(window).height();
      var viewportWidth = $(window).width();
      var scrollTop = $('html').scrollTop();
      var base = '<div id="vsmOverlay" /><div id="vsmHorizon" />';
      var horizon = '#vsmHorizon';
      var overlay = '#vsmOverlay';
      var closeBtn = '#vsmClose';

      if (ie6) { // ie6
        var globalPosition = 'absolute';
        var centralPos = scrollTop + (viewportHeight / 2);
      } else {
        var globalPosition = 'fixed';
        var centralPos = viewportHeight / 2;
      };
      $('body').append(base);
      $(overlay).css({
        'width': '100%',
        'height': bodyHeight + 'px',
        'z-index': '5000',
        'background': settings.ovColor,
        'position': globalPosition,
        'top': '0',
        'left': '0',
        'text-align': 'center',
        'filter': 'alpha(opacity=' + settings.ovOpacity * 100 + ')',
        '-khtml-opacity': settings.ovOpacity,
        '-moz-opacity': settings.ovOpacity,
        'opacity': settings.ovOpacity
      });
      $(horizon).css({
        'width': '100%',
        'height': '50px',
        'z-index': '5001',
        'position': globalPosition,
        'top': centralPos + 'px',
        'left': '0',
        'text-align': 'center',
        'overflow': 'visible',
        'background': 'url("' + settings.spinner + '") 50% 50% no-repeat'
      });

      if (settings.spinner) {
        $(horizon).css({
          'background': 'url("' + settings.spinner + '") 50% 50% no-repeat'
        });
      };

      if (href != undefined && href != '') {
        if (href.length > 1 && href.substr(0, 1) == '#') {
          // local ----------------------
          // console.log('onclick local');
          if (settings.target == '') {
            settings.target = href;
          }
          loadLocal();
        } else {
          // remote ----------------------
          // console.log('onclick remote');
          settings.extPage = href;
          loadRemote();
        }
      } else {
        // onload ----------------------
        if (settings.extPage != '') {
          // console.log('onload remote');
          loadRemote();
        } else {
          // console.log('onload local');
          loadLocal();
        }
      };

      function loadRemote() {
        settings.mode = 'remote';
        if (settings.target == '') {
          settings.target = settings.defaultTarget;
          if (rel != undefined && rel != '') {
            settings.target = rel;
          };
        }
        var remoteContent = settings.extPage + ' ' + settings.target;
        // console.log(remoteContent);
        $(horizon).load(remoteContent,
        function () {
          showModal(settings.target);
        });
      }

      function loadLocal() {
        settings.mode = 'local';
        if (settings.target == '') {
          settings.target = settings.defaultTarget;
        }
        $(settings.target).appendTo(horizon);
        showModal(settings.target);
      }

      function showModal(el) {
        var modalHeight = $(el).outerHeight();
        if (modalHeight == 0) {
          alert('Error: Can\'t find the content to open!');
          closeModal();
          return;
        };
        if (settings.prepend != '') {
          settings.prepend(); // prepend function call
        }
        setPosition(el);
        $(el).css({
          'margin': '0 auto',
          'position': 'relative',
          'top': (- 1) * (Math.abs(modalHeight / 2)) + 'px',
          'display': 'block',
          'opacity': '0'
        }).append('<a href="#" id="vsmClose">Chiudi</a>').animate({
          'opacity': '1'
        }, 500, function () {
          if (!$.support.opacity) {
            $(this).get(0).style.removeAttribute('filter'); // IE png Fix
          }
          if (settings.callback != '') {
            settings.callback(); // richiamo la callback
          }
        });
      };

      function setPosition(el) {
        var modalHeight = $(el).outerHeight();
        var modalWidth = $(el).outerWidth();
        var deltaHeight = viewportHeight - modalHeight;
        var deltaWidth = viewportWidth - modalWidth;
        if (deltaHeight <= 0 || deltaWidth <= 0) { // if modal is taller or larger  than viewport put it on top and allow scroll
          $(horizon).css({
            'position': 'absolute',
            'top': Math.abs(modalHeight / 2) + 'px'
          });
        }
      };

      // close
      var closeTriggers = closeBtn;
      if (settings.closeOnOverlay == true) {
        closeTriggers += ', ' + overlay
      }
      if (settings.addClose != '') {
        closeTriggers += ', ' + settings.addClose
      }
      $(closeTriggers).live('click', closeModal);

      function closeModal() {
        if (settings.mode == 'local') {
          $(settings.target).appendTo('body').hide();
        }
        $(overlay + ', ' + horizon + ', ' + closeBtn).remove();
        // reset settings
        settings.target = '';
        settings.extPage = '';

        if (settings.onModalClose != '') {
          settings.onModalClose(); // callback
        }
        return false;
      };

    });
  };
  //=========================================
})(jQuery);
