
//----------------------------------------------------------

// Some utilities for error reporting:

function customerServiceText ()
{
    return 'If this problem persists, please contact'
         + ' Atomic Learning Customer Service:\r\n'
         + '\r\n'
         + '   1-320-631-5900 ext 8\r\n'
         + '   cs@atomiclearning.com';
}

// Typically used in AJAX onFailure callbacks, where the request
// never hit the server:
//
function ajaxTransportError ()
{
    genericError('There was a problem connecting to the server,'
               + ' please try again.');
}

// Typically used in AJAX onSuccess callbacks, where some sort
// of server error or failure was indicated:
//
function genericError (msg, doParent)
{
    var text = '';
    if (typeof msg == 'object') {
        text = msg.msg + '\r\n\r\n';
    }
    else if (msg) {
        text = msg + '\r\n\r\n';
    }
    text += customerServiceText();

    al_alert(text, doParent);
}

// A generic popup message
//
function al_alert (params, doParent)
{
    var msg   = '';
    var title = 'Atomic Learning';

    if (typeof params == 'object') {
        msg     = params.msg;
        if(typeof params.title != 'undefined'){
                title   = params.title;
        }
    }
    else {
        msg = params;
    }

    var extInstance = null;
    if (doParent && parent.Ext) {
        extInstance = parent.Ext;
    }
    else if (Ext) {
        extInstance = Ext;
    }

    if (extInstance) {
        var htmlMsg = msg.replace(/\r?\n/g, '<br />').replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;');
        var cb = extInstance.emptyFn();
        cb = params.callback;
        extInstance.Msg.alert(title, htmlMsg, cb);
    }
    else {
        alert(msg);
    }

    return true;
}

// Utility function for using the console
// This allows it to be commented out in one
// place.
function console_log (msg) {
    if (window.console) {
        console.log(msg);
    }
}

//----------------------------------------------------------

// Utility for making Ajax requests.
//
// Assumes JSON response includes a "status" value that is
// set to "success" if the onSuccess callback is to be invoked.
//
// If the JSON status is not "success", can optionally include
// a "msg" value to be included in the error message that is
// presented to the user.
//
// "opts" can include:
//     url (required) - e.g. "/admin/customseries"
//     parameters - for form post
//     onSuccess - callback function
//     failureMessage - e.g. "The attempt to reorder failed"
//                      (no trailing punctuation, for default onNotSuccess)
//     onNotSuccess - optional callback function
//
function makeAjaxRequest (opts)
{
    var url = opts.url ? opts.url : '/';
    url = ALBase.make_uri(url);

    var parameters = opts.parameters ? opts.parameters : {};

    var failureMessage = opts.failureMessage ? opts.failureMessage
                                             : 'The request failed';

    var onSuccess = opts.onSuccess ? opts.onSuccess : function () {};

    var onNotSuccess = opts.onNotSuccess
            ? opts.onNotSuccess
            : function (json) {
                  var msg = failureMessage + ', please try again.'
                  if (json.msg) {
                      msg += '\r\n\r\n'
                           + 'The message was:'
                           + '\r\n\r\n'
                           + '\t' + json.msg;
                  }
                  genericError(msg);
              };

    var onFailure = opts.onFailure
            ? opts.onFailure
            : function () { ajaxTransportError(); };

    var ajax = new Ajax.Request(url, {
        method:     'post',
        parameters: parameters,
        onSuccess:  function (transport) {
                        var json = transport.responseJSON;
                        if (! json) {
                            onFailure();
                        }
                        else if (json.status == 'success') {
                            onSuccess(json);
                        }
                        else {
                            onNotSuccess(json);
                        }
                    },
        onFailure:  onFailure
    });
}

function reloadPageFromFB(){
	Ext.get(parent.document.body).mask('Reloading...');
	fb.loadPageOnClose = 'self';    // will reload current page
	fb.end();                       // close floatbox
}

//----------------------------------------------------------

