/**
* proximifade jQueryPlugin
* @version 0.1
* @author Dave Kinsella <kinsella.dave@gmail.com>
* @copyright 2009 Dave Kinsella - http://webdeveloper2.com
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

  $.fn.proximifade = function(options) {
  // work out main settings (without metadata) - only do this work once per plugin call
    $.fn.proximifade.defaults = {
        innerDistance: 20,
        outerDistance: 150,
        minOpacity: 0.1,
        outOpacity: 0,
        activeElement: $(this).parent()
    };
    var main_opts = $.extend({}, $.fn.proximifade.defaults, options);
    return this.each(function() {
        var $this = $(this);
        // if metadata is present, extend main_opts, otherwise just use main_opts
        var opts = $.meta ? $.extend({}, main_opts, $this.data()) : main_opts;

        $this.animate({opacity: opts.outOpacity},{duration:2000, queue:false});
        opts.activeElement.bind("mouseleave", function(e){
          $this.stop();
          $this.animate({opacity: opts.outOpacity},{duration:1000, queue:false});
        });
        opts.activeElement.bind("mousemove", function(e){
              //get the closest bounding values
              var Xbound = $this.position().left;
              if((e.pageX - ($this.position().left + $this.outerWidth())) > 0){
                Xbound += $this.outerWidth();
              }else if((e.pageX - $this.position().left) > 0){
                Xbound = e.pageX;
              }
              var Ybound = $this.position().top;
              if((e.pageY - ($this.position().top + $this.outerHeight())) > 0){
                Ybound += $this.outerHeight();
              }else if((e.pageY - $this.position().top) > 0){
                Ybound = e.pageY;
              }
              // Compare to the mouse position
              var difX = e.pageX - Xbound;
              var difY = e.pageY - Ybound;
              var dist = Math.sqrt ((difX * difX) + (difY * difY));
              var eff = ((dist - opts.innerDistance) / opts.outerDistance).constrain(0,1);
              //$('#debug').text(e.pageX + "," + e.pageY + " : " + Xbound + ", " + Ybound + " : " + dist + "," + eff);
              $this.stop();
              //var targetOpacity = ((opts.minOpacity + 1) - eff);
              $this.animate({opacity: ((opts.minOpacity + 1) - eff).constrain(0,1)},{duration:0, queue:false});
        });
    });
  };
  Number.prototype.constrain = function(v1, v2) {
    var max = Math.max(v1, v2), min = Math.min(v1, v2);
    return this > max ? max : this < min ? min : parseFloat(this);
  };