/* Class PlaylistItemDD 
   makes drag and drop for playlist items
*/
function PlaylistItemDD () 
{
    
    this.rel_offset_x;
    this.rel_offset_y;
    this.max_from_left;
    this.max_from_top;
    
    this.current_left_position=0;
    this.current_top_position=0;
    
    /* dragged object */
    this.draged_object=null;
    
    /* container for dragged object */
    this.container=null;
    
    /* list of possible drop targets */
    this.dropTargets = []; 
    
    /* object under current position of draged object */
    this.underlyingObject=null;
    
    /*active scroll areas*/
    this.scrollHotSpotTop=null;
    this.scrollHotSpotBottom=null;
    this.scrollingNow=false;
    this.scrollStarted=false;
    
    this.dragCursorOffsetRight = 0; 
    this.dragCursorOffsetBottom = 0;
    
    //this.mediaPlayerId = "MediaPlayer";
    this.DDPlayArea = "dd_play_area";
    
    //used for move event trigger fix in IE
    this.mouseStartDragCoordx = null;
    this.mouseStartDragCoordy = null;
    
    
    this.drag = function(evt) 
    {
        this.mouseMovedAfterDown = false;
        /// <summary>Dragging</summary>
        /// <param name="evt" type="object">Event</param>
        /// <returns type="array"/>
        if (this.container!=null) {
         var hoveredItem = $(evt.currentTarget).parent().parent();
   
            var ret=Array();
            ret[0]=Math.round(this.current_left_position);
            ret[1]=Math.round(this.current_top_position);
            
            this.draged_object=$(hoveredItem);
            this.container.html(this.draged_object.html());
            
            var left = this.mouseX(evt);
            var top = this.mouseY(evt);
            this.dragCursorOffsetRight = evt.pageX - hoveredItem.offset().left;
            this.dragCursorOffsetBottom = evt.pageY - hoveredItem.offset().top;
            
            try {
                this.mouseStartDragCoordx = window.curMousePosx;
                this.mouseStartDragCoordy = window.curMousePosy;
            } catch (e) {}
                
            return ret; // actual position of DD object
        }
    }
   
   
    this.move = function(evt)
    {
        /// <summary>Move cursor</summary>
        /// <param name="evt" type="object">Event</param>
        /// <returns type="void"/>
        
        window.curMousePosx = evt.pageX;
        window.curMousePosy = evt.pageY;
        
        if(this.draged_object!=null && this.container!=null && (window.curMousePosx!=this.mouseStartDragCoordx || window.curMousePosy!=this.mouseStartDragCoordy)){


            //this.mouseStartDragCoordx = null;
            //this.mouseStartDragCoordy = null;    

            var left = (this.mouseX(evt)-this.dragCursorOffsetRight); 
            var top = (this.mouseY(evt)-this.dragCursorOffsetBottom);
        	
            if (left < 0) left = 0;
            else if (left > this.max_from_left) left = this.max_from_left;
        	
            if (top < 0) top = 0;
        	
            this.moveContainer(left,top);
            
            var underlyingObject = this.calculateDrop(evt);
            
            this.clearDragBorders();
            
            this.scrollingNow=false;
            
            //if there is any underlying object
            if (underlyingObject!=null) {
             
                if (underlyingObject.id=='scroll_hotspot_top') {

                    this.scrollingNow=true;
                    this.startScroll('top');
                    
                } else if (underlyingObject.id=='scroll_hotspot_bottom') {

                    this.scrollingNow=true;
                    this.startScroll('bottom');
                    
                } else {
                
                    // store the underlying object, so it can be used by this.drop method from now
                    this.underlyingObject = underlyingObject;
                    
                }
            }
            
            if (this.underlyingObject!=null && this.underlyingObject.id!=this.DDPlayArea) {
                    //show possible drop position
                    this.showDragBorder (this.underlyingObject.id);
                }
            
             
            //if we are not moving acros active scroll area, stop scrolling, if there is any
                if (this.scrollingNow==false) {
                    this.stopScroll();
                }
            
            this.current_left_position = left;
            this.current_top_position = top;
        }
    }
    
   
    this.drop = function(evt)
    {
        /// <summary>Drops playlist item</summary>
        /// <param name="evt" type="object">Event</param>
        /// <returns type="void"/>
        if(this.draged_object!=null){
        
            var underlyingObject;
            if (this.underlyingObject!=null) {
                //check underlying object from past of this drag
                underlyingObject = this.underlyingObject;
            } else {
                //check current underlying object
                underlyingObject = this.calculateDrop(evt);
            }
            
            
            if (underlyingObject!=null) {
                
                if (underlyingObject.id==this.DDPlayArea) {
                
                    //succesful drop to flash player
                    document.playlist.playItem(this.draged_object.attr("id"));
                
                } else if (this.draged_object.attr("id")!=underlyingObject.id) {
                
                    //succesful drop to list
                   this.dropToList(this.draged_object, underlyingObject, true);
                    
                }
            }
            
            this.draged_object=null;
            this.underlyingObject=null;
            this.restoreContainer();
            this.clearDragBorders();
            
        }
    }
    
    
    this.dropToList = function (playlistItem, underlyingObject, askServer)
    {
        /// <summary>Adds item before another playlist item</summary>
        /// <param name="playlistItem" type="object">Jquery object with data, this item wil be added</param>
        /// <param name="underlyingObject" type="object">Js DOM object, playlistItem will be added before this object</param>
        /// <param name="askServer" type="bool">If true, request to server with order will be sended</param>
        /// <returns type="void"/>
        var c = $(playlistItem);
        var olddata =playlistItem.data("playlistItem");
        
        itemPos = document.playlist.getItemPosition(playlistItem.attr('id'));

        var itemReturnReference = $('#playlist').children()[itemPos+1];
                    
        $(playlistItem).remove();
                    
        c.data("playlistItem",olddata);
        
        $('#'+underlyingObject.id).before(c);
                    
        //rebind playlist item events again because we created new item
        unbindItemEvents ();
        bindItemEvents ();
                    
        if (askServer!=false) {
            document.playlist.sendOrderToServer(playlistItem, itemReturnReference);
        }
    }
    
    
    this.startScroll = function (direction)
    {
        /// <summary>Scrolls playlist in top or bottom direction</summary>
        /// <param name="direction" type="string">Direction of scrolling, top or bottom</param>
        /// <returns type="void"/>
        if (this.scrollingNow==true && this.scrollStarted==false) {
            
            var topPoint = 0;
            
            var bottomPoint = 0;
            $('#playlist').children().each(function (i) {
                bottomPoint+=$(this).outerHeight();
            });
            
            if (direction=="top") {
                $('#playlist').animate({scrollTop:  topPoint + 'px'}, bottomPoint+200);

            }
            
            if (direction=="bottom") {
                $('#playlist').animate({scrollTop:  bottomPoint + 'px'}, bottomPoint+1000);
            }
            
            this.scrollStarted=true;
       }
    }
    
    
    this.stopScroll = function () {
        this.scrollStarted=false;
        $('#playlist').stop();
    }
    
    
    this.calculateDrop = function (evt)
    {
        /// <summary>Returns object under the dragging object in case it is drop target or active scroll target</summary>
        /// <param name="evt" type="object">Event</param>
        /// <returns type="object"/>
        var left = (this.mouseX(evt));
        var top = (this.mouseY(evt)); 
   
        /* check active scroll areas first */
        var scrollHotSpotTopTarget  = this.scrollHotSpotTop;   
        scrollHotSpotTopTarget = this.locateCurTarget(scrollHotSpotTopTarget,left,top);  
        if(scrollHotSpotTopTarget!=null) {return scrollHotSpotTopTarget;}
        
        var scrollHotSpotBottomTarget  = this.scrollHotSpotBottom;  
        scrollHotSpotBottomTarget = this.locateCurTarget(scrollHotSpotBottomTarget,left,top);  
        if(scrollHotSpotBottomTarget!=null) {return scrollHotSpotBottomTarget;}
        
        /* loop drop targets */
        for(var i=0; i<this.dropTargets.length; i++){
            
            var curTarget  = this.dropTargets[i]; 

            curTarget = this.locateCurTarget(curTarget,left,top);
            if(curTarget!=null) {return curTarget;}
            }
           
            //if there is no drop or active scroll target, return null
            return null;
    }
    
    

    
    this.locateCurTarget = function(curTarget,left,top)
    {
        /// <summary>Calculates, if given target is underlying mouse pos. Returns null if not</summary>
        /// <param name="curTarget" type="object">Tested object</param>
        /// <param name="left" type="number">Left coordinate of mouse position</param>
        /// <param name="top" type="number">Top coordinate of mouse position</param>
        /// <returns type="object"/>
        try{
            var targPos    = $('#'+curTarget.id).position();
            var targWidth  = parseInt(curTarget.offsetWidth); 
            var targHeight = parseInt(curTarget.offsetHeight);
                
                if( 
                   (left > targPos.left) && 
	               (left < (targPos.left + targWidth))  && 
	               (top > targPos.top) && 
	               (top < (targPos.top + targHeight))){ 
    	               return curTarget;
    	            }
               return null;
        } catch(e){
            //may occurs when player is missing
            return null;
        }
    }
    
    
    this.setDropTargets = function (id) 
    {
        /// <summary>Resets all drop targets by loop through their parrent object</summary>
        /// <param name="id" type="string">Id of parent object of drop targets</param>
        /// <returns type="void"/>
        var targets = [];
        
        $('#'+id).children().each(function (i) {
            targets.push(this); 
        });
        
        this.dropTargets = targets;
    }
    
    
    this.addDropTarget = function(dropTarget)
    { 
        /// <summary>Adds one more drop target to DropTarget list</summary>
        /// <param name="dropTarget" type="object">Drop target to add</param>
        /// <returns type="void"/>
        this.dropTargets.push(dropTarget); 
    }
    
    
    this.mouseX = function(evt)
    {
    if (!evt) 
        evt = window.event; 
    if (evt.pageX) 
        return evt.pageX; 
    else 
        if (evt.clientX)
            return evt.clientX + (document.documentElement.scrollLeft ?  document.documentElement.scrollLeft : document.body.scrollLeft); 
        else 
            return 0;
    }
    
    
    this.mouseY = function(evt)
    {
        if (!evt) 
            evt = window.event; 
        if (evt.pageY) 
            return evt.pageY; 
        else 
            if (evt.clientY)
                return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); 
            else 
                return 0;
    }
    
    
    this.moveContainer = function (left,top)
    {
        /// <summary>Move DD container by changing its css values</summary>
        /// <param name="left" type="number">Absolute left coordinate</param>
        /// <param name="top" type="number">Absolute top coordinate</param>
        /// <returns type="void"/>
        this.container.css("position", "absolute");
        this.container.css("display", "block");
        this.container.css("left", left + "px");
        this.container.css("top", top + "px");
        this.container.css("opacity", "0.5");
    }
    
    
    this.restoreContainer = function () 
    {
        /// <summary>Restores drag container to its original settings make it ready for another dd</summary>
        /// <returns type="void"/>
        $(this.container).html("");
        this.container.css("position", "relative");
        this.container.css("display", "none");
        this.container.css("left","0px");
        this.container.css("top", "0px");
    }
    
    
    this.showDragBorder = function (id) 
    {
        /// <summary>Marks possible drop location as border on top of the underlying object</summary>
        /// <param name="id" type="string">Id of item html element</param>
        /// <returns type="void"/>
        $('#'+id).css ("border-top", "2px solid #fd9e3b");
        $('#'+id).css ("padding-top", "0");
    }
    
    
    this.clearDragBorders = function () 
    {
        $('.playlist_item').css ("border-top", "none");
        $('.playlist_item').css ("padding-top", "0");
        $('#bottom_DD_dummy').css ("border-top", "none");
    }
}