/* global $ */
/* global getWindowWidth, getWindowHeight, getCurrentPage */
/* global console_trace */
var g_lightBoxTimer = null;
var g_lightBoxLocked = false;

function resizeLightbox( usePageOffsets )
{
    var lightbox = $( ".lightbox" );
    if ( lightbox.length == 0 )
        return;

    var nHeight = getWindowHeight();
    if ( document.body )
        if ( document.body.clientHeight > nHeight )
           nHeight = document.body.clientHeight;

    $( ".lightbox-background" ).width( getWindowWidth() ).height( nHeight );

    var nOffset_top  = 0;
    var nOffset_left = 0;
    if ( usePageOffsets )
    {
        var nOrientation = window.orientation;
        var isPortrait = (nOrientation === undefined || nOrientation == 0);

	nOffset_top  = isPortrait ? window.pageYOffset : window.pageXOffset;
	nOffset_left = isPortrait ? window.pageXOffset : window.pageYOffset;
    }
    //console_log( "width = " + getWindowWidth() + ", height = " + getWindowHeight() + " (" + nHeight + "), offset = (" + nOffset_top + ", " + nOffset_left + ")" );

    var nTop = parseInt( nOffset_top + (getWindowHeight() - lightbox.height() ) / 2 );
    var nLeft = parseInt( nOffset_left + (getWindowWidth() - lightbox.width() ) / 2 );

    //console_log( "width = " + getWindowWidth() + ", height = " + nHeight );
    //console_log( "off left = " + nOffset_left + ", off top = " + nOffset_top );
    //console_log( "LB width = " + lightbox.width() + ", LB height = " + lightbox.height() );
    //console_log( "setting to top = " + nTop + ", left = " + nLeft );
    lightbox.css( { top: nTop, left: nLeft } );
}

/**
 * options:
 *   text: message to be displayed
 *   canClose: determines whether a Close link is shown.  Defaults to false.
 *   onClose: optional javascript string to be executed upon clicking a Close link (no apostrophes allowed in callback code), this gets run BEFORE the lightbox is dismissed
 *   onClosePost: optional javascript string to be executed upon clicking a Close link (no apostrophes allowed in callback code), this gets run AFTER the lightbox is dismissed
 *   timeout: delay in ms before self-closing (only applies if canClose=false).  Defaults to 1000, use 0 to have never-closing messages (programmatically closed by a subsequent closeLightBox, or openLightbox with force=true)
 *   page: id of page to attach lightbox to.  Omit or set to null to use the current page
 *   labelClose: whether the upper right link says "Close" (default) or something custom
 *   align: one of 'left', 'right', 'center'
 *   size: designation of "[h-<size>] [w-<size>]" (see lightbox.css).  Typically only width is specified, as one of size 'w-medium' (default for canClose=false), 'w-wide' (default for canClose=true), or 'w-xwide'
 *   force: force the closure of an existing lightbox.  Defaults to false.
 *   trace: controls whether the messagebox text is dumped to the console (useful for debugging).  Defaults to true for canClose=true.
 */
