/**
 * 
 * All content on this website (including text, images, source
 * code and any other original works), unless otherwise noted,
 * is licensed under a Creative Commons License.
 * 
 * http://creativecommons.org/licenses/by-nc-sa/2.5/
 * 
 * Copyright (C) Open-Xchange Inc., 2006-2011
 * Mail: info@open-xchange.com 
 * 
 * @author Viktor Pracht <viktor.pracht@open-xchange.com>
 * @author Jan Finsel <jan.finsel@open-xchange.com>
 */

  ///////////////////////
 //   Drag and Drop   //
///////////////////////

/**
 * Registers a drag source.
 * @param {Object} node A DOM element which serves as drag source.
 * @param {String} type The type of the dragged object. The object can be
 * dropped only on targets which accept this type.
 * @param {Function} callback A function which creates a dragged object.
 * This function may be called without a real drag operation; the returned
 * object should therefore be small and inexpensive to create.
 * @param {String} icon URI of the drag icon which is displayed when the object
 * can be dropped.
 * @param {String} disabledIcon URI of the drag icon which is displayed when
 * the object can not be dropped.
 * @type Function
 * @return A value which must be passed to {@link unregisterSource} to
 * unregister the drag source.
 */
var registerSource;

/**
 * Unregisters a previously registered drag source.
 * @param {Object} node A DOM element which served as drag source.
 * @param {Function} event A value previously returned by {@link registerSource}
 * for the same DOM node.
 */
var unregisterSource;

/**
 * Registers a drop target.
 * @param {Object} node A DOM element which serves as drag target.
 * @param {Object} callbacks An object with a field for every accepted type.
 * The value of each field is a callback function which is called when a drag
 * object of the corresponding type is dropped on the target.
 * @type Function
 * @return A value which must be passed to {@link unregisterTarget} to
 * unregister the drag target.
 */
var registerTarget;

/**
 * Unregisters a previously registered drag target.
 * @param {Object} node A DOM element which served as drag target.
 * @param {Function} event A value previously returned by {@link registerTarget}
 * for the same DOM node.
 */
var unregisterTarget;

/**
 * Returns true during a drag operation. Useful in mouse event handlers not
 * directly associated with drop targets.
 * @type Boolean
 * @return true during a drag operation, false otherwise.
 */
var isDragging;

/**
 * Stops event bubbling which was allowed by the 9th parameter to
 * registerTarget.
 * @param {Event} event The DOM mousemove event to stop.
 */
var stopDnDPropagation;

var dragThreshold = 7;