function removeNewlyCreated ()
{
    // Remove the "newly_created" class name
    // from existing elements:
    //
    $$('.newly_created').each(
            function (el) {
                $(el).removeClassName('newly_created');
            }
    );
    $$('.newly_created_dark').each(
            function (el) {
                $(el).removeClassName('newly_created_dark');
            }
    );
}

function removeNewlyCreatedAfterDelay ()
{
    setTimeout('removeNewlyCreated()', 4000);
}

//----------------------------------------------------------

function saveMyTrainingState (divId)
{
    // Need to give the toggle some time to update the div,
    // before we test if it is visible or not:
    //
    setTimeout("_saveMyTrainingState('" + divId + "')", 500);
}

function _saveMyTrainingState (divId)
{
    var state = $(divId).visible() ? 'open' : 'closed';

    var url = ALBase.make_uri('/session/set_mytraining_state/'
                              + divId + '/' + state);

    new Ajax.Request(url, {
        method: 'post'
        // no need for onSuccess or onFailure,
        // silent failure is ok...
    });
}

//----------------------------------------------------------

// E.g.:
//    <textarea
//       onkeydown="textCounter(this,myform.numchars,128)"
//         onkeyup="textCounter(this,myform.numchars,128)"
//    ></textarea>
//    There are <input type="text" name="numchars" value="128" /> chars left
//
function textCounter (textField, countField, maxchars)
{
    var remaining = maxchars - textField.value.length;

    if (remaining < 0) {
        textField.value = textField.value.substring(0, maxchars);
        remaining = 0;
    }

    countField.value = remaining;
}

//----------------------------------------------------------

function floatboxPopupPage (page, opts)
{
    if (typeof opts == 'undefined') {
        opts = {};
    }
    if (typeof opts.showCaption == 'undefined') {
        opts.showCaption = true;
    }
    if (typeof opts.width == 'undefined') {
        opts.width = 480;
    }
    if (typeof opts.height == 'undefined') {
        opts.height = 360;
    }

    var fbOptsString = getGenericFloatboxOptions(opts);

    fbOptsString = decode_html_entities(fbOptsString);    // for caption

    fb.start(
        {
         href: ALBase.make_uri('/' + page) + '?popup=1',
         rev:  fbOptsString
        }
    );

    return;
}

function floatboxPopupLink (url, title, opts)
{
    var fbopts = getGenericFloatboxOptions(opts);

    return '<a href="' + url + '"'
         + ' class="floatbox"'
         + ' onclick="fb.start(this); return false"'
         + ' oncontextmenu="return false"'
         + ' data-fb-options="' + fbopts + '">' + title + '</a>';
}

/*

 IMPORTANT!  This code should be kept in sync in these three places:

 generic_floatbox_options  in perllib/AL/Catalyst/Base.pm
 generic_floatbox_options  in templates/config.tt
 getGenericFloatboxOptions in static/js/Platform/utility.js

*/
function getGenericFloatboxOptions (opts)
{
    if (typeof opts == 'undefined') {
        opts = {};
    }

    if (typeof opts.loadPageOnClose == 'undefined') {
        opts.loadPageOnClose = false;
    }
    if (typeof opts.sameBox == 'undefined') {
        opts.sameBox = false;
    }

    if (typeof opts.width == 'undefined') {
        opts.width = 650;
    }
    if (typeof opts.height == 'undefined') {
        opts.height = 350;
    }

    if (typeof opts.showCaption == 'undefined') {
        opts.showCaption = false;
    }
    if (typeof opts.caption == 'undefined' && opts.showCaption == true) {
        var now = new Date();
        var year = now.getFullYear();
        opts.caption = '`&copy; Copyright ' + year
                     + ' Atomic&nbsp;Learning, Inc. &nbsp; All rights reserved.`';
    }

    var optsParts = new Array();
    for (var part in opts) {
        optsParts.push(part + ':' + opts[part]);
    }

    var optsString = optsParts.join(' ');

    optsString += ''
         + ' disableScroll:true'        // fb stays put if window scrolls
         + ' shadowType:drop'           // shadow on bottom and right
         + ' padding:10'                // padding around content
         + ' panelPadding:4'            // padding above/below "close"
         + ' innerBorder:0'             // pixel width of inner border
         + ' controlPos:tr'             // position of controls (e.g. close)
         + ' infoPos:bc'                // position of info (e.g. caption)
         + ' resizeDuration:0.5'        // time to expand/collapse (0-10)
         + ' overlayFadeDuration:0'     // time to fade page background (0-10)
         + ' navType:none'              // no prev/next options
         + ' hideFlash:false'           // do not hide flash when box opens
         //+ ' autoFitHTML:false'         // do not autosize floatbox
         + '';

    return optsString;
}

