if(typeof(app) == 'undefined'){

    app = {};
}

if(typeof(app.mes) == 'undefined'){

    app.mes = {};
}

if(typeof(app.setup) == 'undefined'){
    
    app.setup = {};
}

if(typeof(app.user) == 'undefined'){

    app.user = {};
}

if(typeof(app.dialogs) == 'undefined'){

    app.dialogs = {};
}

if(typeof(app.util) == 'undefined'){

    app.util = {};
}

if(typeof(app.tests) == 'undefined'){
    
    app.tests = {};
}

if(typeof(app.dashboard) == 'undefined'){
    app.dashboard = {};
}

if(typeof(app.login) == 'undefined'){
    app.login = {};
}

if(typeof(app.myaccount) == 'undefined'){
    app.myaccount = {};
}

app.persistent_overlay = false;
app.elsAboveOverlay = {};
app.dayProfitUserExpScrollerTop = 0;
app.dayProfitUserIncScrollerTop = 0;

var mes = app.mes;
var util = app.util;
var dashboard = app.dashboard;
var login = app.login;
var setup = app.setup;
var myaccount = app.myaccount;

app.resizeWindowPlusOrMinus = 'plus';

app.helpDocShowingId = "";

app.showScreenShot = function(ssId){

    var ss = $(ssId);

    var xandy = util.getPageScrollXandY();
    var bodDims = elementDimensions(document.body);
    var footDims = elementDimensions('foot');
    var viewportDims = getViewportDimensions();

    var ssViewArea = $('ss_view_area');

    var newImage = IMG({'src' : ss.src});
    setNodeAttribute(newImage, 'onclick', 'swapDOM(this, null)');
    setNodeAttribute(newImage, 'onmouseover', 'this.style.cursor=\'pointer\'');
    replaceChildNodes(ssViewArea, newImage);

}

// UTIL

if(typeof(app.util.errorHandler) == 'undefined'){

    app.util.errorHandler = {};
    app.util.errorHandler.elementHandlers = {};
};


app.util.placeElAboveOverlay = function(elId) {

    var origEl = $(elId);
    var origElDims = getElementDimensions(origEl);
    var origElPos = getElementPosition(origEl);

    var modifiedEl = removeElement(elId);
    modifiedEl.style.position = 'absolute';
    setElementPosition(modifiedEl, origElPos);
    modifiedEl.style.zIndex = 2;
    
    appendChildNodes('bod', modifiedEl);
};

app.util.calcAdjustmentValue = function(prevAmount,amount){

    parseFloat(prevAmount);
    parseFloat(amount);

    var adjustment = 0.00;

    if(prevAmount < amount){
        adjustment += amount - prevAmount;
    }
    else{
        adjustment -= prevAmount - amount;
    }
    
    return adjustment;
};

app.util.stripDollarSign = function(str){

    var newStr = strip(str);
    newStr = newStr.substring(1,newStr.length);

    return newStr;
};

app.util.getElCenteredPos = function(el){

    var xCoord = ((window.innerWidth/2) - (parseInt(el.style.width)/2)) + 'px';
    var yCoord = ((window.innerHeight) - (parseInt(el.style.height)/2)) + 'px';

    return {'x' : xCoord, 'y' : yCoord};
};

app.util.showElOverlay = function(elId, color){

    if(color == 'undefined'){
        
        color = '#fff';
    }
    
    var elDims = getElementDimensions(elId);
    var elPos = getElementPosition(elId);
    var overlay = DIV({'id' : elId + '_overlay'});
    overlay.style.position = 'absolute';
    overlay.style.left = '0';
    overlay.style.top = '0';
    overlay.style.width = '100%';
    overlay.style.height = '100%';
    overlay.style.backgroundColor = color;
    overlay.style.opacity = '.6';

    $(elId).style.position = 'relative';
    appendChildNodes($(elId), overlay);

    app.overlay = true;
};

app.util.hideElOverlay = function(elId){

    try{
        var cont = $(elId);
        children = cont.childNodes;
        appendChildNodes(cont, children);
        swapDOM($(elId + '_overlay'), null);
        app.overlay = false;

    } catch(e){
        app.overlay = false;
    }
};

app.util.sendXHRRequest = function(url, keys, vals){

    if(isUndefinedOrNull(keys) || isUndefinedOrNull(vals)){

        var d = doSimpleXMLHttpRequest(url, {isxhr : 'true'});
        d.addErrback(function(xhr){
            //var win = window.open("");
            //win.document.write(xhr.req.responseText);
            document.write(xhr.req.responseText);
        });
        return d;
    }

    keys.push('isxhr');
    vals.push('true');
    var sendContent = queryString(keys, vals);
    var contentLength = sendContent.length;

    var d = doXHR(url,
                  {'method' : 'POST',
                   'sendContent' : sendContent,
                   'headers' : {'Content-type' : 'application/x-www-form-urlencoded',
                                'Content-length' : contentLength}});
    d.addErrback(function(xhr){
        //var win = window.open("");
        //win.document.write(xhr.req.responseText);
//        document.write(xhr.req.responseText);
    });

    return d;
};

