﻿/**
Addon function:
- TODO: hover all elements of the wrapped set
- adds functionality to the wrapped set:
- Sort of Imagemap:
  - Define 
- Define how much overlay the action wil take
- Mousemove on the body tag.
* @author    Jacob Stellingwerf <jacob.stellingwerf@infoprojects.nl>
*/
(function($){
 /*
  Chain functions down here
  */

  // Select nothing as initial set.
  var __addonSet = $("abracadabra");
  // Basket for all actions.
  var __addonActions = new Object();
 /*
  Function description here
  */
  $.fn.addon= function(shapeDefinition, mouseover, mouseout) {
		// default configuration options
    var cfg = $.extend({
        shape: "square", // possible values: square, circle (TODO: triangle, oval, poly)
        shapeDefinition: {
          upperleft: { x: 0, y: 0 },
          bottomright: { x: 10, y:10 }
        }, // example 0,0,10,10 creates a 10 by 10 box at point 0,0 
        mouseover: null,
        mouseout: null
      }, mouseover ? { 
        shapeDefinition: shapeDefinition,
        mouseover: mouseover,
        mouseout: mouseout 
      } : name || {});

    // Create mousemove 
    var _start = function() {
      if (__addonSet.size() == 0) {
        $("body").mousemove(
          function(evt) {
            _handleActions(evt.pageX, evt.pageY);
          }
        ).mouseout(
          function() {
            _handleActions(-1, -1);
          }
        );
      }
    };
    
    // Mouseenter function.
    var mouseenter = function(obj, config) {
      if (obj.attr(config.name) != "true") {
        obj.attr(config.name, "true");
        if (config.mouseover) {
          config.mouseover(obj,config);
        }
      }
    };

    // Mouseout function.
    var mouseout = function(obj,config) {
      if (obj.attr(config.name) == "true") {
        obj.attr(config.name, "false");
        if (config.mouseout) {
          config.mouseout(obj,config);
        }
      }
    };

    var _handleActions = function(x, y) {
      __addonSet.each(
        function() {
          var current = $(this);
          var rect = current.rectangle();
          x -= rect.left;
          y -= rect.top;
          
          for (var addon in __addonActions) {
            if (current.attr(addon)) {
              var config = __addonActions[addon];
	            var shape = $.fn.addon.shapes[config.shape];
	            if ($.isFunction(shape)) {
		            if(shape(current, x, y, config)) {
                  mouseenter(current, config);
                }
                else {
                  mouseout(current, config);
                }
	            }
            }
          }
        }
      );
    };
    
    var name = "addon" + $("<div></div>").makeId().attr("id");
    __addonActions[name] = $.extend(cfg, { "name": name });
    $(this).each( 
      function() {
        _start();
        var addThisOn = $(this);
        addThisOn.attr("addon", "true");
        addThisOn.attr(name, "false");
        __addonSet = __addonSet.add(addThisOn);
      }
    );
    
    return $(this);
  };

  $.fn.addon.getValue = function(current, func, x, y, config) {
      if ($.isFunction(func)) {
        return func(current, x ,y, config);
      }
      else {
        return func;
      }
    };
  


  // shape definitions - only square is defined here, shape pack defines others
  $.fn.addon.shapes = {
    square: function(current, x, y, config) {
    /*    
    shapeDefinition: {
      upperleft: { x: 0, y: 0 },
      bottomright: { x: 10, y:10 }
    } 
    */ 
      var x1 = $.fn.addon.getValue(current, config.shapeDefinition.upperleft.x, x, y, config);
      var x2 = $.fn.addon.getValue(current, config.shapeDefinition.bottomright.x, x, y, config);
      var y1 = $.fn.addon.getValue(current, config.shapeDefinition.upperleft.y, x, y, config);
      var y2 = $.fn.addon.getValue(current, config.shapeDefinition.bottomright.y, x, y, config);
  
      return (x > x1 && x < x2 && y > y1 && y < y2);
    },
    full: function(current, x, y, config) {
      return true;
    }
  };

 /*
  Global functions down here
  */
  
})(jQuery);

(function($) {
  $.fn.addon.shapes.circle = function(x, y, config) {
    /*    
    shapeDefinition: {
      origin: { x: 20, y: 20 },
      radius: 10
    } 
    */
    return (x > config.shapeDefinition.x && x < config.shapeDefinition.x2 && y > config.shapeDefinition.y1 && y < config.shapeDefinition.y2);
  };

})(jQuery);

