//poolPanel.js
//requires sniff.js

//Create a global variable with the z-index of the topmost panel
topPanel = 100;

//Create a global panel manager
panelManager = new Array();

//Create a manager for one-off panels
singlePanelManager = new Array();

function PoolPanel(){
	//This just creates a blank panel.
	//PoolPanel should have 3 args:
	//	title: string for the title (required)
	//	top: top of the panel, in px (def is 50)		DEPRECATED--this may still exist, but is ignored
	//	left: left of the panel, in px (def is 50)		DEPRECATED--this may still exist, but is ignored

	//initialize stage (move this later)
	ppStage = document.getElementById('stage');
	
	//Check args
	if(arguments.length==0){
		alert('PoolPanel construction failed: 0 args passed');
		return false;
	}
	
	var titleText = arguments[0];
	
	//Container for the entire panel
	this.panelHandle = document.createElement('div');
	this.panelHandle.className = 'poolPanel';
	panelTop = ((topPanel % 7) * 25) + 100;
	panelLeft = ((topPanel % 7) * 25) + 100;
	this.panelHandle.style.top = panelTop + 'px';
	this.panelHandle.style.left = panelLeft + 'px';
	//Manually add the z-index so it is available in javascript
	this.panelHandle.style.zIndex = ++topPanel;
	
	//Add id and send to panel manager
	this.panelHandle.panelId = topPanel;
	panelManager[topPanel] = this.panelHandle;
	this.panelHandle.panel = this;
	
	//Add top and bottom rounded corners 'cause they're pretty.
	var rowClasses = ['panelTitleOutline panelCorner1', 'panelTitleBG panelCorner2', 'panelTitleBG panelCorner3', 'panelTitleBG panelCorner4'];
	
	var topCorners = document.createElement('div');
	topCorners.className = 'panelTop';
	for(var i=0; i<=3; i++){
		var cornerRow = document.createElement('span');
		cornerRow.className = rowClasses[i];
		topCorners.appendChild(cornerRow);
	}
	
	var bottomCorners = document.createElement('div');
	bottomCorners.className = 'panelBottom';
	for(var i=3; i>=0; i--){
		var cornerRow = document.createElement('span');
		cornerRow.className = rowClasses[i];
		bottomCorners.appendChild(cornerRow);
	}
	
	this.panelHandle.appendChild(topCorners);
	this.panelHandle.appendChild(bottomCorners);
	
	//Add titlebar
	var titleBG = document.createElement('div');
	titleBG.className = 'panelTitleBG panelTitle';
	this.panelHandle.appendChild(titleBG);
	
	this.panelTitle = document.createElement('div');
	this.panelTitle.innerHTML = titleText;
	this.panelTitle.className = 'panelTitleText';
	//include references necessary for dragging
	//See methods section for drag functions
	makeDraggable(this.panelHandle, this.panelTitle);
	this.panelHandle.appendChild(this.panelTitle);	
	
	var titleControls = document.createElement('div');
	titleControls.innerHTML = '<a href="javascript:topMenu.newDockedPanel('+this.panelHandle.panelId+')">&#8211;</a> <a href="javascript:closePanel('+this.panelHandle.panelId+')">X</a>';
	titleControls.className = 'panelTitleControls';	
	this.panelHandle.titleControls = titleControls;
	this.panelHandle.appendChild(titleControls);	
	
	//Add content area
	var contentBG = document.createElement('div');
	contentBG.className = 'panelBG panelContent';
	this.panelHandle.appendChild(contentBG);
	
	this.panelContent = document.createElement('div');
	this.panelContent.className = 'panelContentArea';
	this.panelHandle.appendChild(this.panelContent);
	this.panelHandle.panelContent = this.panelContent;
	
	document.body.appendChild(this.panelHandle);
	
	//Standard Methods
}

