$(function() {
  $.bbzoom = function(settings) {
    var config = {
      thumbs : $("#other_images"),
      image : $(".product_main"),
      zoom : $("#image_zoom"),
      width : 403,
      height : 300
    };
    if (settings) $.extend(config, settings);
    
    config.image.css({cursor : "crosshair"});
    config.image.parent("a").css({display:"block"});
    
    $("#product_image_loading").css({
      "margin-left" : (315 / 2) - ($("#product_image_loading").outerWidth() / 2) + "px"
    });
    
    var as = config.thumbs.find("a");
    
    as.bind("click", function() {
      var a = $(this);
      var img = a.find("img");
      if (img.hasClass("img_selected")) return false;
      
      var loaded;
      as.find("img").removeClass("img_selected");
      $("#viewport").remove();
      
      var coord = $.coordinate(2, function() {
        var finish = function() {
          $("#product_image_loading").hide();
          $(this).attr("src", loaded.src).animate({opacity : 1});
          
          img.addClass("img_selected");
          config.image.parent("a").attr("href", a.attr("large"));
        }
        if (config.image.css("height") == loaded.height) {
          finish.apply(config.image);
        } else {
          config.image.animate({height : loaded.height}, finish);
        }
      });
      
      config.image.animate({opacity : 0}, function() { $("#product_image_loading").show(); coord(); });
      loaded = $.loadimage(a.attr("href"),  coord);

      return false;
    });
    
    var imgzoomratio;
    var zoomviewratio;
    var viewporttimer = false;

    $(config.image.selector+", #viewport").live("click", function() {
      return false;
    }).live("mouseenter mousemove", function(e) {
      if (viewporttimer) clearTimeout(viewporttimer);

      var img = config.image;
      
      if (img.filter(":animated").length) return;
      if ($("#product_image_loading:visible").length) return;
      
      var a = img.parent("a");
      var zoomimg = config.zoom.find("img");
      
      var finish = function() {
        var x = Math.round((e.pageX - img.offset().left) * imgzoomratio) - (config.width/2);
        var y = Math.round((e.pageY - img.offset().top) * imgzoomratio) - (config.height/2);
            
        if (x < 0) x = 0;
        if (y < 0) y = 0;
        if (x + config.width > zoomimg.width()) x = zoomimg.width() - config.width;
        if (y + config.height > zoomimg.height()) y = zoomimg.height() - config.height;
        
        zoomimg.css({
          margin: (-y)+"px 0 0 "+(-x)+"px",
          clip: "rect("+y+"px, "+(x+config.width)+"px, "+(y+config.height)+"px, "+x+"px)"
        });
        
        //put viewport thingy here
        if (!$("#viewport").length) {
          img.before("<div id='viewport'></div>");
          $("#viewport").css({
            position: "absolute",
            background: "#fff",
            opacity: 0.6,
            width: config.width / imgzoomratio,
            height: config.height / imgzoomratio,
            cursor: "crosshair"
          });
        }
        $("#viewport").css({
          top: img.position().top + (y / imgzoomratio),
          left: img.position().left + (x / imgzoomratio),
        }).show();
      };

      if (config.zoom.filter(":visible").length == 0) {
        $("#product_image_loading").show();
        $.loadimage(a.attr("href"), function() {
          $("#product_image_loading").hide();
          zoomviewratio = this.height / config.height;
          imgzoomratio = this.height / img.height();
          
          config.zoom.empty().append("<img>").show();
          zoomimg = config.zoom.find("img");

          zoomimg.attr("src", this.src).css({position: "absolute"});
          finish();
        });
      } else {
        finish();
      }
    }).live("mouseleave", function(e) {
      if (viewporttimer) clearTimeout(viewporttimer);
      viewporttimer = setTimeout(function() {
        $("#viewport").hide();
        config.zoom.hide();
      }, 100);
    });
  }
});
