/**
 * @license 
 * jQuery Tools 1.2.5 Overlay - Overlay base. Extend it.
 * 
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 * 
 * http://flowplayer.org/tools/overlay/
 *
 * Since: March 2008
 * Date:    Wed Sep 22 06:02:10 2010 +0000 
 */
(function($) { 

  // static constructs
  $.tools = $.tools || {version: '1.2.5'};
  
  $.tools.overlay = {
    
    addEffect: function(name, loadFn, closeFn) {
      effects[name] = [loadFn, closeFn];  
    },
  
    conf: {  
      close: null,  
      closeOnClick: true,
      closeOnEsc: true,      
      closeSpeed: 'fast',
      effect: 'default',
      
      // since 1.2. fixed positioning not supported by IE6
      fixed: !$.browser.msie || $.browser.version > 6, 
      
      left: 'center',    
      load: false, // 1.2
      mask: null,  
      oneInstance: true,
      speed: 'normal',
      target: null, // target element to be overlayed. by default taken from [rel]
      top: '10%'
    }
  };

  
  var instances = [], effects = {};
    
  // the default effect. nice and easy!
  $.tools.overlay.addEffect('default', 
    
    /* 
      onLoad/onClose functions must be called otherwise none of the 
      user supplied callback methods won't be called
    */
    function(pos, onLoad) {
      
      var conf = this.getConf(),
         w = $(window);         
        
      if (!conf.fixed)  {
        pos.top += w.scrollTop();
        pos.left += w.scrollLeft();
      } 
        
      pos.position = conf.fixed ? 'fixed' : 'absolute';
      this.getOverlay().css(pos).fadeIn(conf.speed, onLoad); 
      
    }, function(onClose) {
      this.getOverlay().fadeOut(this.getConf().closeSpeed, onClose);       
    }    
  );    

  
  function Overlay(trigger, conf) {    
    
    // private variables
    var self = this,
       fire = trigger.add(self),
       w = $(window), 
       closers,            
       overlay,
       opened,
       maskConf = $.tools.expose && (conf.mask || conf.expose),
       uid = Math.random().toString().slice(10);    
    
       
    // mask configuration
    if (maskConf) {      
      if (typeof maskConf == 'string') { maskConf = {color: maskConf}; }
      maskConf.closeOnClick = maskConf.closeOnEsc = false;
    }       
     
    // get overlay and triggerr
    var jq = conf.target || trigger.attr("rel");
    overlay = jq ? $(jq) : null || trigger;  
    
    // overlay not found. cannot continue
    if (!overlay.length) { throw "Could not find Overlay: " + jq; }
    
    // trigger's click event
    if (trigger && trigger.index(overlay) == -1) {
      trigger.click(function(e) {        
        self.load(e);
        return e.preventDefault();
      });
    }         
    
    // API methods  
    $.extend(self, {

      load: function(e) {
        
        // can be opened only once
        if (self.isOpened()) { return self; }
        
        // find the effect
         var eff = effects[conf.effect];
         if (!eff) { throw "Overlay: cannot find effect : \"" + conf.effect + "\""; }
        
        // close other instances?
        if (conf.oneInstance) {
          $.each(instances, function() {
            this.close(e);
          });
        }
        
        // onBeforeLoad
        e = e || $.Event();
        e.type = "onBeforeLoad";
        fire.trigger(e);        
        if (e.isDefaultPrevented()) { return self; }        

        // opened
        opened = true;
        
        // possible mask effect
        if (maskConf) { $(overlay).expose(maskConf); }        
        
        // position & dimensions 
        var top = conf.top,          
           left = conf.left,
           oWidth = overlay.outerWidth({margin:true}),
           oHeight = overlay.outerHeight({margin:true}); 
        
        if (typeof top == 'string')  {
          top = top == 'center' ? Math.max((w.height() - oHeight) / 2, 0) : 
            parseInt(top, 10) / 100 * w.height();      
        }        
        
        if (left == 'center') { left = Math.max((w.width() - oWidth) / 2, 0); }

        
         // load effect           
        eff[0].call(self, {top: top, left: left}, function() {          
          if (opened) {
            e.type = "onLoad";
            fire.trigger(e);
          }
        });         

        // mask.click closes overlay
        if (maskConf && conf.closeOnClick) {
          $.mask.getMask().one("click", self.close); 
        }
        
        // when window is clicked outside overlay, we close
        if (conf.closeOnClick) {
          $(document).bind("click." + uid, function(e) { 
            if (!$(e.target).parents(overlay).length) { 
              self.close(e); 
            }
          });            
        }            
      
        // keyboard::escape
        if (conf.closeOnEsc) { 

          // one callback is enough if multiple instances are loaded simultaneously
          $(document).bind("keydown." + uid, function(e) {
            if (e.keyCode == 27) { 
              self.close(e);   
            }
          });      
        }

        
        return self; 
      }, 
      
      updatePosition: function(e) {
        
        // nothing to do
        if (!self.isOpened()) { return self; }
        
        // position & dimensions 
        var top = conf.top,          
           left = conf.left,
           oWidth = overlay.outerWidth({margin:true}),
           oHeight = overlay.outerHeight({margin:true}); 
        
        if (typeof top == 'string')  {
          top = top == 'center' ? Math.max((w.height() - oHeight) / 2, 0) : 
            parseInt(top, 10) / 100 * w.height();      
        }        
        
        if (left == 'center') { left = Math.max((w.width() - oWidth) / 2, 0); }
        
        overlay.css({left: left, top: top});
        
      },
      
      close: function(e) {

        if (!self.isOpened()) { return self; }
        
        e = e || $.Event();
        e.type = "onBeforeClose";
        fire.trigger(e);        
        if (e.isDefaultPrevented()) { return; }        
        
        opened = false;
        
        // close effect
        effects[conf.effect][1].call(self, function() {
          e.type = "onClose";
          fire.trigger(e); 
        });
        
        // unbind the keyboard / clicking actions
        $(document).unbind("click." + uid).unbind("keydown." + uid);      
        
        if (maskConf) {
          $.mask.close();    
        }
         
        return self;
      }, 
      
      getOverlay: function() {
        return overlay;  
      },
      
      getTrigger: function() {
        return trigger;  
      },
      
      getClosers: function() {
        return closers;  
      },      

      isOpened: function()  {
        return opened;
      },
      
      // manipulate start, finish and speeds
      getConf: function() {
        return conf;  
      }      
      
    });
    
    // callbacks  
    $.each("onBeforeLoad,onStart,onLoad,onBeforeClose,onClose".split(","), function(i, name) {
        
      // configuration
      if ($.isFunction(conf[name])) { 
        $(self).bind(name, conf[name]); 
      }

      // API
      self[name] = function(fn) {
        if (fn) { $(self).bind(name, fn); }
        return self;
      };
    });
    
    // close button
    closers = overlay.find(conf.close || ".close");    
    
    if (!closers.length && !conf.close) {
      closers = $('<a class="close"></a>');
      overlay.prepend(closers);  
    }    
    
    closers.click(function(e) { 
      self.close(e);  
    });  
    
    // autoload
    if (conf.load) { self.load(); }
    
  }
  
  // jQuery plugin initialization
  $.fn.overlay = function(conf) {   
    
    // already constructed --> return API
    var el = this.data("overlay");
    if (el) { return el; }         
    
    if ($.isFunction(conf)) {
      conf = {onBeforeLoad: conf};  
    }

    conf = $.extend(true, {}, $.tools.overlay.conf, conf);
    
    this.each(function() {    
      el = new Overlay($(this), conf);
      instances.push(el);
      $(this).data("overlay", el);  
    });
    
    return conf.api ? el: this;    
  }; 
  
})(jQuery);


