/*	SaveActionManager: Creates and keeps track of the action items
	------------------------------------------------------- */
    hasActionUi = true;

	function SaveActionManager(args){
		//instance vars passed to constructor
		this.setGroupListData(args.groupListData);
		this.saveActionPath = args.saveActionPath;
		this.saveToNewGroupActionPath = args.saveToNewGroupActionPath;
        this.detailPath = args.detailPath;
        this.firstSaveInvitationText = args.firstSaveInvitationText;
        this.invitationToSaveText = args.invitationToSaveText;
        this.openMenuText = args.openMenuText;
		this.saveConfirmText = args.saveConfirmText;
		this.joinNowHTML = args.joinNowHTML;
		this.illegalCharError = args.illegalCharError;
		this.groupNameLengthError = args.groupNameLengthError;
		this.groupNameTakenError = args.groupNameTakenError;
        this.saveError = args.saveError;
		this.groupType = args.groupType;
		
        //general instance vars
		this.activeActionBox = null;
		this.actionButtonEls = getElements('saveButton', 'A' ,null); //can isolate this to prim content?
		this.saveActionBoxes = this.createActionBoxes( );
		
        //init stuff
		this.defineActionItemsBehavior( );
		this.openInitialActionBox( )

		//Code to make whole 'Save for Later' buttons clickable
		var saveForLater = getElements('greenLabel', 'h6' ,null)[0];
		if(saveForLater){
			saveForLater.onmouseover = function() {
				var event, button;
				button = getElements('saveButton', 'A' ,null)[0];
				if(document.createEvent){
				   event = document.createEvent("MouseEvents");
				   event.initEvent("mouseover", true, false);
				   button.dispatchEvent(event);
				}
				else if(document.createEventObject){
				   event = document.createEventObject();
				   button.fireEvent("onmouseover", event);
				}
			};
		}
	}
	SaveActionManager.prototype.openInitialActionBox = function(){
        if( location.hash.match(/save_/) && this.groupListData.groups ){ 
            /*if 'save_' has been written into the url hash by the sign in or register 
            component and the logged in user myConcierge ajax call has been made*/
            this.initialActionBoxId = unescape(location.hash.substring(6));
            var activeButtonEl, saveActionManager;
            saveActionManager = this;
            for(var i=0; i<this.saveActionBoxes.length; i++){
                if(this.initialActionBoxId == this.saveActionBoxes[i].getButtonEl( ).id){
                    this.activeActionBox = this.saveActionBoxes[i];
                    activeButtonEl = this.activeActionBox.getButtonEl( );
                    this.activeActionBox.createActionBoxEl( );
                    this.onmouseout = this.onclick = activeButtonEl.onmouseover = null;
                    this.engageMenu( ); 
                    this.activeActionBox.getCloseLink( ).onclick = function( ){saveActionManager.closeActiveItemAndReset( )}
                    this.scrollToActiveActionBox( );
                    this.requestTracking( );
                }
            }
        }
	}
    SaveActionManager.prototype.requestTracking = function( ){
        var util, xhr, trackingPath;
        util = new ConciergeUtility( );
        xhr = util.getXHR( );
        trackingPath = '/ajax/trips/apptracking'
        xhr.open('GET', trackingPath, true)
        xhr.onreadystatechange = null;
        xhr.send( null );
    }
	SaveActionManager.prototype.scrollToActiveActionBox = function( ){
		var offsetTop, actionBoxEl, totalOffset, element;
		totalOffset = 0;
		actionBoxEl = this.activeActionBox.getActionBoxEl( );
		element = actionBoxEl;
		while(element.offsetParent){
			totalOffset += element.offsetTop;
			element = element.offsetParent;
		}
		totalOffset -= 188;
		window.scrollTo(0,totalOffset);
	}
	SaveActionManager.prototype.createActionBoxes = function( ){
		var saveActionBoxes = new Array( );
		for(var i=0; i<this.actionButtonEls.length; i++)
			saveActionBoxes.push( new ActionBox({buttonElement: this.actionButtonEls[i]}) );
		return saveActionBoxes;
	}
    SaveActionManager.prototype.defineActionItemsBehavior = function( ){  //add a function in here to delete the activeActionBox property onclick of its closelink
        var buttonEl, saveActionManager;
        saveActionManager = this;
		for(var i=0; i<this.saveActionBoxes.length; i++){
            buttonEl = this.saveActionBoxes[i].getButtonEl( );
            buttonEl.onmouseover = buttonOverHandler;
        }
		
        function buttonOverHandler(event){
            if(saveActionManager.activeActionBox) return;
            var evt, buttonEl;
            evt = event || window.event;
            buttonEl = evt.target || evt.srcElement;
            for(var i=0; i<saveActionManager.saveActionBoxes.length; i++){
                if( buttonEl == saveActionManager.saveActionBoxes[i].getButtonEl( ) ){
                    saveActionManager.activeActionBox = saveActionManager.saveActionBoxes[i];
                    break;
                }
            }
            saveActionManager.activeActionBox.createActionBoxEl( );
            saveActionManager.activeActionBox.writeToHeadline(saveActionManager.invitationToSaveText);
            saveActionManager.activeActionBox.getActionBoxEl( ).onmouseout = function(event){
                var evt, nextEl;
                evt = event || window.event;
                nextEl = evt.relatedTarget || evt.toElement;
                if( nextEl!=this && !isDescendant(this,nextEl) ){
                    saveActionManager.closeActiveItemAndReset( )
                }
            }
            saveActionManager.activeActionBox.getActionBoxEl( ).onclick = function(event){
				this.onmouseout = this.onclick = buttonEl.onmouseover = null;
				if(saveActionManager.groupListData.groups){
                    saveActionManager.engageMenu( ); //if we have data, the user is logged in.. so open the menu
				}else{
                    saveActionManager.engageSignInOrRegisterComponent( );
                }
				saveActionManager.activeActionBox.getCloseLink( ).onclick = function( ){saveActionManager.closeActiveItemAndReset( )}
            }
        }
    }
	SaveActionManager.prototype.engageSignInOrRegisterComponent = function( ){
		var loginForm, joinInvite, clearer;
		clearer = document.createElement('DIV');
		clearer.className = 'clearer';
		loginForm = this.makeLoginForm( );
		joinInvitation = this.makeJoinInvitation( );
		this.activeActionBox.writeToHeadline('Sign In Or Register');
		this.activeActionBox.addClassName('signInOrRegister');
		this.activeActionBox.addElementToEnd(loginForm);
		this.activeActionBox.addElementToEnd(joinInvitation);
		this.activeActionBox.addElementToEnd(clearer);
		this.activeActionBox.expandActionBoxEl( );
	}
	SaveActionManager.prototype.makeLoginForm = function( ){
		var container, saveButtonId;
		saveButtonId = this.activeActionBox.getButtonEl( ).id ;
		container = document.createElement('DIV');
		container.id = 'sior_login_form';
		signInHTML = '<form method="post" action="/user/signin" name="loginForm">'
        if( !location.hash )
            signInHTML += '<input type="hidden" name="returnto" value="' + location + '#save_' + saveButtonId + '" />'
        else{
            signInHTML += '<input type="hidden" name="returnto" value="' + location.href.replace(location.hash, '') + '#save_' + saveButtonId + '" />'
        }
        signInHTML += '<h3>Member Sign-In</h3>' +
			'<div>' +
				'<p>Username:<br /><input type="text" class="textField" name="username" ></p>' +
				'<p>Password:<br /><input type="password" class="textField" name="password"></p>' +
			'</div>' +
			'<p>' +
				'<span class="yellowOnBlackCssButton">' +
					'<a href="javascript:document.loginForm.submit()">Sign In &#8250;</a>' +
				'</span>' +
				'<a class="forgotInfo" href="/user/forgotpassword?returnto=' + location + '">Forgot your sign-in information?</a>' +
				'<input id="submit" type="image" src="/images/x.gif"/>' +
			'</p>' +
		'</form>';
		container.innerHTML = signInHTML;
		return container;
	}
	SaveActionManager.prototype.makeJoinInvitation = function( ){
		var container;
		container = document.createElement('DIV');
		container.id = 'sior_join_invite';
		container.innerHTML = this.joinNowHTML;
		return container;
	}
    SaveActionManager.prototype.engageMenu = function( ){
        var existingGroupsEl, newGroupEl; 
        if( this.groupListData.groups.length > 0 ){
            existingGroupsEl = this.createGroupListEl( );
            newGroupEl = this.getCreateGroupLinkEl( );
        } else{
            existingGroupsEl = this.getFirstSaveInvitationEl( );
            newGroupEl = this.getCreationFormEl( );
        }
        if(this.openMenuText){
            var actionManager = this;
            setTimeout( function( ){actionManager.activeActionBox.writeToHeadline(actionManager.openMenuText)}, 0);
        }
        this.activeActionBox.addElementToEnd(existingGroupsEl);
        this.activeActionBox.addElementToEnd(newGroupEl);
        this.activeActionBox.expandActionBoxEl( );
    }
    SaveActionManager.prototype.getFirstSaveInvitationEl = function( ){
        var element = document.createElement("DIV");
        element.className = 'sysMsg';
        element.innerHTML = this.firstSaveInvitationText;
        return element;
    }
	SaveActionManager.prototype.createGroupListEl = function( ){
		var groupListEl, itemEl, saveToGroupLinkEls;
		groupListEl = document.createElement('UL');
        groupListEl.className = 'groupList';
        groupListEl.className += " " + this.groupType.toLowerCase( ) + "List";
        this.saveToGroupLinkEls = this.createSaveToGroupLinkEls( );
		for(var i=0; i<this.saveToGroupLinkEls.length; i++){
			itemEl = document.createElement('LI');
			itemEl.appendChild(this.saveToGroupLinkEls[i]);
			groupListEl.appendChild(itemEl);
		}
		return groupListEl;
	}
    SaveActionManager.prototype.createSaveToGroupLinkEls = function( ){
		var actionItem, groupId, saveToGroupLinkEls, saveToGroupLinkEl, saveActionManager;
        saveActionManager = this;
        saveToGroupLinkEls = new Array( )
		for(var i=0; i<this.groupListData.groups.length; i++){
			saveToGroupLinkEl = document.createElement('A');
			saveToGroupLinkEl.innerHTML = this.groupListData.groups[i].groupTitle;
			saveToGroupLinkEl.id = this.groupType.toLowerCase( ) + "_" + this.groupListData.groups[i].groupId; //one way of passing group id.. try another way without using the dom
            saveToGroupLinkEl.onclick = function(event){ saveActionManager.saveToExistingGroup(event) }
            saveToGroupLinkEls.push(saveToGroupLinkEl);
		}
        return saveToGroupLinkEls;
    }
	SaveActionManager.prototype.getCreateGroupLinkEl = function( ){
		var newLink, saveActionManager;
        saveActionManager = this;
        newLink = document.createElement('A');
		newLink.className = 'newLink';
		newLink.innerHTML = 'Create A New ' + this.groupType;
        newLink.onclick = function( ){
            saveActionManager.activeActionBox.removeContent(newLink)
            saveActionManager.activeActionBox.addElementToEnd(saveActionManager.getCreationFormEl( ));
        }
        return newLink;
	}
    SaveActionManager.prototype.getCreationFormEl = function( ){ //create backup standard form submission if request fails
        var creationForm, lowercaseGroupType, groupTitleLabel, groupTitleEntryField, saveButton, cancelButton, saveActionManager;
        saveActionManager = this;
        lowercaseGroupType = this.groupType.toLowerCase( )
        creationForm = document.createElement('FORM');
        creationForm.name = creationForm.id = 'new_'+ lowercaseGroupType +'_form';
        groupTitleLabel = document.createElement("LABEL");
        groupTitleLabel.innerHTML = "new " + lowercaseGroupType + " title:";
        groupTitleLabel.setAttribute("FOR", lowercaseGroupType + '_text');
        groupTitleEntryField = document.createElement('INPUT');
        groupTitleEntryField.type = 'TEXT';
        groupTitleEntryField.name = lowercaseGroupType + '_title';
        groupTitleEntryField.id = lowercaseGroupType + '_text';
        groupTitleEntryField.setAttribute("MAXLENGTH", 50);
        saveButton = document.createElement('A');
        saveButton.innerHTML = 'Save';
        cancelButton = document.createElement('A');
        cancelButton.innerHTML = 'Cancel';
        creationForm.appendChild(groupTitleLabel);
        creationForm.appendChild(groupTitleEntryField);
        creationForm.appendChild(saveButton);
        creationForm.appendChild(cancelButton);
        creationForm.onsubmit = function( ){
            saveActionManager.validateCreationForm(this, groupTitleEntryField);
            return false;
        }
        saveButton.onclick = function( ){creationForm.onsubmit( )};
        cancelButton.onclick = function( ){saveActionManager.closeActiveItemAndReset( );}
        return creationForm;
    }
    SaveActionManager.prototype.validateCreationForm = function(creationForm, groupTitleEntryField){
        var titleEntryValue, illegalChars, titleEntryLength, saveActionManager;
        saveActionManager = this;
		illegalChars = ['<', '>', '?', '/', '&'];
		
        titleEntryValue = groupTitleEntryField.value;
        titleEntryLength = titleEntryValue.length;
        if(titleEntryLength>50 || titleEntryLength<1){ //extend this to match on characters (space) casing & make 20 an argument
            provideErrorMessage('lengthError');
            return;
        }
        for(var i=0; i<this.groupListData.groups.length; i++){
            if(titleEntryValue.toLowerCase( ) == this.groupListData.groups[i].groupTitle.toLowerCase( )){ //add checking against decoded title
                provideErrorMessage('nameTakenError');
                return;
            }
        }
		for(var i=0; i<illegalChars.length; i++){
			if(titleEntryValue.indexOf(illegalChars[i]) != -1){
				provideErrorMessage('illegalCharError');
				return;
			}
		}
        function provideErrorMessage(errorType){
            var errorMsgText, errorMsgEl, previousErrorMsgs;
            previousErrorMsgs = getElements('errorMsg', 'P', creationForm);
            errorMsgEl = document.createElement('P');
            errorMsgEl.className = 'errorMsg';
            switch(errorType){
            case 'lengthError':
                errorMsgText = saveActionManager.groupNameLengthError;
                break;
            case 'nameTakenError':
                errorMsgText =  saveActionManager.groupNameTakenError
                break;
			case 'illegalCharError':
				errorMsgText = saveActionManager.illegalCharError;
				break;
			}
            errorMsgEl.innerHTML = errorMsgText;
            for(var i=0; i<previousErrorMsgs.length; i++)
                creationForm.removeChild(previousErrorMsgs[i]);
            creationForm.insertBefore(errorMsgEl, creationForm.firstChild);
        }
        this.createAndSaveToNewGroup(titleEntryValue);
    }
    SaveActionManager.prototype.createAndSaveToNewGroup = function(groupTitle){
        var util, fullRequestPath, saveActionManager, xhr;
        saveActionManager = this;
		fullRequestPath = this.saveToNewGroupActionPath + saveActionManager.activeActionBox.getContentType( ) + 
                                  '/' + groupTitle + '/' + saveActionManager.activeActionBox.getContentId( );
		util = new ConciergeUtility( );
		xhr  = util.getXHR( );
		xhr.onreadystatechange = function( ) {
			if (xhr.readyState == 4 && xhr.status == 200){
				newGroupData = eval('('+xhr.responseText+')');
                saveActionManager.handleSaveToNew(newGroupData, groupTitle);
			}
            if (xhr.readyState == 4 && xhr.status != 200){
                saveActionManager.showErrorState(xhr.status)
            }
		}
		xhr.open("GET", fullRequestPath, true); //replace this with a post request
        this.showProgressIndication('Saving');
		xhr.send(null);
    }
	SaveActionManager.prototype.saveToExistingGroup = function(event){
		var evt, requestedGroupSaveLinkEl, saveActionPath, fullRequestPath, groupId, contentItemType, contentItemId, util, xhr, newGroupData, saveActioManager;
        evt = event || window.event;
		requestedGroupSaveLinkEl = evt.srcElement || evt.target;
		saveActionManager = this;

		for(var i=0; i<this.saveToGroupLinkEls.length; i++)
			if(this.saveToGroupLinkEls[i] == requestedGroupSaveLinkEl)
				groupId = this.saveToGroupLinkEls[i].id.split('_')[1]; //one way of getting the trip id.. try to do it without the dom
        saveActionPath = this.saveActionPath;
		contentItemType = this.activeActionBox.getContentType( );
		contentItemId = this.activeActionBox.getContentId( );
        fullRequestPath = saveActionPath + '/' + groupId + '/add' + contentItemType + '/' + contentItemId;
		saveActionManager.showProgressIndication( );
		util = new ConciergeUtility( );
		xhr  = util.getXHR( );
		xhr.onreadystatechange = function( ) {
			if (xhr.readyState == 4 && xhr.status == 200){
					newGroupData = eval('('+xhr.responseText+')');
					saveActionManager.handleSaveToExisting(newGroupData, requestedGroupSaveLinkEl);
			}
            if (xhr.readyState == 4 && xhr.status != 200){
                saveActionManager.showErrorState(xhr.status)
            }
		}
		xhr.open("GET", fullRequestPath, true);
		xhr.send(null);
	}
    SaveActionManager.prototype.showErrorState = function(status){
        var errorDiv;
        errorDiv = document.createElement('DIV');
        errorDiv.className = 'saveError'
        errorDiv.innerHTML = this.saveError;
        this.activeActionBox.removeAllContent( );
        this.activeActionBox.addElementToBeginning(errorDiv);
    }
    SaveActionManager.prototype.handleSaveToExisting = function(newGroupData, requestedGroupSaveLinkEl){
        var groupTitle = requestedGroupSaveLinkEl.innerHTML;
		this.setGroupListData(newGroupData);
		this.showSuccessMessage(groupTitle);
		updateGroupListsOnPage(newGroupData);
    }
	SaveActionManager.prototype.handleSaveToNew = function(newGroupData, groupTitle){
        this.setGroupListData(newGroupData);
		this.showSuccessMessage(groupTitle);
		updateGroupListsOnPage(newGroupData);
    }
	SaveActionManager.prototype.showSuccessMessage = function(groupTitle){
        var successMsgEl, saveActionManager, closeLink, clearer, detailLink;
        successMsgEl = document.createElement('DIV');
		detailLink = document.createElement('A');
        successMsgEl.className = "sysMsg";
		successMsgEl.innerHTML = this.saveConfirmText + groupTitle;
		detailLink.innerHTML = "Go to your " + this.groupType + 's';
		detailLink.href = this.detailPath;
        this.activeActionBox.removeAllContent( );
        this.activeActionBox.addElementToEnd(successMsgEl);
        if(detailLink) this.activeActionBox.addElementToEnd(detailLink);
		saveActionManager= this;
        clearer = window.setTimeout(function( ){saveActionManager.closeActiveItemAndReset( );}, 3000)
        closeLink = saveActionManager.activeActionBox.getCloseLink( );
        closeLink.onclick = function( ){
            clearTimeout(clearer);
            saveActionManager.closeActiveItemAndReset( );
        }
	}
    SaveActionManager.prototype.showProgressIndication = function(message){
        var progressEl, msgText;
        msgText = message || 'In Progress';
        progressEl = document.createElement('DIV');
        progressEl.className = 'inProgress';
        progressEl.innerHTML = msgText;
        this.activeActionBox.removeAllContent( );
        this.activeActionBox.addElementToBeginning(progressEl);
    }
    SaveActionManager.prototype.closeActiveItemAndReset = function( ){
        this.activeActionBox.destroyActionBoxEl( );
        delete this.activeActionBox;
        this.defineActionItemsBehavior( );
    }
	SaveActionManager.prototype.getActiveActionItem = function(buttonEl){
		for(var i=0; i<this.saveActionBoxes.length; i++)
			if(buttonEl == this.saveActionBoxes[i].buttonEl)
				return this.saveActionBoxes[i];
	}
	SaveActionManager.prototype.setGroupListData = function(groupListData){ //this will be used for updates via ajax response
		this.groupListData = groupListData;
	}

    /**************************************/

    function instantiateActionManager( tripsGroups){
		var invitationToSaveText, openMenuText, type, joinNowHTML, initialActionBoxId;
		tripsData.groups = tripsGroups;
		invitationToSaveText = (isCopy ? 'Copy This Item' : 'Save for Later');
		openMenuText = (isCopy ? 'Copy To Another Trip Plan:' : 'Save To A Trip Plan:');
		saveConfirmText = (isCopy ? 'Copied to ' : 'Saved to ');
		
		joinNowHTML =
		'<h3>Not A Member?</h3>' +
		'<p>Join Concierge.com to create Trip Plans, upload photos, post tips and reviews, and get answers to your travel questions.</p>' +
		'<p>It\'s fast and free!</p>' +
		'<span class="yellowOnBlackCssButton"><a href="/user/registration?application=trips&returnto=' + location + '">Join Now&nbsp;&#8250;</a></span>'
		tripsSaveManager = new SaveActionManager({
				groupListData:  tripsData, //global var set by response
				saveActionPath: '/myconcierge/trips',
				saveToNewGroupActionPath: '/myconcierge/trips/createtripadd',
                detailPath: '/myconcierge/trips/mostrecent',
				groupType: 'Trip',
				firstSaveInvitationText: 'You do not have any Trip Plans. Create one here:',
				illegalCharError: "Sorry. You've included a character that's not allowed. Please try a different title for your Trip Plan.",
				groupNameTakenError: "A Trip Plan with this name already exists.",
				groupNameLengthError: "Trip Plan name must contain between 1 and 50 characters.",
                saveError: "Error:  Unable to save item to your Trip Plan. Please try again later.",
                invitationToSaveText: invitationToSaveText,
                openMenuText: openMenuText,
				saveConfirmText: saveConfirmText,
				joinNowHTML: joinNowHTML
		});
    }
	
