(function($) {

    $.imagery = function(options) {
        return $.imagery.impl.init(options);
    };

    $.fn.imagery = function(options) {
        return $.imagery.impl.init(this, options);
    };

    /*
    * default options
    */
    $.imagery.defaults = {
        res: {/* translated text goes here */
    }
};

$.imagery.impl = {

    /*
    * options
    */
    opts: null,

    /*
    * helper
    */
    helper: {},

    /*
    * alternates
    */
    alternates: {},

    /*
    * variants
    */
    variants: [],

    /*
    * dimensions
    */
    dim: {},

    /*
    * scale
    */
    scale: 1,

    /*
    * Initializes the plugin
    */
    init: function(container, options) {

        var self = this;

        this.opts = $.extend({}, $.imagery.defaults, options);

        // helper objects
        self.helper.container = container;

        self.helper.container.find('ul.variant-collection').children()
            .each(function(i, item) {

                var variant = {
                    id: $(item).attr('id'),
                    src: $.data($(item).find('img.image-detail').get(0), 'src'),
                    alternates: []
                };

                self.variants.push(variant);

            })
            ;

        self.helper.container.empty();
        self.helper.open = $('<a class="open-modal" href="#">' + self.opts.res.zoomAdditionalViews + '</a>');
        self.helper.overlay = $('<div class="modal-overlay"></div>').appendTo($('#container'));
        self.helper.modal = $('<div class="imagery-modal"><div class="imagery-bg"></div><div class="imagery"><div class="cropper"></div><ul class="thumb-collection"></ul></div><div id="debug"></div></div>').appendTo($('#container'));
        self.helper.cropper = self.helper.modal.find('div.cropper');
        self.helper.zoomTip = $('<div>' + self.opts.res.clickToZoomIn + '</div>');

        return self;
    },

    /*
    * Gets the variant
    */
    getVariant: function(id) {

        var self = this;
        var v = null;

        $.each(self.variants, function(i, item) {

            if (item['id'] == id) {
                v = item;
                return v;
            }

        });

        return v;
    },

    /*
    * Variant
    */
    variant: function(variant) {

        var self = this;
        variant = variant.replace('#', '');
        var v = self.getVariant(variant);

        self.opts.variant = variant;
        self.helper.container.empty();

        // load the detail
        $(new Image()).load(function() {

            self.helper.container.empty();

            $(this)
	            .css({
	                display: 'none'
	            })
	            .prependTo(self.helper.container)
            //.fadeIn(1000)
	            .css({
	                display: 'block'
	            })
	            ;

            // append "open" link
            self.helper.container.append(self.helper.open);

        }).attr('src', v.src);

        // bind open modal click
        self.helper.container
            .unbind()
            .click(function(e) {
                e.preventDefault();
                self.modal();
            })
            ;

        return;
    },

    /*
    * Modal
    */
    modal: function() {

        var self = this;
        var v = self.getVariant(self.opts.variant);

        self.helper.thumbs = self.helper.modal.find('.thumb-collection').empty();
        self.helper.cropper = self.helper.modal.find('.cropper').empty();
        self.helper.close = $('<a class="close-imagery" href="#">' + self.opts.res.close + '</a>').appendTo(self.helper.modal);

        function callback() {

            $.each(v.alternates, function(i, item) {

                var $thumb = $('<li class="thumb"></li>').appendTo(self.helper.thumbs);

                $(new Image()).load(function() {

                    $thumb
                        .append($(this).addClass('image-a'))
                        ;

                }).attr('src', v.alternates[i].srcA);

            });

            // show the overlay
            self.helper.overlay
                .fadeIn(1000)
                ;

            // show the modal
            self.helper.modal
                .css({
                    marginLeft: -parseInt(self.helper.modal.css('width')) / 2 + 'px',
                    marginTop: -parseInt(self.helper.modal.css('height')) / 2 + 'px'
                })
                .fadeIn(1000, function() {

                    // set the dimensions
                    self.dim.w = $(self.helper.thumbs.children()[0]).width();
                    self.dim.h = $(self.helper.thumbs.children()[0]).height();

                    // load the image
                    self.load(0);

                    self.helper.cropper
                        .tooltip({
                            id: 'imagery-tooltip',
                            track: true,
                            showURL: false,
                            delay: 0,
                            bodyHandler: function() {
                                return self.helper.zoomTip;
                            }
                        })
                        ;
                })
                ;

            // bind thumb click
            self.helper.thumbs.children().click(function(e) {

                if ($(this).hasClass('thumb-active'))
                    return;

                // relative cursor position relative to thumb
                var pos = {
                    x: (e.pageX - $(this).offset().left) / self.dim.w,
                    y: (e.pageY - $(this).offset().top) / self.dim.h
                };

                self.load($(this).prevAll('.thumb').length, 'b', pos);

            });

            // bind close click
            self.helper.close.click(function(e) {
                e.preventDefault();

                self.hide();

            });

            self.helper.overlay.click(function(e) {
                e.preventDefault();

                self.hide();

            });

        }

        if (v.alternates.length < 1)
            CreateThe.Com.Web.CodeBase.WebServices.ProductService.GetImages(self.opts.productId, self.opts.folderId, self.opts.root, self.opts.lang, self.opts.region, self.opts.priceCode, v.id, $.imagery.impl.getImagesSuccess, $.imagery.impl.getFailure, callback);
        else
            callback();

        return;
    },

    /*
    * GetImages success
    */
    getImagesSuccess: function(data, callback) {

        var self = $.imagery.impl;
        var variant = self.getVariant(self.opts.variant);

        if (data.length < 1)
            return;

        $.each(data, function(i, image) {

            var alt = {
                srcA: String.format(image, 'products/' + self.opts.dimensions.thumb + '/'),
                srcB: String.format(image, 'products/' + self.opts.dimensions.detail + '/'),
                srcC: String.format(image)
            };

            variant.alternates.push(alt);

        });

        callback();

    },

    /*
    * Hide
    */
    hide: function() {

        var self = this;

        self.helper.overlay
            .fadeOut(1000)
            ;

        self.helper.modal
            .fadeOut(1000)
            ;

        return;
    },

    /*
    * Load
    */
    load: function(index, size, pos) {

        var self = this;
        var v = self.getVariant(self.opts.variant);

        index = index || 0;
        size = size || 'b';
        pos = pos || { x: 0, y: 0 };

        // reset
        self.helper.thumbs.find('div.handle')
		        .remove()
		        ;
        self.helper.cropper
		        .empty()
		        ;
        $('div#imagery-tooltip')
		        .css({
		            display: 'none'
		        })
		        ;

        var $thumb = $(self.helper.thumbs.children()[index]);
        var $handle = $('<div class="handle"><div class="handle-border"></div><div class="handle-bg"></div></div>').css('display', 'none').appendTo($thumb);
        var src = (size == 'c') ? v.alternates[index].srcC : v.alternates[index].srcB;

        $thumb
		        .addClass('thumb-active')
		        .siblings()
		        .removeClass('thumb-active')
		        ;

        // load the image
        $(new Image()).load(function() {

            self.helper.imgB = $(this);

            // append the image
            self.helper.imgB
		            .appendTo(self.helper.cropper)
		            .css({
		                display: 'block',
		                opacity: 0
		            })
		            ;

            // set the dimensions
            self.dim.W = self.helper.imgB.width();
            self.dim.H = self.helper.imgB.height();
            self.scale = self.dim.H / self.dim.h;

            var $tip = $('#imagery-tooltip .body div');

            // resize the handle
            if (size == 'c') {
                $handle
                        .css({
                            width: Math.floor(parseInt($handle.css('width')) * 2 / 3) + 'px',
                            height: Math.floor(parseInt($handle.css('height')) * 2 / 3) + 'px'
                        })
                        ;

                $tip
                        .text(self.opts.res.clickToZoomOut)
                        ;
            }
            else {
                $tip
                        .text(self.opts.res.clickToZoomIn)
                        ;
            }

            // set initial offset of the handle
            var hOffset = self.getHandleOffset(pos, $handle);

            // init the handle
            $handle.find('.handle-border')
                .css({
                    width: $handle.width() - 2 + 'px',
                    height: $handle.height() - 2 + 'px'
                })
                ;

            $handle
                .css({
                    left: hOffset.x,
                    top: hOffset.y
                })
                .draggable({
                    containment: $handle.parent(),
                    drag: self.drag
                })
                .fadeIn(500)
                ;

            // show the image
            self.helper.imgB
                .css({
                    left: -hOffset.x * self.scale,
                    top: -hOffset.y * self.scale,
                    display: 'none',
                    opacity: '1.00'
                })
                .fadeIn(1000)
                ;

            // bind the zoom click
            self.helper.imgB.unbind().click(function(e) {

                // relative cursor position relative to image
                var pos = {
                    x: (e.pageX - $(this).offset().left) / self.dim.W,
                    y: (e.pageY - $(this).offset().top) / self.dim.H
                };

                var newSize = 'c';

                if (size == 'c')
                    newSize = 'b'

                self.load(index, newSize, pos);
            });

        }).attr('src', src);

        return;
    },

    /*
    * Drag
    */
    drag: function(e, ui) {

        var self = $.imagery.impl;
        var pos = {
            x: ui.position.left,
            y: ui.position.top,
            X: ui.position.left * self.scale,
            Y: ui.position.top * self.scale
        }

        //$('#debug').html(pos.x + ', ' + pos.y + '<br />' + pos.X + ', ' + pos.Y);

        self.helper.imgB
		        .css({
		            left: -pos.X + 'px',
		            top: -pos.Y + 'px'
		        })
		        ;

        return;
    },

    /*
    * Gets the handle offset
    */
    getHandleOffset: function(pos, $h) {

        var self = this;
        var h = { x: 0, y: 0 }
        var hW = $h.width();
        var hH = $h.height();

        if (pos.x >= 0) {
            h.x = Math.floor(pos.x * self.dim.w) - Math.floor(hW / 2);

            if (h.x < 0)
                h.x = 0;
            else if (h.x + hW > self.dim.w)
                h.x = self.dim.w - hW;
        }

        if (pos.y >= 0) {
            h.y = Math.floor(pos.y * self.dim.h) - Math.floor(hH / 2);

            if (h.y < 0)
                h.y = 0;
            else if (h.y + hH > self.dim.h)
                h.y = self.dim.h - hH;
        }

        return h;
    },

    /*
    * Get Failure
    */
    getFailure: function() {

        //alert('failure');

    }

};
})(jQuery);

// string format function
String.format = function(text) {
    
    if (arguments.length <= 1)
        return text;
    
    var tokenCount = arguments.length - 2;
    
    for(var token = 0; token <= tokenCount; token++)
        text = text.replace(new RegExp('\\{' + token + '\\}', 'gi' ), arguments[token + 1]);
    
    return text;
};