function closePanel(panelId){
	panelManager[panelId].style.display='none';
	if(defined(panelManager[panelId].json)){
		//This is an artifact panel that was probably registered in the state manager.  Remove it.
		for(var i=workingBasin.state.panels.length - 1; i>=0; i--){
			var state = workingBasin.state.panels[i];
			//using a switch here screws up my break statements in IE, so I'm going with if/else...
			if(state[0] == 'art' && panelManager[panelId].panelType == 'art'){
				var json = panelManager[panelId].json.project; 
				if(state[0] == json.pool_type && state[1] == json.id){
					workingBasin.state.panels.splice(i, 1);
					break;
				}
			}
			else if (state[0] == 'person' && panelManager[panelId].panelType == 'person'){
				var json = panelManager[panelId].json.person;
				if(state[0] == 'person' && state[1] == json.id){
					workingBasin.state.panels.splice(i, 1);
					break;
				}
			}
			else if (state[0] == 'code' && panelManager[panelId].panelType == 'code'){
				var json = panelManager[panelId].json.project;
				if(state[0] == json.pool_type && state[1] == json.id){
					workingBasin.state.panels.splice(i, 1);
					break;	
				}	
			}
			else if (state[0] == 'artreference' && panelManager[panelId].panelType == 'artreference'){
				var json = panelManager[panelId].json.reference;
				if(state[0] == json.pool_type && state[1] == json.id){
					workingBasin.state.panels.splice(i, 1);
					break;	
				}	
			}
			else if (state[0] == 'codereference' && panelManager[panelId].panelType == 'codereference'){
				var json = panelManager[panelId].json.reference;
				if(state[0] == json.pool_type && state[1] == json.id){
					workingBasin.state.panels.splice(i, 1);
					break;	
				}	
			}
		}
		ProtoHistoryObj.savePool(workingBasin.state);
	}
}

function tabSet(tabNames, isForm){
	//tabNames is an array of the text that should go on tab labels
	//Note that this function only creates empty pages--to fill the pages, insert content into tabSet.content[tabName]
	//isForm is optional.  If it exists, the tabset will be created as a form
	
	if(arguments.length == 2){
		this.tabBox = document.createElement('form');
		this.tabBox.onsubmit = ajax.parseForm;
	} else {
		this.tabBox = document.createElement('div');
	}		
	this.tabBox.className = 'panelTabBox';
	this.tabBox.tabs = {};
	this.tabBox.content = {};
	
	this.tabRow = document.createElement('div');
	this.tabRow.className = 'panelTabRow panelTabRowColor';
	this.tabBox.appendChild(this.tabRow);
	
	for(var i=0; i<tabNames.length; i++){
		//build the tab
		var leftSlant = document.createElement('div');
		leftSlant.className = 'panelTabSlant panelTabLeftColor';
		this.tabRow.appendChild(leftSlant);
		
		this.tabBox.tabs[tabNames[i]] = document.createElement('div');
		this.tabBox.tabs[tabNames[i]].className = 'panelTab panelTabColor';
		this.tabBox.tabs[tabNames[i]].appendChild(document.createTextNode(tabNames[i]));
		this.tabBox.tabs[tabNames[i]].tabBox = this.tabBox;
		this.tabRow.appendChild(this.tabBox.tabs[tabNames[i]]);
		
		var rightSlant = document.createElement('div');
		rightSlant.className = 'panelTabSlant panelTabRightColor';
		this.tabRow.appendChild(rightSlant);
		
		//build the content area
		this.tabBox.content[tabNames[i]] = document.createElement('div');
		this.tabBox.content[tabNames[i]].className = 'panelTabContent panelTabContentColor';
		this.tabBox.tabs[tabNames[i]].contentArea = this.tabBox.content[tabNames[i]];
		this.tabBox.appendChild(this.tabBox.content[tabNames[i]]);
		
		//add the function to change tabs
		this.swapTabs = function(e){
			var tab = browsers.getTargetElement(e);
			for(tabID in tab.tabBox.content) tab.tabBox.content[tabID].style.display = 'none';
			tab.contentArea.style.display = 'block';
			for(tabID in tab.tabBox.tabs) tab.tabBox.tabs[tabID].style.fontWeight = 'normal';
			tab.style.fontWeight = 'bold';
		}
		browsers.addEventListener('mouseup', this.tabBox.tabs[tabNames[i]], this.swapTabs, false);
	}
	
	//set the first tab contents to be visible
	this.tabBox.content[tabNames[0]].style.display = 'block';
	this.tabBox.tabs[tabNames[0]].style.fontWeight = 'bold';
}

