//////////////////////////////////////////////////////////////////////////////
// custom drag and drop implementation
// Modified by Alex Nelson from example at:
//   http://developer.yahoo.com/yui/examples/dragdrop/dd-reorder_clean.html
// Most recent build of YUI at the time of adapting this example code: 2.4.1
//////////////////////////////////////////////////////////////////////////////

YAHOO.namespace("example");

(function() {

//Helper variables
var Dom = YAHOO.util.Dom;
var Event = YAHOO.util.Event;
var DDM = YAHOO.util.DragDropMgr;
var Logger;
if(YAHOO.com && YAHOO.com.lgan && YAHOO.com.lgan.Logger){
    Logger = YAHOO.com.lgan.Logger; 
} else {
    Logger = YAHOO;
}

YAHOO.example.DDList = function(id, sGroup, config) {

    YAHOO.example.DDList.superclass.constructor.call(this, id, sGroup, config);

    var el = this.getDragEl();
    Dom.setStyle(el, "opacity", 0.67); // The proxy is slightly transparent

    this.goingUp = false;
    this.lastY = 0;
    
    this.elDestParent = null;
    
    this.anim = null;
};


YAHOO.extend(YAHOO.example.DDList, YAHOO.util.DDProxy, {
    /**
      Base function to add an element to a parent's childNode list.
      @param {HTMLElement} elParentToBe
      @param {HTMLElement} elChild
    */
    AdoptChild: function(elParentToBe, elChild){
        //Logger.log("Called.", "trace", "DDList.AdoptChild");
        //Logger.log(this, "debug", "DDList.AdoptChild");  //Scope test
        elParentToBe.appendChild(elChild);
        //Logger.log("Finished.", "trace", "DDList.AdoptChild");
    },
    
    startDrag: function(x, y) {
        Logger.log(this.id + " startDrag");

        // make the proxy look like the source element
        var dragEl = this.getDragEl();
        var clickEl = this.getEl();
        Dom.setStyle(clickEl, "visibility", "hidden");

        dragEl.innerHTML = clickEl.innerHTML;

        Dom.setStyle(dragEl, "font-size", Dom.getStyle(clickEl, "font-size"));
        Dom.setStyle(dragEl, "color", Dom.getStyle(clickEl, "color"));
        Dom.setStyle(dragEl, "backgroundColor", Dom.getStyle(clickEl, "backgroundColor"));
        Dom.setStyle(dragEl, "border", "2px solid gray");
        
        this.anim = new YAHOO.util.Motion( 
          dragEl,
          {  //Configuration set in endDrag
          }, 
          0.2, 
          YAHOO.util.Easing.easeOut 
        )
    },

    endDrag: function(e) {
        Logger.log(this.id + " endDrag on " + Event.getTarget(e).id);
        
        var srcEl = this.getEl();
        var proxy = this.getDragEl();

        // Show the proxy element and animate it to the src element's location
        Dom.setStyle(proxy, "visibility", "");
        this.anim.attributes["points"] = { to: Dom.getXY(srcEl) };
        var proxyid = proxy.id;
        var thisid = this.id;

        // Hide the proxy and show the source element when finished with the animation
        this.anim.onComplete.subscribe(function() {
            Dom.setStyle(proxyid, "visibility", "hidden");
            Dom.setStyle(thisid, "visibility", "");
        });
        this.anim.animate();
            
        //Remove highlight
        Dom.removeClass(this.elDestParent,"ddlist-highlit");
    },

    onDragDrop: function(e, id) {
        Logger.log(this.id + " onDragDrop on " + id);
        // If there is one drop interaction, the li was dropped either on the list,
        // or it was dropped on the current location of the source element.
        if (DDM.interactionInfo.drop.length === 1) {

            // The position of the cursor at the time of the drop (YAHOO.util.Point)
            var pt = DDM.interactionInfo.point; 

            // The region occupied by the source element at the time of the drop
            var region = DDM.interactionInfo.sourceRegion; 

            // Check to see if we are over the source element's location.  We will
            // append to the bottom of the list once we are sure it was a drop in
            // the negative space (the area of the list without any list items)
            if (!region.intersect(pt)) {
                var destEl = Dom.get(id);
                var destDD = DDM.getDDById(id);
                this.AdoptChild(destEl, this.getEl());
                destDD.isEmpty = false;
                DDM.refreshCache();
            }

        }
    },

    onDrag: function(e) {

        // Keep track of the direction of the drag for use during onDragOver
        var y = Event.getPageY(e);

        if (y < this.lastY) {
            this.goingUp = true;
        } else if (y > this.lastY) {
            this.goingUp = false;
        }

        this.lastY = y;
    },
    
    //This event handler changes the dd's element's DOM position.
    onDragOver: function(e, id) {
        //Logger.log(this.id + " onDragOver " + Event.getTarget(e));
        
        var destEl = Dom.get(id);

        var srcEl = this.getEl();
        var elOrigList = srcEl.parentNode;
        var elDestList = destEl;  //This may be incorrect; we want a ul element; correct in next check

        // For changing the srcEl DOM position, we are only concerned with list items.
        // The dragover notifications for the list can deal with highlighting.
        
        switch(destEl.nodeName.toLowerCase()){
            case "li":
                elDestList = elDestList.parentNode;
                
                if (this.goingUp) {
                    elDestList.insertBefore(srcEl, destEl); // insert above
                } else {
                    elDestList.insertBefore(srcEl, destEl.nextSibling); // insert below
                }
                
                DDM.refreshCache(this.groups);
                
                this.RefreshHighlight(elDestList);
            break;
            case "ul":  //Fallthrough
            case "dl":
                this.RefreshHighlight(elDestList);
            break;
            default:
                //Nop
            break;
        }
    },
    
    RefreshHighlight: function(elDestList){
        if(elDestList != this.elDestParent){
            Dom.removeClass(this.elDestParent,"ddlist-highlit");
            Dom.addClass(elDestList,"ddlist-highlit");
            this.elDestParent = elDestList;
        }
    }
});

})();