/************************************************************************************************************/


/************************************************************************************************************/

/*	ActionBox
	--------- */
	function ActionBox(args){
		this.buttonEl = args.buttonElement;
	}
	ActionBox.prototype.getContentId = function( ){
		return this.buttonEl.id.split('_')[1];
	}
	ActionBox.prototype.getContentType = function( ){
		return this.buttonEl.id.split('_')[0];
	}
    ActionBox.prototype.getButtonEl = function( ){
        return this.buttonEl;
    }
	ActionBox.prototype.createActionBoxEl = function( ){
		if(this.actionBoxEl) return;
		this.actionBoxEl = document.createElement('DIV');
        this.actionBoxHeadline = document.createElement('H6');
        this.actionBoxContentEl = document.createElement('DIV');
		this.actionBoxEl.className = 'actionBox';
		this.actionBoxContentEl.className = 'actionBoxContent';
        this.buttonEl.parentNode.replaceChild(this.actionBoxEl, this.buttonEl);
		this.actionBoxEl.appendChild(this.actionBoxHeadline);
		this.actionBoxEl.appendChild(this.buttonEl);
		this.actionBoxEl.appendChild(this.actionBoxContentEl);
	}
    ActionBox.prototype.getActionBoxEl = function( ){
        return this.actionBoxEl;
    }
	ActionBox.prototype.destroyActionBoxEl = function( ){
        var actionBoxAncestors = getAncestors(this.actionBoxEl);
        for(var i=0; i<actionBoxAncestors.length; i++)
            actionBoxAncestors[i].style.zIndex = '';
        this.actionBoxEl.parentNode.replaceChild(this.buttonEl, this.actionBoxEl);
		delete this.actionBoxEl;
        delete this.actionBoxHeadline;
		delete this.actionBoxContentEl;
        this.isOpen = false;
	}
    ActionBox.prototype.writeToHeadline = function(content){
        this.actionBoxHeadline.innerHTML = content;
    }
	ActionBox.prototype.addElementToEnd = function(element){ //rename
		this.actionBoxContentEl.appendChild(element);
	}
    ActionBox.prototype.addElementToBeginning = function(element){ //rename
		this.actionBoxContentEl.insertBefore(element,this.actionBoxContentEl.firstChild); 
	}
	ActionBox.prototype.removeContent = function(element){
        if(element) this.actionBoxContentEl.removeChild(element);
	}
	ActionBox.prototype.removeAllContent = function( ){
        while(this.actionBoxContentEl.childNodes.length > 0)
            this.actionBoxContentEl.removeChild(this.actionBoxContentEl.firstChild)
	}
	ActionBox.prototype.expandActionBoxEl = function( ){
		if(!this.actionBoxEl || this.isOpen) return;
        var actionBoxAncestors = getAncestors(this.actionBoxEl);
        for(var i=0; i<actionBoxAncestors.length; i++)
            actionBoxAncestors[i].style.zIndex = '1000';
		this.actionBoxEl.className += ' expandedActionBox';
		this.addCloseLink( );
        this.isOpen = true;
	}
	ActionBox.prototype.addCloseLink = function( ){
        var thisActionBox = this;
        this.closeLink = document.createElement("A");
		this.closeLink.className = 'closeLink';
		this.closeLink.innerHTML = 'x';
		this.actionBoxEl.appendChild(this.closeLink);
	}
    ActionBox.prototype.getCloseLink = function( ){
        return this.closeLink;
    }
	ActionBox.prototype.hideTooltip = function(event){
		var nextEl = event.relatedTarget || event.toElement;
		if(!this.actionBoxEl || !nextEl) return;
		if( !isDescendant(this.actionBoxEl, nextEl) && nextEl != this.actionBoxEl )
			this.destroyActionBoxEl( );
	}
	ActionBox.prototype.addClassName = function( classname ){
		this.actionBoxEl.className += ' ' + classname;
	}
	ActionBox.prototype.removeClassName = function( classname ){
		this.actionBoxEl.className = this.actionBoxEl.className.replace(classname,'');
	}