app.util.processFormErrors = function(xhr){

    var res = evalJSONRequest(xhr);

    if(res['status'] == 'success'){
        
        return xhr;

    }

    if(res['status'] == 'failed__pass_to_error_handler'){
        var elId = res['element_id'];
        app.util.errorHandler.registerElementHandler(elId, 
                res['handle_func'], res['func_params']);
        app.util.errorHandler.activateElementHandler(elId);
        app.util.errorHandler.processOneElementHandler(elId);
    }

    if(res['status'] == 'failed'){
        
        for(field_name in res['errors']){
            var el = $(field_name + "_error");
            if(el.style.display == 'none'){
                el.style.display = 'block';
                if(el.innerHTML == ''){
                    el.innerHTML = res['errors'][field_name];
                }
            }
        }
    }

    return false;
};

app.util.createCenteredDiv = function(parentId, percentOfParentWidth, percentOfParentHeight){

    var parentEl = $(parentId);

    var parentElDimensions = getElementDimensions(parentEl);

    var parentWidth = parentElDimensions.w;
    var parentHeight = parentElDimensions.h;

    var parentStylePosition = parentEl.style.position;

    if(parentStylePosition != 'relative' && parentStylePosition != 'absolute'){

        parentEl.style.position = 'relative';
    }

    var newDiv = DIV(null);
    newDiv.style.position = 'absolute';
    newDiv.style.width = percentOfParentWidth + "%";
    newDiv.style.height = percentOfParentHeight + "%";

    var x = (100 - percentOfParentWidth) / 2;
    var y = (100 - percentOfParentHeight) / 2;
    
    newDiv.style.left = x + "%";
    newDiv.style.top = y + "%";

    return newDiv;
};

app.util.createWindowCenteredDiv = function(desiredWidth, desiredHeight){

    var windowSize = app.util.getWindowDimensions();
    var pageScrolled = app.util.getPageScrollXandY();
    
    var newDiv = DIV(null);
    newDiv.style.position = "absolute";
    newDiv.style.width = desiredWidth+"px";
    newDiv.style.height = desiredHeight+"px";
    newDiv.style.left = (windowSize[0]/2) - (parseInt(newDiv.style.width)/2)+"px";
    newDiv.style.top = (windowSize[1]/2) - (parseInt(newDiv.style.height)/2) + pageScrolled[1] + "px";
   
    return newDiv;
};

app.util.createViewportCenteredDiv = function(desiredWidth, desiredHeight){

    var elementSize = getElementDimensions(document.getElementsByTagName("body")[0]);
    var windowSize = app.util.getWindowDimensions();
    var pageScrolled = app.util.getPageScrollXandY();

    var newDiv = DIV(null);
    newDiv.style.position = "absolute";
    newDiv.style.width = desiredWidth + "px";
    newDiv.style.height = desiredHeight + "px";
    newDiv.style.left = (elementSize.w/2) - (parseInt(newDiv.style.width)/2) + "px";
    newDiv.style.top = (windowSize[1]/2) - (parseInt(newDiv.style.height)/2) + pageScrolled[1] + "px";

    return newDiv;
};

app.util.createElCenteredDiv = function(desiredWidth, desiredHeight, elId){

    var elementSize = getElementDimensions(elId);

    var newDiv = DIV(null);
    newDiv.style.position = "absolute";
    newDiv.style.width = desiredWidth + "px";
    newDiv.style.height = desiredHeight + "px";
    newDiv.style.left = (elementSize.w/2) - (parseInt(newDiv.style.width)/2) + "px";
    newDiv.style.top = (elementSize.h/2) - (parseInt(newDiv.style.height)/2) + "px";

    return newDiv;
};

app.util.createDivRelativeTo = function(el, width, height, alignTop){
    
    var elDimensions = getElementDimensions(el);

    var elWidth = elDimensions.w;
    var elHeight = elDimensions.h;

    var elPosition = getElementPosition(el);

    var elX = elPosition.x;
    var elY = elPosition.y;

    var newDiv = DIV(null);
    newDiv.style.position = "absolute";
    newDiv.style.width = width + "px";
    newDiv.style.height = height + "px";
    newDiv.style.left = elX + elWidth + "px";

    if(alignTop){
	newDiv.style.top = elY + "px";
    }
    else{
	newDiv.style.top = elY - height + "px";
    }
	
    return newDiv;
};

// this function was taken from the following website.
// http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
app.util.getWindowDimensions = function(){

    var myWidth = 0, myHeight = 0;

    if( typeof( window.innerWidth ) == 'number' ) {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
    } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
    } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
    }
   
    return [myWidth,myHeight];
};