makeDraggable = function(draggedDiv, targetDiv){
//draggedDiv is the actual div which is being moved
//targetDiv is the div which must be dragged and the target for mouse events
	draggedDiv.mouseOffset = {x:0,y:0};
	targetDiv.dragOn = function(e){
		draggedDiv.style.zIndex = ++topPanel;
		draggedDiv.mouseOffset = browsers.mousePosition(e);
		draggedDiv.originalLocation = { left: parseInt(browsers.calculatedStyle(draggedDiv, "left")),
										top: parseInt(browsers.calculatedStyle(draggedDiv, "top"))};
		browsers.addEventListener("mousemove", document, targetDiv.drag, false); 
		browsers.addEventListener("mouseup", document, targetDiv.dragOff, false);
		return false;
	}
	targetDiv.dragOff = function(){
		browsers.removeEventListener("mousemove", document, targetDiv.drag, false);
		browsers.removeEventListener("mouseup", document, targetDiv.dragOff, false);
		return false;
	}
	targetDiv.drag = function(e){
		var mousePosition = browsers.mousePosition(e);
		var newTop = (mousePosition.y - draggedDiv.mouseOffset.y) + draggedDiv.originalLocation.top;
		var newLeft = (mousePosition.x - draggedDiv.mouseOffset.x) + draggedDiv.originalLocation.left;
		draggedDiv.style.top = newTop+"px";
		draggedDiv.style.left = newLeft+"px";
		return false;
	}
	browsers.addEventListener("mousedown", targetDiv, targetDiv.dragOn, false);
	
}

function GenericPanel(titleText, content, panelName){
	if(defined(singlePanelManager[panelName])){
		singlePanelManager[panelName].panelHandle.style.display = 'block';
		singlePanelManager[panelName].panelHandle.style.zIndex = ++topPanel;
		return false;
	} else {
		var panel = new PoolPanel(titleText, 200, 500);
		panel.panelContent.innerHTML = content;
		singlePanelManager[panelName] = panel;
		if(titleText == 'Login') panel.panelHandle.className = 'personPanel';
		return panel;
	}
}

WrapPanel = function(interceptedFish){
	var panel = new GenericPanel('Welcome', panelContent.clickwrap, 'clickwrapPanel');
	if(!defined(panel.panelContent)) return false;	
	panel.panelHandle.className = 'personPanel clickwrap';
	
	panel.panelHandle.agree = function(){
		topMenu.agreed = true;
		ajax.get(siteBaseDir+'ajaxHandlers/clickwrap.js.php', {}, function(){return});	
		panel.panelHandle.style.display = 'none';
		interceptedFish.launchPanel();
	}
	
	return panel;
}

