/* Copyright IBM Corp. 2006, 2007  All Rights Reserved.              */

//document.onclick=handleClick;
document.onkeyup=hideDropDownMenu;


var OA = {

    //constants
    "UUID_LENGTH": 36,
    "FOCUS_DELAY": 100,
    "OUTLINE_PREFIX": 'handle_',
    "OUTLINE_SUFFIX": '_outlinechild',
    "COLLAPSE_PREFIX": 'collapseTree',
    "UUID_PREFIX": 'uuid_',
    "EDIT_SUFFIX": '_edit',
    "DESC_SUFFIX": '_desc',
    "TITLE_SUFFIX": '_title',  
    
    "Now": /*new Date()*/ "",
    "Now_Mills": /*this.Now.getTime()*/ 0,
        
    "globals": {
        "parentUuid": '',
        "postMenuDropOffElement": '',
        "activityUuid": '',
        "returnto": '',
        "nodeBeingViewed": '',
        "nodeHoverTimer": 0,
        "nodeHovers": Object(),
        "pageLoaded": false,
        "menuIsReply": false,
        "reorderDrops": [],
        "outlineSelection": '',
        "currentOutlineNodeUuid": '',
        "currentEditForm": null,
        "applicationContext": 'oa',
                     "helpWindow": null,
        "selectedCalendarDate": null,
        "selectedMember":null
    }

};

OA.utils = {
    buildUrl: function(url) {
        absUrl = OA.globals.applicationContext + '/service/html/' + url;
        return absUrl;
    },

    trim: function(str) {
        str = str.replace( /^[\s\u3000]+/g, "");
        str = str.replace( /[\s\u3000]+$/g, "");

        return str;
    },

    cleanseCommas: function(str, bForNames, bCleanEnd) {
        var outstr= OA.utils.trim(str);
        if(outstr == "")
            return "";

        //\u3000 represents a Unicode ideographic space character
        if (bForNames) //cleansing Name fields, which have plenty of correct spaces
            outstr = outstr.replace( /([\s\u3000]*,[\s\u3000]*)+/g, ", ");
        else           //tag fields, where spaces are not important
            outstr = outstr.replace(/[\s\u3000,]+/g, ", ");
        var len = outstr.length;
        //assume by design, that all \u3000 are gone now
        if( outstr.indexOf(", ") == 0 ) //if start of string is ', '
            outstr = outstr.substring(2, len);
        len = outstr.length;
        if( bCleanEnd && outstr.substring(len-2, len) == ", " )
            outstr = outstr.substring(0, len-2);
        else if ( !bCleanEnd && outstr.substring(len-2, len) != ", " ) //add , to the end if we need to
            outstr += ", ";
        return outstr;
    },

    cleanseTagCommas: function(str) {
        return OA.utils.cleanseCommas(str, false, false);
    },

    cleanseNameCommas: function(str) {
        return OA.utils.cleanseCommas(str, true, false);
    },

    checktaglen: function(_tagelt) {
        var tagstr = _tagelt.value;
        // This strips out any doublequotes present to avoid any js errors
        tagstr = OA.utils.checkForDblQuotes(tagstr);
        tagstr = OA.utils.cleanseTagCommas(tagstr);
        //if the tags are not too long, this string will be posted
        _tagelt.value = tagstr;

        //if any of the tags are too long, return false to the POST to stop the operationn
        var tags = tagstr.split(/[,\s\u3000]+/);
        for (var i=0; i<tags.length; i++) {
            if (!OA.utils.check1taglen(OA.utils.trim(tags[i]))) {
                OA.currentForm.submitInProgress = false;
                return false;
            }
        }
        return true;
    },

    check1taglen: function( tag) {
        var count = OA.utils.bytelenofstring(tag);
        if (count > 63) {
            var alertstext = dojo.i18n.getLocalization("jsresources.activities", "strings");
            var tagalert = alertstext.tagtoolong;
            tagalert = dojo.string.substituteParams(tagalert, tag);
            alert(tagalert);
            return false;
        }
        return true;
    },

    bytelenofstring: function(str) {
        var escapedStr = encodeURIComponent(str);
        if (escapedStr.indexOf("%") != -1) {
            var count = escapedStr.split("%").length - 1;
            if (count == 0) count++; //perverse case; can't happen with real UTF-8
            var tmp = escapedStr.length - (count * 3);
            count = count + tmp;
        } else {
            count = escapedStr.length;
        }
        return count;
    },


    checkForDblQuotes: function( strToBeChecked ) {
        var arrWithoutDoubleQts = new Array();
        var strWithoutDoubleQts="";
        arrWithoutDoubleQts = strToBeChecked.split("\"");
        strWithoutDoubleQts = arrWithoutDoubleQts.join("");
        return strWithoutDoubleQts;
    }
};


OA.setCurrentForm = function(id) { OA.globals.currentEditForm = id; };
OA.clearCurrentForm = function() { OA.globals.currentEditForm = null; };
    
// hiding the post drop down menu for new UI
function hideDropDownMenu(event){
    if( typeof(event) != "undefined" && event !== null && event.keyCode == Event.KEY_ESC) {
        hideMenu( event);
        setFocusOnHidePostmenu();
    }
}