// this function was taken from the following website.
// http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
app.util.getPageScrollXandY = function(){

    var scrOfX = 0, scrOfY = 0;

    if( typeof( window.pageYOffset ) == 'number' ) {
        //Netscape compliant
        scrOfY = window.pageYOffset;
        scrOfX = window.pageXOffset;
    } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        //DOM compliant
        scrOfY = document.body.scrollTop;
        scrOfX = document.body.scrollLeft;
    } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
        //IE6 standards compliant mode
        scrOfY = document.documentElement.scrollTop;
        scrOfX = document.documentElement.scrollLeft;
    }

    return [ scrOfX, scrOfY ];
};

app.util.makeButton = function(type, label, whenClicked){

    var newSpan = SPAN({'onclick' : whenClicked},label); 
    setElementClass(newSpan, "button_style_"+type);

    return newSpan;
};

// The wrapInTextBox functions are used to allow a user to edit a value.
// a parent element is passed in as el.  A textbox, a save link, and a 
// cancel link is appended to the parent element.  The innerHTML of the
// parent is put inside the textbox so that the user can edit it.  
// saveFuncName is the function name that will be used to construct a
// function call.  Any other arguments that are passed in will be passed
// along to the save function.

// The function wrapInTextBoxCurrency is supplied to facilitate the special circum
// stance where the '$' sign needs to remain outside the textbox, leaving only
// the number to edit.

// every textbox that is produced will need its own unique id.  
// wrapInTextBoxCurId is used to facilitate that purpose.  It 
// gets incremented whenever a new textbox is produced.  When 
// this script gets reloaded it is set back to zero, of course.

//app.util.wrapInTextBoxCurId = 0;
//app.util.wrapInTextBoxBoxes = {};

app.util.wrapInTextBox = function(el, isCurrency, saveFuncName){

    var argsList = [];
    var commaSepArgs = "";
    var argsListStr = [];

    var wrapInTextBoxArguments = arguments;

    var hasArgs = false;
    if(arguments.length > 3){
        hasArgs = true;
    }

    for(var i = 3; i < arguments.length; i++){
        argsList.push(arguments[i]);
        argsListStr.push("'"+arguments[i]+"'");
    }

    if(hasArgs)
        commaSepArgs = argsListStr.join(",");

    var value = strip(el.innerHTML);

    if(isCurrency){
        value = value.substring(1, value.length);
    }

    var len = value.length-1;

//    el.innerHTML = '';

    if(!isCurrency)
        len = arguments[3];

//   removeElementClass(el, "std-link");
//    setNodeAttribute(el, null);
//    el.onclick = null;

//    var textBoxId = "wrapintextboxidnumber_"+app.util.wrapInTextBoxCurId;
    var textBoxId = 'wrap_in_text_box_' + el.id;
    var newTextBox = INPUT({"id" : textBoxId,
                            "type" : "text",
                            "size" : len,
                            "value" : value});
    var argsStr = "";
    if(hasArgs)
        argsStr = app.util.formatArgsFromList(argsList);
    var saveLink = DIV({"class" : "clickable",
                         "onclick" : ""+saveFuncName+"('"+el.id+"'"+argsStr+")"},"save");
    var onclickStr = "";
    if(isCurrency){
        onclickStr = "app.util.unwrapFromTextBox('" + 
                        el.id + "','" +
                        "$" + value + "', true); return false;";
/*
        onclickStr = "app.util.unwrapFromTextBox('" + 
                            el.id +
                            "','" + value + "', true,'" +
                            saveFuncName + 
                            "', " +
                            commaSepArgs + ")";
*/
    }
    else{
        onclickStr = "app.util.unwrapFromTextBox('" +
                            el.id +
                            "','" + value +"', false,'" +
                            saveFuncName +
                            "', " +
                            commaSepArgs + ")";
    }

    var cancelLink = DIV({"class" : "clickable",
                           "onclick" : onclickStr},"cancel");

    var newSpan = SPAN(null);

    newSpan.style.background = '#fff';
    newSpan.style.border = 'thin solid #e0eee0';
    newSpan.style.position = 'absolute';
    newSpan.style.padding = '0.4em';
    newSpan.style.zIndex = '1';
    newSpan.id = 'cancel_and_save_div_' + el.id;

    if(isCurrency){
        //appendChildNodes(el,"$",newTextBox,cancelLink,"   ",saveLink);
        el.style.display = 'none';
        appendChildNodes(newSpan, cancelLink, "     ", saveLink);
        insertSiblingNodesAfter(el, SPAN({'id' : el.id + '_dollar_sign'},'$'), newTextBox, newSpan);
        //insertSiblingNodesBefore(newTextBox, '$');
        //appendChildNodes(el, "$", newTextBox);
        //appendChildNodes(el.parentNode, newSpan);

    }else{

        // not implemented yet.
        //appendChildNodes(el,newTextBox,cancelLink,"   ",saveLink);
        el.style.display = 'none';
        appendChildNodes(newSpan, cancelLink, "    ", saveLink);
        insertSiblingNodesAfter(el, newTextBox, newSpan);
        //appendChildNodes(el, newTextBox);
        //appendChildNodes(el.parentNode, newSpan);
    }
    newTextBox.focus();
    newTextBox.select();

    setNodeAttribute(newTextBox, "onkeyup", function(e){
   
        var keynum = app.util.getEventKeyCode(e);

        if(keynum == 13){

            eval(saveFuncName+"('"+el.id+"',"+argsStr.substring(1,argsStr.length)+")");
        }
    });
};