GraphPanel = function(poolType, hide){
	//Panel used to change the settings of the graph   GenericPanel(titleText, content, panelName)
	var panel = new GenericPanel('Graph Settings', '', 'graphControlPanel');
	if(!defined(panel.panelContent)) return false;
	var contentDiv = new tabSet(['axes', 'scope']);
	contentDiv.tabBox.style.display = 'block';
	panel.panelContent.appendChild(contentDiv.tabBox);
	panel.panelHandle.tabBox = contentDiv.tabBox;	
	panel.panelHandle.className = 'personPanel';
	
	
	//Load the controls page
	contentDiv.tabBox.content['axes'].innerHTML = panelContent.graph_axes;
	
	//Add the valid axes
	var axes = new Array();
	
	switch(poolType){
		case 'art':	axes = {'rating': 'Overall Approval', 
							'basis': 'Overall Recognition', 
							'cardinality': 'Project Development', 
							'subratings.conceptual.rating': 'Conceptual Approval', 
							'subratings.conceptual.basis': 'Conceptual Recognition', 
							'subratings.perceptual.rating': 'Perceptual Approval', 
							'subratings.perceptual.basis': 'Perceptual Recognition', 
							'subratings.technical.rating': 'Technical Approval', 
							'subratings.technical.basis': 'Technical Recognition',
							'relations': 'Number of Relationships',	
							'contributor_count': 'Number of Contributors',
							'lm_unix': 'Date'};
								var defaultZ = 'Project Development';							
		break;
		case 'code': axes = {'rating': 'Overall Approval', 
							'basis': 'Overall Recognition', 
							'cardinality': 'Project Development', 
							'subratings.conceptual.rating': 'Conceptual Approval', 
							'subratings.conceptual.basis': 'Conceptual Recognition', 
							'subratings.utility.rating': 'Utility Approval', 
							'subratings.utility.basis': 'Utility Recognition', 
							'subratings.technical.rating': 'Technical Approval', 
							'subratings.technical.basis': 'Technical Recognition',
							'relations': 'Number of Relationships',
							'contributor_count': 'Number of Contributors',
							'lm_unix': 'Date'};
								var defaultZ = 'Project Development';
		break;
		case 'artreference':	axes = {'rating': 'Overall Approval', 
							'basis': 'Overall Recognition', 
							'relations': 'Number of Relationships',
							'subratings.conceptual.rating': 'Conceptual Approval', 
							'subratings.conceptual.basis': 'Conceptual Recognition', 
							'subratings.perceptual.rating': 'Perceptual Approval', 
							'subratings.perceptual.basis': 'Perceptual Recognition', 
							'subratings.technical.rating': 'Technical Approval', 
							'subratings.technical.basis': 'Technical Recognition',
							'lm_unix': 'Date'};		
								var defaultZ = 'Number of Relationships';					
		break;
		case 'codereference':	axes = {'rating': 'Overall Approval', 
							'basis': 'Overall Recognition', 
							'relations': 'Number of Relationships',
							'subratings.conceptual.rating': 'Conceptual Approval', 
							'subratings.conceptual.basis': 'Conceptual Recognition', 
							'subratings.utility.rating': 'Utility Approval', 
							'subratings.utility.basis': 'Utility Recognition', 
							'subratings.technical.rating': 'Technical Approval', 
							'subratings.technical.basis': 'Technical Recognition',
							'lm_unix': 'Date'};	
								var defaultZ = 'Number of Relationships';						
		break;
		default: '';
	}
	
	var xSelect = insertXMLSelectWidget(contentDiv.tabBox.content['axes'], 'ppXAxisSelect', 'xAxisSelect', axes, 'Overall Recognition');
	var ySelect = insertXMLSelectWidget(contentDiv.tabBox.content['axes'], 'ppYAxisSelect', 'yAxisSelect', axes, 'Overall Approval');
	
	var zSelect = insertXMLSelectWidget(contentDiv.tabBox.content['axes'], 'ppZAxisSelect', 'zAxisSelect', axes, defaultZ);			
	
	insertXMLMouseUp(contentDiv.tabBox.content['axes'], 'ppChangeAxes', 'GraphPanel.changeAxes()');
	
	//This is a semi-temporary hack until the menubar is rewritten to reflect the Pool3 interface changes
	var xSlider = topMenu.newSlider("x", 11, workingBasin.state.axes.xAcc,"sliderHandler();", {	top: 0,
																	left: 0,
																	width: 275,
																	height: 10});
	var ySlider = topMenu.newSlider("y", 11, workingBasin.state.axes.xAcc,"sliderHandler();", {	top: 0,
																	left: 0,
																	width: 275,
																	height: 10});
	var zSlider = topMenu.newSlider("z", 11, workingBasin.state.axes.xAcc,"sliderHandler();", {	top: 0,
																	left: 0,
																	width: 275,
																	height: 10});
																												
	insertXMLTagChild(contentDiv.tabBox.content['axes'], 'ppXAxisAccuracy', xSlider.element);
	insertXMLTagChild(contentDiv.tabBox.content['axes'], 'ppYAxisAccuracy', ySlider.element);
	insertXMLTagChild(contentDiv.tabBox.content['axes'], 'ppZAxisAccuracy', zSlider.element);
	
	//Load the scope page
	contentDiv.tabBox.content['scope'].innerHTML = panelContent.graph_scope;
	for(var i=0; i<document.forms.length; i++) if(document.forms[i].id == 'ScopeSelect') var scopeForm = document.forms[i];
	for(var i=0; i<scopeForm.length; i++){
		if(scopeForm[i].value == '200' && Fishes.length <= 200) scopeForm[i].checked = true;
		if(scopeForm[i].value == 'all' && Fishes.length > 200) scopeForm[i].checked = true;	
	}
	insertXMLMouseUp(contentDiv.tabBox.content['scope'], 'ppSetScope', 'GraphPanel.setScope()');	
	
	if(hide==true){
		panel.panelHandle.style.display = 'none';	
	}
	
	return panel;
}