/************************************************************************************************************/

/*	DeleteActionManager: Deletes an item from a group
	------------------------------------------------- */
	function deleteActionManager(args){
		this.container = document.getElementById(args.containerId);
		this.deleteClass = args.deleteClass;
		this.confirmText = args.confirmText;
		this.actionPath = args.actionPath;
		this.deleteEls = this.getDeleteEls( );
		this.deleteActionItems = this.setDeleteActionItems( );
	}
	deleteActionManager.prototype.setDeleteActionItems = function( ){
		for(var i=0; i<this.deleteEls.length; i++)
			new deleteActionItem({deleteEl: this.deleteEls[i], confirmText: this.confirmText, actionPath: this.actionPath});
	}
	deleteActionManager.prototype.getDeleteEls = function( ){
		return getElements(this.deleteClass, null, this.container)
	}
	function deleteActionItem(args){
		var deleteActionItem = this;
		this.deleteEl = args.deleteEl;
		this.contentEl = this.deleteEl.parentNode; //this can be made more general later
		this.contentType = this.getContentType( );
		this.contentId = this.getContentId( );
		this.confirmText = args.confirmText;
		this.actionPath = args.actionPath;
		this.deleteEl.onclick = function( ){deleteActionItem.requestDelete( )};
	}
	deleteActionItem.prototype.requestDelete = function( ){
		var deleteConfirmation, util, fullRequestPath, deleteActionItem, newGroupData;
		deleteConfirmation = confirm(this.confirmText)
		if(!deleteConfirmation) return;
		fullRequestPath = this.actionPath + this.contentType + '/' + this.contentId;
		deleteActionItem = this;
		util = new ConciergeUtility( );
		xhr  = util.getXHR( );
		xhr.onreadystatechange = function( ) {
			if (xhr.readyState == 4 && xhr.status == 200){
				newGroupData = eval('('+xhr.responseText+')');
				deleteActionItem.handleDelete(newGroupData);
			}
		}
		xhr.open("GET", fullRequestPath, true);
		xhr.send(null);
	}
	deleteActionItem.prototype.handleDelete = function(newGroupData){
		this.showDeleted( );
		updateGroupListsOnPage(newGroupData);
	}
	deleteActionItem.prototype.showDeleted = function( ){
		var removeMethod, deleteActionItem;
		deleteActionItem = this;
		removeMethod = function( ){deleteActionItem.contentEl.parentNode.removeChild(deleteActionItem.contentEl)};
		fadeOut(this.contentEl, 10, removeMethod);
	}
	deleteActionItem.prototype.getContentType = function( ){
		return this.deleteEl.id.split('_')[0];
	}
	deleteActionItem.prototype.getContentId = function( ){
		return this.deleteEl.id.split('_')[1];
	}
