/*
 * Custom jQuery UI Swappable for MatchTextQuestion
 *
 * Based on jquery.ui.swappable.js
 *
 * Depends:
 *		jquery.ui.core.js
 *		jquery.ui.mouse.js
 *		jquery.ui.widget.js
 *  	jquery.ui.sortable.js
 *  	jquery.ui.swappable.js
 *
 * Usage:
 *
 *		Option's specific:
 *
 *		1. Always set option "cursorAt: {top: -nnn}" as a Negative Integer.
 *		2. Always set option "items" with items' class name, not element or filter.
 *
 *		Example:
 *			
 *			<ul id="foo">
 *				<li class="bar"><li>
 *				<li class="bar"><li>
 *				<li class="bar"><li>
 *			</ul>
 *			
 *			$("#foo").swappable_matchtextquestion({
 *				items:'.bar', // Mandatory option, class only.
 *				cursorAt: {top:-20}, // MUST be set to negative. Default doesn't work!
 *			});
 */

(function($) {

    $.widget("ui.swappable_matchtextquestion", $.ui.swappable, {

        _mouseStop: function(event, noPropagation) {

            if (!event) return;

            var o = this.options;
            var target = event.target;

            var scrollY = $(window).scrollTop();

            // coordinates of ative item rect
            var topLeftX = event.pageX - coordClickRelativeToItemX - coordClickRelativeToItemX / 2;
            var topLeftY = event.pageY - coordClickRelativeToItemY - o.cursorAt.top - coordClickRelativeToItemY / 2 - scrollY;
            var bottomRightX = event.pageX - coordClickRelativeToItemX + target.clientWidth + coordClickRelativeToItemX / 2;
            var bottomRightY = event.pageY - coordClickRelativeToItemY - o.cursorAt.top + target.clientHeight + coordClickRelativeToItemY / 2 - scrollY;

            var itemActive = this.currentItem.closest(o.items);

            // calculate squares of intersections
            var squares = new Array(this.items.length);

            for (var i = 0; i < this.items.length; i++) {
                if (this.items[i].item[0] != undefined && itemActive[0] != undefined && this.items[i].item[0].id != itemActive[0].id) {
                    var rect = this.items[i].item[0].getBoundingClientRect();

                    if (rect.left <= topLeftX && rect.top <= topLeftY &&
                        topLeftX <= rect.right && topLeftY <= rect.bottom) {
                        squares[i] = (rect.right - topLeftX) * (rect.bottom - topLeftY);
                    }
                    else if (bottomRightX >= rect.left && topLeftY <= rect.bottom &&
                             rect.left >= topLeftX && rect.bottom <= bottomRightY) {
                        squares[i] = (bottomRightX - rect.left) * (rect.bottom - topLeftY);
                    }
                    else if (topLeftX <= rect.left && topLeftY <= rect.top &&
                             rect.left <= bottomRightX && rect.top <= bottomRightY) {
                        squares[i] = (bottomRightX - rect.left) * (bottomRightY - rect.top);
                    }
                    else if (bottomRightX >= rect.right && topLeftY <= rect.top &&
                             rect.right >= topLeftX && rect.top <= bottomRightY) {
                        squares[i] = (rect.right - topLeftX) * (bottomRightY - rect.top);
                    }
                    else {
                        squares[i] = 0;
                    }
                }
                else {
                    squares[i] = 0;
                }
            }

            // find index of maximum square value
            var indexOfMaxSquare = -1;
            var maxSquareValue = 0;
            for (var i = 0; i < squares.length; i++) {
                if (squares[i] > maxSquareValue) {
                    maxSquareValue = squares[i];
                    indexOfMaxSquare = i;
                }
            }

            var itemPassive;
            if (indexOfMaxSquare > -1) {
                itemPassive = this.items[indexOfMaxSquare].item[0];
            }

            var itemPlaceholder = $(itemActive).next();

            $(itemPassive).after(itemActive);
            $(itemPlaceholder).after(itemPassive);

            //If we are using droppables, inform the manager about the drop
            if ($.ui.ddmanager && !this.options.dropBehaviour)
                $.ui.ddmanager.drop(this, event);

            if (this.options.revert) {
                var self = this;
                var cur = self.placeholder.offset();

                self.reverting = true;

                $(this.helper).animate({
                    left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
                    top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
                }, parseInt(this.options.revert, 10) || 500, function() {
                    self._clear(event);
                });
            } else {
                /***************************************/
                /* NOTE: VYL 20110608.
                hack to fix defect:
                reproduced in IE8.
                swap 1st and 3d elements such way that 1st element will be between 3d and 4th.
                than when you drop the item, the items 1 and 3 will be swapped. But you will see no margins between 2, 1 and 4.
                See http://vadimkir.blogspot.com/2010/08/swappable-jquery-plugin.html?showComment=1306928185643#c2792865959584553591
                */
                if ($.browser.msie) {
                    target.click();
                }
                /***************************************/

                this._clear(event, noPropagation);
            }

            return false;

        }

    });

    $.extend($.ui.swappable_matchtextquestion, {
        version: "0.9.5"
    });

})(jQuery);