GraphPanel.setScope = function(){
	//Adds a scope get variable to the current pool URL and reloads the page
	
	//Read the form
	for(var i=0; i<document.forms.length; i++) if(document.forms[i].id == 'ScopeSelect') var scopeForm = document.forms[i];
	for(var i=0; i<scopeForm.length; i++) if(scopeForm[i].checked == true) var newScope = scopeForm[i].value;
	
	//Break down the current URL and rebuild it.
	var currentURL = document.location.href;
	
	if(currentURL.indexOf('#') != -1){
		var locArray = currentURL.split('#');
		var loc = locArray[0];
		var hash = locArray[1];	
	} else {
		var loc = currentURL;
		var hash = '';	
	}
	if(loc.indexOf('?') != -1){
		var getStr = loc.split('?')[1];
		loc = loc.split('?')[0];
		var getArray = getStr.split('&');
		for(var i=getArray.length - 1; i>=0; i--){
			var getName = getArray[i].split('=')[0];
			if(getName == 'scope') 	getArray.splice(i, 1);
		}
		getArray.push('scope='+newScope);
		getStr = getArray.join('&');
	} else {
		var getStr = 'scope='+newScope;	
	}
	
	var newURL = loc + '?' + getStr;
	if(hash != '') newURL += '#' + hash;
	
	document.location.href = newURL;
}

GraphPanel.changeAxes = function(xValue, yValue, zValue){
	//Changes the axes of the graph based on what's in the AxesSelect form, unless they are passed
	//In that case, synch the form with the passed values

	for(var i=0; i<document.forms.length; i++) if(document.forms[i].id == 'AxesSelect') var axesForm = document.forms[i];
	var newAxes = {x: '', y: '', z: ''};
	for(var i=0; i<axesForm.length; i++){
		if(axesForm[i].name == 'xAxisSelect') var xAxis = axesForm[i];
		if(axesForm[i].name == 'yAxisSelect') var yAxis = axesForm[i];
		if(axesForm[i].name == 'zAxisSelect') var zAxis = axesForm[i];	
	}
	if(arguments.length > 0) {
		//synch the form with the passed values
		for(var i=0; i<xAxis.length; i++){
			if(xAxis[i].value == xValue){
				xAxis.selectedIndex = i;
				break;
			}
		}
		for(var i=0; i<yAxis.length; i++){
			if(yAxis[i].value == yValue){
				yAxis.selectedIndex = i;
				break;
			}
		}
		for(var i=0; i<zAxis.length; i++){
			if(zAxis[i].value == zValue){
				zAxis.selectedIndex = i;
				break;
			}
		}
	}
//
//	var xAxis = axesForm.xAxisSelect;
//	var yAxis = axesForm.yAxisSelect;
//	var zAxis = axesForm.zAxisSelect;
	
	//alert(axesForm.xAxisSelect);
	
	workingBasin.moveFishes(xAxis[xAxis.selectedIndex].value, yAxis[yAxis.selectedIndex].value, zAxis[zAxis.selectedIndex].value);
	var xAxisLabel = xAxis[xAxis.selectedIndex].innerHTML;
	var xMinLabel = 'Low';
	var xMaxLabel = 'High';
	var yMinArray = new Array('L', 'o', 'w');
	var yMaxArray = new Array('H', 'i', 'g', 'h');
	if(xAxis[xAxis.selectedIndex].value == 'lm_unix'){
		xMinLabel = workingBasin.minDate;
		xMaxLabel = workingBasin.maxDate;
	}
	if(yAxis[yAxis.selectedIndex].value == 'lm_unix'){
		yMinArray = new Array();
		yMaxArray = new Array();
		for(var i=0; i<workingBasin.minDate.length; i++) yMinArray.push(workingBasin.minDate.charAt(i));
		for(var i=0; i<workingBasin.maxDate.length; i++) yMaxArray.push(workingBasin.maxDate.charAt(i));
	}
	yMinLabel = yMinArray.join('<br />');
	yMaxLabel = yMaxArray.join('<br />');
	var yAxisText = yAxis[yAxis.selectedIndex].innerHTML;
	var yAxisArray = new Array();
	for(var i=0; i<yAxisText.length; i++) yAxisArray.push(yAxisText.charAt(i));
	var yAxisLabel = yAxisArray.join('<br />');
	document.getElementById('xAxisLabel').innerHTML = xAxisLabel;
	document.getElementById('yAxisLabel').innerHTML = yAxisLabel;
	document.getElementById('xAxisMin').innerHTML = xMinLabel;
	document.getElementById('yAxisMin').innerHTML = yMinLabel;
	document.getElementById('xAxisMax').innerHTML = xMaxLabel;
	document.getElementById('yAxisMax').innerHTML = yMaxLabel;
	workingBasin.setActive();
}

