microstrategy.MOUSE_MOVES_BUFFER = 5;
microstrategy.HTMLATTR_DRAG = 'DG';
microstrategy.HTMLATTR_DRAG_OFF = 0;
microstrategy.HTMLATTR_DRAG_DRAGGABLE = 1;
microstrategy.HTMLATTR_DRAG_DOCKABLE = 2;

// *************************************   EVENT MANAGER OBJECT ***********************************************
// Responsible for capturing events & transmitting them to the event handlers of the appropriate bone(s).
// Handles document event handlers for window loading & resizing.  Also includes methods that can be used
// to enable dragging events for bone elements, if desired.
// ************************************************************************************************************

//properties
mstrEventsManagerImpl.prototype = new Object;
mstrEventsManagerImpl.prototype.source = new Object;
mstrEventsManagerImpl.prototype.browserHeight = null;
mstrEventsManagerImpl.prototype.browserWidth = null;

//event handlers
mstrEventsManagerImpl.prototype.onload = function(e) {
//@class=mstrEventsManagerImpl;@method=onload;
    //Usage: to be called from a BODY onload event.
    try {
    	//#367569, #372071, #367950, #370530 - dynamic JS loading in IE  
    	microstrategy.loadDynamicJS(e, true);

        return true;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

mstrEventsManagerImpl.prototype.initializeBones = function(e) {
//@class=mstrEventsManagerImpl;@method=initializeBones;
    try {
    	microstrategy.registerNewBones();
        //notify the appropriate bones
        this.notifyOrphanBones('onload', e);
        this.notifyOrphanBones('onpostload', e);
        this.onforcerepaint();

        return true;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

mstrEventsManagerImpl.prototype.onforcerepaint = function() {
    //@class=mstrEventsManagerImpl;@method=onforcerepaint;
    try {
        //notify the appropriate bones
        this.notifyOrphanBones('onforcerepaint');
        return true;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

mstrEventsManagerImpl.prototype.onnotifydrag = function(items, bone, types) {
    //@class=mstrEventsManagerImpl;@method=onnotifydrag;
    try {
        //notify the appropriate bones
        this.notifyOrphanBones("onnotifydrag", items, bone, types);
        return true;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

mstrEventsManagerImpl.prototype.onreload = function(e) {
    //Usage: to be called from a BODY onload event.
    try {
        //notify the appropriate bones
        microstrategy.IS_RELOAD = true;
        if (microstrategy.updateManager) microstrategy.updateManager.acknowledgeRequest();
        this.notifyOrphanBones('onreload', e);
        this.notifyOrphanBones('onrepostload', e);

        /*
            TQMS:347436; notify that the onreload of the bones is done, we need to notify the 
            properties editor to reinitialize the children models
        */
        if (microstrategy.updateManager) microstrategy.updateManager.acknowledgeReloadEnd();
 	window.setTimeout("microstrategy.eventManager.onforcerepaint()", 0);//issue 232662
        microstrategy.IS_RELOAD = false;

        return true;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

mstrEventsManagerImpl.prototype.onwinresize = function() {
    //@class=mstrEventsManagerImpl;@method=onwinresize;
    //Usage: to be called from a BODY onresize event.
    try {
        if (this.hasWindowResized()) {
            this.notifyOrphanBones("onwinresize");
            this.notifyOrphanBones("onforcerepaint");
            if (typeof resizePromptContent != 'undefined') resizePromptContent();
        }
        return true;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

mstrEventsManagerImpl.prototype.ondialogresize = function(e) {
    //@class=mstrEventsManagerImpl;@method=ondialogresize;
    try {
        this.getSource(e);
        this.notifyOrphanBones("ondialogresize", e);
        this.notifyOrphanBones("onforcerepaint");
        if (typeof resizePromptContent != 'undefined') resizePromptContent();
        return true;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

//methods
mstrEventsManagerImpl.prototype.getSource = function(e, obj) {
    //Purpose: create a .source object to cache event information, so that the object
    //may be publicly read by event handlers in s.
    //Usage: called privately from event handlers of mstrEventsManagerImpl object.

    try {
        this.source = new Object;
        try {
            getMouse(e);
            this.source.mousedownX = lMouseX;
            this.source.mousedownY = lMouseY;
            this.source.shiftKey = ((bIsIE4) ? event.shiftKey : e && e.shiftKey); //shiftKey(e);
            this.source.button = getButtonId(e);
            this.source.elem = (obj) ? obj : microstrategy.findAncestor(getEventTarget(e));
        }
        catch(localerr) {
            this.source.elem = null;
        }
        if (this.source.elem) {
            this.source.id = this.source.elem.getAttribute('id');
            this.source.type = microstrategy.objectType(this.source.elem);
            this.source.subType = microstrategy.subObjectType(this.source.elem);
            this.source.bone = microstrategy.findBone(this.source.elem);
            this.source.left = getObjSumLeftScrolled(this.source.elem);
            this.source.top = getObjSumTopScrolled(this.source.elem);
            this.source.width = this.source.elem.offsetWidth;   //getObjWidth won't work in Mozilla
            this.source.height = this.source.elem.offsetHeight; //getObjHeight won't work in Mozilla
            this.source.draggable = (this.source.bone && this.source.bone.elem) ? this.source.bone.elem.getAttribute(microstrategy.HTMLATTR_DRAG) : null;
            this.source.draggable = (!isNaN(parseInt(this.source.draggable))) ? parseInt(this.source.draggable) : microstrategy.HTMLATTR_DRAG_OFF;
        } else {
            this.source.id = null;
            this.source.type = null;
            this.source.subType = null;
            this.source.bone = null;
            this.source.left = lMouseX;
            this.source.top = lMouseY;
            this.source.width = 0;
            this.source.height = 0;
            this.source.draggable = microstrategy.HTMLATTR_DRAG_OFF;
        }
        this.source.offsetX = this.source.left - lMouseX;
        this.source.offsetY = this.source.top - lMouseY;

        return this.source;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }

}

mstrEventsManagerImpl.prototype.notifyBone = function(eventName, e) {
    //Usage: to notify a single  that an event fired in its gui.
    //Purpose: fire event handler of the  in this.source object.
    try {
        //fire event handler in source , if any
        if (this.source && this.source.bone && eventName in this.source.bone) {
            return this.source.bone[eventName](e, this.source);
        }

        return false;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

mstrEventsManagerImpl.prototype.notifyOrphanBones = function() {
    //@class=mstrEventsManagerImpl;@method=notifyOrphanBones;
    //Usage: to broadcast a global event, like window being loaded or resized.
    //Purpose: fire event handlers in all orphan s.
    try {

        var i;
        
        var evtName = arguments[0];
        
        var args = [];
        for (i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
        
        // Create arrays of primary and secondary bones.
        var cnt = 0;
        var pBones = [];
        var sBones = [];
        for (var id in microstrategy.bones) {
            var b = microstrategy.bones[id];
            if (b && !b.parentBone && !b.isDormant && b[evtName]) {
                cnt++;
                if (b.primaryBone) {
                    pBones.push(b);
                } else {
                    sBones.push(b);
                }
            }
        }
        
        // Reverse the collections of bones so that the last ones loaded are the first to hear events.
        pBones.reverse();
        sBones.reverse();
        
        // Create one collection of bones (primary first, then secondary) and loop through them calling the event.
        var bones = pBones.concat(sBones);
        var __result = true;

        for (i = 0; i < cnt; i++) {
            // If the return of the event call is exactly equal to false (not 'undefined') then return false.
            if (bones[i][evtName].apply(bones[i], args) == false) {
                __result = false;
            }
        }
        
        return __result;
        
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}
mstrEventsManagerImpl.prototype.notifyZones = function(eventName, e) {
    //Usage: to broadcast a global event, like window being loaded or resized.
    //Purpose: fire event handlers in all zone objects.
    try {
        var ozones = microstrategy.zones;
        var izones = ozones.length;
        for (var i = 0; i < izones; i++) {
            if (ozones[i] && eventName in ozones[i]) {
                ozones[i][eventName](e);
            }
        }
        return false;
    }
    catch(err) {
        microstrategy.errors.log(err);
        return false;
    }
}

mstrEventsManagerImpl.prototype.executeFunction = function(functionToExecute) {
    for (var bone in microstrategy.controlVariables) {
        if (!microstrategy.controlVariables[bone]) {
            window.setTimeout("microstrategy.eventManager.executeFunction('" + functionToExecute + "');", 250);
            return;
        }
    }
    eval(functionToExecute);
    microstrategy.controlVariables = new Object();
}

mstrEventsManagerImpl.prototype.hasWindowResized = function() {
    //@class=mstrEventsManagerImpl;@method=hasWindowResized;
    try {
        var __result = false;
        var h = mstr.utils.BoxModel.getBrowserWindowHeight(document); //getBrowserWindowHeight();
        var w = mstr.utils.BoxModel.getBrowserWindowWidth(document); //getBrowserWindowWidth();
        if (h != this.browserHeight || w != this.browserWidth) {
            this.browserHeight = h;
            this.browserWidth = w;
            __result = true;
        }
    }
    catch(err) {
        microstrategy.errors.log(err);
    }
    return __result;
}

function mstrEventsManagerImpl() {
    return this;
}

if (microstrategy) microstrategy.eventManager = new mstrEventsManagerImpl();

