/* 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_',
	"UUID_PREFIX": 'uuid_',
	"EDIT_SUFFIX": '_edit',
	"DESC_SUFFIX": '_desc',
	
	"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;
	}
}
