(function($){

  // XXX Any way to get selector name rather than string riteral?
  var selector = ".elastic";

  $.fn.elasticate = function() {

	$(document).ready(function() {
	  $(selector).initialize();
	  $(selector).fit();
	});

	$(window).bind("resize", function(){
      $(selector).fit(); 
	});
  }

  $.fn.initialize = function() {
    this.each(function() {
      this.ratio = custom_round($(this).height() / $(this).width());
      this.fixHorizontal = $(this).attr("align");
      this.fixVertical = $(this).attr("valign");
    });
  };

  $.fn.fit = function() {
    return this.each(function() {
      if (this.style.display == "none") {
        return;
      }

      //alert(isNaN(this.ratio) + " - " + $(this).height() + "/" + $(this).width());
      if (isNaN(this.ratio)) {
        this.ratio = custom_round($(this).height() / $(this).width());
        this.fixHorizontal = $(this).attr("align");
        this.fixVertical = $(this).attr("valign");
      }

      if (isNaN(this.ratio)) {
        return;
      }

	  var imageWidth = $(this).width();
	  var imageHeight = $(this).height();
	  var windowWidth = getWindowWidth();
	  var windowHeight = getWindowHeight();
	  if ((windowHeight/windowWidth) > this.ratio){
        var newWidth = custom_round(windowHeight / this.ratio);
        //alert("resize to: width " + windowHeight+ "*" + this.ratio + " = " + newWidth);
        // adjust image height to window
        if (this.fixHorizontal == "left") {
          $(this).css("left", 0);
        } else if (this.fixHorizontal == "center") {
          $(this).css("left", (windowWidth - newWidth) / 2);
        } else if (this.fixHorizontal == "right") {
          $(this).css("right", 0);
        }
		$(this).height(windowHeight);
		$(this).width(newWidth);
	  } else {
        var newHeight = custom_round(windowWidth * this.ratio);
        //alert("resize to: height " + $(window).width() + "*" + this.ratio + " = " + newHeight);
        // adjust image width to window
		$(this).width(windowWidth);
		$(this).height(newHeight);
        if (this.fixVertical == "top") {
          $(this).css("top", 0);
        } else if (this.fixVertical == "middle") {
          $(this).css("top", (windowHeight - newHeight) / 2);
        } else if (this.fixVertical == "bottom") {
          $(this).css("top", windowHeight - newHeight);
        }
	  }
      //alert($(this).css("top") + "/" + $(this).css("left"));
    });

  };

  function custom_round(num) {
    //alert("round: " + num + " -> " + (Math.round(num / 0.00001) * 0.00001));
    return Math.round(num / 0.00001) * 0.00001;
  }


  // XXX safari returns invalid value with jquery '$(window).width()'
  function getWindowWidth() {
    if ($.browser.safari) {
      return window.innerWidth;
    }
    return $(window).width();
  }

  // XXX safari returns invalid value with jquery '$(window).height()'
  function getWindowHeight() {
    if ($.browser.safari) {
      return window.innerHeight;
    }
    return $(window).height();
  }

})(jQuery);