function setFocusOnHidePostmenu(){
    if( OA.globals.postMenuDropOffElement != null && OA.globals.postMenuDropOffElement == 'portForm'){
        $( 'focusPostButton').focus();
    }else{
        var uuid = '';
        var index = OA.globals.postMenuDropOffElement.indexOf( OA.EDIT_SUFFIX);
        if(index >=0 && OA.globals.postMenuDropOffElement.length > 5)
            uuid = OA.globals.postMenuDropOffElement.substring(5,index);
        $( 'focusReplyTo' + uuid).focus();
    }       
}


// to hide the post menu using for old ui
function hidePostMenu( event){
// Pressing the 'Esc' button while showing the 'Post' menu
// will hide that menu
    if( typeof(event) != "undefined" && event !== null && event.keyCode == Event.KEY_ESC) {
        hideMenu( event);
        
        // after hiding the Post menu, set the focus to the next available link
        // from which the post menu has populated. OA.globals.source is postMenuDropOffElement
        // value passed in the showPostMenu() function.
        var elements = new Array( 4);
        if( OA.globals.postMenuDropOffElement !== null && OA.globals.postMenuDropOffElement == 'portForm'){
            elements[0] = "focusDelete";
            elements[1] = "focusUndelete";
            elements[2] = "focusTuneOut";
            elements[3] = "focusTuneIn";
            setFocusTo( elements);
        }else{
            var uuid = '';
            var index = OA.globals.postMenuDropOffElement.indexOf( OA.EDIT_SUFFIX);
            if(index >=0 && OA.globals.postMenuDropOffElement.length > 5)
                uuid = OA.globals.postMenuDropOffElement.substring(5,index);
                
            elements[0] = "focusEdit" + uuid;
            elements[1] = "focusDeleteNode" + uuid;
            elements[2] = "focusUndeleteNode" + uuid;
            elements[3] = "focusPermalink" + uuid;
            setFocusTo( elements);
        }       
    }
}
// setting the focus depends on the availability of the ids.
function setFocusTo( elements){
    var element;
    for( i=0; i< elements.length;i++){
        element = $( elements[i]);
        if( element !== null){
            element.focus();
            break;
        }
    }
}




function generateReturnToString() {
    var returnStr = 'returnto=' + OA.globals.returnto + '&start=' + OA.globals.start + '&count=' + OA.globals.count;
    
    if ( OA.globals.nodeBeingViewed.length == OA.UUID_LENGTH) {
        returnStr += '&nodeinview=' + OA.globals.nodeBeingViewed;
    }
    
    if ( OA.globals.currentOutlineNodeUuid.length == OA.UUID_LENGTH) {
        returnStr += '&currentOutlineNodeUuid=' + OA.globals.currentOutlineNodeUuid;
    }
    
    return returnStr;
}

// wrapper to showPostMenu to add 'uuid_' to postMenuDropOffElement
function showReplyMenu( postMenuDropOffElement, event, parentUuid, activityUuid) {
    showReplyMenu( postMenuDropOffElement, event, parentUuid, activityUuid, "ltr");
}

function showReplyMenu( postMenuDropOffElement, event, parentUuid, activityUuid, bidir) {
    OA.globals.menuIsReply = true;
    showPostMenu( OA.UUID_PREFIX + postMenuDropOffElement, event, parentUuid, activityUuid,bidir);
}


function showPostMenu( postMenuDropOffElement, event, parentUuid, activityUuid)
{
    showPostMenu( postMenuDropOffElement, event, parentUuid, activityUuid,"ltr");
}

// show post menu modified to position it for RTL and LTR
function showPostMenu( postMenuDropOffElement, event, parentUuid, activityUuid, bidir)
{
    OA.globals.activityUuid = activityUuid;
    OA.globals.postMenuDropOffElement = postMenuDropOffElement;
    if( typeof( parentUuid) != "undefined") {
        OA.globals.parentUuid = parentUuid;
    }
    else {
        OA.globals.parentUuid = "";
    }
    showMenu('postMenu',event,bidir);

    // to set the focus to the 'Message' ( 1st item in the Post menu).
    var messageElement = $( 'focusMessage'); 
    if( messageElement !== null) {
        messageElement.focus( );
    }
}

function toggleBannerForm( formString ) {
    //the current form is the same as the place where toggle was called
    //so this must be the cancel button for that form
    if(formString == OA.globals.currentEditForm) {
        Element.hide(formString);
        OA.clearCurrentForm();
    } else if ( checkForExistingEditForm()) {
        Element.show(formString);       
        
        OA.setCurrentForm(formString);
    }
}

function togglePostForm(formString )
{
    if( OA.globals.postMenuDropOffElement === '') {
        return;
    }
    
    if ( checkForExistingEditForm()) {
    
        var portForm = $(OA.globals.postMenuDropOffElement);
        portForm.innerHTML = '';
        
        
        Element.show(OA.globals.postMenuDropOffElement);
            
        var options = {};
        var formId = "newPostForm";
        
        options.method = 'get';
        options.asynchronous = true;
        options.evalScripts = true;
        options.parameters = generateReturnToString() + '&activityUuid=' + OA.globals.activityUuid + '&elementId=' + OA.globals.postMenuDropOffElement + '&parentUuid=' + OA.globals.parentUuid;
        
        //reply param used to help determine the id of the form (depends if this is a new post, or a reply to something)
        if (OA.globals.menuIsReply) {
            options.parameters += "&reply=true";
            formId = "reply_form";
        }
        formId += "_" + formString; 
        
        //unset globals (TODO this a better way)
        OA.globals.menuIsReply = false;
        
        new Ajax.Updater( portForm, formString, options);
        OA.setCurrentForm(portForm.id);
    }
}

