// checkFormInput: does some basic input validation
// on the Collections Search form criteria entered by the user
function checkFormInput(form, errorPopup){

	// loop through all input elements, trim, and check for empty values
	var inputs = $(form).getElementsByTagName('input');
	var allInputsEmpty = true;
	for (var i = 0; i < inputs.length; i++)
	{
		// Trim function is defined in form_validation.js, a standard dotCMS file.
		// it's included in the Search Results template.		
		var trimmedInput = Trim(inputs[i].value);
		inputs[i].value = trimmedInput;
		// don't include checkboxes in this test
	 	if (inputs[i].value.length > 0 && !inputs[i].type.match('checkbox') && !inputs[i].type.match('hidden'))
		{
			allInputsEmpty = false;
		}
	}

	// TEMP alert box for testing
	//alert("allInputsEmpty: " + allInputsEmpty);

	// the form has two date fields with class 'date'
	// check that if one is non-empty, that the other is non-empty
	// 03.19.09: Now allow startDate without endDate, and treat as single date search
	var startDate = document.getElementById('startDate');
	var endDate = document.getElementById('endDate');
	var startDateBC = document.getElementById('startDateBC');
	var endDateBC = document.getElementById('endDateBC');

	// grab the correct elements depending on which form we're dealing with
	if ($(form).id.match(document.getElementById('collectionsSearchFrm1').id))
	{
		startDate = document.getElementById('startDate1');
		endDate = document.getElementById('endDate1');
		startDateBC = document.getElementById('startDateBC1');
		endDateBC = document.getElementById('endDateBC1');
	}

	var startDateMissing = false;
	var endDateMissing = false;

	// 03.19.09: Now allow startDate without endDate, and treat as single date search
	if (startDate.value.length > 0 && endDate.value.length == 0)
	{
		//endDateMissing = true;
		endDate.value = startDate.value;
		if (startDateBC.checked == true)
			endDateBC.checked = true;
		else
			endDateBC.checked = false;
	}
	else if (startDate.value.length == 0 && endDate.value.length > 0)
	{
		startDateMissing = true;
	}

	// our dates should be 4 (or fewer) digit years
	// set all flags to true - if both dates aren't present, we won't test
	// otherwise, we'll detect false values and present a message
	var isStartDateNumber = true;
	var isEndDateNumber = true;
	var isDateRangeValid = true;

	if (startDate.value.length > 0 && endDate.value.length > 0)
       	{
		// validate dates are numerical
		// using the Number function because this detects non-digit
		// characters whereas parseInt ignores them & anything after.
		var startDateStr = Number(startDate.value).toString();
		var endDateStr = Number(endDate.value).toString();

		if (startDateStr.match("NaN"))
		{
			isStartDateNumber = false;
		}
		if (endDateStr.match("NaN"))
		{
			isEndDateNumber = false;
		}

		if (isStartDateNumber && isEndDateNumber)
		{
			// validate the date range is OK
			var startYear = parseInt(startDate.value);
			var endYear = parseInt(endDate.value);

			// this is more complicated when we evaluate the BC flags
		 	/* orig:
			if (startYear > endYear)
			{
				isDateRangeValid = false;
			}
			*/
			// if BC was checked only for endDate, that's an error
			if (startDateBC.checked == false && endDateBC.checked == true)
			{
				isDateRangeValid = false;
			}
			else if (startDateBC.checked == true)
			{
				// then it's OK if the endDate happens to be less than 
				// the start date, regardless of whether endDateBC
				// is checked.  however, it's not OK if endDateBC
				// is checked and endDateBC > startDateBC.
				if (endDateBC.checked == true && endYear > startYear)
				{
					isDateRangeValid = false;
				}
			}
			else if (startYear > endYear)
			{
				isDateRangeValid = false;
			}
		}
	}
	

	// loop through all select elements and check for empty values
	var selects = $(form).getElementsByTagName('select');
	var allSelectsEmpty = true;
	for (var j = 0; j < selects.length; j++)
	{
		if (selects[j].value.length > 0)
		{
			allSelectsEmpty = false;
			break;
		}
	}

	//alert("allSelectsEmpty: " + allSelectsEmpty);

	// combine the results of the input and select empty tests
	// and set the 'searchErrors' p element accordingly.
	//var errorPar = document.getElementById('searchErrors');
	// 12/22/08: problem... now putting the search widget on
	// /collections/index.dot, which has no 'searchErrors' p element -
	// so for now just skip the evaluation if it's not present
	// 2/27/09: new approach: show a hidden popup if errors. commenting out previous impl.
	//if (errorPar != null)
	//{
		var errorText = "";
		if (allInputsEmpty && allSelectsEmpty)
		{
			//errorPar.innerHTML = "<br/>Please enter your search criteria to begin a new search.";
			errorText = "Please enter your search criteria to begin a new search.";
		}
		// if one date specified but not the other, indicate the missing date.
		else if (startDateMissing || endDateMissing)
		{
			if (startDateMissing)
				//errorPar.innerHTML = "<br/>You must enter a Start Date for a search by Date Range.";
				errorText = "You must enter a Start Date for a search by Date Range.";
			else
				//errorPar.innerHTML = "<br/>You must enter an End Date for a search by Date Range.";
				errorText = "You must enter an End Date for a search by Date Range.";
		}
		// if dates were entered, make sure both start and end dates are numbers
		else if (!isStartDateNumber || !isEndDateNumber)
		{
			//errorPar.innerHTML = "<br/>Both the Start Date and End Date must be numerical years.";
			errorText = "Both the Start Date and End Date must be numerical years.";
		}
		else if (!isDateRangeValid)
		{
			//errorPar.innerHTML = "<br/>The Start Date must be less than or equal to the the End Date.";
			errorText = "The Start Date must be less than or equal to the the End Date.";
		}
		// if no error conditions, make sure we erase whatever message might have been there before.
		//else if (errorPar.innerHTML.length > 0)
		//{
			//errorPar.innerHTML = "";
		//}
		if (errorText.length > 0)
			showErrors(errorPopup, form, errorText);
		else
			return true;

		//if (errorPar.innerHTML.length == 0)
			//return true;

		return false;
	//}
	//return true;
}
// copyFormValues: this function copies all the input and select
// element values from formSrc to formDst.  It is used to keep things
// consistent between the "narrow" and "expanded" forms.
function copyFormValues(formSrc, formDst)
{
	// loop through all input elements and copy them
	var inputsSrc = $(formSrc).getElementsByTagName('input');
	var inputsDst = $(formDst).getElementsByTagName('input');
	for (var i = 0; i < inputsSrc.length; i++)
	{
		if (inputsDst[i].type.match('checkbox'))
		{
			inputsDst[i].checked = inputsSrc[i].checked;
		}
		else
		{
			inputsDst[i].value = inputsSrc[i].value;
		}
	}

	// loop through all select elements and copy them
	var selectsSrc = $(formSrc).getElementsByTagName('select');
	var selectsDst = $(formDst).getElementsByTagName('select');
	for (var j = 0; j < selectsSrc.length; j++)
	{
		selectsDst[j].value = selectsSrc[j].value;
	}

	return false;
}