app.util.unwrapFromTextBox = function(elId, value, isCurrency, saveFuncName){

    var el = $(elId);
    el.style.display = 'inline';  
    el.innerHTML = value;
    swapDOM($("wrap_in_text_box_" + elId), null);

    if(isCurrency)
        swapDOM($(elId + '_dollar_sign'), null);

    swapDOM('cancel_and_save_div_' + elId, null);

    //var parentEl = el.parentNode;
    app.util.clearErrors(el);

    return false;
};

// looks for sibling elements that have an id that ends in:
// _error and that come before this element. clears the innerHTML
// of all elements found that meet the above conditions.
app.util.clearErrors = function(el){

    var parentEl = el.parentNode;

    var children = parentEl.childNodes;

    for(var i = 0; i < children.length; i++){
        
        // we only process errors that come before
        // this element.
        if(children[i] == el){
            break;
        }
        var theId = children[i].id;
        if(theId){
            var len = theId.length;
            if(len > 6 && theId.lastIndexOf('_error') ==
                len - 6){
                var tarEl = $(theId);
                tarEl.innerHTML = '';
                tarEl.style.display = 'none';
            }
        }
    }
};

// delete sibling elements that contain the given
// str as part of their id.
app.util.delSiblingsWithPartialId = function(el, str){

    var parentEl = el.parentNode;

    var children = parentEl.childNodes;

    for(var i = 0; i < children.length; i++){
        
        var theId = children[i].id;
        if(theId){
            if(theId.indexOf(str) != -1){
                swapDOM(theId, null);
            }
        }
    }
};

app.util.formatArgsFromList = function(list){
    
    var argStr = ""; 
    
    for(var i = 0; i < list.length; i++){
        argStr += ",'" + list[i] + "'";
    }
    
    return argStr;
};

// END wrap in text box related stuff.

app.util.getEventKeyCode = function(e){

    var keynum;

    if(window.event){
        keynum = e.keyCode;
    }
    else if(e.which){
        keynum = e.which;
    }
    
    return parseInt(keynum);
};

app.util.mdyToISODateStr = function(dateStr){

    var parts = dateStr.split(',');

    var year = parts[1].substring(1, parts[1].length);

    parts = parts[0].split(' ');

    var month = parts[0];
    var day = parts[1];
    
    switch(month){
        
        case 'Jan':
            month = 1;
            break;
        case 'Feb':
            month = 2;
            break;
        case 'Mar':
            month = 3;
            break;
        case 'Apr':
            month = 4;
            break;
        case 'May':
            month = 5;
            break;
        case 'Jun':
            month = 6;
            break;
        case 'Jul':
            month = 7;
            break;
        case 'Aug':
            month = 8;
            break;
        case 'Sep':
            month = 9;
            break;
        case 'Oct':
            month = 10;
            break;
        case 'Nov':
            month = 11;
            break;
        case 'Dec':
            month = 12;
            break;
    }

    var isoDateStr = year + '-' + month + '-' + day;

    return isoDateStr;
};

app.util.iso_date_to_str = function(iso_date){

    var parts = iso_date.split('-');
    var year = parts[0];
    var month = parts[1];
    var day = parts[2];

    if(month[0] == '0')
        month = month.substring(1, month.length);

    if(day[0] == '0')
        day = day.substring(1, day.length);
   
    var monthStr = '';
    switch(parseInt(month)){
    
        case 1:
            monthStr = 'Jan';
            break;
        case 2:
            monthStr = 'Feb';
            break;
        case 3:
            monthStr = 'Mar';
            break;
        case 4:
            monthStr = 'Apr';
            break;
        case 5:
            monthStr = 'May';
            break;
        case 6:
            monthStr = 'Jun';
            break;
        case 7:
            monthStr = 'Jul';
            break;
        case 8:
            monthStr = 'Aug';
            break;
        case 9:
            monthStr = 'Sep';
            break;
        case 10:
            monthStr = 'Oct';
            break;
        case 11:
            monthStr = 'Nov';
            break;
        case 12:
            monthStr = 'Dec';
            break;
    }

    return monthStr + ' ' + day + ', ' + year;
};

