
// --------- begin initialization code ---------

function disableLink(linkObj) {
    linkObj.disabled = true;
    $(linkObj).addClassName('disabledLink');
}
function enableLink(linkObj) {
    linkObj.disabled = false;
    $(linkObj).removeClassName('disabledLink');
}
function keepSessionAlive(sessionTimeoutSeconds) {
    var intervalMs = (sessionTimeoutSeconds * 1000) - (30 * 1000);
    if (intervalMs < (30 * 1000)) {
        // should never happen, but paranoia runs deep in the heartland
        intervalMs = (30 * 1000);
    }
    setInterval(extendSession, intervalMs);
}
function extendSession() {
    // hit a page via Ajax to automatically extend the session
    ajaxUrl = '/glapp/keepAlive.jsp?nocache=' + (new Date()).getTime();
    new Ajax.Request(ajaxUrl, { method: 'get' } );
}

// --------- end initialization code ---------

// --------- begin navigation initialization code ---------

/**
 * Initialize the accordions used in the left navigation.
 */
function initializeNavAccordion(accordionId) {
    // first initialize the top-level navigation accordion
    var navAccordion = new accordion(accordionId, {
        classNames : {
            toggle : 'nav_accordion_toggle',
            toggleActive : 'nav_accordion_toggle_active',
            content : 'nav_accordion_content'
        },
        direction : 'vertical'
    });
    // now see if any accordions should be open by default
    var accordionCounter = 0;
    var activeAccordionFound = false;
    $$('#nav_accordion_container h3.nav_accordion_toggle').each(function(accordionObj) {
        $(accordionObj).adjacent('ul.nav_accordion_content li a').each(function(accordionEntryObj) {
            if (accordionEntryObj.href == document.location.href) {
                navAccordion.activate($$('#nav_accordion_container h3.nav_accordion_toggle')[accordionCounter]);
                $(accordionEntryObj).up('li').addClassName('active');
                throw $break;
            }
        });
        if (activeAccordionFound) {
            throw $break;
        }
        accordionCounter++;
    });
    // if no active accordion, see if a link can be marked selected
    if (!activeAccordionFound) {
        $$('#nav_accordion_container h3 a').each(function(menuLinkObj) {
            if (menuLinkObj.href == document.location.href) {
                menuLinkObj.addClassName('activeLink');
                throw $break;
            }
        });
    }
}

// --------- end navigation initialization code ---------

// --------- begin ajax form handling code ---------

var SubmitWatcher = Class.create();
/**
 * SubmitWatcher is used with Ajax to submit a form and then process the result.  This class
 * adds an event handler to a form submit button that intercepts any clicks of that button
 * and instead submits the form using Ajax.  To implement this functionality a SubmitWatcher
 * must be initialized using the form to be watched, the form element to be watched, and
 * any options.
 *
 * Example:
 *
 *   new SubmitWatcher(submitId, formId, optionsArray);
 *
 * The SubmitWatcher optionsArray parameter can contain any of the following:
 *
 *   successHandler - The successHandler is used to define a function to call if the Ajax
 *       returns with a response indicating success.  The function will be called with two
 *       parameters: the form object that the SubmitWatcher is defined for, and the JSON
 *       object returned by the back-end.
 *   failureHandler - The failureHandler is used to define a function to call if the Ajax
 *       returns with a response indicating failure.  The function will be called with two
 *       parameters: the form object that the SubmitWatcher is defined for, and the JSON
 *       object returned by the back-end.
 *   createHandler - The createHandler is used to define a function to invoke prior to sending
 *       the form submission.  If this method returns false then the form will not be submitted.
 *       The function will be called with two parameters: the form object that the SubmitWatcher
 *       is defined for, and the form element that the SubmitWatcher is defined for.
 *
 * Full example:
 *
 *   var watcherHandlers = {
 *       create : function(formObj, submitObj) {
 *           // perform initialization or other functionality needed prior to form submission
 *           return true;
 *       },
 *       success : function(formObj, json) {
 *           // handle Ajax form submit success
 *           if (!json.success) {
 *               watcherOptions.failure(formObj, json);
 *               return;
 *           }
 *           alert('Ajax returned successfully');
 *       },
 *       failure : function(formObj, json) {
 *           // handle Ajax form submit error
 *           alert('Ajax failed');
 *       }
 *   };
 *   var watcherOptions = {
 *       createHandler:  watcherHandlers.create,
 *       successHandler: watcherHandlers.success,
 *       failureHandler: watcherHandlers.failure
 *   };
 *   new SubmitWatcher(selectObj, formObj, watcherOptions);
 */