function RelationPanel(projectPanelId, subjectID, subjectType, subjectTitle){
	//Panel used to input relationships
	if(!browsers.readCookie('poolauth')){
		alert('You must be logged in to add a relation.');
		return false;
	}
	
	var panel = new PoolPanel('Add Relationship to '+subjectTitle.substr(0,20));
	
	if(subjectType.indexOf('code') != -1) panel.panelHandle.className += ' codePanel';
	
	var contentDiv = new tabSet(['relationship', 'related to', 'description', 'submit'], true);
	contentDiv.tabBox.style.display = 'block';
	panel.panelContent.appendChild(contentDiv.tabBox);
	panel.panelHandle.tabBox = contentDiv.tabBox;
	panel.panelHandle.titleControls.innerHTML = '<a href="walkthrough/#relation-type" target="_blank">?</a> '+panel.panelHandle.titleControls.innerHTML;

	panel.relationPhrase = document.createElement('div');
	panel.relationPhrase.innerHTML = panelContent.relation_phrase;
	panel.relationPhrase.className = 'ppRelationPhrase panelOutlineFG';
	insertXMLTagData(panel.relationPhrase, 'ppSubject', subjectTitle);
	panel.panelContent.appendChild(panel.relationPhrase);
	
	//assign templates
	contentDiv.tabBox.content['description'].innerHTML = panelContent.relation_description;
	contentDiv.tabBox.content['relationship'].innerHTML = panelContent.relation_relationship;
	contentDiv.tabBox.content['related to'].innerHTML = panelContent.relation_predicate;
	contentDiv.tabBox.content['submit'].innerHTML = panelContent.relation_submit;
	
	//fill in the hidden fields
	var hiddenFields = '<input type="hidden" name="panelId" value="'+panel.panelHandle.panelId+'">';
	hiddenFields += '<input type="hidden" name="projectPanelId" value="'+projectPanelId+'">';
	hiddenFields += '<input type="hidden" name="subject" value="'+subjectID+'_'+subjectType+'">';
	hiddenFields += '<input type="hidden" name="target" value="'+siteBaseDir+'ajaxHandlers/relationship_handler.js.php">';
	insertXMLTagData(contentDiv.tabBox.content['submit'], 'ppHidden', hiddenFields);
	
	panel.relationTitleSearch = function(title, panelId){
	//Does a title search.  This function should be called on keyup from within a text field in a panel.  It assumes that the text field has .panelId attached to it.
	//If title and panelId exist, that means this function is being called from a timeout.  (This is necessary because the ajax port may be busy when the initial keyup fires from the form field)

		if(arguments.length < 2){
		//this means the search is being called directly from the form element.
			if(this.value.length != 3) return false;
			var title = this.value;
			var panelId = this.panelId;
		}

		var responseHandler = function(ajaxData){
			eval(ajaxData);
		}
		if(ajax.port.readyState == 0 || ajax.port.readyState == 4){
			ajax.get(siteBaseDir+'ajaxHandlers/title_search.js.php', {title: title, panelId: panelId}, responseHandler);
		} else setTimeout('panelManager["'+panelId+'"].panel.relationTitleSearch("'+title+'", "'+panelId+'")', 100);
	}
	
	panel.updatePhrase = function(panelId){
	//Updates the phrasebox at the bottom of the relationship panel
	//if panelId exists, this function is being called outside the context of the panel and thus should be found via the panelManager
	
		if(arguments.length==0 || typeof(panelId) == 'object'){
		//need to check both since IE doesn't send e as an argument
			var panel = this.panel;
		} else {
			var panel = panelManager[panelId].panel;
		}

		var relationshipField = panel.panelHandle.tabBox.relationship;
		var predicateField = panel.panelHandle.tabBox.predicate;

		if(relationshipField.value == ''){
			var relationshipPhrase = '???';
		} else {
			var options = relationshipField.getElementsByTagName('option');
			for(var i=0; i<options.length; i++){
				if(options[i].selected == true) var relationshipPhrase = options[i].innerHTML;
			}
		}
		
		if(predicateField.value == ''){
			var predicatePhrase = '???';
		} else {
			var options = predicateField.getElementsByTagName('option');
			for(var i=0; i<options.length; i++){
				if(options[i].selected == true) var predicatePhrase = options[i].innerHTML;
			}
		}
		
		insertXMLTagData(panel.relationPhrase, 'ppRelationship', relationshipPhrase);
		insertXMLTagData(panel.relationPhrase, 'ppPredicate', predicatePhrase);
		
	}
	
	//Set up the title search box for predicates
	contentDiv.tabBox.predicate.panel = panel;
	contentDiv.tabBox.relationship.panel = panel;
	contentDiv.tabBox.relationship.onchange = panel.updatePhrase;
	contentDiv.tabBox.predicate.onchange = panel.updatePhrase;
	contentDiv.tabBox.predicateSearch.panelId = panel.panelHandle.panelId;
	contentDiv.tabBox.predicateSearch.onkeyup = panel.relationTitleSearch;
	
	return panel;
}