function toggleClearPostForm()
{
    var portForm = $(OA.globals.currentEditForm);
    
    if ( portForm == null) {
        return;
    }
    
    /*document.getElementById('portForm').style.display = 'none'; */
    Element.hide(OA.globals.currentEditForm);

    portForm.innerHTML = '';
    
    //clear out current form
    OA.clearCurrentForm();
    
    setFocusOnHidePostmenu();
}

function grabFullDescription( uuid, descriptionUrl, morelink)
{
    var descHtml = $( OA.UUID_PREFIX + uuid + OA.DESC_SUFFIX);
    descHtml.innerHTML = '';
    
    //hide the more link
    Element.toggle(morelink);
    
    new Ajax.Updater( descHtml, descriptionUrl, {method:'get', asynchronous:true});
}


/* Enure that only one action form is open at a time to prevent
   losing data when submitting with multiple edit forms open */
function checkForExistingEditForm() {
    var returnBool = true;
    
    if ( OA.globals.currentEditForm != null) {
        if ( confirm('You have an existing form open, continuing will discard those changes')) {
            //have the form clean up itself
            //$$('#' + OA.globals.currentEditForm + ' .cancelEditButton').click(); //we need prototype 1.5 for this
            
            //Manual dom walking since we don't have prototype 1.5 yet
            //depends on the cancel button being the last input button
            var form = $( OA.globals.currentEditForm);
            var inputElements = form.getElementsByTagName( 'input');
            inputElements[ inputElements.length - 1].click();
            
            //delete the contents of the div surrounding the form if it is from an AJAX edit
            //or reply to action            
            if ( /_edit/.test( OA.globals.currentEditForm)) {
                nodeHtml.innerHTML = '';
            }
        } else {
            returnBool = false;
            Element.scrollTo( OA.globals.currentEditForm);
        }
    }
    
    return returnBool;
}

function editNode( uuid, type) {
    editType( uuid, translateType( type));
}

function editActivity( uuid) {
    editType( uuid, 'activityedit');
}

function editActivity( uuid, viewNode) {
    OA.globals.nodeBeingViewed = viewNode;  
    editType( uuid, 'activityedit');
}


function editType( uuid, submitUrl) {

    
    if ( checkForExistingEditForm()) {
        var nodeHtml = $( OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX);
        nodeHtml.innerHTML = '';
        
        var form_name = 'edit_form_' + submitUrl;
        /* Ajax update to insert the edit form.
         * The onSuccess callback is used to set the focus on the first field of the form.
         * A timeout is necessary since at the exact moment the ajax call returns the form
         * has not been inserted to the DOM yet.
         */
        
        
        Element.toggle( OA.UUID_PREFIX + uuid);
        Element.toggle( nodeHtml);
        
        OA.setCurrentForm(OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX);
    }
}

function toggleActionForm( nodeuuid, activityUuid, actionString ) {
    if ( checkForExistingEditForm()) {
        var nodeHtml = $( OA.UUID_PREFIX + nodeuuid + OA.EDIT_SUFFIX);
        nodeHtml.innerHTML = '';
        var formString = actionString;
        var params = generateReturnToString() + "&uuid=" + nodeuuid + "&activityUuid=" + activityUuid;
        new Ajax.Updater( nodeHtml, formString, {method:'get', asynchronous:true, evalScripts:true, parameters:params});    
     
        Element.toggle( nodeHtml);
        OA.setCurrentForm( nodeHtml.id);
    }

}

function toggleNotifyForm( nodeuuid, activityUuid) { toggleActionForm( nodeuuid, activityUuid, 'notifyForm'); } 
function toggleMoveToForm( nodeuuid, activityUuid) { toggleActionForm( nodeuuid, activityUuid, 'moveToForm'); }

function showNode( uuid)
{
    Element.toggle(  OA.UUID_PREFIX + uuid);
    Element.toggle(  OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX);
    
    //clear out the existing form
    $(  OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX).innerHTML = '';
    OA.clearCurrentForm();
    
    return false;
}

function showNode( uuid,action)
{
    if( action != null && action=='edit'){
        Element.toggle(  OA.UUID_PREFIX + uuid);
        Element.toggle(  OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX);
        
        //clear out the existing form
        $(  OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX).innerHTML = '';
        OA.clearCurrentForm();
        
        if($( 'focusEdit' + uuid) != null){
            $( 'focusEdit' + uuid).focus( );
        }
    }else if( action != null && (action=='notify' || action=='moveto')){
        Element.toggle(  OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX);
        
        //clear out the existing form
        $(  OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX).innerHTML = '';
        OA.clearCurrentForm();
        
        
        if( action=='notify' && ( $( 'focusNotify' + uuid) != null)){
            $( 'focusNotify' + uuid).focus( );
        }else if( action=='moveto' && ( $( 'focusMoveto' + uuid) != null)){
            $( 'focusMoveto' + uuid).focus( );
        }
    }
    return false;
}

function hideEdit ( uuid)
{
    Element.toggle(  OA.UUID_PREFIX + uuid + OA.EDIT_SUFFIX);
    return false;
}
function translateType( type)
{
    var action = 'nodefileedit';
    if ( type == 'activities/comment') {
        action = 'nodecommentedit';
    } 
    else if ( type == 'activities/weblink') {
        action = 'nodeweblinkedit';
    } 
    else if ( type == 'activities/task') {
        action = 'nodetaskedit';
    } 
    else if ( type == 'application/activitynode') {
        action = 'nodecommentedit';
    }
    else if ( type == 'application/activity') {
        action = 'activityedit';
    }
    else if ( type == 'application/file') {
        action = 'nodefileedit';
    }
    else if ( type == 'activities/file') {
        action = 'nodefileedit';
    }
    

    return action;
}