// displays a hidden div containing all images and captions, if available
// this is what runs when "View More Images" on the Object Detail page is selected
function showAdditionalImages()
{
	$('additionalImages').setStyles({
		display: 'block',
		opacity: '0'
	});


	$('additionalImages').fade('in');
	$('additionalImages').removeClass('noActive');
}

// simply closes the additional image display
function closeAdditionalImages()
{
	$('additionalImages').addClass('noActive');
	$('additionalImages').fade('out');
}

// displays a hidden div containing Search Tips
function showSearchTips()
{
	// 5/1/09: Needed to add 'overflow: auto' and remove it in closeSearchTips()
	// due to conflicts with the Flash grid of Collection Images... the "More" link
	// was not rendered in the right place in Firefox.
	$('searchTips').setStyles({
		display: 'block',
		overflow: 'auto',
		opacity: '0'
	});

// additional code to create table column borders
	var tds = $('searchTips').getElementsByTagName('td');
	for (var t = 0; t < tds.length; t++)
	{
		$(tds[t]).setStyles({
			border: '1px solid #000'
		});
	}

	$('searchTips').fade('in');
	$('searchTips').removeClass('noActive');
}

// closes the Search Tips div
function closeSearchTips()
{
	$('searchTips').setStyles({
		overflow: 'hidden'
	});

	$('searchTips').addClass('noActive');
	$('searchTips').fade('out');
}