function openLightBox( options )
{
    // we can only have one lightbox open at a time
    if ( ! closeLightBox( options.force ) )        // were we denied closure? (because of a extant modal)
        return;                     // ... then don't create another one

    if ( options.trace === undefined && options.canClose || options.trace )		// for simple timeout messages (e.g., "Login updated") don't bother doing a trace by default
	console_trace( `lightbox: ${options.text}` );

    var pageID = options.page;
    if ( pageID == null )
        pageID = getCurrentPage();     // use the current page

    $( "#" + pageID ).append( "<div class='lightbox'></div>" );

    // lightboxes require a dark background div, which goes after the lightbox content (but has a lower z-index)
    // destroy any extant background div from any current lightboxes, and create a new one for us
    $( ".lightbox-background" ).remove();

    var lightbox = $( ".lightbox" );
    lightbox.after( "<div class='lightbox-background'></div>" );
    var strSize = "";

    var strContent = "";
    if ( options.canClose || options.callbackTrue !== undefined && options.callbackTrue || options.callbackFalse !== undefined && options.callbackFalse )
    {
	var strCloseCallback = "";
	var strClose = "";

	if ( options.canClose )
	{
	    if ( options.onClose !== undefined )
		strCloseCallback += options.onClose;

	    strCloseCallback += ";closeLightBox(true);";

	    if ( options.onClosePost !== undefined )
		strCloseCallback += options.onClosePost;

	    strClose = "Close";
	}

	if ( options.labelClose !== undefined )
	    strClose = options.labelClose;

	strContent += "<div class='lightbox-close'>" + (strCloseCallback ? ("<a href='javascript:void(0)' onclick=\"" + strCloseCallback + "\">" + strClose + "</a>") : strClose) + "</div>";
        strContent += "<div class='lightbox-message closeable'><div>" + options.text + "</div></div>";

        g_lightBoxLocked = true;
    }

    else
    {
        //strContent += "<div class='lightbox-size'></div>";
        strContent += "<div class='lightbox-message non-closable'><div>" + options.text + "</div></div>";

        unlockLightBox();

        if ( options.timeout !== undefined && options.timeout <= 0 )		// never timeout?
	    ;	// don't timeout.  This means the lightbox must be closed with subsequent call with force=true, or explicit call to closeLightBox
        else
            closeLightBoxDelayed( options.timeout ? options.timeout : 1000 );
    }

    if ( options.size !== undefined )
	strSize = options.size;
    else
	strSize = "h-small";

    if ( ! strSize.match( /w-/ ) )		// did the user not specify a width?
	strSize += true || options.canClose ? " w-wide" : " w-medium";

    //console_log( "pageID = '" + pageID + "', text='" + options.text + "', canClose = '" + options.canClose + "'" );
    lightbox.html( strContent );

    $( "div.lightbox-message" ).addClass( strSize );
    $( "div.lightbox-message" ).css( "text-align", options.align === undefined ? "center" : options.align );

    if ( options.tag === undefined && options.tag )
        setLightBoxTag( options.tag );

    resizeLightbox( true );
    lightbox.show();
}

// is there a lightbox currently being displayed?
/* exported hasLightBox */
function hasLightBox()
{
    return $( ".lightbox" ).is( ":visible" );
}

/* exported getLightBoxTag */
function getLightBoxTag()
{
    return $( ".lightbox" ).attr( "tag" );
}

function setLightBoxTag( strTag )
{
    $( ".lightbox" ).attr( "tag", strTag );
}

/* exported rehomeLightBox */
function rehomeLightBox( selector )
{
    var lightbox = $( ".lightbox" ).detach();
    var background = $( ".lightbox-background" ).detach();

    if ( lightbox.length > 0 && background.length > 0 )
    {
        $(selector).append( lightbox );
        lightbox.after( background )
    }
}

/**
 * Close the currently open lightbox, after a delay in milliseconds
 */
function closeLightBoxDelayed( delay )
{
    // is there already a pending close?  If so, cancel it
    if ( g_lightBoxTimer )
    {
        window.clearTimeout( g_lightBoxTimer );
        g_lightBoxTimer = null;
    }

    if ( g_lightBoxLocked )
    {
	// I think it's possible with dynamically created pages that we can blow away the lightbox
	// and therefore leave the lightbox locked
	if ( $( "div.lightbox" ).length > 0 )	// it's a legitimate lock
	    return false;

	// hmmm... this seems to happen when the "Updating application..." lightbox is opens when the enter pin box is already open
	//console_trace( "unlocking non-existant lightbox" );

        unlockLightBox();		// continue with the closing (which is probably a moot point since we couldn't find div.lightbox
    }

    if ( delay === undefined )
        delay = 0;

    if ( delay == 0 )
    {
        $( ".lightbox-background" ).remove();
        $( ".lightbox" ).remove();
    }
    else
    {
        g_lightBoxTimer = window.setTimeout( function() {
            $( ".lightbox-background" ).remove();
            $( ".lightbox" ).remove();
            g_lightBoxTimer = null;
        }, delay );
    }

    return true;
}

function unlockLightBox()
{
    g_lightBoxLocked = false;
}

/**
 * Close the currently open lightbox, with an optional override on already-open modal lightboxes
 */