function toggleTask( titleElement, uuid) 
{
    //var titleElement = $(  OA.UUID_PREFIX + uuid + "_title");
    new Ajax.Request('nodetasktoggle', {parameters:'uuid=' + uuid, asynchronous:true});
    if( Element.hasClassName( titleElement, 'completed')) {
        Element.removeClassName( titleElement, 'completed');
    }
    else {
        Element.addClassName( titleElement, 'completed');
    }
}

function startNodeHover( element, uuid) {
    //only do hover color if the node is not expanded
    if (Element.classNames(element).include('hiddenNode')) {
        element.style.backgroundColor = '#ffe25c';
        if ( OA.globals.pageLoaded && (!OA.globals.nodeHovers[uuid] || OA.globals.nodeHovers[uuid] == "off")) {
            OA.globals.nodeHoverTimer = setTimeout( "showListMeta('" + uuid + "')", 500);
        }
    }
}

function killHoverTimer( element) {
    //undo hover color
    element.style.backgroundColor = getBackgroundColorOfEntry( element.id);
    
    clearTimeout( OA.globals.nodeHoverTimer);
}

function getBackgroundColorOfEntry( elementId) {
    var bgColor = '#FFFFFF';
    
    if ( Element.hasClassName( elementId, 'private')) {
        bgColor = '#E1E1E1';
    } else if ( Element.hasClassName( elementId, 'overdue')) {
        bgColor = '#FFCECE';
    }
    
    return bgColor;
}

function clearNodeHover( uuid ) {
    clearTimeout( OA.globals.nodeHoverTimer);
    
    if ( OA.globals.pageLoaded && OA.globals.nodeHovers[uuid] == "on" ) {
        OA.globals.nodeHoverTimer = setTimeout( "hideListMeta('" + uuid + "')", 500);
    }
}

function showListMeta( uuid) {
    OA.globals.nodeHovers[uuid] = "moving-to-on";
    
    //$(OA.UUID_PREFIX + uuid).style.backgroundColor = null;
    
    endBgColor = getBackgroundColorOfEntry(OA.UUID_PREFIX + uuid);
    
    Element.removeClassName( OA.UUID_PREFIX + uuid, 'hiddenNode');
    new Effect.Highlight( OA.UUID_PREFIX + uuid, {startcolor:'#ffe25c', endcolor: endBgColor , restorecolor: endBgColor});
    Effect.AdvBlindDown( OA.UUID_PREFIX + uuid + '_extra', function () {
            OA.globals.nodeHovers[uuid] = "on";
        });
}

function hideListMeta( uuid) {
    if ( OA.globals.nodeHovers) {
        OA.globals.nodeHovers[uuid] = "moving-to-off";
        Effect.AdvBlindUp( OA.UUID_PREFIX + uuid + '_extra', function () {
                OA.globals.nodeHovers[uuid] = "off";
                Element.addClassName( OA.UUID_PREFIX + uuid, 'hiddenNode');
            });
    }
}

function showAllByClassName( className)
{
    for (id in OA.globals.nodeHovers) {
        //alert(id);
        OA.globals.nodeHovers[id] = "on";
    }
    
    var elements = document.getElementsByClassName( className);
    for ( var i=0; i < elements.length; i++) {
        Element.show( elements[i]);
        Element.classNames(elements[i].parentNode.parentNode).remove('hiddenNode');
    }
}

function hideAllByClassName( className)
{
    for (id in OA.globals.nodeHovers) {
        OA.globals.nodeHovers[id] = "off";
    }
        
    var elements = document.getElementsByClassName( className);
    for ( var i=0; i < elements.length; i++) {
        Element.hide( elements[i]);
        Element.classNames(elements[i].parentNode.parentNode).add('hiddenNode');
    }
}

function initHoverLocks() {
    var elements = document.getElementsByClassName( "listextra");
    for ( var i=0; i < elements.length; i++) {
        var displayStyle = elements[i].style.display;
        
        if ( !( /none/i.test( displayStyle))) {
            var id = elements[i].getAttribute('id');
            //substring to cut off the "uuid_" prefix and any suffix after the id
            OA.globals.nodeHovers[id.substring(5,41)] = "on";
        }
    }
}

function initPageLoad() {
    OA.globals.pageLoaded = true;
}

function initShowDetailsExistingValue( expectedShowDetailsBool) {
    var checkbox = $('showDetailsCheckbox');
    
    /* if the checkbox was not the value we expected (maybe the browser is saving it across refreshes)
     * then change the view appropriately */
    if (( checkbox != null) && ( checkbox.checked != expectedShowDetailsBool)) {
        toggleShowDetails( checkbox);
    }
}

Effect.AdvBlindUp = function(element, callback) {
  element = $(element);
  Element.makeClipping(element);
  return new Effect.Scale(element, 0, 
    Object.extend({ scaleContent: false, 
      duration: 0.5,
      scaleX: false, 
      restoreAfterFinish: true,
      afterFinishInternal: function(effect)
        { 
          Element.hide(effect.element);
          Element.undoClipping(effect.element);
          callback();
        } 
    }, arguments[1] || {})
  );
};