app.util.errorHandler.registerElementHandler = function(elId, handle_func, func_params){

    var eh = app.util.errorHandler;
    eh.elementHandlers[elId] = {};
    eh.elementHandlers[elId]['func'] = eval(handle_func);
    eh.elementHandlers[elId]['func_params'] = eval(func_params);
};

app.util.errorHandler.removeElementHandlerFunc = function(elId){

    var eh = app.util.errorHandler;
    if(typeof(eh.elementHandlers[elId]) == 'object' &&
            typeof(eh.elementHandlers[elId]['func']) != 'undefined'){

        eh.elementHandlers[elId]['func'] = undefined;
    }
};

app.util.errorHandler.removeElementHandler = function(elId){

    var eh = app.util.errorHandler;
    if(typeof(eh.elementHandlers[elId]) == 'object'){

        eh.elementHandlers[elId] = undefined;
    }
};

app.util.errorHandler.deactivateElementHandler = function(elId){

    var eh = app.util.errorHandler;
    if(typeof(eh.elementHandlers[elId]) == 'object'){

        eh.elementHandlers[elId]['activated'] = false;
    }
};

app.util.errorHandler.activateElementHandler = function(elId){

    var eh = app.util.errorHandler;
    if(typeof(eh.elementHandlers[elId]) == 'object'){

        eh.elementHandlers[elId]['activated'] = true;
    }
};

app.util.errorHandler.processOneElementHandler = function(elId){

    var eh = app.util.errorHandler;

    if(typeof(eh.elementHandlers[elId]['func']) != 'undefined'){

        var handle_func = eh.elementHandlers[elId]['func'];
        var funcParams = eh.elementHandlers[elId]['func_params'];

        if(eh.elementHandlers[elId]['activated']){
            handle_func(funcParams);
        }
    }
};

app.util.errorHandler.processHandlers = function(){

    var eh = app.util.errorHandler;
    for(elId in eh.elementHandlers){

        if(typeof(eh.elementHandlers[elId]['func']) != 'undefined'){

            var handle_func = eh.elementHandlers[elId]['func'];
            var funcParams = eh.elementHandlers[elId]['func_params'];

            if(eh.elemenHandlers[elId]['activated']){
                handle_func(funcParams);
            }
        }
    }
};

app.util.processServerResponse = function(xhr){

    var resp = evalJSONRequest(xhr);

    var js_statements_to_exec_last = []

    var no_hide_load_message = false;

    for(boxId in resp){
        if(boxId.indexOf("pre_js_statements") != -1) {
            eval(resp[boxId]);
        }
    }
   
    for(boxId in resp){
        
        if(boxId.indexOf("NO_HIDE_LOAD_MESSAGE") != -1){
            no_hide_load_message = true;
            continue;
        }
        if(boxId.indexOf("PERSISTENT_OVERLAY_ON") != -1){
            app.persistent_overlay = true;
            continue;
        }
        if(boxId.indexOf("PERSISTENT_OVERLAY_OFF") != -1){
            app.persistent_overlay = false;
            continue;
        }
        var box = $(boxId);
        
        if(box){
            box.innerHTML = resp[boxId]['html'];
        }
        var js_statements = '';
        if(!isUndefinedOrNull(resp[boxId]['js_statements'])){
            js_statements = resp[boxId]['js_statements'];
        }
        var js_func = '';
        if(!isUndefinedOrNull(resp[boxId]['js_func'])){
            js_func = resp[boxId]['js_func'];
        }
        if(js_statements != ''){

            js_statements_to_exec_last.push(js_statements);
        }
        if(js_func != ''){
            eval(js_func)();
        }
    }

    for(i= 0; i < js_statements_to_exec_last.length; i++){
        if(js_statements_to_exec_last[i] != ''){
            eval(js_statements_to_exec_last[i]);
        }
    }

    if(!no_hide_load_message){
        app.hideLoadingMessage();    
    }

    // ie bug fix.  resize browser window.
    if(navigator.appName.indexOf('Internet Explorer') != -1){
        if(app.resizeWindowPlusOrMinus == 'plus'){
            app.resizeWindowPlusOrMinus = 'minus';
            window.resizeBy(1,0);
        }else{
            app.resizeWindowPlusOrMinus = 'plus';
            window.resizeBy(-1,0);
        }
    }
};