// swaps the image shown in the Object Detail (tombstone) page
// with one selected from the additional image display
function swapImage(newImageURL, newCaption, imageIndex, imageCount, artobj)
{
	$('primaryImage').src = newImageURL;

	// also need to update the next/previous nav links
	updatePicNavLinks(imageIndex, Number(imageCount), JSON.encode(artobj).replace(/"/g,"&quot;"));

	// and replace the currently shown caption, if there is one
	if (newCaption.indexOf("(no caption") < 0)
	{	
		$('primaryCaption').innerHTML = newCaption;
	}
	else
	{
		$('primaryCaption').innerHTML = "";
	}

	var artists = JSON.decode(artobj.artists);
	artobj.artists = artists;

	$('lbanchor').innerHTML = "Add to Lightbox";
	$('lbanchor').onclick = function() { return LightBox('add', artobj, $('lbanchor')); };

	for (var i = 0; i < lightboxObjs.length; i++)
	{
		if (lightboxObjs[i].objectNumber == artobj.objectNumber && lightboxObjs[i].renditionNumber == artobj.renditionNumber)
		{
			$('lbanchor').innerHTML = "Remove from Lightbox";
			$('lbanchor').onclick = function() { return LightBox('remove', artobj, $('lbanchor')); };
			break;
		}
	}

	$('additionalImages').fade('out');
}

// called from the Object Detail page Previous/Next image links
// to change the image shown on the page with that of the selected index
function changeDetailImage(index, artobj)
{
	var imageList = $$('ul.detailImages');
	if(!imageList[0]) 
	{
		return true;
	}
	var lis = imageList[0].getElements('li');

	var renditionList = $$('ul.renditions');
	var rlis = renditionList[0].getElements('li');

	var largeImageUrls = $$('ul.largeImageURLs');
	var limglis = largeImageUrls[0].getElements('li');

	var thumbnailImageUrls = $$('ul.thumbnailImageURLs');
	var simglis = thumbnailImageUrls[0].getElements('li');

	for (var i = 1; i <= lis.length; i++)
	{
		if (index == i)
		{
        		// then we've found the desired image
			var newURL = lis[i-1].firstChild.src;
			//alert("i is: " + i + "; image src: " + newURL);
			// replace the currently shown image
			$('primaryImage').src = newURL;

			// and replace the currently shown caption
			var newCaption = lis[i-1].firstChild.title;
			$('primaryCaption').innerHTML = newCaption;

			artobj.idsid = simglis[i-1].innerHTML.trim();
			artobj.largeImageUrl = limglis[i-1].innerHTML.trim();
			artobj.renditionNumber = rlis[i-1].innerHTML.trim();

			updatePicNavLinks(index, lis.length, JSON.encode(artobj).replace(/"/g,"&quot;"));
			break;
		}
	}

	var artists = JSON.decode(artobj.artists);
	artobj.artists = artists;

	$('lbanchor').innerHTML = "Add to Lightbox";
	$('lbanchor').onclick = function() { return LightBox('add', artobj, $('lbanchor')); };

	for (var i = 0; i < lightboxObjs.length; i++)
	{
		if (lightboxObjs[i].objectNumber == artobj.objectNumber && lightboxObjs[i].renditionNumber == artobj.renditionNumber)
		{
			$('lbanchor').innerHTML = "Remove from Lightbox";
			$('lbanchor').onclick = function() { return LightBox('remove', lightboxObjs[i], $('lbanchor')); };
			break;
		}
	}

}

// updatePicNavLinks: common function called by changeDetailImage() and swapImage()
// to update the Prev/Next image navigation links regardless of whether the
// source was those links or the "View More Images" display.  So if an image
// is selected from the table supporting "View More Images", the Prev/Next links
// will be kept consistent when they reappear.
function updatePicNavLinks(index, imageCount, artobj)
{
			// replace the picnav p with new navigation links
			var prevLink = "&lt;";
			if (index > 1)
			{
				var prevIndex = Number(index) - 1;
				prevLink = "<a href=\"javascript:changeDetailImage(" + prevIndex + ", " + artobj + ");\" title=\"Previous Image\">&lt;</a>";
			}

			var nextLink = "&gt;";
			if (index < imageCount)
			{
				var nextIndex = Number(index) + 1;
				nextLink = "<a href=\"javascript:changeDetailImage(" + nextIndex + ", " + artobj + ");\" title=\"Next Image\">&gt;</a>";
			}

			var newLinkNav = prevLink + "&nbsp;&nbsp;&nbsp;" + index + "&nbsp;&nbsp;&nbsp;of&nbsp;&nbsp;&nbsp;" + imageCount + "&nbsp;&nbsp;&nbsp;" + nextLink;
			$('picnav').innerHTML = newLinkNav;
}


// showSearchInfo: using the ID of the hidden search <div> passed in,
// this function displays that div.  It attempts to align the
// top (vertical) coordinate with the vertical position of the link,
// based on heuristics (couldn't find a better way to do this, since
// the div's height must be taken into account.)
function showSearchInfo(searchId)
{
	var link = searchId + "_link";
	var linkTop = $(link).getCoordinates().top;

	var searchIdHeight = $(searchId).getCoordinates().height;

        // heuristic based method for offsetting the height of the searchId div further
	var addlOffset = 10;
	if (searchIdHeight > 50 && searchIdHeight < 100)
		addlOffset = 20;
	if (searchIdHeight > 100 && searchIdHeight < 150)
		addlOffset = 40;
	if (searchIdHeight > 150 && searchIdHeight < 175)
		addlOffset = 55;
	if (searchIdHeight > 175)
		addlOffset = 75;

	var searchInfoTop = linkTop - $$('.content')[0].getCoordinates().top - (searchIdHeight/2) - addlOffset;

	$(searchId).setStyles({
		display: 'block',
		opacity: '0',
		top: searchInfoTop+'px'
	});

	$(searchId).fade('in');
}

// hideSearchInfo: hides the displayed search <div> indicated by its ID.
function hideSearchInfo(searchId)
{
	$(searchId).fade('out');
}


// populateFormValues: supports re-populating the search form
// with the values for corresponding fields taken from
// the hidden <div> search ID passed in.
function populateFormValues(searchId)
{
  // attempts at document.evaluate...
  //var medTekId = searchId + "_medTek";
  //var medTekVal = $(medTekId).innerHTML;
  //$('mediaTek').value = medTekVal;

  // for the drop-downs / option lists, tried this fancy XPath approach to set
  // the selected index at the right place based on the value... found something like
  // this could work, but it turns out simply setting the value automatically
  // sets the right index, so this is unnecessary
  //document.evaluate("//select[@id='mediaTek']/option[@value='$(medTekId).innerHTML']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).selected = true;


  var fullTextId = searchId + "_fullText";
  var artistId = searchId + "_artist";
  var titleId = searchId + "_title";
  var accessionId = searchId + "_accession";
  var startDateId = searchId + "_startDate";
  var startDateBCId = searchId + "_startDateBC";
  var endDateId = searchId + "_endDate";
  var endDateBCId = searchId + "_endDateBC";
  var objectTypeId = searchId + "_objectType";
  var medTekId = searchId + "_medTek";
  var centuryId = searchId + "_century";
  var periodId = searchId + "_period";
  var cultureId = searchId + "_culture";
  var creationPlaceId = searchId + "_creationPlace";
  var imageRequiredId = searchId + "_imageRequired";

  // now test whether each is present and populate appropo. form value
  // 'fulltext' must be targetted using document.forms[] to avoid discrepancy with
  // the global search's 'fulltext' input.
  if ($(fullTextId) != null)
    document.forms['collectionsSearchFrm'].fulltext.value = $(fullTextId).innerHTML;
  else
    document.forms['collectionsSearchFrm'].fulltext.value = "";

  if ($(artistId) != null)
    $('artist').value = $(artistId).innerHTML;
  else
    $('artist').value = "";

  if ($(titleId) != null)
    $('objtitle').value = $(titleId).innerHTML;
  else
    $('objtitle').value = "";

  if ($(accessionId) != null)
    $('accession').value = $(accessionId).innerHTML;
  else
    $('accession').value = "";

  if ($(startDateId) != null)
  {
    $('startDate').value = $(startDateId).innerHTML;
    if ($(startDateBCId) != null)
      $('startDateBC').checked = true;
  }
  else
  {
    $('startDate').value = "";
    $('startDateBC').checked = false;
  }
  if ($(endDateId) != null)
  {
    $('endDate').value = $(endDateId).innerHTML;
    if ($(endDateBCId) != null)
      $('endDateBC').checked = true;
  }
  else
  {
    $('endDate').value = "";
    $('endDateBC').checked = false;
  }

  if ($(objectTypeId) != null)
    $('object').value = $(objectTypeId).innerHTML;
  else
    $('object').value = "";

  if ($(medTekId) != null)
    $('mediaTek').value = $(medTekId).innerHTML;
  else
    $('mediaTek').value = "";

  if ($(centuryId) != null)
    $('century').value = $(centuryId).innerHTML;
  else
    $('century').value = "";

  if ($(periodId) != null)
    $('historicalPeriod').value = $(periodId).innerHTML;
  else
    $('historicalPeriod').value = "";

  if ($(cultureId) != null)
    $('culture').value = $(cultureId).innerHTML;
  else
    $('culture').value = "";

  if ($(creationPlaceId) != null)
    $('creationPlace').value = $(creationPlaceId).innerHTML;
  else
    $('creationPlace').value = "";

  if ($(imageRequiredId) != null)
    $('show').checked = true;
  else
    $('show').checked = false;

  // make sure both the narrow and expanded forms get these values
  copyFormValues(document.forms['collectionsSearchFrm'], document.forms['collectionsSearchFrm1']);
}

// showErrors: populates the specified "errorPopup" (hidden div)
// with the specified errorText and shows it.
function showErrors(errorPopup, form, errorText)
{
	// prepare HTML to be rendered
	errorText = "<br/><b>" + errorText + "</b>";
	errorText = errorText + "<br/><br/>Please correct this problem and try again.";

	$(errorPopup).getElements('.errorText')[0].innerHTML = errorText;

	$(errorPopup).removeClass('noActive');

	// set different 'right' property if current search form is the 'expanded' one
	if ($(form).id.match($('collectionsSearchFrm1').id)) {
		$(errorPopup).setStyles({
			right: '428px'
		});
	}
	else {
		// in case the user has gone back and forth with the forms
		$(errorPopup).setStyles({
			right: '336px'
		});
	}
	$(errorPopup).setStyles({
		visibility: 'visible',
		top: '117px',
		opacity: '1'
	});

}

// simply closes the error display
function closeErrors(errorPopup)
{
	$(errorPopup).addClass('noActive');
	$(errorPopup).setStyles({
		visibility: 'hidden',
		top: '-6000px',
		opacity: '0'
	});
}

// showRelatedWorks: invokes a search for works related to the specified
// accessionNumber.  origPage: the original search results page to
// link back to in the related works search results.
function showRelatedWorks(accessionNumber, origPage)
{
	document.forms['collectionsSearchFrm'].elements['relatedworks'].value = "true";
	document.forms['collectionsSearchFrm'].elements['relatedworksAccession'].value = accessionNumber;
	document.forms['collectionsSearchFrm'].elements['origPage'].value = origPage;
	document.forms['collectionsSearchFrm'].submit();
	return false;
}

// showErrorDetails(): displays a search error stack trace from <div id="errorDetails">
function showErrorDetails()
{
	var details = $('errorDetails');
	if (details != null)
	{
		var paging = $$('.paging');
		if (paging[0]) 
		{
			$(paging[0]).innerHTML = $(details).innerHTML;
		}
	}
}

