/*
 * objectZoomer
 * Description: This plugin slowly zooms and zooms out the given object when clicked 
 * Author: Lukas Pesl
 * Version : 0.1 
 * 
 * Long Description: Intention of the plugin is to allow zoom (resize) any element like div or img.
 * If given, the element is zoomed to options.maxWidth value, and as maximized height is used the height which
 * is equivalent to ratio of current minimized width and height and the maxWidth value.
 * 
 * If the options.maxWidth is not given, and the actual element is image, then as maxWidth is used the width=""
 * attr of the image (Which is taken as the informative original size of the image). If the current element is not img, the 
 * img.zoomable is being searched withing the current element.
 * 
 * Another important parameter is options.maxAllowedWidth, which if computed maxWidth > options.maxAllowedWidth, then
 * options.maxAllowedWidth is used instead.        
 *  
 */   

(function($){
  
  $.fn.extend({ 
		objectZoomer: function(options) {

			var defaults = {
 				maxAllowedWidth: 0, 
				supressMarginBeforeMaximize: {Left : false, Right : false},
        onBeforeMaximized : function(){},
				onAfterMinimized : function(){},
				onAfterMaximized : function(){}
			};
			
			var options = $.extend(defaults, options);
			var selector = this.selector;
    	var getElementAttr = function($obj, attr) {
        //obj[0].getAttribute(attr); unfortunatelly this does not work good in IE6-7 
        var html = $('<div>').append($obj.clone()).remove().html().toLowerCase();
        var a = html.indexOf(attr + '=');
        var b = html.indexOf(' ', a) != -1 ? html.indexOf(' ', a) : html.indexOf('>', a);
        return html.substring(a + String(attr + '=').length, b).replace(/"/g,'');
      }
		
  		return this.each(function() {
				var obj = $(this);
				
        var dimensions = {
  				minWidth: obj.width(),
  				minHeight: obj.height(),
  				maxWidth: options.maxWidth,
  				maxHeight: 0,
  				onBeforeMaximized : function(){},
  				onAfterMinimized : function(){},
  				originalMargin : {},
  				originalMarginSum : 0
  			};

  			// If there is no options.maxWidth given, then the maxWidth will be get from the width attr of the image .zoomable class
        if (dimensions.maxWidth == null)
  			{
    			// or taken from actual element, if actual element is directly image.
          if (obj[0].nodeName == 'IMG')
          {
            dimensions.maxWidth = getElementAttr(obj, 'width');
          } else
          {
            var $img = $('.zoomable', obj); 
            dimensions.maxWidth = parseFloat(getElementAttr($img, 'width')) + parseFloat(dimensions.minWidth - $img.width());
          }
        }
        dimensions.maxWidth = dimensions.maxWidth > options.maxAllowedWidth ? options.maxAllowedWidth : dimensions.maxWidth;
        dimensions.maxWidth = dimensions.maxWidth - parseFloat(obj.css('paddingLeft')) - parseFloat(obj.css('paddingRight'));

        $.each(options.supressMarginBeforeMaximize, function(key, val){
          if (val) {
            dimensions.originalMargin[key] = obj.css('margin' + key);
            dimensions.originalMarginSum += parseFloat(obj.css('margin' + key));  
          }
        });

        // maxHeight is computed using ratio and maxWidth value
        var ratio = dimensions.minWidth / dimensions.minHeight;
  			dimensions.maxHeight = dimensions.maxWidth / ratio;
  			obj.data('dimensions', dimensions);
        
        obj.click(function() {

          var zoomed = obj.hasClass('zoomed');
					var selectorList = selector.split(',');
          $.each(selectorList, function(key, value){
            $(selectorList[key] + '.zoomed').each(function(){
              var fnc = function (obj) {
                return function()
                {
                  $.each(options.supressMarginBeforeMaximize, function(key, val){
                    if (val) {
                      $(obj).css('margin' + key, $(obj).data('dimensions').originalMargin[key]); 
                    }
                  });
                  options.onAfterMinimized.call(obj);
                }
              }
              $(this).animate({width: $(this).data('dimensions').minWidth/*, height: $(this).data('dimensions').minHeight*/}, 300, 'swing', fnc(this)).removeClass('zoomed');
            });
          });
					if (!zoomed)
					{
            $.each(options.supressMarginBeforeMaximize, function(key, val){
              if (val) {
                if (dimensions.originalMarginSum + dimensions.maxWidth > options.maxAllowedWidth)
                  obj.css('margin' + key, '0');
              }
            });
					  options.onBeforeMaximized.call(this);
            var c = function() {options.onAfterMaximized.call(this);};
						obj.animate({width: dimensions.maxWidth/*, height: dimensions.maxHeight*/}, 300, 'swing', c);
					  obj.addClass('zoomed');
					}
				}); // click()
				
  		});
  	}
	});
})(jQuery);