SubmitWatcher.prototype = {
    // constructor
    initialize: function(submitObj, formObj, options) {
        this.formObj = formObj;
        if (!$(submitObj)) {
            throw "submitObj does not exist in SubmitWatcher.initialize()";
        }
        if (!$(this.formObj)) {
            throw "formObj does not exist in SubmitWatcher.initialize()";
        }
        this.setOptions(options);
        $(submitObj).onclick = this.hijackNode.bindAsEventListener(this);
        // additionally set a watcher for the form submit to handle submits where the user simply
        // presses the enter key without clicking a button.
        $(formObj).onsubmit = this.hijackNode.bindAsEventListener(this);
    },
    // set up the default options array, and then override those values with any values
    // initialized in the constructor.
    setOptions: function(options) {
        this.options = {
            successHandler:    null,
            failureHandler:    null,
            createHandler:     null
        };
        Object.extend(this.options, options || { });
    },
    // hijackNode is called if a user clicks on the form element that was specified in submitObj
    // when this class was initialized.  it will serialize the form, submit the ajax request,
    // and execute any handlers that have been defined.
    hijackNode: function(e) {
        if (this.options.createHandler != null) {
            var submitObj = Event.element(e);
            var createStatus = this.options.createHandler(this.formObj, submitObj);
            if (!createStatus) {
                return false;
            }
        }
        var _this = this;
        var params = {
            requestHeaders: {Accept: 'application/json'},
            method: 'post',
            parameters: Form.serialize($(this.formObj), true),
            mimetype: "application/json",
            onSuccess: function(transport) {
                _this._applyHandler(_this.options.successHandler, transport.responseText.evalJSON());
            },
            onFailure: function(transport) {
                _this._applyHandler(_this.options.failureHandler, transport.responseText.evalJSON());
            }
        };
        // submit the Ajax request
        new Ajax.Request($(this.formObj).action, params);
        // fire a custom event from the form object to indicate that a button was clicked.
        // since the onclick function is overwritten during SubmitWatcher initialization a
        // custom event is the only way to notify watchers that something happened.
        $(this.formObj).fire('dtv:ajaxSubmit');
        return false;
    },
    // _applyHandler is an internal helper method used to execute handlers defined for this class.
    _applyHandler: function(handler, json) {
        if (handler == null) {
            return;
        }
        handler(this.formObj, json);
    }
}

// --------- end ajax form handling code ---------

// --------- begin tabbed content code ---------

/**
 * This class provides the capability for setting up a tabbed content box.  The way that
 * the class works is that the HTML must contain a container element that will have tab elements
 * and content elements.  For example:
 *
 *   <div id="sj_tab_container">
 *      <span class="sj_tab_title">Tab 1 Title</span>
 *      <span class="sj_tab_title">Tab 2 Title</span>
 *      <span class="sj_tab_title">Tab 3 Title</span>
 *      <div class="sj_tab_content">Tab 1 Content</div>
 *      <div class="sj_tab_content" style="display:none">Tab 2 Content</div>
 *      <div class="sj_tab_content" style="display:none">Tab 3 Content</div>
 *   </div>
 *
 * Note that order matters - tab content MUST be included in the same order as the corresponding
 * tab title.  This class can then be initialized (AFTER the DOM has loaded) using:
 *
 *   new SJTabContent($('sj_tab_container'));
 *
 * Additionally, it is possible to specify custom options by passing an optional "options" array
 * as the second argument to the SJTabContent constructor.
 */
