var Global = {

    /**
     * Writes a debug statement to the Firefox console if it is available. Make sure to use this method instead of
     * console.debug() since that method causes a Javascript error if the console is not available.
     * @param text Debug content.
     */
    debug: function( text )
    {
        if ( typeof(console) != "undefined" && this.enableDebug )
        {
            console.debug( text );
        }
    },

    /**
     * Writes an error statement to the console if it is available.
     * @param text Text to write to the console.
     */
    error: function( text )
    {
        if ( typeof(console) != "undefined" && this.enableDebug )
        {
            console.error( text );
        }
    },

    /**
     * Reloads the current page in the browser.
     */
    reloadPage: function()
    {
        location.reload( true );
    },

    /**
     * Navigates the browser to the given url.
     * @param url
     */
    nav: function( url )
    {
        document.location.href = url;
    },

    /**
     * Closes a modal dialog.
     * @param id Id of the dialog in the dom.
     */
    closeDialog: function( id )
    {
        $( "#" + id ).dialog( 'close' )
    },

    /**
     * Builds a modal dialog.
     * @param id Id of the dialog in the dom (optional).
     * @param title Title of the dialog (optional).
     * @param body Body of the dialog (optional)
     */
    buildDialog: function( id, title, body )
    {
        if ( !id )
        {
            id = "dialog_" + (new Date()).getTime();
        }
        var dialog = $( "#" + id );

        if ( dialog.length == 0 )
        {
            dialog = $( '<div id="' + id + '" style="display:none;"></div>' ).appendTo( "body" );

            dialog.dialog( {
                autoOpen: false,
                bgiframe: true,
                resizable: false,
                width: 400,
                modal: true
            } );
        }

        if ( title )
        {
            dialog.dialog( 'option', 'title', title );
        }
        if ( body )
        {
            dialog.html( body );
        }

        return dialog;
    },

    /**
     * Displays an alert dialog.
     * @param message Message to display.
     */
    alert: function( message )
    {
        $( "<div></div>" ).html( message ).dialog( {
            autoOpen: false,
            bgiframe: true,
            resizable: false,
            width: 350,
            modal: true,
            show: "blind",
            buttons: {
                Ok: function()
                {
                    $( this ).dialog( "close" );
                }
            }
        } ).addClass( "dialog-alert" ).dialog( "open" );
    },

    /**
     * Replaces all instances in the string of items in the replacements array.
     * @param string String to update.
     * @param replacements Array of replacements.
     */
    replace: function( string, replacements )
    {
        if ( replacements )
        {
            $.each( replacements, function( index, value )
            {
                string = string.replace( index, value );
            } );
        }
        return string;
    },

    /**
     * Displays a modal confirmation dialog.
     * @param title Title of the modal dialog.
     * @param body Body html.
     * @param yesCallback Function to call if the "yes" button is pressed.
     * @param noCallback Function to call if the "no" button is pressed.
     */
    confirm: function( title, body, yesCallback, noCallback )
    {
        Global.debug( "Global.confirm()" );

        var confirmDialog = Global.buildDialog( null, title, body );
        confirmDialog.dialog( 'option', 'buttons', {
            "Confirm": function()
            {
                $( this ).dialog( 'close' );
                if ( $( this ).dialog.yesCallback )
                {
                    $( this ).dialog.yesCallback();
                }
            },
            "Cancel": function()
            {
                $( this ).dialog( 'close' );
                if ( $( this ).dialog.noCallback )
                {
                    $( this ).dialog.noCallback();
                }
            }
        } );
        confirmDialog.dialog.yesCallback = yesCallback;
        confirmDialog.dialog.noCallback = noCallback;
        confirmDialog.dialog( 'open' );
    },

    /**
     * Returns the id from a node id.
     * For example: user-123 returns 123.
     * @param node Html node.
     * @param prefix Node id prefix (ex: user-).
     */
    getId: function( node, prefix )
    {
        if ( !node || node.length == 0 )
        {
            return null;
        }
        return node.prop( "id" ).substring( prefix.length );
    }
};
Global.enableDebug = true;