var iconOffset = 8;
var cancelfunc = true;
var draggingdisable=false;
(function() {
    var dragging = false;
    var dropCallback;
    var dropNode;
    var draggedObjects;
    var dragType;
    var iconNode;
    var iconURI;
    var disabledIconURI;
    var savelocal; //REMOVE TIMEOUT EXPAND FOLDERS
    var disabled;
    var disabledRemove;
    var mouseposition = {};
    var targetNode;
    var fnOutNode = function (){};
    var handleDnDEvent = false;
    
    stopDnDPropagation = function(e) {
        if (handleDnDEvent) cancelBubbling(e);
    };
    
    var cancel2 = function (e) {
        // fix event
        e = jQuery.event.fix(e || window.event);
        // is input field
        if (jQuery(e.target).is("input")) {
            return true;
        } else {
            if (cancelfunc) {
                stopEvent(e);
            }
            return !cancelfunc;
        }
    };
    var cancel = function() { return false; };

    registerSource = function(node, type, callback, icon, disabledIcon,fnDisabled2,disabledRemove2) {
        addDOMEvent(node, "mousedown", down);
        if ("onselectstart" in node) addDOMEvent(node, "selectstart", cancel2);
        if ("ondrag" in node) addDOMEvent(node, "drag", cancel2);
        return down;
        
        var startX, startY;
        var cursor;
        function disabled(e) {
            fnDisabled2(e,dragType,draggedObjects,mouseposition,targetNode);
        }
        function down(e) {            
            if(draggingdisable) return;
            cancelfunc=true;
            if (e.button != LeftButton) return;
            draggingdisable=true;
            startX = e.clientX;
            startY = e.clientY;
            mouseposition = {};
            mouseposition.clientX=startX;
            mouseposition.clientY=startY;
            cancelDefault(e);
            addDOMEvent(document, "mousemove", move);
            addDOMEvent(document, "mouseup", up);
            return false;
            
        }
        function move(e) {
            if (Math.abs(e.clientX - startX) + Math.abs(e.clientY - startY) <= dragThreshold) return;
            if(window.setHoverActive) {
                setHoverActive(false);
            }
            draggedObjects = callback();            
            disabledRemove=disabledRemove2;
            dragType = type;
            dragging = true;            
            cursor = setMouseCursor("move");
            hideIFrames();
            removeDOMEvent(document, "mousemove", move);
            if(fnDisabled2) {
                addDOMEvent(document, "mousemove", disabled);
            } else {
                addDOMEvent(document, "mousemove", move2);
            }
            //TMPSTART
            iconURI=icon;
            disabledIconURI=disabledIcon;
            //TMPEND
            stopEvent(e);
            return false;
            
        }        
        function move2(e) {
            if(!iconNode) {
                iconNode = newnode("img", {position: "absolute",left: (e.clientX + iconOffset) + "px",top: (e.clientY + iconOffset) + "px"},
                 {src: disabledIcon, alt: ""});
                body.appendChild(iconNode);
            }
            iconNode.style.left = (e.clientX + iconOffset) + "px";
            iconNode.style.top = (e.clientY + iconOffset)+ "px";
            stopEvent(e);
            return false;
        }

        function up(e) {
            if (e.button != LeftButton) return;
            draggingdisable=false;
            if(!disabled) {
                removeDOMEvent(document, "mousemove", dragging ? move2 : move);
            } else {
                removeDOMEvent(document, "mousemove", dragging ? disabled : move);
            }
            if(window.setHoverActive) {
                setHoverActive(true);
            }
            removeDOMEvent(document, "mouseup", up);
            if (dragging) {
                showIFrames();
                if(!disabledRemove) {
                    if(iconNode) {
                        body.removeChild(iconNode);
                        iconNode = null;
                    }
                } else {
                    disabledRemove(e,dragType,draggedObjects,mouseposition,targetNode);
                }
                removeMouseCursor(cursor);
                dragging = false;
                //if (dropCallback) dropCallback(draggedObjects,e,mouseposition,targetNode);
                if (dropCallback) dropCallback(e,dragType,draggedObjects,mouseposition,targetNode,dropNode);
                dropCallback = null;
                dropNode=null;
            }
            draggedObjects = null;
        }
    };
    unregisterSource = function(node, myfunc) {
        removeDOMEvent(node, "mousedown", myfunc);
        if ("onselectstart" in node) removeDOMEvent(node, "selectstart", cancel2);
        if ("ondrag" in node) removeDOMEvent(node, "drag", cancel2);
    };
    
    function tOut(e) {
        if (!dragging) return;
        var target = e.currentTarget;
        target.className = removeClass(target.className, "dndOver");
        
        if(!iconNode) {
            iconNode = newnode("img", {position: "absolute",left: (e.clientX + iconOffset) + "px",top: (e.clientY + iconOffset) + "px"},
            {src: disabledIconURI, alt: ""});
            body.appendChild(iconNode);
        }
        iconNode.src = disabledIconURI;
        dropCallback = null;
        dropNode=null;
        fnOutNode(savelocal);
    }
    
    registerTarget = function(node, callbacks,fn_Over,fnOutParam,fn_In,fn_Move,fn_Out,holdsourcedisabled, allowPropagation) {
        var mymove = function(e) {
            if (!dragging) return;
            dropCallback = callbacks[dragType];
            dropNode=node;
            handleDnDEvent = Boolean(dropCallback);
            if (handleDnDEvent) {
                targetNode=node;
                if(fn_Move) {
                    fn_Move(e,dragType,draggedObjects,mouseposition);
                }
                if(disabledRemove && !holdsourcedisabled) {
                    disabledRemove(e,dragType,draggedObjects,mouseposition,targetNode);
                }
                cancelDefault(e);
                if (!allowPropagation) cancelBubbling(e);
            }
        };
        var myout = function(e) {
            if (!dragging) return;
            if(!realMouseOutIn(e,true)) return;
            dropCallback = callbacks[dragType];
            dropNode = node;
            
            if(dropCallback) {
                targetNode=undefined;
                if(fn_Out) {
                    fn_Out(e,dragType,draggedObjects,mouseposition,savelocal);
                } 
                dropCallback=null;
                dropNode=null;
                stopEvent(e);
            }
            
        };
        var myin = function(e) {
            if (!dragging) return;
            if(!realMouseOutIn(e,false)) return;
            dropCallback = callbacks[dragType];
            if(dropCallback) {
                targetNode=node;
                if(fn_In) {
                    savelocal=fn_In(e,dragType,draggedObjects,mouseposition);
                } else {
                    event(e,dragType,draggedObjects,mouseposition);
                }
                stopEvent(e);
            }
            
        };
        
        var event = function(e) {
            if (fn_Over) savelocal = fn_Over(draggedObjects, node.id);
            dropCallback = callbacks[dragType];
            if(dropCallback)
                node.className += " dndOver";
                if(!iconNode) {
                    iconNode = newnode("img", {position: "absolute",left: (e.clientX + iconOffset) + "px",top: (e.clientY + iconOffset) + "px"},
                    {src: "", alt: ""});
                    body.appendChild(iconNode);    
                }
                if(dropCallback && iconURI) {
                    iconNode.src = iconURI;                            
                } else if(disabledIconURI) {
                    iconNode.src = disabledIconURI;                            
                } 
                

        };
        addDOMEvent(node, "mouseout", myout);
        addDOMEvent(node, "mouseover", myin);
        addDOMEvent(node, "mousemove", mymove);

        return event;
    };
    
    unregisterTarget = function(node,myin,mymove,myout) {
        if(myin) removeDOMEvent(node, "mouseover", myin);
        if(myout) removeDOMEvent(node, "mouseout", myout);
        if(mymove) removeDOMEvent(node, "mouseover", mymove);            
    };

    isDragging = function() { return dragging; };

})();

