$.fn.drag = function(option, callback)
{
    if(arguments.length == 1)
    {
         if(typeof option == 'function')
         {
            var callback = option;
            var option = {};
         }
         else if (typeof option == 'object'){
            var callback = false;
            var option = option;   
         }
    }
    else if(arguments.length == 0)
    {
        var callback = false;
        var option = {};
    }
    else
    {
        var callback = callback;
        var option = option;
    }
    
    /* option */
    option = jQuery.extend({
        x: false,
        y: true,
        testX: true,
        testY: true,
        maxX : false, // pravy okraj
        minX : false, // levy okraj  
        maxY : false, // dolni okraj 
        minY : false, // horni okraj 
        backAnimation: true,
        dragSelector: '.drag'
    }, option);

    function dimension(el){
        this.el = el;
        this.width = this.el.outerWidth();
        this.height = this.el.outerHeight();
        this.left = this.el[0].offsetLeft;
        this.right = this.left + this.width;
        this.top = this.el[0].offsetTop;
        this.bottom = this.top + this.height;
        this.middle = this.top + (this.height/2);
        this.center = this.left + (this.width/2);
    }
    
    $(this).each(function(){
        var that = $(this);
        var target = null;
        var list = [];
        var pos = {};
        var help = $('<li class="helpDrag controlEl"></li>');
        var allEl = $(that).find(''+option.dragSelector);
    
        var Drag = {
            init: function(){
                    allEl.bind('mousedown', Drag.drag);
                }
            // Chycení elementu
            ,drag: function(e){
                if(e.target.tagName != 'A'){

                    e.preventDefault();
                    e.stopPropagation();
                    //alert(e.originalEvent.layerY);
                    
                    
                    if(option.backAnimation){
                        allEl.stop().css({'position': 'relative', 'top': '0px', 'left': '0px', 'z-index': '1'});
                    }
                    
                    // seznam vsech presunovatelnych elementu    
                    allEl.each(function(i){
                        $(this).addClass('controlEl').removeClass('dragged');
                        list[i] = new dimension($(this));
                    });
                    
                    // aktuální element
                    var index = allEl.index($(this));
                    target = list[index];
                    target.el.removeClass('controlEl').addClass('dragged');
                    target.pTop = target.el.offsetParent().offset().top;
                    target.pLeft = target.el.offsetParent().offset().left;
                    target.layerY = e.pageY - target.el.offset().top;
                    target.layerX = e.pageX - target.el.offset().left;
                    target.index = index;                    
                    height = target.el.height() + 5;
                    $('.shadow', target.el).css('height', height);
										//$('.shadow', this).css('height', height);
                    
                    //alert(target.layerY)
                    
                    //pozice
                    var x = option.x ? e.pageX - target.pLeft - target.layerX : 0;
                    var y = option.y ? e.pageY - target.pTop - target.layerY : 0;
                    $(target.el).css({'position':'absolute', 'top':y + 'px', 'left':x + 'px', 'z-index':'99'});
                    help.insertAfter(target.el).css({'width': target.width, 'height': target.height});
                    
                    // zapsani aktualní pozice
                    pos.x = x;
                    pos.y = y;
                     
                    // funkce
                    $(document).bind('mousemove', Drag.move);
                    $(document).bind('mouseup', Drag.drop);
               
                
                }

            }
            // Táhnutí elementu
            ,move: function(e){
                
                e.preventDefault();
                e.stopPropagation();
                
                // prepocitavani pozice
                var x = option.x ? e.pageX - target.pLeft - target.layerX : pos.x;
                    x = option.minX === false ? x : x < option.minX ? option.minX : x;
                    x = option.maxX === false ? x : x + target.width > option.maxX ? option.maxX - target.width : x;             
                var y = option.y ? e.pageY - target.pTop - target.layerY : pos.y;
                    y = option.minY === false ? y : y < option.minY ? option.minY : y;
                    y = option.maxY === false ? y : y + target.height > option.maxY ? option.maxY - target.height : y; 
                target.el.css({'top': y + 'px', 'left': x + 'px'})
                
                // podminky
                var up = pos.y > y;
                var down = pos.y < y;
                var left = pos.x > x;
                var right = pos.x < x;
                var recalc = false;
                
                // zapsani aktualní pozice
                pos.x = x;
                pos.y = y;
                
                // POSUN po Y-ové souřadnici
                if(option.testY){
                    // táhnutí nahoru
                    if(up){
                        $.each(list, function(i){
                                if(list[i].top < y && y <= list[i].middle && i != target.index)
                                {
                                    list[i].el.before(help);
                                    recalc = true;
                                    return;
                                }
                            
                        });
                    }
                    // táhnutí dolů
                    if(down){
                        $.each(list, function(i){
                                if(list[i].bottom > (y + target.height) && (y + target.height) >= list[i].middle && i != target.index)
                                {
                                    list[i].el.after(help);
                                    recalc = true;
                                    return;  
                                }
                            
                        });
                    }
                }
                // rekalkulace
                if(recalc){
                    $(that).find('.controlEl').each(function(i){
                        list[i] = new dimension($(this));
                    });
                    target.index = $(that).find('.controlEl').index(help);
                } 
            }
            // Puštění elementu
            ,drop: function(e){
                
                e.preventDefault();
                e.stopPropagation();
            		
            		$('.shadow', target.el).css('height', '0');
            		
                $(document).unbind('mousemove mouseup');
                help.after(target.el);
                if(option.backAnimation){
                    var time = Math.max(Math.abs(help[0].offsetTop - pos.y), Math.abs(help[0].offsetLeft - pos.x)) * 3;
                        time = time > 500 ? 500 : time;
                    target.el.animate({'top': help[0].offsetTop, 'left': help[0].offsetLeft}, time, function(){
                    target.el.removeClass('dragged');
                        help.remove();
                        target.el.css({'position': 'relative', 'top': '0px', 'left': '0px', 'z-index': '1'});  
                        if(callback){
                            callback.call(target.el);
                        }  
                    });
                }
                else{
                    target.el.removeClass('dragged');
                    help.remove();
                    target.el.css({'position': 'relative', 'top': '0px', 'left': '0px', 'z-index': '1'});
                    if(callback){
                        callback.call(target.el);
                    }
                }
                
                //target = null;
            }
        };
        Drag.init();
    });
};