var SJTabContent = Class.create({
    // currently active tab, null if none
    activeTab: null,
    container: null,
    // constructor
    initialize: function(container, options) {
        if (!$(container)) {
            throw(container + " does not exist.  Unable to initialize SJTabContent.");
            return false;
        }
        this.container = container;
        this.setOptions(options);
        var tabs = $(this.container).select('.' + this.options.titleClass);
        tabs.each(function(tab) {
            Event.observe(tab, this.options.onEvent, this.activate.bind(this, tab), false);
            Event.observe(tab, 'dtv:activateSJTabContent', this.activate.bind(this, tab), false);
        }.bind(this));
        // activate the first tab
        this.activate(tabs[0]);
    },
    // set up the default options array, and then override those values with any values
    // initialized in the constructor.
    setOptions: function(options) {
        this.options = {
            titleClass:       'sj_tab_title',
            activeTitleClass: 'sj_tab_title_active',
            contentClass:     'sj_tab_content',
            onEvent:          'click'
        };
        Object.extend(this.options, options || { });
    },
    activate : function(tab) {
        // if current tab was clicked just return
        if (this.activeTab == tab) {
            return;
        }
        // otherwise deactivate currently active and replace with new tab
        this._deactivate(false);
        tab.addClassName(this.options.activeTitleClass);
        var contents = $(this.container).select('.' + this.options.contentClass);
        var content = contents[this._tabIndex(tab)];
        $(content).show();
        this.activeTab = tab;
    },
    _deactivate: function(collapseEffect) {
        if (this.activeTab == null) {
            return;
        }
        var contents = $(this.container).select('.' + this.options.contentClass);
        var content = contents[this._tabIndex(this.activeTab)];
        if (content.visible()) {
            content.hide();
        }
        this.activeTab.removeClassName(this.options.activeTitleClass);
    },
    _tabIndex: function(indexTab) {
        var tabs = $(this.container).select('.' + this.options.titleClass);
        var activeIndex = 0;
        tabs.each(function(tab, index) {
            if (tab == indexTab) {
                activeIndex = index;
            }
        });
        return activeIndex;
    }
});

// --------- end tabbed content code ---------

// --------- begin div transition effect code ---------

// keep track of which elements are currently being used in transitions.  necessary to
// avoid executing effects out of order
var _transitionEffect = null;
/**
 * Hide one div and use a nice effect to make a new div appear.
 *
 * Example:
 *
 *   transition('divToHide', 'divToShow');
 *
 * @param currentDiv The div that will be replaced/hidden.
 * @param nextDiv The new div to display.
 */
function transition(currentDiv, nextDiv) {
    if ($(nextDiv) == null) {
        throw "function transition() called with nextDiv element '" + nextDiv + "' that does not exist";
    }
    if (_transitionEffect != null) {
        // if there is an effect in progress then there is an ordering issue so kill the
        // old effect.
        _transitionEffect.cancel();
    }
    _transitionEffect = Effect.Appear(nextDiv, {afterFinish: _transitionComplete});
    Element.hide(currentDiv);
}
function _transitionComplete(obj) {
    _transitionEffect = null;
}

// --------- end div transition effect code ---------

// --------- begin gamer card lightbox code ---------

function openGamerCardLightbox(userName) {
    var sjDialog = Dialog.info({
        url:     '/glapp/layout/component/ajaxGamerCard.jsp',
        options: {
        	method: 'get',
            parameters: 'userName=' + userName
        }
    }, 
    {
        className:    'dialog',
        width:        359,
        height:       254,
        zIndex:       3,
        recenterAuto: false
    });
}

// --------- end gamer card lightbox code ---------

// --------- begin my gamelounge page code ---------

function openLoginLightbox() {
	if (passwordWatcherHandlers.hasLoggedIn) {
		transition('sj_userinfo_display', 'sj_userinfo_edit_profile')
	} else {
	    // create the login lightbox and copy the enter password form into it
	    var sjDialog = Dialog.info('<div id="loginLightboxContainer"></div>', {
	        className:    'dialog',
	        width:        400,
	        height:       160,
	        zIndex:       3,
	        recenterAuto: false
	    });
	    $('loginLightboxContainer').appendChild($('loginLightbox'));
	}
}
function closeLoginLightbox() {
    // hide the enter password form and close the lightbox
    $('loginLightboxUserPassword').value = '';
    $('loginLightboxError').innerHTML = '';
    $('loginLightboxError').hide();
    $('lightboxHiddenDiv').appendChild($('loginLightbox'));
    Dialog.closeInfo();
}
var passwordWatcherHandlers = {
	hasLoggedIn : false,
    success : function(formObj, json) {
    	$('loginLightboxError').innerHTML = '';
        $('loginLightboxError').hide();
        // handle Ajax form submit success
        if (!json.success) {
            passwordWatcherHandlers.failure(formObj, json);
            return;
        }
        passwordWatcherHandlers.hasLoggedIn = true;
        closeLoginLightbox();
        transition('sj_userinfo_display', 'sj_userinfo_edit_profile');
    },
    failure : function(formObj, json) {
        // handle Ajax form submit error
        var message = '';
        for (var i=0; i < json.errors.length; i++) {
            message += json.errors[i] + '<br />';
        }
        $('loginLightboxError').innerHTML = message;
        $('loginLightboxError').show();
        /*
        // FIXME - debugging only
        var msg = 'JSON: ' + $H(json).inspect().escapeHTML();
        alert(msg);
        */
    }
};
var passwordWatcherOptions = {
    successHandler: passwordWatcherHandlers.success,
    failureHandler: passwordWatcherHandlers.failure
};
function initMyGameLounge() {
    new SubmitWatcher('mygameloungePasswordSubmit', 'mygameloungePasswordForm', passwordWatcherOptions);
}