function realMouseOutIn(event, isout) {
    var node = event.currentTarget || event.srcElement || false;
    if(isout) {
        var toElement = event.relatedTarget || event.toElement || false;
    } else {
        var toElement = event.relatedTarget || event.fromElement || false;
    }
    if(!node || !toElement) return true;
    if(node == toElement) return false;
    var oParent=null;
    try {
       oParent = toElement.parentNode;
    } catch (e) { }
    while(oParent != null) {
        if(oParent == node) {
            return false;
        }
        oParent=oParent.parentNode; 
    }
    return true;
}

var dnd_defaultNode;
//*
function createDefaultNode() {
    if (dnd_defaultNode) return dnd_defaultNode.cloneNode(true);    
    dnd_defaultNode = newnode("div", null,
    { className : "dragdropdefaultnode background-color-default border-color-design", id: "dragdrop_default_node"},[
        newnode("table",{ width:"100%" , height: "100%" },{ cellPadding:"0" , cellSpacing :"0" , border : "0" },[
            newnode("tbody",null,null,[
                newnode("tr",null,null,[
                    newnode("td",{ width: "22px", lineHeight: "0px", verticalAlign: "middle"},null,[
                        newnode("div",{ width: "22px",overflow: "hidden" },null,[
                            newnode("img",{},{ src : getFullImgSrc("img/dnd_disabled.gif") },[]),
                            newnode("img",{ display : "none" },{ src : getFullImgSrc("img/dnd.gif") },[])
                        ])                
                    ]),
                    newnode("td",{ fontSize : "8pt", padding : "0px 5px 0px 5px" , whiteSpace : "nowrap", textAlign: "left" },null,[
                        newnode("div",{ overflow: "hidden" },null,[addTranslated(_("No subject"))])
                    ])
                ])
            ])
        ])
    ]);    
    return dnd_defaultNode;
}
function setDefaultNodeType(node,active) {
    node.getElementsByTagName("td")[0].className = active?" dnd_possibleBG":" dnd_NOTpossibleBG";
    if(active) {
        node.getElementsByTagName("img")[0].style.display="none";
        node.getElementsByTagName("img")[1].style.display="block";
    } else {
        node.getElementsByTagName("img")[1].style.display="none";
        node.getElementsByTagName("img")[0].style.display="block";
    }
}
function nodeSetSubjectDefault(node,title) {
    node.getElementsByTagName("div")[1].firstChild.data= (title) ? title : "";
}
function defaultdisabled(e, dragType, draggedObjects, mouseposition, targetNode,
                         getstring, field)
{    
    var iconNode = document.getElementById("dragdrop_default_node");
    if (iconNode == undefined) {
        iconNode=createDefaultNode();
        iconNode.style.left = (e.clientX + iconOffset) + "px";iconNode.style.top = (e.clientY + iconOffset)+ "px";
        body.appendChild(iconNode);
        
        setDefaultNodeType(iconNode,false);
        
        // set default text
        var count = draggedObjects.currentObjects.length;
        var text = count <= 1 ? "" : format(getstring(count), count);
        nodeSetSubjectDefault(iconNode,text);
        
        if (draggedObjects.currentObjects.length == 1) {
            var module = draggedObjects.currentModule;
            
            // do we have some data to display?! if not, try to get it from the object cache            
            if (draggedObjects.currentObjects[0][field] || draggedObjects.currentObjects[0]["livegridfield"]) {
                nodeSetSubjectDefault(iconNode, draggedObjects.currentObjects[0][field] || draggedObjects.currentObjects[0]["livegridfield"]);
                
            } else if (typeof OXCache.moduleMappings[module] == "function") {
                var collection={};
                var mapping = OXCache.moduleMappings[module];           
                collection.columns = [ field ];
                collection.objects = [mapping.createKeyFromObject(
                          { module: module, 
                            folder_id: draggedObjects.currentObjects[0].folder || 
                                   draggedObjects.currentObjects[0].folder_id, 
                            id: draggedObjects.currentObjects[0].id }
                      )];
                
                OXCache.newRequest(null,module,collection,null,          
                    function(daten) {
                        if (daten.objects[0]) {             
                            var text=daten.objects[0][field] || draggedObjects.currentObjects[0]["livegridfield"];
                            nodeSetSubjectDefault(iconNode,text);
                        }
                    });
            }
        }
    }
    
    iconNode.style.left = (e.clientX + iconOffset) + "px";
    iconNode.style.top = (e.clientY + iconOffset)+ "px";    
    stopEvent(e);
    
    return false;
}
function mailaddressdefaultdisabled(e,dragType,draggedObjects,mouseposition,targetNode) {
    var iconNode = document.getElementById("dragdrop_default_node");
    if(iconNode == undefined) {
        iconNode=createDefaultNode();
        iconNode.style.left = (e.clientX + iconOffset) + "px";iconNode.style.top = (e.clientY + iconOffset)+ "px";
        body.appendChild(iconNode);
    }
    iconNode.style.left = (e.clientX + iconOffset) + "px";
    iconNode.style.top = (e.clientY + iconOffset)+ "px";
    setDefaultNodeType(iconNode,false);
    var text=draggedObjects.email1;
    nodeSetSubjectDefault(iconNode,text);                            
    stopEvent(e);
    return false;
}
function calendardefaultdisabled(e,dragType,draggedObjects,mouseposition,targetNode) {
    defaultdisabled(e, dragType, draggedObjects, mouseposition, targetNode,
        function(n) {
            //#. %d is the number of appointments.
            //#, c-format
            return ngettext("%d appointment", "%d appointments", n);
        }, "title");
}
function taskdefaultdisabled(e,dragType,draggedObjects,mouseposition,targetNode) {
    defaultdisabled(e, dragType, draggedObjects, mouseposition, targetNode,
        function (n) {
            //#. %d is the number of tasks.
            //#, c-format
            return ngettext("%d task", "%d tasks", n);
        }, "title");
}
function contactdefaultdisabled(e,dragType,draggedObjects,mouseposition,targetNode) {
    defaultdisabled(e, dragType, draggedObjects, mouseposition, targetNode,
        function (n) {
            //#. %d is the number of contacts.
            //#, c-format
            return ngettext("%d contact", "%d contacts", n);
        }, "display_name");
}
function infostoredefaultdisabled(e,dragType,draggedObjects,mouseposition,targetNode) {
    defaultdisabled(e, dragType, draggedObjects, mouseposition, targetNode,
        function(n) {
            //#. %d is the number of info items.
            //#, c-format
            return ngettext("%d info item", "%d info items", n);
        }, "title");
}
function maildefaultdisabled(e,dragType,draggedObjects,mouseposition,targetNode) {
    defaultdisabled(e, dragType, draggedObjects, mouseposition, targetNode,
        function(n) {
            //#. %d is the number of e-mails.
            //#, c-format
            return ngettext("%d E-Mail", "%d E-Mails", n);
        }, "subject");
}
function foldertreeenable(e,dragType,draggedObjects,mouseposition,targetNode,folder) {
    var iconNode = document.getElementById("dragdrop_default_node");
    if (iconNode == undefined) {
        iconNode=createDefaultNode()
        iconNode.style.left = (e.clientX + iconOffset) + "px";
        iconNode.style.top = (e.clientY + iconOffset)+ "px";
        body.appendChild(iconNode);
    } else {
        iconNode.style.left = (e.clientX + iconOffset) + "px";
        iconNode.style.top = (e.clientY + iconOffset)+ "px";
    }
    var tmp_module = folder.module;
    if (   dragType == tmp_module
        && computePerm(folder.own_rights,0) >=2
        && !(folder.type == 3 && tmp_module == "tasks")
        && !(   folder.type == 2
             && draggedObjects.currentObjects[0].private_flag))
    {
        setDefaultNodeType(iconNode,true);
        
    } else if (dragType=="folder/1" || dragType=="folder/2" || dragType=="folder/3" || dragType=="folder/7") {
        // get folder
        ox.api.folder.get({
            folder: draggedObjects,
            success: function (source) {
                nodeSetSubjectDefault(iconNode, source.title);
                ox.api.folder.canMove(source, folder, function() {
                    setDefaultNodeType(iconNode,true);
                }, function() {
                    setDefaultNodeType(iconNode,false);
                });
            }
        });
    } else if (dragType == "mailaddress" && folder.module == "contacts") {
        myrights = computePerm(folder.own_rights, 0);
        if(myrights >= 2) {
            setDefaultNodeType(iconNode,true);
        } else {
            setDefaultNodeType(iconNode,false);
        }
    } else {
        setDefaultNodeType(iconNode,false);
    }
    iconNode.style.left = (e.clientX + iconOffset) + "px";
    iconNode.style.top = (e.clientY + iconOffset)+ "px";
}