function ArtifactPanel(titleText){
	var panel = new PoolPanel(titleText, 150, 150);
		
	var treePane = document.createElement('div');
	treePane.className = 'artifactPanelTreePane panelOutlineFG';
	panel.panelHandle.appendChild(treePane);
	
	var contentPane = document.createElement('div');
	contentPane.className = 'artifactPanelContentPane';
	panel.panelContent.appendChild(contentPane);
	
	//Methods
	panel.loadData = function(dataArray){
		switch(dataArray.project.pool_type){
			case 'art':	ArtPanel.loadPanel(panel, treePane, contentPane, dataArray);	break;
			case 'code': CodePanel.loadPanel(panel, treePane, contentPane, dataArray);	break;
			default: ;
		}
	}
	
	return panel;
}

function ReferencePanel(titleText){
	var panel = new PoolPanel(titleText);
	panel.loadData = function(dataArray){
		switch(dataArray.reference.pool_type){
			//case 'artreference': ArtReferencePanel.loadPanel(panel, panel.panelContent, dataArray);	break;
			case 'artreference':  Loader.require('artReferencePanel', 'ArtReferencePanel.loadPanel', [panel, panel.panelContent, dataArray]); break;
			case 'codereference': Loader.require('codeReferencePanel', 'CodeReferencePanel.loadPanel', [panel, panel.panelContent, dataArray]); break;
			default: ;	
		}	
	}
	return panel
}

function poolDateTransform(dateString){
	//Transforms a date string in the format YYYY-MM-DD to MM/DD/YYYY
	var year = dateString.substr(0,4);
	var month = dateString.substr(5,2);
	var day = dateString.substr(8,2);
	return month.toString() + "/" + day.toString() + "/" + year.toString();
}