function closeLightBox( bForce )
{
    if ( bForce !== undefined && bForce )
        unlockLightBox();

    // is there already a pending close?  If so, cancel it
    if ( g_lightBoxTimer )
    {
        window.clearTimeout( g_lightBoxTimer );
        g_lightBoxTimer = null;
    }

    if ( g_lightBoxLocked )
    {
	// I think it's possible with dynamically created pages that we can blow away the lightbox
	// and therefore leave the lightbox locked
	if ( $( "div.lightbox" ).length > 0 )	// it's a legitimate lock
	    return false;

	// hmmm... this seems to happen when the "Updating application..." lightbox is opens when the enter pin box is already open
	//console_trace( "unlocking non-existant lightbox" );

	unlockLightBox(); 		// continue with the closing (which is probably a moot point since we couldn't find div.lightbox
    }

    //if ( $( ".lightbox" ).length > 0 )
	//console_trace( "closing" );

    $( ".lightbox-background" ).remove();
    $( ".lightbox" ).remove();

    return true;
}

/**
 * options:
 *   defaultChoice: null (no action), false (default) or true.  If null, the default value of labelClose is "Cancel"
 *   disabledTrue: false (default)
 *   labelTrue: "Okay" (default) or something custom
 *   labelFalse: "Cancel" (default) or something custom
 *   callbackTruePre: javascript that will be executed when the TRUE button is clicked, BEFORE the dialog closes. A return value of false aborts the button click.
 *   callbackFalsePre: javascript that will be executed when the FALSE button is clicked, BEFORE the dialog closes. A return value of false aborts the button click.
 *   callbackTrue: javascript that will be executed when the TRUE button is clicked, after the dialog closes.  Default is nothing.
 *   callbackFalse: javascript that will be executed when the FALSE button is clicked, after the dialog closes.  Default is nothing.
 *   size: (as per openLightBox, defaults to "x-wide")
 *
 * This function sets options.canClose to true (unless explicitly set to false), sets options.onClosePost, and appends buttons to the provided options.text
 */
/* exported lightBoxConfirm */
function lightBoxConfirm( options )
{
    if ( options.canClose != false && options.defaultChoice == null )	// if we can close the dialog, and we don't want a defaultChoice
        if ( ! options.labelClose )					// make sure labelClose defaults to "Cancel"
	    options.labelClose = "Cancel";

    options = $.extend( {
        defaultChoice: false,
        labelTrue: "Okay",
        labelFalse: "Cancel",
        disabledTrue: false,
        callbackTruePre: "return true;",
        callbackTrue: "console_warn('callbackTrue not defined');",
        callbackFalsePre: "return true;",
        callbackFalse: "",
	canClose: true,
	size: "w-xwide"
    }, options );

    options.onClosePost = options.defaultChoice == null ? "" : (options.defaultChoice ? options.callbackTrue : options.callbackFalse);
    options.text +=
               '<table class="button-row no-print" style="margin-top:10px;margin-bottom:-5px;"><tr>' +
               '<td class="button2"><div class="lightbox-true button no-inset' + (options.disabledTrue ? ' noaccess' : '') + '" style="padding-top:5px;padding-bottom:5px;" onclick="if($(this).hasClass(\'noaccess\')) return false;if ( ! (function(){' + options.callbackTruePre + '})() )return false;closeLightBox(true);' + options.callbackTrue + '">' + options.labelTrue + '</div></td>' +
               (options.labelFalse == null ? '' : ('<td class="button2"><div class="lightbox-false button no-inset" style="padding-top:5px;padding-bottom:5px;" onclick="if ( ! (function(){' + options.callbackFalsePre + '})() )return false;closeLightBox(true);' + options.callbackFalse + '">' + options.labelFalse + '</div></td>')) +
               '</tr></table>';

    openLightBox( options );
}

/* exported lightBoxEnableTrue */
function lightBoxEnableTrue( bEnable )
{
    if ( bEnable === undefined )		// actually toggle
	$( ".lightbox td.button2 div.lightbox-true" ).toggleClass( "noaccess" );
    else
	$( ".lightbox td.button2 div.lightbox-true" ).toggleClass( "noaccess", ! bEnable );
}