/**
 * @license 
 * jQuery Tools 1.2.5 / Expose - Dim the lights
 * 
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 * 
 * http://flowplayer.org/tools/toolbox/expose.html
 *
 * Since: Mar 2010
 * Date:    Wed Sep 22 06:02:10 2010 +0000 
 */
(function($) {   

  // static constructs
  $.tools = $.tools || {version: '1.2.5'};
  
  var tool;
  
  tool = $.tools.expose = {
    
    conf: {  
      maskId: 'exposeMask',
      loadSpeed: 'slow',
      closeSpeed: 'fast',
      closeOnClick: true,
      closeOnEsc: true,
      
      // css settings
      zIndex: 9998,
      opacity: 0.8,
      startOpacity: 0,
      color: '#fff',
      
      // callbacks
      onLoad: null,
      onClose: null
    }
  };

  /* one of the greatest headaches in the tool. finally made it */
  function viewport() {
        
    // the horror case
    if ($.browser.msie) {
      
      // if there are no scrollbars then use window.height
      var d = $(document).height(), w = $(window).height();
      
      return [
        window.innerWidth ||               // ie7+
        document.documentElement.clientWidth ||   // ie6  
        document.body.clientWidth,           // ie6 quirks mode
        d - w < 20 ? w : d
      ];
    } 
    
    // other well behaving browsers
    return [$(document).width(), $(document).height()]; 
  } 
  
  function call(fn) {
    if (fn) { return fn.call($.mask); }
  }
  
  var mask, exposed, loaded, config, overlayIndex;    
  
  
  $.mask = {
    
    load: function(conf, els) {
      
      // already loaded ?
      if (loaded) { return this; }      
      
      // configuration
      if (typeof conf == 'string') {
        conf = {color: conf};  
      }
      
      // use latest config
      conf = conf || config;
      
      config = conf = $.extend($.extend({}, tool.conf), conf);

      // get the mask
      mask = $("#" + conf.maskId);
        
      // or create it
      if (!mask.length) {
        mask = $('<div/>').attr("id", conf.maskId);
        $("body").append(mask);
      }
      
      // set position and dimensions       
      var size = viewport();
        
      mask.css({        
        position:'absolute', 
        top: 0, 
        left: 0,
        width: size[0],
        height: size[1],
        display: 'none',
        opacity: conf.startOpacity,               
        zIndex: conf.zIndex 
      });
      
      if (conf.color) {
        mask.css("backgroundColor", conf.color);  
      }      
      
      // onBeforeLoad
      if (call(conf.onBeforeLoad) === false) {
        return this;
      }
      
      // esc button
      if (conf.closeOnEsc) {            
        $(document).bind("keydown.mask", function(e) {              
          if (e.keyCode == 27) {
            $.mask.close(e);  
          }    
        });      
      }
      
      // mask click closes
      if (conf.closeOnClick) {
        mask.bind("click.mask", function(e)  {
          $.mask.close(e);    
        });          
      }      
      
      // resize mask when window is resized
      $(window).bind("resize.mask", function() {
        $.mask.fit();
      });
      
      // exposed elements
      if (els && els.length) {
        
        overlayIndex = els.eq(0).css("zIndex");

        // make sure element is positioned absolutely or relatively
        $.each(els, function() {
          var el = $(this);
          if (!/relative|absolute|fixed/i.test(el.css("position"))) {
            el.css("position", "relative");    
          }          
        });
       
        // make elements sit on top of the mask
        exposed = els.css({ zIndex: Math.max(conf.zIndex + 1, overlayIndex == 'auto' ? 0 : overlayIndex)});      
      }  
      
      // reveal mask
      mask.css({display: 'block'}).fadeTo(conf.loadSpeed, conf.opacity, function() {
        $.mask.fit(); 
        call(conf.onLoad);
        loaded = "full";
      });
      
      loaded = true;      
      return this;        
    },
    
    close: function() {
      if (loaded) {
        
        // onBeforeClose
        if (call(config.onBeforeClose) === false) { return this; }
          
        mask.fadeOut(config.closeSpeed, function()  {          
          call(config.onClose);          
          if (exposed) {
            exposed.css({zIndex: overlayIndex});            
          }        
          loaded = false;
        });        
        
        // unbind various event listeners
        $(document).unbind("keydown.mask");
        mask.unbind("click.mask");
        $(window).unbind("resize.mask");  
      }
      
      return this; 
    },
    
    fit: function() {
      if (loaded) {
        var size = viewport();        
        mask.css({width: size[0], height: size[1]});
      }        
    },
    
    getMask: function() {
      return mask;  
    },
    
    isLoaded: function(fully) {
      return fully ? loaded == 'full' : loaded;  
    }, 
    
    getConf: function() {
      return config;  
    },
    
    getExposed: function() {
      return exposed;  
    }    
  };
  
  $.fn.mask = function(conf) {
    $.mask.load(conf);
    return this;    
  };      
  
  $.fn.expose = function(conf) {
    $.mask.load(conf, this);
    return this;      
  };


})(jQuery);