app.util.showHelpDoc = function(el, server_action){

    var d = app.util.sendXHRRequest(server_action);

    app.showLoadingMessage(false);

    d.addCallback(function(xhr){

        
        var newDiv = DIV(null);

        var elPos = getElementPosition(el);
        var elDims = getElementDimensions(el);

        addElementClass(newDiv, 'hi');
        addElementClass(newDiv, 'clickable');
        newDiv.style.width = '350px';
        newDiv.style.position = 'absolute';
        newDiv.style.left = elPos.x + elDims.w + 20 + 'px';
        newDiv.style.top = elPos.y + 'px';
        newDiv.innerHTML = xhr.responseText;
        newDiv.style.zIndex = '2';
        newDiv.style.fontSize = '1em';
        newDiv.style.fontFamily = 'Arial, sans-serif';
        setNodeAttribute(newDiv, "id", "help_doc_container_for_" + el.id);
        appendChildNodes('bod', newDiv);
 
        app.helpDocShowingId = newDiv.id;

        var bodDims = getElementDimensions('bod');

        if(elPos.x + elDims.w + 10 + getElementDimensions(newDiv).w > bodDims.w){
            newDiv.style.left = (bodDims.w - (getElementDimensions(newDiv).w + 10)) + 'px';
        }

        app.hideLoadingMessage(false);

    });

};

app.getMastheadDims = function(){
   return getElementDimensions('masthead'); 
};

app.getNavDims = function(){
    return getElementDimensions('nav');
};

app.getFootDims = function(){
    return getElementDimensions('foot');
};

app.getCombinedHeightExceptMain = function(){
    
    return app.getMastheadDims().h + app.getNavDims().h + app.getFootDims().h;
};

dashboard.showMyEbaySelling = function(ebayId){

    var keys = ['ebay_id']; 
    var vals = [ebayId]

    var d = util.sendXHRRequest('/dashboard/show_my_ebay_selling', keys, vals);

    d.addCallback(function(xhr){
        
        document.location = '/mes';
    });
};

app.showLoadingMessage = function(){

    var el = $('loading_message');

    removeElementClass(el, 'hidden');
    
    var xandy = util.getPageScrollXandY();
    var bodDims = elementDimensions(document.body);
    var viewportDims = getViewportDimensions();
    var middle = xandy[1] + viewportDims.h/2;
    
    el.style.top = (xandy[1] + 5) + 'px';
    el.style.left = ((getElementDimensions('bod').w /2) - (getElementDimensions(el).w /2)) + 'px';
        
    if(arguments.length == 0)
        app.showOverlay();

};

app.hideLoadingMessage = function(){
    addElementClass('loading_message', 'hidden');

    if(!app.persistent_overlay){
        if(arguments.length == 0)
            app.hideOverlay();
    }
    else{
    
        var overlay = $('application_overlay');

        var docDims = getElementDimensions('bod');

        overlay.style.width = docDims.w + 'px';
        overlay.style.height = docDims.h + 'px';
    }
};

app.reportEvent = function(eventObj){

    var keys = eventObj.paramKeys;
    var vals = eventObj.paramVals;
    
    var d = app.util.sendXHRRequest(eventObj.action, keys, vals);
    d.addCallback(app.util.processServerResponse);
    
    var showDefLoadMessage = true;

//    if(arguments.length > 1 && arguments[1]){
//        showDefLoadMessage = false;
//    }

    for(var i = 0; i < arguments.length; i++){
        if(arguments[i] == 'overlay_up_one')
            app.stepOverlayUpOne();
        if(arguments[i] == 'no_show_load_message')
            showDefLoadMessage = false;
    }

    if(showDefLoadMessage)
        app.showLoadingMessage();
};

// code called from the /login.mako template.
login.showSignUp = function(){

    var d = util.sendXHRRequest('/login/get_signup_html');

    d.addCallback(function(xhr){
        
        $("login__cont").innerHTML = xhr.responseText;
    });
};

login.showSignIn = function(){

    var d = util.sendXHRRequest('/login/get_signin_html');

    d.addCallback(function(xhr){

        $("login__cont").innerHTML = xhr.responseText;
    });
};

login.signup = function(){

    var email = $("login__email_address_sign_up").value;
    var confEmail = $("login__email_address_confirm_sign_up").value;
    var password = $("login__password").value;
    
    var keys = ["email", "conf_email", "fields_match", "password"];
    var vals = [email, confEmail, "fields_match", password];

    var d = util.sendXHRRequest('/login/signup', keys, vals);

    d.addCallback(function(xhr){

        var resp = util.processFormErrors(xhr);

        if(!resp){

            return;

        }else{

            resp = evalJSONRequest(xhr);
        }

        $("login__cont").innerHTML = resp['html'] //xhr.responseText;
    });
};