function minicalenable(e,dragType,draggedObjects,mouseposition,targetNode,node) {
    var iconNode = document.getElementById("dragdrop_default_node");
    if(iconNode == undefined) {
        iconNode=createDefaultNode();
        iconNode.style.left = (e.clientX + iconOffset) + "px";
        iconNode.style.top = (e.clientY + iconOffset)+ "px";
        body.appendChild(iconNode);
    } else {
        iconNode.style.left = (e.clientX + iconOffset) + "px";
        iconNode.style.top = (e.clientY + iconOffset)+ "px";
    }
    setDefaultNodeType(iconNode,true);
    iconNode.style.left = (e.clientX + iconOffset) + "px";
    iconNode.style.top = (e.clientY + iconOffset)+ "px";
}
function foldertreedisable(e,dragType,draggedObjects,mouseposition,targetNode) {
    var iconNode = document.getElementById("dragdrop_default_node");
    if(iconNode == undefined) {
        iconNode=createDefaultNode();
        iconNode.style.left = (e.clientX + iconOffset) + "px";iconNode.style.top = (e.clientY + iconOffset)+ "px";
        body.appendChild(iconNode);
    }
    iconNode.style.left = (e.clientX + iconOffset) + "px";
    iconNode.style.top = (e.clientY + iconOffset)+ "px";
    setDefaultNodeType(iconNode,false);
    ox.api.folder.get({
        folder: draggedObjects,
        success: function (data) {
            nodeSetSubjectDefault(iconNode, data.title);
        }
    });
}
function defaultdisabledremove(e) {
    if(document.getElementById("dragdrop_default_node")) {
        document.getElementById("dragdrop_default_node").parentNode.removeChild(document.getElementById("dragdrop_default_node"));
    }
}
fileloaded();