Effect.AdvBlindDown = function(element, callback) {
  element = $(element);
  var oldHeight = element.style.height;
  var elementDimensions = Element.getDimensions(element);
  return new Effect.Scale(element, 100, 
    Object.extend({ scaleContent: false, 
      duration: 0.5,
      scaleX: false,
      scaleFrom: 0,
      scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
      restoreAfterFinish: true,
      afterSetup: function(effect) {
        Element.makeClipping(effect.element);
        effect.element.style.height = "0px";
        Element.show(effect.element); 
      },  
      afterFinishInternal: function(effect) {
        Element.undoClipping(effect.element);
        effect.element.style.height = oldHeight;
        callback();
      }
    }, arguments[1] || {})
  );
};

function setIEHoverWorkaround( element) {
    element.onmouseover=function() {
        this.className+=" iehover";
    };
    element.onmouseout=function() {
        this.className=this.className.replace(new RegExp(" iehover\\b"), "");
    };
}

function toggleNodeOutline(pImg, pNode){
    toggleNodeHelper(pImg, pNode, true);
}

function toggleNode(pImg, pNode){
    toggleNodeHelper(pImg, pNode, false);
}

function toggleNodeHelper(pImg, pNode, inSidebar){
    var vSrc=pImg.src.toLowerCase();
    if (vSrc.indexOf("collapse")!=-1){
        //collapse tree
        pImg.src=vSrc.replace("collapse","expand");
        
        //var fullId = pImg.parentNode.parentNode.getAttribute('id');
        var id =  pNode.substring(5,41); //substring to cut off the "uuid_" prefix and any suffix after the id
        
        if (!inSidebar) {
            // hide the parent's description when collapsing children
            hideListMeta( id);
        }
        
        Effect.AdvBlindUp( pNode, function() { } );
    }else{
        pImg.src=vSrc.replace("expand","collapse");
        Effect.AdvBlindDown( pNode, function() { });
    }
}

function activityPicker (element, selection) {
    $('activityUuid').value = selection.lastChild.innerHTML;
    $('submitButton').disabled = false;
}


function changeToList() {
    hideAllByClassName( 'listextra');
    Element.addClassName( $('contentArea'), 'list');
}

function changeToDetails() {
    showAllByClassName( 'listextra');
    Element.removeClassName( $('contentArea'), 'list');
}

function changeToReorderMode( uuid) {
    Element.hide('outlineArea');
    Element.hide('reorderModeLink');
    Element.show('outlineModeLink');
    Element.show('reorderArea');
    new Ajax.Updater( 'reorderAjax', 'reorderactivity', {method:'post', asynchronous:true, evalScripts:true, parameters: 'activityUuid=' + uuid,
                        onComplete: setupReorderDragAndDrop });
}

function addReorderDraggables() {
        var dragElements = document.getElementsByClassName( 'drag');
        for ( var i=0; i < dragElements.length; i++) {
            new Draggable( dragElements[i],  { revert: true } );
        }
}

function removeReorderDraggables() {
    Draggables.drags.each( function( value, index) {
            value.destroy();
        });
}

function setupReorderDragAndDrop() {
        addReorderDroppables( $('dragRoot'));
        addReorderDraggables();
        
        Element.hide('inProgressGraphic');
}


function dropCallback( dragElement, dropElement) {
    var dragId = dragElement.getAttribute('id').substring(7,43);
    var newParentId = dropElement.getAttribute('parent').substring(7,43);
    var newPosition = dropElement.getAttribute('position');

    dropElement.parentNode.replaceChild( dragElement, dropElement);
    
    removeReorderDroppables();
    removeReorderDraggables();
    
    Element.show('sidebarProgressGraphic');
    new Ajax.Updater( 'outlineContainer', 'movesidebarnode', {method:'get', asynchronous:true, evalScripts:true, parameters: '&uuid=' + dragId + '&parentUuid=' + newParentId + '&position=' + newPosition, onComplete: initSidebarReorder});
    
}

function dropCallbackIter2( dragElement, dropElement) {
    var dragId = dragElement.getAttribute('id').substring(7,43);
    var newParentId = dropElement.getAttribute('parent').substring(7,43);
    var newPosition = dropElement.getAttribute('position');

    dropElement.parentNode.replaceChild( dragElement, dropElement);
    
    removeReorderDroppables();
    removeReorderDraggables();
    
    Element.show('sidebarProgressGraphic');
    grabOutline(uuid, true);
}

function makeElementDropHandle( element) {
    Droppables.add( element,  { hoverclass: 'dropHover',
                    onDrop: function ( drag, drop) {
                        dropCallback( drag, drop);
                       }});
    OA.globals.reorderDrops[OA.globals.reorderDrops.length] = element;
}

function makeElementDropHandleIter2( element) {
    Droppables.add( element,  { hoverclass: 'dropHover',
                    onDrop: function ( drag, drop) {
                        dropCallbackIter2( drag, drop);
                       }});
    OA.globals.reorderDrops[OA.globals.reorderDrops.length] = element;
}

function addReorderDroppables(element) {

    var children = element.childNodes;

    for ( var i=0; i < children.length; i++) {
        if ((children[i].tagName == 'DIV') || (children[i].tagName == 'UL') || (children[i].tagName == 'LI') || (children[i].tagName == 'SPAN')) {
            addReorderDroppables(children[i]);
        }
    }

    if (Element.hasClassName( element, 'dropBar') || Element.hasClassName( element, 'drop')) {
        makeElementDropHandle( element);
    }

}