function insertXMLTagData(parentDiv, xmlTag, data){
//It's not really xml any more because mozilla is bugged...it is replace a span with the class xmlTag
	var spans = parentDiv.getElementsByTagName('span');
	for(var i=0; i<spans.length; i++){
		if(spans[i].className == xmlTag){
			spans[i].innerHTML = nl2br(data);
			return 0;
		}
	}
}

function insertXMLTagChild(parentDiv, xmlTag, childDiv){
//Does an insert the DOM way rather than as innerHTML
	var spans = parentDiv.getElementsByTagName('span');
	for(var i=0; i<spans.length; i++){
		if(spans[i].className == xmlTag){
			spans[i].appendChild(childDiv);
			return 0;
		}
	}	
}

function insertXMLSrc(parentDiv, xmlTag, src){
//Same as insertXMLTagData, but it sets the src of an img
	var obj = parentDiv.getElementsByTagName('img');
	for(var i=0; i<obj.length; i++){
		if(obj[i].className == xmlTag){
			obj[i].src = src;
		}
	}
}

function insertXMLMouseUp(parentDiv, xmlTag, evalFunc){
//Adds a mouseup function to the specified xml tag
	var obj = parentDiv.getElementsByTagName('span');
	for(var i=0; i<obj.length; i++){
		if(obj[i].className == xmlTag){
			obj[i].onmouseup = xmlMouseUpHandler;
			obj[i].mouseUpFunction = evalFunc;
		}
	}
}

function xmlMouseUpHandler(){
	eval(this.mouseUpFunction);
}

function loadFragmentToStage(fragName){
//Loads a fragment to the stage
	var tempNode = document.createElement('div');
	ppStage.innerHTML = '';
	ppStage.appendChild(tempNode);
	tempNode.innerHTML = panelContent[fragName];
	return tempNode;
}

function insertXMLTagDataFragment(xmlTag, data, divNode){
//Loads the specified data into the staged fragment
	var spans = divNode.getElementsByTagName('span');
	for(var i=0; i<spans.length; i++){
		if(spans[i].className == xmlTag){
			spans[i].innerHTML = nl2br(data);
			return 0;
		}	
	}
	//alert('Attempt to load '+data+' into staged fragment '+xmlTag+' failed.');
	return 1;
}

function insertXMLSelectWidget(parentDiv, xmlTag, widgetName, data, defaultSelection){
//Creates a select widget in xmlTag and adds options from data
//data is an assoc array with value: optionText
//Note that this is appended to xmlTag, not replaced
	var spans = parentDiv.getElementsByTagName('span');
	var selectBoxes = new Array();
	for(var i=0; i<spans.length; i++){
		if(spans[i].className == xmlTag){
			var selectBox = document.createElement('select');
			selectBox.name = widgetName;
			selectBox.id = widgetName;
			selectBox.style.width = '200px';
			for(option in data){
				if(data[option] != null){
					var selectOption = document.createElement('option');
					selectOption.value = option;
					if(defined(defaultSelection) && defaultSelection == data[option]) selectOption.selected = true;
					selectOption.innerHTML = data[option];
					selectBox.appendChild(selectOption);
				}
			}
			spans[i].appendChild(selectBox);
			selectBoxes.push(selectBox);
		}
	}
	return selectBoxes;
}

function getFragment(){
//returns the currently staged fragment
	return ppStage.innerHTML;
}

function nl2br(nlString){
//Converts \n to <br />
	var tempString = new String(nlString);
	return tempString.replace(/\n/g, '&nbsp; <br />');
}

function genericToggle(divTag){
	var parentNode = divTag.parentNode;
	
	var siblings = parentNode.getElementsByTagName('div');
	for(var i=0; i<siblings.length; i++){
		if(siblings[i].className == 'collapsed'){
			if(siblings[i].style.display == 'block'){
				siblings[i].style.display = 'none';
				divTag.className = 'dropArrowCollapsed';
			} else {
				siblings[i].style.display = 'block';
				divTag.className = 'dropArrowExpanded';
			}
			return 0;
		}
	}
}

function openThumbUpload(id, thumb_type, panelID){
	window.open("image_upload.php?id="+id+"&thumb_type="+thumb_type+"&panel_id="+panelID, "", "location=no,menubar=no,resizable=no,height=200,width=350");
}