/************************************************************************************************************/


/*	Price Key
	--------- */
	function PriceRatingItem(args){
		var instance = this;
		this.ratingElement = args.ratingElement;
        this.dynPos = this.getType( );
		this.ratingElement.onmouseover = function( ){instance.showKey( )};
		this.ratingElement.onmouseout = function( ){instance.hideKey( )};
	}
    PriceRatingItem.prototype.getType = function( ){
        if( isMember(this.ratingElement, 'dPos') ) return true
        return false;
    }
	PriceRatingItem.prototype.showKey = function( ){
		this.keyActionBox = this.createPriceKey( );
		this.ratingElement.appendChild(this.keyActionBox);
		setCssOpacity(this.keyActionBox,0);
		this.keyActionBox.style.visibility = 'visible';
        if(this.dynPos){
            var newTop, newLeft;
            newTop = this.ratingElement.offsetTop+17;
            newLeft = this.ratingElement.offsetLeft>105 ? this.ratingElement.offsetLeft-105 : this.ratingElement.offsetLeft + 40;
            this.keyActionBox.style.top = newTop + 'px';
            this.keyActionBox.style.left = newLeft + 'px';
        }
        var keyAncestors = getAncestors(this.keyActionBox);
        for(var i=0; i<keyAncestors.length; i++)
            keyAncestors[i].style.zIndex = '1000';
		fade(this.keyActionBox, 5);
	}
	PriceRatingItem.prototype.hideKey = function( ){
        if(!this.keyActionBox) return 
        var keyAncestors = getAncestors(this.keyActionBox);
        for(var i=0; i<keyAncestors.length; i++)
            keyAncestors[i].style.zIndex = '';
        this.ratingElement.removeChild(this.keyActionBox);
		delete this.keyActionBox;
	}
	PriceRatingItem.prototype.createPriceKey = function( ){
		if(this.keyActionBox) return;
		var actionBox = document.createElement('DIV');
		actionBox.className = 'priceKey actionBox';
		var actionHeadline = document.createElement('H6');
		actionHeadline.innerHTML = 'Price Key';
		var keyList = document.createElement('DIV');
		keyList.className = 'actionBoxContent';
		keyList.innerHTML = priceKeyText;
		actionBox.appendChild(actionHeadline);
		actionBox.appendChild(keyList);
		return actionBox;
	}
    var priceKeyText = 
        '<p>$<span class="off">$$$</span> = <strong>$199 or less</strong></p>' +
		'<p>$$<span class="off">$$</span> = <strong>$200 to $299</strong></p>' + 
		'<p>$$$<span class="off">$</span> = <strong>$300 to $399</strong></p>' + 
		'<p>$$$$ = <strong>$400 or more</strong></p>'
    /**************************************/
	function instantiatePriceRatingItems( ){
		var costRatingEls = getElements('costRating','DIV',null);
		for(var i=0; i<costRatingEls.length; i++)
			new PriceRatingItem({ratingElement: costRatingEls[i]});
	}
	runOnLoad(instantiatePriceRatingItems);