function addReorderDroppablesIterTwo(element) {

    var children = element.childNodes;

    for ( var i=0; i < children.length; i++) {
        if ((children[i].tagName == 'DIV') || (children[i].tagName == 'UL') || (children[i].tagName == 'LI') || (children[i].tagName == 'SPAN')) {
            addReorderDroppables(children[i]);
        }
    }

    if (Element.hasClassName( element, 'dropBar') || Element.hasClassName( element, 'drop')) {
        makeElementDropHandleIter2( element);
    }

}


function removeReorderDroppables() {
    OA.globals.reorderDrops.each( function( value, index) {
            Droppables.remove(value);
        });
}

function changeFocus( id){
    var focusId = $( id);
    if(focusId !== null)
        focusId.focus( );
}


var DirectoryAutoComplete = Class.create();
Object.extend(Object.extend( DirectoryAutoComplete.prototype, Ajax.Autocompleter.prototype), {
  initialize: function(element, update, theindicator) {
    var options = {};
        
    options.paramName = "member";
    options.tokens = [','];
    options.updateElement= this.myUpdateElement.bind(this);
    options.frequency= 0.01;
    options.minChars= 2;


    this.baseInitialize(element, update, options);
    this.options.asynchronous  = true;
    this.options.onComplete    = this.onComplete.bind(this);
    this.options.defaultParams = this.options.parameters || null;
    this.options.indicator     = theindicator;
    this.directoryUrl          = 'autoCompleteMembersDirectory.do';
    this.standardUrl           = 'autoCompleteMembers.do';
    this.useDirectory          = false;

  },
  
  myUpdateElement: function( li)
  {
    this.options.updateElement = null;
    if (li.id == "directory") {
        this.useDirectory = true;
        this.startIndicator();
        this.activate ();
        // always turn the directory off
        // after this ajax call.. we will otherwise bring down the directory
        // and I do not want them call my cell phone
        this.useDirectory = false;

    } else {
        this.updateElement ( li );
    }
    this.options.updateElement= this.myUpdateElement.bind(this);
  },
  
  startIndicator: function() {
    if(this.options.indicator && this.useDirectory) Element.show(this.options.indicator);
  },
  
  hide: function() {
    if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
    if(this.iefix) Element.hide(this.iefix);
  },  
      
  getUpdatedChoices: function() {
    entry = encodeURIComponent(this.options.paramName) + '=' + 
      encodeURIComponent(this.getToken());

    this.options.parameters = this.options.callback ?
      this.options.callback(this.element, entry) : entry;

    if(this.options.defaultParams) 
      this.options.parameters += '&' + this.options.defaultParams;

    new Ajax.Request( (this.useDirectory ? this.directoryUrl : this.standardUrl), this.options);
  }
    
});



function grabOutline(uuid, reorderEnabled) {
    var params = 'activityUuid=' + uuid;
    
    if (reorderEnabled == true) {
        params += '&reorderEnabled=true';
    }
    
    Element.show('sidebarProgressGraphic');
    new Ajax.Updater( 'navbarOutline', 'minioutline', {asynchronous:true, evalScripts:true, parameters: params, onComplete: function() { Element.hide('sidebarProgressGraphic'); } });  
}

function switchToInfo(uuid) {
    var currentTab = $('currentNavTab');
    
    if ( Element.hasClassName( currentTab, 'outlineTab')) {
        Element.show('navbarInfo');
        Element.hide('navbarOutline');
        currentTab.id = 'nonSelectedOutlineTab';
        
        //hacky, need to next twice since the "\n" is a sibling
        $('nonSelectedInfoTab').id = 'currentNavTab';
    }
}

function switchToOutline() {
    var currentTab = $('currentNavTab');
    
    if ( Element.hasClassName( currentTab, 'infoTab')) {
        Element.show('navbarOutline');
        Element.hide('navbarInfo');
        currentTab.id = 'nonSelectedInfoTab';
        
        //hacky, need to next twice since the "\n" is a sibling
        $('nonSelectedOutlineTab').id = 'currentNavTab';
        
        //grabOutline(uuid, reorderEnabled);
    }
}

/* Stops events from bubbling up to parent elements.
   This function is cross-browser */
function stopEventPropagation(e) {
    if (!e) var e = window.event;
        e.cancelBubble = true;
        if (e.stopPropagation) e.stopPropagation();
}



function selectOutlineNode( uuid, actUuid, event, viewActUuid) {
    /* Don't do outline selection if we are ing reorder mode */
    if ( !Element.hasClassName('miniOutlineRoot', 'reorderMode')) {
        switchToOutline();
        setOutlineSelection( uuid);
    
        var options = {};
        
        options.method = 'get';
        options.asynchronous = true;
        options.evalScripts = true;
        options.parameters = 'uuid=' + uuid + '&activityUuid=' + actUuid + '&viewActUuid=' + viewActUuid + '&count=' + 20;
        
        new Ajax.Updater( 'contentArea', 'ajaxOutlineSelection', options);
        
        if ( event != null) { 
            stopEventPropagation( event);
        }
    }
}

function setOutlineSelection( newUuidSelected) {
    if ( OA.globals.outlineSelection != null && OA.globals.outlineSelection.length == OA.UUID_LENGTH) {
        Element.removeClassName( OA.OUTLINE_PREFIX + OA.globals.outlineSelection, 'selected');
    }
        
    Element.addClassName( OA.OUTLINE_PREFIX + newUuidSelected, 'selected');
    OA.globals.outlineSelection = newUuidSelected;
}

