(function($) {

    $.fn.zooms = function(settings) {
        var settings = jQuery.extend({
            ZoomFactor : 200,
            InnerUpperOffset : 0,
            ImageId : 0,
            ImageWidth : 400,
            ImageHeight: 277,
        }, settings);

        var see;

        self.ZOOM_IN = 1;
        self.ZOOM_OUT = -1;
        self.ZOOM_RESET = 0;
        self.obj = this;
        self.reseted = true;
        self.search_img = $('.search_img[rel=' + settings.ImageId + ']');

        self.isDragged = false;
        self.lastLeft = self.lastTop = self.lastX = self.lastY = null;
        self.loader = $('<div class="image-loader"></div>').css({'background': 'url(/images/loader.gif) no-repeat 0 0', width: 16, height: 16, float: 'left', margin: '4px 6px 0 0'});
        self.image = $('<img class="" />').addClass('photosImage')
                                          .css({position: 'relative', border: 'none', height: settings.ImageHeight})
                                          .bind('load', _image_load)
                                          .attr({'title': self.search_img.attr('title'), 'alt': self.search_img.attr('alt')});

        function _initialize()
        {
            _start();
            return true;
        }

        function _start()
        {
            _clear_prev();
            _set_interface();
            _set_positions();
            _set_image(settings.ImageHeight);
        }

        function _clear_prev()
        {
            el = $('.photosCanvas', self.obj);
            if (el.length > 0)
                el.remove();
        }

        function _set_interface()
        {
            self.canvas = $('<div>')
                           .addClass('photosCanvas')
                           .css('cursor', 'move')
                           .bind('mousedown', _handleMouseDown)
                           .bind('mouseup', _handleMouseUp)
                           .bind('mouseout', _handleMouseUp)
                           .bind('mousemove', _handleMouseMove);


            self.obj.css('background-image', 'none')
                    .append(self.canvas.append(self.image)
                                       .append($('<div>')
                                                .append(loader)
                                                .append($('<button title="Zoom in">+</button>').bind('click', {delta: ZOOM_IN}, _zoom_click))
                                                .append($('<button title="Zoom out">-</button>').bind('click', {delta: ZOOM_OUT}, _zoom_click))
                                                .append($('<button title="Reset">Reset</button>').bind('click', {delta: ZOOM_RESET}, _zoom_click))
                                                .css({float: 'right', position: 'absolute', bottom: '0px', right: '0px'})));
        }

        function _set_image(height)
        {
            var preloadImage = new Image();
            preloadImage.onload = function() {
                self.image.attr('src', preloadImage.src);
                self.loader.hide();
                if (self.image.css('top') != 'auto' && self.image.css('left') != 'auto')
                {
                    old_left = parseFloat(self.image.css('left'))
                    old_top  = parseFloat(self.image.css('top'))
                    scaling = preloadImage.width/self.image.width(); 
                    center_x = self.canvas.width()/2;
                    center_y = self.canvas.height()/2;

                    new_left = center_x + (old_left - center_x) * scaling;
                    new_top = center_y - (center_y - old_top)  * scaling;

                    self.image.css({left: new_left, top: new_top});
                }
                self.image.css({width: preloadImage.width, height: (height < preloadImage.height) ? preloadImage.height : height});
                preloadImage.onload = function() { }
            }
            self.loader.show();
            preloadImage.src = _get_url(height);
        }

        function _get_url(height)
        {
            return (self.reseted) ? self.search_img.attr('src') : '/product/image/' + settings.ImageId + '.' + height + '.jpg';
        }

        function _image_load()
        {
            var canvasWidth = self.canvas.width();
            var canvasHeight = self.canvas.height();

            if ($(this).height() == settings.ImageHeight)
            {
                ($(this).width() > canvasWidth)
                    ? self.image.css('left', settings.InnerUpperOffset + 'px')
                    : self.image.css('left', ((canvasWidth / 2) - $(this).width() / 2) + 'px');

                ($(this).height() > canvasHeight)
                    ? self.image.css('top', settings.InnerUpperOffset + 'px')
                    : self.image.css('top', ((canvasHeight / 2) - $(this).height() / 2) + 'px');
            }
        }

        function _set_positions()
        {
            _positionCanvas();
        }

        function _positionCanvas()
        {
            self.obj.css({ position: 'relative', overflow: 'hidden'});
            self.canvas.css({position: 'absolute', left: '0px', right: '0px', top: '0px', bottom: '0px', width: '100%', height: '100%', visibility: 'visible'});
        }

        function _zoom_click(event)
        {
            var delta = event.data.delta;
            var zoomFactor = settings.ZoomFactor;
            var newHeight = null;
            var pHeight = self.image.height();
            self.reseted = false;

            if (0 == delta)
            {
                self.reseted = true;
                newHeight = settings.ImageHeight;
            }
            else if (delta > 0)
                newHeight = pHeight + zoomFactor;
            else if (delta < 0)
                newHeight = pHeight - zoomFactor;
            else
                throw new Error('Invalid delta value: ' + delta);

            _set_image(newHeight);
        }


        function _handleMouseDown(event)
        {
            self.isDragged = true;
            self.lastLeft = parseFloat(self.image.css('left'));
            self.lastTop  = parseFloat(self.image.css('top'));
            self.lastX    = event.pageX;
            self.lastY    = event.pageY;

            return false;
        }

        function _handleMouseUp(event)
        {
            self.isDragged = false;
        }

        function _handleMouseMove(event)
        {
            if (self.isDragged)
                self.image.css({left: self.lastLeft + (event.pageX - self.lastX) + 'px', top:  self.lastTop  + (event.pageY - self.lastY) + 'px'});

            return false;
        }

        return _initialize();
    }

})(jQuery);