/************************************************************************************************************/

/************************************************************************************************************/

/*	Expandable Units
	---------------- */
	function expandableUnit(args){
		this.unitEl = args.unitEl;
		this.isExpanded = this.getInitialState( ); //default is collapsed, classname of expanded asserts initial open state
		this.init( );
	}
	expandableUnit.prototype.init = function( ){
		var expandableUnit = this;
		this.knob = getElements('knob', null, this.unitEl)[0];
		this.knob.onclick = function(event){expandableUnit.switchState(event)}
	}
    expandableUnit.prototype.getInitialState = function( ){
        if(this.unitEl.className.match("expanded") ) return true;
        if(this.unitEl.className.match("collapsed") ) return false;
        this.unitEl.className += " collapsed";
        return false;
    }
	expandableUnit.prototype.switchState = function(event){
		this.isExpanded ? this.collapse( ) : this.expand( );
	}
	expandableUnit.prototype.expand = function( ){
        this.unitEl.className = this.unitEl.className.replace(/collapsed/, "expanded")
		this.isExpanded = true;
	}
	expandableUnit.prototype.collapse = function( ){
		this.unitEl.className = this.unitEl.className.replace(/expanded/, "collapsed")
		this.isExpanded = false;
	}
	
	/*************************************/
	function instantiateExpandableUnits( ){
		var expanders = getElements('expandable','DIV',null);
		for(var i=0; i<expanders.length; i++)
			new expandableUnit({
                unitEl: expanders[i]
            });
	}
	runOnLoad(instantiateExpandableUnits);