function activityPicker (element, selection) {
    $('activityUuid').value = selection.lastChild.innerHTML;
    $('submitButton').disabled = false;
}

function toggleShowDetails( checkbox) {
    if ( !checkbox.checked) {
        changeToList();
    } else {
        changeToDetails();
    }   
}

/* For sidebar outline (only iter2 - need to remove iter1 reordering js in future) */
function toggleSidebarOutlineReordering( checkbox, actSize) {
    if ( checkbox.checked) {
        if ( (actSize < 75) || (actSize >= 75 && confirm( 'Caution, reordering very large activities may result in slower performance'))) {
            initSidebarReorder();
        } else if (actSize >= 75) { //pressed cancel during confim
            checkbox.checked = false;
        }
    } else {
        Element.removeClassName( 'miniOutlineRoot', 'reorderMode');
        removeReorderDroppables();
        removeReorderDraggables();
    }   
}

function initSidebarReorder() {
    addReorderDroppables( $('miniOutlineRoot'));
    addReorderDraggables();
    
    Element.addClassName( 'miniOutlineRoot', 'reorderMode');
    Element.hide( 'sidebarProgressGraphic');
}

function getLocalBrowserTime ( dateMillis ) {
            var currentDate = new Date();
            var offsetMinutes = currentDate.getTimezoneOffset();

            var serverDate = new Date ();
            serverDate.setTime ( dateMillis ); //- (offsetMinutes * 60 * 1000) );
            
            var transDate = new Date ();
            transDate.setTime ( dateMillis - (offsetMinutes * 60 * 1000) );                     
            
            var localDate = new Date ();
            localDate.setFullYear ( transDate.getUTCFullYear() );
            localDate.setMonth ( transDate.getUTCMonth() );
            localDate.setDate ( transDate.getUTCDate() );
            localDate.setHours ( transDate.getUTCHours() );
            localDate.setMinutes ( transDate.getUTCMinutes() );
            localDate.setSeconds ( transDate.getUTCSeconds() );
            localDate.setMilliseconds ( transDate.getUTCMilliseconds() );   
            
            //document.write( localDate.toLocaleString() );     
            return localDate.toLocaleString();
}

/* Toggle the tag this form for a particular activity or entry */
function toggleTagThis( uuid) {
    var tagBlockElement = $('tagblock_' + uuid);
    
    if ( Element.hasClassName(tagBlockElement, 'tagThisEnabled')) {
        Element.removeClassName(tagBlockElement, 'tagThisEnabled');
    } else {
        Element.addClassName(tagBlockElement, 'tagThisEnabled');
    }
}

function removeTag( tagName, nodeUuid, liElement) {
    Element.hide( liElement);
    
    new Ajax.Request('removetag', {parameters: 'tag=' + tagName + '&nodeUuid=' + nodeUuid, asynchronous:true});
}

/* Seems like datePicker.toggle is not a function yet, so writing my own */

function toggleDojoWidget ( widget ) {
    if ( widget.isShowing() ) {
        widget.hide();
    } else {
        widget.show();
    }
}

function onCalendarSetDate ( widget ) {
    var picker = dojo.widget.byId ("datePickerWidget");
    
    var lowerBound = new Date();
    lowerBound.setTime (picker.date.getTime());
    lowerBound.setHours(0);
    lowerBound.setMinutes(0);
    lowerBound.setSeconds(0);
    lowerBound.setMilliseconds(0);
    
    var upperBound = picker.date;
    upperBound.setHours(23);
    upperBound.setMinutes(59);
    upperBound.setSeconds(59);
    upperBound.setMilliseconds(59);
    
    goToDueDateURL ( lowerBound, upperBound, picker.date.getTime() );
}

function dueToday () {
    var lowerBound = new Date();
    lowerBound.setHours(0);
    lowerBound.setMinutes(0);
    lowerBound.setSeconds(0);
    lowerBound.setMilliseconds(0);
    
    var upperBound = new Date ();
    upperBound.setHours(23);
    upperBound.setMinutes(59);
    upperBound.setSeconds(59);
    upperBound.setMilliseconds(59);

    goToDueDateURL ( lowerBound, upperBound );  
}

function dueThisWeek () {
    
    var lowerBound = new Date ();
    lowerBound.setDate ( lowerBound.getDate() - lowerBound.getDay() ); 
    lowerBound.setHours(0);
    lowerBound.setMinutes(0);
    lowerBound.setSeconds(0);
    lowerBound.setMilliseconds(0);
    
    var upperBound = new Date ();
    upperBound.setDate ( upperBound.getDate() + ( 6 - upperBound.getDay() ) );
    upperBound.setHours(23);
    upperBound.setMinutes(59);
    upperBound.setSeconds(59);
    upperBound.setMilliseconds(59); 

    goToDueDateURL ( lowerBound, upperBound );  
}

function goToDueDateURL ( lowerBound, upperBound, calendarDateTime ) {
    /*
    var lower = dojo.date.format ( lowerBound, "%F %T");
    var upper = dojo.date.format ( upperBound, "%F %T");
    */
    
    var lower = getRfcDate (lowerBound);
    var upper = getRfcDate (upperBound);
    
    var url = OA.globals.applicationContext + "/service/html/duedate?"
        + "activityUuid=" + OA.globals.activityUuid
        + "&dueDateLowerBound=" + lower
        + "&dueDateUpperBound=" + upper 
        + "&" + generateReturnToString();

    window.location = url;  
}