login.signupErrorCallback = function(errorObj){

    var extraPadding = '15';

    var errorDiv = $("signup__form_errors");
    errorDiv.innerHTML = '';

    var the_html = '<p>Invalid Input. correct the errors below and resubmit.</p>';
    
    if(typeof(errorObj['email']) != 'undefined'){

        the_html += '<br />email: ' + errorObj['email'];
    }
    if(typeof(errorObj['confirm_email']) != 'undefined'){
        the_html += '<br />confirm email: ' + errorObj['confirm_email'];
    }
    if(typeof(errorObj['password']) != 'undefined'){
        the_html += '<br />password: ' + errorObj['password'];
    }

    the_html += '</p>';

    errorDiv.style.color = '#d33';
    errorDiv.style.fontSize = '12px';
    errorDiv.innerHTML = the_html;
    
    errorDiv.style.display = 'block';

};

login.signin = function(){

    var email = $("login__email_address_sign_in").value;
    var password = $("login__password_sign_in").value;

    var keys = ['email', 'password']
    var vals = [email, password]

    var d = util.sendXHRRequest('/login/signin', keys, vals);

    d.addCallback(function(xhr){
        
       var resp = util.processFormErrors(xhr);
        if(!resp){

            return;
        }

        document.location = "/";

    });
};

login.signinErrorCallback = function(errorObj){

    var extraPadding = '15';

    var errorDiv = $("signin__form_errors");
    errorDiv.innerHTML = '';

    var the_html = "<p style='color: #d33;'>Invalid username or password</p>";

    errorDiv.innerHTML = the_html;
    errorDiv.style.color = '#d33';
   
    errorDiv.style.display = 'block';

};

login.signOut = function(){

    document.location = "/login/signout";
};

login.forgotPassword = function(){

    var d = util.sendXHRRequest('/login/forgot_password');

    d.addCallback(function(xhr){

        var newDiv = util.createViewportCenteredDiv(400,200);
        setNodeAttribute(newDiv, 'id', 'forgot_password__dialog');

        newDiv.style.border = 'medium solid #eaeaea';
        newDiv.style.background = 'white';
        newDiv.innerHTML = xhr.responseText;

        util.showElOverlay('main','#444');
        appendChildNodes('bod', newDiv);
    });
};

login.forgotPasswordSend = function(){

    var email = strip($('forgot_password__email_address').value);

    var keys = ['email_address'];
    var vals = [email];

    var d = util.sendXHRRequest('/login/forgot_password_send', keys, vals);

    d.addCallback(function(xhr){

        var resp = util.processFormErrors(xhr);

        if(!resp){

            return;
        }else{

            resp = evalJSONRequest(xhr);
        }

        $("forgot_password__dialog").innerHTML = resp['html'];
    });
};

login.forgotPasswordSendErrorCallback = function(errObj){

    var extraPadding = '15';

    var errorDiv = $("forgot_password__form_errors");
    errorDiv.innerHTML = '';
    
    var emailNotExistsErr = errObj['invalid_email_address'];

    var the_html = '';

    if(emailNotExistsErr){
        the_html = '<p>' + emailNotExistsErr + '</p>';
    }else{
        
        the_html = '<p>' + errObj['error_message'] + '</p>';
    }

    errorDiv.style.color = '#d33';
    errorDiv.style.fontSize = '12px';
    errorDiv.innerHTML = the_html;
    
    errorDiv.style.display = 'block';
};

myaccount.showChangePassword = function(){

    var cp_cont = $("myaccount__change_password_cont_id");

    var newDiv = util.createViewportCenteredDiv(400,100);

    cp_cont.style.position = 'absolute';
    cp_cont.style.zIndex = '2';
    cp_cont.style.left = newDiv.style.left;
    cp_cont.style.top = newDiv.style.top;
    cp_cont.style.width = newDiv.style.width;
    cp_cont.style.height = newDiv.style.height;
    cp_cont.style.padding = '3px';
    setElementClass(cp_cont, 'content-box-a');
    
    util.showElOverlay("bod", '#aaa');
    cp_cont.style.display = 'block';

};

myaccount.saveChangedPassword = function(){

    var password = strip($("myaccount__change_password_password_id").value);

    var keys = ['password'];
    var vals = [password];

    var d = util.sendXHRRequest('/myaccount/save_changed_password', keys, vals);

    d.addCallback(function(xhr){

        var resp = util.processFormErrors(xhr);

        if(!resp){
            return;
        }else{
            resp = evalJSONRequest(xhr);
        }

        var errDiv = $("myaccount__change_password_form_errors");
        if(errDiv.style.display == 'none'){
            errDiv.style.color = '#d33';
            errDiv.style.display = 'block';
        }
        errDiv.innerHTML = '<p>' + resp['html'] + '</p>';

        $("myaccount__change_password_password_id").value = '';
    });
};

myaccount.saveChangedPasswordErrorCallback = function(errObj){

    var errDiv = $("myaccount__change_password_form_errors");

    errDiv.innerHTML = "<p style='color: #d33;'>" + errObj['error_message'] + "</p>";
    errDiv.style.display = 'block';
};

myaccount.newFeaturesNotificationsYes = function(){

    var d = util.sendXHRRequest('/myaccount/new_features_notifications_yes');

};