// --------- end my gamelounge page code ---------

// --------- begin reset password code -----------

function openResetPasswordLightbox() {
    // create the reset lightbox and copy the reset password form into it
    var sjDialog = Dialog.info('<div id="resetPasswordLightboxContainer"></div>', {
        className:    'dialog',
        width:        400,
        height:       160,
        zIndex:       3,
        recenterAuto: false
    });
    $('resetPasswordLightboxContainer').appendChild($('resetPasswordLightbox'));
}
function closeResetPasswordLightbox(url) {
    // hide the reset password form and close the lightbox
    $('resetPasswordEmail').value = '';
    $('resetPasswordLightboxError').innerHTML = '';
    $('lightboxResetPasswordHiddenDiv').appendChild($('resetPasswordLightbox'));
    Dialog.closeInfo();
    
    if (url != null) {
        window.location.href = url;
    }
}
var resetPasswordWatcherHandlers = {
    success : function(formObj, json) {
        $('resetPasswordLightboxError').hide();
        $('resetPasswordEmail').value = '';
        // handle Ajax form submit success
        if (!json.success) {
            resetPasswordWatcherHandlers.failure(formObj, json);
            return;
        }
        closeResetPasswordLightbox("/glapp/mygamelounge/mygameloungeProspect.jsp");
    },
    failure : function(formObj, json) {
        // handle Ajax form submit error
        var message = '';
        for (var i=0; i < json.errors.length; i++) {
            message += json.errors[i] + '<br />';
        }
        $('resetPasswordLightboxError').innerHTML = message;
        $('resetPasswordLightboxError').show();
        /*
        // FIXME - debugging only
        var msg = 'JSON: ' + $H(json).inspect().escapeHTML();
        alert(msg);
        */
    }
};
var resetPasswordWatcherOptions = {
    successHandler: resetPasswordWatcherHandlers.success,
    failureHandler: resetPasswordWatcherHandlers.failure
};
function initResetPassword() {
    new SubmitWatcher('resetPasswordSubmit', 'resetPasswordForm', resetPasswordWatcherOptions);
}

// --------- end reset password code -------------

// --------- begin game details page code ---------

function displayScreenshot(screenshotCount) {
    var divId = 'sj_screenshot_img_' + screenshotCount;
    if (!($(divId))) {
        // no such screenshot available
        return false;
    }
    $('sj_screenshot_img_display').innerHTML = $(divId).innerHTML;
    $('sj_screenshot_count').innerHTML = screenshotCount;
    var previousDivId = 'sj_screenshot_img_' + (screenshotCount - 1);
    if (!($(previousDivId))) {
        disableLink('sj_screenshot_previous');
    }
    var nextDivId = 'sj_screenshot_img_' + (screenshotCount + 1);
    if (!($(nextDivId))) {
        disableLink('sj_screenshot_next');
    }
    return true;
}
function previousScreenshot(currentValue) {
    if (displayScreenshot(currentValue - 1)) {
        currentValue--;
        enableLink('sj_screenshot_next');
    }
    return currentValue;
}
function nextScreenshot(currentValue) {
    if (displayScreenshot(currentValue + 1)) {
        currentValue++;
        enableLink('sj_screenshot_previous');
    }
    return currentValue;
}
function openGamePopup(gameId) {
    var popupUrl = '/glapp/games/gamePopup.jsp?gameId=' + gameId;
    window.open(popupUrl, 'sj_game_popup', 'width=800,height=650');
    return false;
}
function closeGamePopup(gameId) {
    if (window.opener != null) {
        window.opener.location.href = '/glapp/games/gameOver.jsp?gameId=' + gameId;
    }
    window.close();
    return false;
}

// --------- end game details page code ---------

// temp code to display blackjack message
Event.observe(window, 'load', function() {
    if (document.location.href.indexOf('gameId=286') >= 0 && $('sj_game_popup_close')) {
        var msg = new Element('div');
        msg.update('Note: If you exit the game without completing it, your score will be 0.');
        msg.setStyle({color:'white',width:'500px',fontSize:'12pt',fontWeight:'bold',textAlign:'left',position:'absolute',marginLeft:'40px',marginTop:'2px'});
        $('sj_game_popup_close').insert({'before':msg});
    }
});