function getRfcDate ( date ) {
    var rfcDate = date.getFullYear();
    rfcDate += "-" + padTime (date.getMonth()+1);
    rfcDate += "-" + padTime (date.getDate()) + " ";
    
    rfcDate += padTime (date.getHours());
    rfcDate += ":" + padTime (date.getMinutes());
    rfcDate += ":" + padTime (date.getSeconds());
    
    return rfcDate;
}

function padTime ( t ) {

    if ( t < 9 ) 
        return "0" + t;
    else
        return t;
}

OA.MoveToForm = {
    id: "moveto_form",
    
    actControlId: "activitySelectionArea",
    entryControlId: "entrySelectionArea",
    
    actToggleLinkId: "moveToActivityToggle",
    entryToggleLinkId: "moveToEntryToggle",
    
    returnTypeId: "moveToReturnType",
    
    ACTIVITY: "activity",
    ENTRY: "entry",
    
    toggleSelectionControl: function( control) {
        if (control == OA.MoveToForm.ACTIVITY) {
            Element.show( OA.MoveToForm.actControlId);
            Element.hide( OA.MoveToForm.entryControlId);
            
            Element.show( OA.MoveToForm.entryToggleLinkId);
            Element.hide( OA.MoveToForm.actToggleLinkId);
            
            $( OA.MoveToForm.returnTypeId).value = OA.MoveToForm.ACTIVITY;
            
        } else if (control == OA.MoveToForm.ENTRY) {
            Element.show( OA.MoveToForm.entryControlId);
            Element.hide( OA.MoveToForm.actControlId);
            
            Element.show( OA.MoveToForm.actToggleLinkId);
            Element.hide( OA.MoveToForm.entryToggleLinkId);
            
            $( OA.MoveToForm.returnTypeId).value = OA.MoveToForm.ENTRY;
        }
    }
};

function focusTabRTE(){
    if( $ ('autocomplete') !== null && ($('tagsarea') === null || ($('tagsarea') !== null && $('tagsarea').style.display !=='none'))){
        $ ('autocomplete').focus();
    }
    else{
        var elements = new Array( 3);
        elements[0] = "autocompletetags_editform";
        elements[1] = "editTaskDuedate";
        elements[2] = "createTaskDuedate";
        setFocusTo( elements);
    }
    
}
function focusShiftTabRTE(){
    $( 'rteInsertLink').focus();
}


OA.MoveToForm = {
    id: "moveto_form",
    
    actControlId: "activitySelectionArea",
    entryControlId: "entrySelectionArea",
    
    actToggleLinkId: "moveToActivityToggle",
    entryToggleLinkId: "moveToEntryToggle",
    
    returnTypeId: "moveToReturnType",
    
    ACTIVITY: "activity",
    ENTRY: "entry",
    
    toggleSelectionControl: function( control) {
        if (control == OA.MoveToForm.ACTIVITY) {
            Element.show( OA.MoveToForm.actControlId);
            Element.hide( OA.MoveToForm.entryControlId);
            
            Element.show( OA.MoveToForm.entryToggleLinkId);
            Element.hide( OA.MoveToForm.actToggleLinkId);
            
            $( OA.MoveToForm.returnTypeId).value = OA.MoveToForm.ACTIVITY;
            
        } else if (control == OA.MoveToForm.ENTRY) {
            Element.show( OA.MoveToForm.entryControlId);
            Element.hide( OA.MoveToForm.actControlId);
            
            Element.show( OA.MoveToForm.actToggleLinkId);
            Element.hide( OA.MoveToForm.entryToggleLinkId);
            
            $( OA.MoveToForm.returnTypeId).value = OA.MoveToForm.ENTRY;
        }
    }
};

OA.MemberAddForm = {
    ID: 'memberAddForm',
    USER: 'autocompletemembers',
    OWNER: 'autocompleteowners',

    toggle: function( showOrHide) {
        if ( showOrHide == "show" && checkForExistingEditForm()) {
            Element.show( this.ID);
            OA.setCurrentForm( this.ID);
        } else if ( showOrHide == "hide") {
            Element.hide( this.ID);
            $(this.USER).value = "";
            $(this.OWNER).value = "";
            OA.clearCurrentForm();
        }
    }
};

OA.MemberSettingsForm = {
    ID: 'memberSettingsForm',
    
    toggle: function( showOrHide) {
        if ( showOrHide == "show" && checkForExistingEditForm()) {
            Element.show( this.ID);
            OA.setCurrentForm( this.ID);
        } else if ( showOrHide == "hide") {
            Element.hide( this.ID);
            OA.clearCurrentForm();
        }
    }
};

function showHideDeleteMemberIcon( element, action, event){
    if(action == 'showhide' && typeof(event) != "undefined" && event !== null && event.keyCode != Event.KEY_TAB && Element.visible( element)){
        Element.hide(OA.globals.selectdMember);
        OA.globals.selectdMember=null;
    }
    else if( action == 'show' && !Element.visible( element)){
        if(OA.globals.selectdMember){
            Element.hide(OA.globals.selectdMember);
        }
        Element.show(element);
        OA.globals.selectdMember = element; 
    }else if( action == 'hide' && Element.visible( element)){
        Element.hide(element);
        OA.globals.selectdMember=null;
    }
}

