$.namespace("ProspectDirector");
$.namespace("ProspectDirector.Types");

/**
EVERYTHING STARTS HERE!
@class RUNTIME
@namespace ProspectDirector
*/
ProspectDirector.RUNTIME = Class.extend({

    init: function (options) {
    }

});

/**
This method <b><u>MUST</u></b> be called before any other client side script is called.
@static
@method start
@param args {Object}
@param args.environmentVariables
*/
ProspectDirector.RUNTIME.start = function (environmentVariables) {

    environmentVariables = environmentVariables ? environmentVariables : {};

    ProspectDirector.RUNTIME.ENVIRONMENT = $.extend(ProspectDirector.RUNTIME.ENVIRONMENT, environmentVariables);

    ProspectDirector.RUNTIME.MODULES = {};

    /* global ajax setup */

    $.ajaxSetup({
        cache: false,
        error: function (jqXHR, status, thrownError) {
            new PD.Web.AjaxErrorHandler({
                config: this,
                jqXHR: jqXHR
            });
        }
    });

    /* global ajax event handlers */

    $(document).ajaxSend(function (e, xhr, settings) {

        var guid = ProspectDirector.RUNTIME.guid();

        xhr.guid = guid;

        setTimeout(function () {
            if (xhr.state() === "pending" && xhr.guid === guid) {
                PDJS.Shared.MessageStack.instance.info("Your request is being processed... please wait.", "~/application/icons/32x32/CLOCK.PNG");
            }
        }, 1500);

    });

    /* window event handlers */

    $(document).ready(function () {
        ProspectDirector.RUNTIME.loadModule(new ProspectDirector.Modules.Core.Main(), "Main");
    });

    /* break out of IFRAME? */
    if (window.top !== window.self) {
        window.top.location = window.self.location;
    }

};

/**
Loads a new instance of a module and adds the instance to the RUNTIME.MODULES object.
@static
@method loadModule
@param fqn {String} The fully qualified name of the module to load.
@param args {Object} A dictionary used to pass arguments to the module constructor.
@param [id] {String} An ID to identify the module after it has been added to the RUNTIME object. If this parameter is omitted the name of the module will be used instead.
@return {Object} The instantiated module.
*/
ProspectDirector.RUNTIME.loadModule =
function (module, id) {

    ProspectDirector.RUNTIME.MODULES[id] = module;
    
    return ProspectDirector.RUNTIME.MODULES[id];

};

/**
Stores runtime environment variables. It is expected that properties exposed by this class are set.
@static
@class ENVIRONMENT
@namespace ProspectDirector.RUNTIME
**/
ProspectDirector.RUNTIME.ENVIRONMENT = {

    /** 
    The virtual directory of the application.
    @property VIRTUAL_DIRECTORY
    @final
    */
    VIRTUAL_DIRECTORY: null,


    /** 
    The user name of the current logged in user.
    @property USER_NAME
    @final
    */
    USER_NAME: null,

    /** 
    The user id of the current logged in user.
    @property USER_ID
    @final
    */
    USER_ID: null

};

ProspectDirector.RUNTIME.guid = function () {

    var S4 = function () {
        return Math.floor(
                Math.random() * 0x10000 /* 65536 */
            ).toString(16);
    };

    return (
        S4() + S4() + "-" +
        S4() + "-" +
        S4() + "-" +
        S4() + "-" +
        S4() + S4() + S4()
    );

};