var Ajax = {

    /**
     * Handles an error thrown during an AJAX request.
     * @param request Request data.
     * @param textStatus Status of the response (ex: 404)
     * @param errorThrown The error that was thrown.
     */
    handleError: function( request, textStatus, errorThrown )
    {
        //var exceptionMsg = request.getResponseHeader( 'ExceptionMsg' );
        //alert( "An Error has occured:\n\n\t" + exceptionMsg );
        Global.error( "handleError: " + request + " " + textStatus + " " + errorThrown );
        Global.debug( request )
        if ( request.status == 401 )
        {
            Global.login();
        }
        else
        {
            alert( "An Error has occured: " + errorThrown );
        }
    },

    /**
     * Uses GET to load the given url. Used for requests that do not return content such as "live" calls. If the returned
     * data is an empty string it is considered a successful call, otherwise the data is displayed to the user.
     * @param url Url to call, can contain an optional {id} placeholder.
     * @param callBack Function to call if the request is successful.
     */
    doGet: function( url, callBack )
    {
        Global.debug( "Ajax.doGet(): url=" + url );

        Ajax.doGetData( url, function( data )
        {
            if ( data != '' )
            {
                var dialog = Global.buildDialog( null, null, data );
                dialog.dialog( 'open' );
            }

            else
            {
                if ( callBack )
                {
                    callBack();
                }
            }
        }, {} );
    },

    /**
     * Calls the given url to get data.
     * @param url Url to call, can contain an option {id} placeholder.
     * @param callBack Function to call if the request is successful.
     */
    doGetData: function( url, callBack, data )
    {
        Global.debug( "Ajax.doGetData(): url=" + url );

        $.ajax( {
            type: "GET",
            url: url,
            data: data,
            traditional: true,
            success: function( data )
            {
                callBack( data );
            },
            error: function( request, textStatus, errorThrown )
            {
                Ajax.handleError( request, textStatus, errorThrown );
            }
        } );
    },

    /**
     * Uses POST to submit the given form to get data.
     * @param form Html form
     * @param callBack Function to call if the request is successful.
     */
    doPostFormData: function( form, callBack )
    {
        Global.debug( "Ajax.doPostFormData(): url=" + form.attr( 'action' ) );

        $.ajax( {
            type: "POST",
            url: form.attr( 'action' ),
            data: form.serialize(),
            success: function( data )
            {
                callBack( data );
            },
            error: function( request, textStatus, errorThrown )
            {
                Ajax.handleError( request );
            }
        } );
    },

    /**
     * Sends a post request to the url.
     * @param url Url to the method, can contain {id} as a placeholder for the Persistable Id.
     * @param data Data to send in the post.
     * @param callBack Function to call if the method is successful.
     */
    doPostData: function( url, data, callBack, error )
    {
        Global.debug( "Ajax.doPostData(): url=" + url );

        $.ajax( {
            type: "POST",
            url: url,
            dataType: 'json',
            data: data,
            success: function( data )
            {
                if ( callBack )
                {
                    callBack( data );
                }
            },
            error: function( request, textStatus, errorThrown )
            {
                $( "div#workspace-pane-contents" ).hide();
                Ajax.handleError( request, textStatus, errorThrown );
                if ( error )
                {
                    error();
                }
            }
        } );
    }
}

$( function()
{
    // Set the height of the left nav background.
    $( "div#body div#left-nav-bg" ).height( $( "div#body ul#left-nav" ).height() + 40 );

    // Markets menu.
    $( "div#body ul#left-nav #nav-markets" ).click( function( e )
    {
        e.preventDefault();
        e.stopPropagation();
        $( "div#body div#nav-markets-menu-bg, div#body ul#left-nav ul#nav-markets-menu" ).toggle();
        $( "div#body div#nav-markets-menu-bg" ).height( $( "div#body ul#left-nav ul#nav-markets-menu" ).height() );
    } );

    $( "body" ).click( function( e )
    {
        $( "div#body div#nav-markets-menu-bg, div#body ul#left-nav ul#nav-markets-menu" ).each( function()
        {
            if ( $( this ).is( ":visible" ) )
            {
                $( this ).hide()
            }
        } );
    } );
} );