//----------------------------------------------------------

// Set checkInterval = -1 to NOT do periodic AJAX check
// for updated status.  This will cause the mask to stay up
// until the masked object is reloaded.
//
function startProgressMask (opts)
{
    var message  = opts.message  || 'Loading...';

    var checkURL = opts.checkURL || ALBase.make_uri('/getProgressMaskStatus');

    var checkInterval = opts.checkInterval || 1;    // in seconds

    var maskedElement = opts.maskElementId ? Ext.get(opts.maskElementId)
                                           : Ext.getBody();

    var successCallback = opts.successCallback || false;
    var failureCallback = opts.failureCallback || false;

    // Not too worried if this fails - just attempting to keep
    // the message on the server in sync with what's on screen:
    //
    var params = {message: message};
    if (opts.initialExpireSeconds) {
        params.expire_seconds = opts.initialExpireSeconds;
    }
    makeAjaxRequest({
                     url:          '/setProgressMaskStatus',
                     parameters:   params,
                     onSuccess:    function () {},
                     onNotSuccess: function () {},
                     onFailure:    function () {}
                    });

    maskedElement.mask(message);

    if (checkInterval == -1) return;

    var myDummyElement = document.createElement('div');
    var updater = Ext.get(myDummyElement).getUpdater();

    var stopFunction = function () {
        maskedElement.unmask();
        updater.stopAutoRefresh();
    };

    updater.startAutoRefresh(checkInterval, checkURL);

    updater.on('update', function () {

        newMessage = myDummyElement.innerHTML;

        if (!newMessage || newMessage == 'CLOSE') {
            stopFunction();
            if (successCallback) successCallback();
            return;
        }

        if (newMessage != 'KEEP') {
            maskedElement.mask(newMessage);
        }
    });

    updater.on('failure', function () {
        stopFunction();
        if (failureCallback) failureCallback();
    });

}

//----------------------------------------------------------

function getTextForSelectedOption (select)
{
    var i = select.selectedIndex;
    if (i < 0) return '';
    return select.options[i].text;
}

function decode_html_entities (str)
{
  var myTextarea = document.createElement('textarea');

  myTextarea.innerHTML = str.replace(/</g, '&lt;').replace(/>/g, '&gt;');

  return myTextarea.value;
}

/*
 * Given an Ext Date object, format into either the application
 * default or the date supplied for the given theme/language.
 */
function format_date(date1,format){
	if (date1 == '' || date1 == null){
		return '';
	}

	// Fixup any badly formatted dates
	if(typeof date1 == 'string'){
		date1 = date1.replace(/-/g,'/'); 
	}

	var date_obj = new Date(date1);

	var use_format = 'mdy';
	
	// If Date.patterns.local exists, assume it as default
	if(Date.patterns.local > ''){
		use_format = 'local';
	}

	// If they asked for a format and it exists
	if(Date.patterns[format]){
		use_format = format;
	}

	var formatted_date = date_obj.format(Date.patterns[use_format]);
	
	return formatted_date;
}

// Get the localized format for a date. Because this can come from
// different places or not exist, we call it from here.
function get_local_date_format() {
	// Try the local
	if (Date.patterns.local){
		return Date.patterns.local;
	// Try the local embedded in the parent
	} else if (parent.Date.patterns.local) {
		return parent.Date.patterns.local;
	} else {
     	return Date.patterns.mdy;
	}
}

