//DRAGDROP-JavaScript library

var dd_registry = new Array();
var dd_object   = null;
var dd_callback = null;
var dd_zindex   = 0;
var dd_left     = 0;
var dd_top      = 0;
var dd_flag     = false;

function dd_register(object,
                     type,
                     accept) //arguments: 3 => fixed
{
        if (typeof object != "object")
        {
                object = document.getElementById(object);
                if (typeof object != "object") return false;
        };

        dd_zindex              = dd_registry.length;

        //property
        object.dd_type         = type;
        object.dd_accept       = accept;
        object.dd_fixed        = (dd_register.arguments.length > 2) && (dd_register.arguments[3] == true);

        //style
        object.style.cursor    = "default";
        object.style.zIndex    = dd_zindex;

        //event
        object.ondragstart     = new Function("return false;");
        object.onmousedown     = new Function("return false;");
        object.onselectstart   = new Function("return false;");

        dd_registry[dd_zindex] = object;
};
//................................
/*
 * set callback function
 *
 * example:
 * function my_callback_function(my_event, my_source, my_target) { ... };
 * dd_set_callback(my_callback_function);
 *
 * possible values for my_event:
 * "activate", "dragstart", "dragover", "drag", "dropon", "drop"
 */
function dd_set_callback(callback)
{
        dd_callback = callback;
};
//................................
function dd_get_object()
{
        var object, _object = null,
            x1, y1, x2, y1, x3, y3;

        for (object in dd_registry)
        {
                object = dd_registry[object];

                if (
                     (dd_object == null)
                     ||
                     (dd_object != object)
                   )
                {
                        x1 = fx_width(object);
                        y1 = fx_height(object);
                        x2 = fx_left(object);
                        y2 = fx_top(object);
                        x3 = x2 + x1;
                        y3 = y2 + y1;

                        if (
                             (fx_mouse_x >= x2)
                             &&
                             (fx_mouse_x <= x3)
                             &&
                             (fx_mouse_y >= y2)
                             &&
                             (fx_mouse_y <= y3)
                             &&
                             (
                               (_object == null)
                               ||
                               (object.style.zIndex > _object.style.zIndex)
                             )
                           )
                                _object = object;
                };
        };

        return _object;
}
//................................
function dd_event(event)
{
        switch (event)
        {
        case "mousedown":
                var object             = dd_get_object();
                if (object == null)      return; //no target

                //global
                dd_left                = fx_mouse_x;
                dd_top                 = fx_mouse_y;
                dd_flag                = fx_keyboard_keystate == 17;
                dd_object              = object;

                if (dd_object.dd_fixed)  break;  //fixed

                //relative cursor position
                dd_object.dd_offset_x  = fx_mouse_x - fx_left(object);
                dd_object.dd_offset_y  = fx_mouse_y - fx_top(object);

                //style
                dd_object.style.cursor = "move";
                dd_object.style.zIndex = ++dd_zindex;

                //callback
                if (dd_callback != null) dd_callback("dragstart", dd_object, null);
                break;

        case "mousemove":
                if (dd_object == null)   return; //no source
                if (dd_object.dd_fixed)  break;  //fixed

                //position
                fx_move(dd_object,
                        fx_mouse_x - dd_object.dd_offset_x,
                        fx_mouse_y - dd_object.dd_offset_y);

                var object             = dd_get_object();

                if ((object != null) && ((object.dd_accept & dd_object.dd_type) != 0))
                {
                        //style
                        dd_object.style.cursor = "pointer";

                        //callback
                        if (dd_callback != null) dd_callback("dragover", dd_object, object);
                }
                else
                {
                        //style
                        dd_object.style.cursor = "move";

                        //callback
                        if (dd_callback != null) dd_callback("drag", dd_object, null);
                };
                break;

        case "mouseup":
                if (dd_object == null)   return; //no source

                var object             = dd_get_object();

                //style
                dd_object.style.cursor = "auto";

                //callback
                if (dd_callback != null)
                {
                        if (
                             (Math.abs(dd_left - fx_mouse_x) > 4)
                             ||
                             (Math.abs(dd_top - fx_mouse_y) > 4)
                           )
                        {
                                if (dd_object.dd_fixed) break; //fixed

                                if ((object != null) && ((object.dd_accept & dd_object.dd_type) != 0))
                                        dd_callback("dropon", dd_object, object);
                                else
                                        dd_callback("drop", dd_object, null);
                        }
                        else
                        {
                                if (dd_flag)
                                        dd_callback("select", dd_object, null);
                                else
                                        dd_callback("activate", dd_object, null);
                        };
                };

                dd_object              = null;
        };

        fx_event_consume();
};

fx_register_callback(dd_event);