myaccount.newFeaturesNotificationsNo = function(){

   var d = util.sendXHRRequest('/myaccount/new_features_notifications_no'); 

};

app.showOverlay = function(){

    if($('application_overlay') != null)
        return;

    var overlay = DIV({'id' : 'application_overlay'});

    var docDims = getElementDimensions('bod');
    var viewportDims = getViewportDimensions();
    
    overlay.style.width = docDims.w + 'px';
    overlay.style.height = docDims.h + 'px';
    overlay.style.backgroundColor = '#000';
    overlay.style.position = 'absolute';
    overlay.style.top = '0';
    overlay.style.left = '0';
    overlay.style.zIndex = '1';
    overlay.style.visibility = 'hidden';
    setOpacity(overlay, 0.3);

    if(navigator.appName.indexOf('Microsoft Internet Explorer') != -1){
        var ifrm = document.createElement('iframe');
        ifrm.style.position = 'absolute';
        ifrm.style.top = overlay.style.top;
        ifrm.style.left = overlay.style.left;
        ifrm.style.width = overlay.style.width;
        ifrm.style.height = overlay.style.height;
        setNodeAttribute(ifrm, 'src', '/blank')
        setOpacity(ifrm, 0);

        appendChildNodes('bod', ifrm);
        app.overlayIframe = ifrm;
    }

    appendChildNodes('bod', overlay);

    overlay.style.visibility = 'visible';

};

app.hideOverlay = function(){

    if(!app.persistent_overlay){
        swapDOM('application_overlay', null);    

        if(navigator.appName.indexOf('Microsoft Internet Explorer') != -1){
            swapDOM(app.overlayIframe, null);
        }
    }
};

app.stepOverlayUpOne = function(){
    
    var overlay = $('application_overlay');
    if(!overlay)
        return;

    var curZ = parseInt(overlay.style.zIndex);

    overlay.style.zIndex = curZ + 1 + '';
};

app.stepOverlayDownOne = function(){
    
    var overlay = $('application_overlay');
    if(!overlay)
        return;

    var curZ = parseInt(overlay.style.zIndex);

    overlay.style.zIndex = curZ - 1 + '';
};

app.handleGlobalOnClicks = function(e){

    var posx = 0;
    var posy = 0;
    if (!e) var e = window.event;
    if (e.pageX || e.pageY)     {
        posx = e.pageX;
        posy = e.pageY;
    }

    else if (e.clientX || e.clientY)    {
        posx = e.clientX + document.body.scrollLeft
            + document.documentElement.scrollLeft;
        posy = e.clientY + document.body.scrollTop
            + document.documentElement.scrollTop;
    }

    app.lastMouseClick = {'x' : posx, 'y' : posy}

    if(app.helpDocShowingId != ""){
        swapDOM(app.helpDocShowingId, null);
        app.helpDocShowingId = "";
    }
    else{
        return false;
    }
};

app.util.placeElNextTo = function(elId){

    var el = $(elId);
    el.style.display = 'block';

    var dims = getElementDimensions(el);
    var scrDims = getViewportDimensions();

    newEl = removeElement(el);
    newEl.style.position = 'absolute';
    newEl.style.left = app.util.elLastClickedPos.x + 'px';
    newEl.style.top = app.util.elLastClickedPos.y - (dims.h/2) + 'px'; 
    newEl.style.visibility = 'visible';
    newEl.style.zIndex = '3';
    newEl.style.fontFamily = 'Arial, sans-serif';
    newEl.style.fontSize = '12px';
    setElementClass(newEl, getNodeAttribute(el, 'class'));

    // if the new placement would result in part of the element positioned
    // off the screen, then we need to adjust it.
    var padding = 10;
    var scrollbarWidth = 20;
    var newElPos = {'x' : parseFloat(rstrip(newEl.style.left, 'px')),
                    'y' : parseFloat(rstrip(newEl.style.top, 'px'))};
   
    if((newElPos.x + dims.w) > scrDims.w - (padding + scrollbarWidth)){
        newEl.style.left = scrDims.w - (dims.w + padding + scrollbarWidth) + 'px';
    }

    if(newElPos.x < padding){
        newEl.style.left = padding + 'px';
    }
    
    if(newElPos.y < padding){
        newEl.style.top = padding + 'px';
    }
    
    appendChildNodes('bod', newEl);
};

app.showSessionTimeout = function(){
    var el = $('session_timeout');
    window.scrollTo(0,0);
    removeElementClass(el, 'hidden');
};

app.markNavItemSelected = function(item){
    if(item == 'mes'){
        setElementClass($('nav_mes'), 'mes-selected');
    }
    if(item == 'dashboard'){
    }
    if(item == 'myaccount'){
    }
    if(item == 'admin'){
    }
};
