// See http://www.quirksmode.org/js/mouseov.html
var W3CDOM = (document.createElement && document.getElementsByTagName);

// Sometimes this line is overridden by other code (e.g., <body onload="...")
// and you have to add actions_onload there instead.
window.onload = actions_onload;

function actions_onload() {
  if (!W3CDOM) {
    alert("Your browser does not support some important functions.  This page will not work correctly.");
    return;
  }
  // Attach Javascript to page elements
  attachMovieLinkMouseOvers();
}

var imageChangesOk = -1;

function checkImageChanges() {
  if ( imageChangesOk < 1 ) {
    var ti = new Image();
    // This test image must be of a form to not get deep-linked.  See bug#580.
    // A "." in the name suffices.
    ti.src = "images/spacer.gif";
    imageChangesOk = ti.src.length;
  }

  if ( imageChangesOk == 0 ) {
    alert("Your browser doesn't let JavaScript programs like MovieLens change images.  MovieLens needs this ability to work properly.  See http://movielens.umn.edu/html/browser.html for more info and instructions on how to enable image changes.");
  } else {
    imageChangesOk = 1;
  }
}

// This is to create a string out of the attributes of a node.
// Used for debugging.
function attributes2string(attributes) {
  var ret = '(';
  if (attributes != null) {
    for (var i=0; i<attributes.length; i++) {
      var item = attributes.item(i);
      ret += item.nodeName + ':' + item.nodeValue + ' ';
    }
  }
  ret += ')';
  return ret;
}

//
// Return all nodes with the given parameters.
//
// parent       the parent node from which to search (often 'document.body')
// tag          HTML tag (e.g., "input", "img", "select")
// attName      The other attribute to check (e.g., "name" or "class")
// namePrefix   a string that the value of the 'attName' attribute has to start with
//
function getNodesByTagAndAttributePrefix(parent, tag, attName, attPrefix) {
    var elements = parent.getElementsByTagName(tag);

    // If this is true, this function will spew out lots of alert()s.
    var debugHere = false;
    if (debugHere) {
      alert('getNodesByTagAndAttrPrefix(' + tag + ', ' + attName + ', ' + attPrefix
       +'): elements.length is ' + elements.length);
    }

    var ret = new Array();
    for (var i = 0; i < elements.length; i++) {
        var element = elements[i];
        var atts = element.attributes;
        if (atts != null) {
          var attNode = atts.getNamedItem(attName);
          if (attNode != null) {
            var attVal = attNode.nodeValue;
            if (attVal != null) {
              var substr = attVal.substring(0, attPrefix.length);

              if (debugHere) {
                alert('attPrefix ' + attPrefix + ' attName ' + attName
                  + ' attVal "' + attVal
                  + '" substr ' + substr
                  + ' element ' + element
                  + ' attributes ' + attributes2string(atts));
              }

              if (attPrefix == substr) {

                if (debugHere) {
                  alert('MATCH: Tag ' + tag + ' attPrefix ' + attPrefix
                    + ' attVal "' + attVal + '" element ' + element);
                }

                ret[ret.length] = element;
              }
            }
            else {
              //alert('elements[' + i + '] has null name and attributes ' + element.className);
            }
          }
        }
    }
    return ret;
}

// Get nodes whose "name" attribute starts with namePrefix
function getNodesByTagAndNamePrefix(parent, tag, namePrefix) {
    return getNodesByTagAndAttributePrefix(parent, tag, "name", namePrefix);
}

// Get nodes whose "class" attribute starts with namePrefix
function getNodesByTagAndClassPrefix(parent, tag, classPrefix) {
    return getNodesByTagAndAttributePrefix(parent, tag, "class", classPrefix);
}

/**
 * Toggle the state of the tack (on/off).
 *
 * @param  movieId
 * @param  listid   1 is wishlist, others unknown
 * @param  obj      the "this" of the object to which this is attached via onChange.
 *                  Allows us to grab the form.
 */
function changeTack(movieId, listid, obj) {
    var boxes = getNodesByTagAndNamePrefix(document.body, 'input', 'box' + movieId + '.');
    var tacks = getNodesByTagAndNamePrefix(document.body, 'img', 'tack' + movieId + '.');
    var newValue = obj.checked;
    submitListChange(movieId, newValue ? 1 : 0, listid);

    for (var i = 0; i < boxes.length; i++) {
        boxes[i].checked = newValue;
    }
    for (var i = 0; i < tacks.length; i++) {
        var imgName = tacks[i].name;
        tacks[i].src = newValue ? "/images/tack.gif" : "/images/spacer.gif";
    }
}

//
// Change the state of the rating stars.
//
// @param movieId   Movie whose rating to change
// @param obj       The "this" of the object to which this is attached via onChange.
//                  That allows us to grab the form.
// @param source    The source of the rating (i.e., place in the U/I)
// @param dimension Dimension of rating.  buddystudy only.
//
function changeStar(movieId, obj, source, dimension) {
  var sclValue = obj.options[obj.selectedIndex].value;

  // Submit rating
  submitAction(movieId, 'rate', sclValue, source, dimension);

  // Change drop-downs
  var selects = getNodesByTagAndNamePrefix(document.body, 'select', 'rate' + movieId + '.');
  for (var i = 0; i < selects.length; i++) {
    selects[i].value = sclValue;
  }

  // Change images
  var images  = getNodesByTagAndNamePrefix(document.body, 'img', 'star' + movieId + '.');

  // ratDelta is +1 if they've rated something new, -1 if they've unrated
  // something, otherwise 0.
  var ratDelta = 0;

  // If the image shows a rating and it's not 0 ("unknown") or -1 ("hide"),
  // then decrement
  if ( images[0].src.indexOf("rate") != -1 &&
       images[0].src.indexOf("0.0") == -1 &&
       images[0].src.indexOf("hate") == -1 ) {
    ratDelta = -1;
  }
  // If it's 0.0 ("not seen") or -1.0 ("hide"), do nothing,
  // otherwise they just rated something
  if ( sclValue != 0.0 && sclValue != -1 ) {
    ratDelta++;
  }

  if(sclValue !=0){
  // Convert -1rate.gif => haterate.gif so we don't store a file starting with "-" in CVS
  sclImgPrefix = (-1 == sclValue) ? 'hate' : sclValue;
  var imgSrc = '/images/stars/' + sclImgPrefix + 'rate.gif';
  for (var i = 0; i < images.length; i++) {
    images[i].src=imgSrc;
  }
  }else{
  //we are unrating the movie so user the ratestar scr value to link to the current rating
  var predimages  = getNodesByTagAndNamePrefix(document.body, 'img', 'predstar' + movieId + '.');
  var imgSrc = predimages[0].src;
  
  for (var i = 0; i < images.length; i++) {
    images[i].src=imgSrc;
  }
  
  }
  // Change the ## in "You've rated ## movies".
  var numRatsElem = document.getElementById("numRats");
  if (numRatsElem != null) {
      var numRats = parseInt(numRatsElem.childNodes[0].nodeValue);
      numRats += ratDelta;
      document.getElementById("numRats").childNodes[0].nodeValue = numRats;
      
      // take care of the new-user's case
  	  if ( document.getElementById("newUserNumRats") != null ){
	  	document.getElementById("newUserNumRats").childNodes[0].nodeValue = numRats;	
  	  }
  }
  
  var movieUri = "http://movielens.org/movieDetail?movieId="+movieId;
  MLPlugin.triggerPluginEvent("movieRate",{"movieUri":movieUri,"value":sclValue});
}

//
// Change the state of the mpaa rating image
//
// @param movieId   Movie whose rating to change
// @param obj       The "this" of the object to which this is attached via onChange.
//                  That allows us to grab the form.
//
function changeMpaa(movieId, obj, source, dimension) {
    //sclValue = index of dropdown item that the user just selected
    var sclValue = obj.options[obj.selectedIndex].value; 

  // Submit rating
  submitAction(movieId, 'mpaa', sclValue, source, dimension);

  // Change drop-downs
  var selects = getNodesByTagAndNamePrefix(document.body, 'select', 'mpaa' + movieId);
  for (var i = 0; i < selects.length; i++) {
    selects[i].value = sclValue;
  }

  // Change images
  var images  = getNodesByTagAndNamePrefix(document.body, 'img', 'mpaa' + movieId);
  
  // ratDelta is +1 if they've rated something new, -1 if they've unrated
  // something, otherwise 0.
  var mpaaDelta = 0;

  // If the image shows a rating and it's not 0 ("unknown") 
  // then decrement
  //images[0] = filename of image that appears before action occurs
  if ( images[0].src.indexOf("0.gif") == -1) {
    mpaaDelta = -1;
  }

  // If it's unknown, do nothing,
  // otherwise they just rated something
  if ( sclValue != "0" ) {
    mpaaDelta++;
  }
  
  // Convert -1rate.gif => haterate.gif so we don't store a file starting with "-" in CVS
  sclImgPrefix = (-1 == sclValue) ? '0' : sclValue;
  var imgSrc = '/images/mpaa/' + sclImgPrefix + '.gif';
  for (var i = 0; i < images.length; i++) {
    images[i].src=imgSrc;

    if(sclImgPrefix != 0) {
        images[i].border="1";
        document.getElementById("mpaa"+movieId+"span").style.display = "inline";
    }else {
        images[i].border="0";
        document.getElementById("mpaa"+movieId+"span").style.display = "none";
    }
  }

  // Change the ## in "You've added MPAA ratings for ## movies".
  var numMpaaElem = document.getElementById("newUserNumMpaa");
  if (numMpaaElem != null) {
      var numMpaa = parseInt(numMpaaElem.childNodes[0].nodeValue);
      numMpaa += mpaaDelta;
      document.getElementById("newUserNumMpaa").childNodes[0].nodeValue = numMpaa;
  }
}




//changes text on [add/edit mpaa] link in movieRow
//@param movieId
//@param obj  The "this" of the object to which this is attached via onChange. (i.e. MPAA drop down select)
function mpaaUpdateShowHideLink(movieId, obj) {
    var addtxt = "add MPAA rating";
    var edittxt = "change MPAA rating";
    var addedit_text= document.getElementById("mpaa_text"+movieId);

    if (addedit_text != null) {
        var txt = addedit_text.childNodes[0].nodeValue;
        var mpaaRating = obj.options[obj.selectedIndex].value; 
        
        if (txt == addtxt && mpaaRating > 0) { //link currently says "add" but should say "change"
            document.getElementById("mpaa_text"+movieId).childNodes[0].nodeValue = edittxt;
        }else if (txt == edittxt && mpaaRating <=0) { //link currently says "change" but should say "add"
            document.getElementById("mpaa_text"+movieId).childNodes[0].nodeValue = addtxt;     
        }
    }    
}




// Attach a mouse-over function to all anchors ("a" tags) with class "movieLink.*"
function attachMovieLinkMouseOvers() {
  var classPrefix = 'movieLink.';
  var tables  = getNodesByTagAndClassPrefix(document.body, 'a', classPrefix);
  for (var i=0; i<tables.length; i++) {
    var name = tables[i].attributes.getNamedItem("class").nodeValue;
    var movieId = name.substring(classPrefix.length);
    tables[i].movieId = movieId;
    tables[i].onmouseover = toggleMovieRowHighlight; 
    tables[i].onmouseout = toggleMovieRowHighlight;

    //alert('element is ' + tables[i] + ' mouseOver id: ' + movieId + ' tables[i].movieId: ' + tables[i].movieId);
  }
}

// Toggle the class associated with any "table" element starting with
// "movieRow<id>.", where <id> is this.movieId.
// "Toggle" means add or remove a "-highlighted" to the end of the class,
// whichever is appropriate.
function toggleMovieRowHighlight() {
  var movieId = this.movieId;
  var tables = getNodesByTagAndNamePrefix(document.body, 'table', 'movieRow' + movieId + '.');
  var highlightStr = '-highlighted';
  for (var i=0; i<tables.length; i++) {
    // Get the class name from the first one
    var className = tables[i].attributes.getNamedItem('class').nodeValue;
    var newClassName = className;
    // Toggle it
    if (-1 == className.indexOf(highlightStr)) {
      newClassName += highlightStr;
    }
    else {
      //alert('toggling off: c.l-h.l ' + (className.length - highlightStr.length));
      newClassName = className.substr(0, className.length - highlightStr.length);
    }

    tables[i].attributes.getNamedItem('class', newClassName).nodeValue = newClassName;
    //alert("highlightMovieRow: tables[i] set class from " + className + " to " + newClassName);
  }
}

// This image is not actually used for anything.  However, submitAction sets
// its src in order to effect a change on the server side.
// NOTE: It is a global variable so IE won't optimize it away.
var actionImg = new Image();

/*
 * Submit a list change to the server (by requesting a URL).
 *
 * @param movieId      movie to be acted upon
 * @param actionValue  0 to delete from list, 1 to add to list
 * @param listId       1 is wishlist, others to be defined ..
 */
function submitListChange(movieId, actionValue, listId) {
    // This functionality relies on being able to change image source
    checkImageChanges();
    if ( imageChangesOk == 0 ) {
      return;
    }

    var myRand = Math.round(Math.random()*(1000000));
    var imgSrc = "/img?"
        + "movieId=" + movieId
        + "&actionType=list"
        + "&actionValue=" + actionValue
        + "&listId=" + listId
        + "&rand=" + myRand;
    //alert('submitListChange: imgSrc ' + imgSrc);
    actionImg.src = imgSrc;
}

/*
 * Submit an action to the server (by requesting a URL).
 * @param movieId      movie to be acted upon
 * @param actionType   At least 'info', 'list', 'rate'
 * @param actionValue  Value to be passed on
 * @param source       Where the action came from
 *
 * @param dimension    Just for buddystudy
 */
function submitAction(movieId, actionType, actionValue, source, dimension) {
    // This functionality relies on being able to change image source
    checkImageChanges();
    if ( imageChangesOk == 0 ) {
      return;
    }

    var myRand = Math.round(Math.random()*(1000000));
    var imgSrc = "/img?"
        + "movieId=" + movieId
        + "&actionType=" + actionType
        + "&actionValue=" + actionValue
        + "&ratingSource=" + source
        + "&dimension=" + dimension
        + "&rand=" + myRand;
//   alert('submitAction: imgSrc ' + imgSrc);
    actionImg.src = imgSrc;
}

// Added for easy logging for member maint
function editListInfoClick(movieId, context) {
    submitAction(movieId, "editInfo", context, 0, 0);
}

function openSmallWindow(theURL,winName,features) {
  window.open(theURL,winName,features);
}

function initTab(){
    document.getElementById('Shortcuts').style.visibility = "hidden";
    document.getElementById('Search').style.visibility = "hidden";
    document.getElementById('Shortcuts').style.display = "none";
    document.getElementById('Search').style.display = "none";
}

function showTab(tabName) {
    initTab();
    if (document.getElementById) {
       document.getElementById(tabName).style.visibility = "visible";
       document.getElementById(tabName).style.display = "block";
    }
}


function synchBox(master, slave){
    for (var i=0; i<master.length; i++) {
   if (master[i].checked) { slave.checked = true; return; }
    else {slave.checked = false;}
    }
}

/**
 * Show/hide a block level html element
 *
 * @param cellName  Id of block to open/close.
 */
function toggleHelp(cellName){
  if ( document.getElementById(cellName).style.display=="none" ) {
    document.getElementById(cellName).style.display = "block";
  } else {
    document.getElementById(cellName).style.display = "none";
  }
}

/**
 * Open or close an 'info' cell.
 *
 * @param cellName  Id of cell to open/close.
 * @param source    The source of the click (i.e., place in the U/I).
 */
function expandCell(cellName, source) {
    var type;
    if (document.getElementById(cellName).style.display=="none"){
        document.getElementById(cellName).style.display="block";
        type = 1;
    } else {
        document.getElementById(cellName).style.display="none";
        type = 0;
    }
    // Lop off the 'cell' at the front of cellName.
    //var movieId = cellName.substring(4);
    //submitAction(movieId, "info", type, source);
}

function expandTab(context, cellName) {
    var context = document.getElementById(context);
    var tab = document.getElementById(cellName);
	
    if (tab.style.display=="none"){
        //tab is hidden.
    	//unhide tab
    	tab.style.display="block";
        MLPlugin.triggerPluginEvent("loadTab", {"tabId":cellName});
        
        //hide other tab
        if(context.shownTab != undefined){
        	var oldTab = document.getElementById(context.shownTab);
        	oldTab.style.display = "none";
        	MLPlugin.triggerPluginEvent("hideTab", {"tabId":context.shownTab});
        }
        context.shownTab = cellName;
    } else {
    	//tab was not hidden.
    	//hide tab
    	tab.style.display="none";
    	MLPlugin.triggerPluginEvent("hideTab", {"tabId":cellName});
    	
    	context.shownTab = undefined;
        
    }
}

/**
 * TAG_VORTEX: Open or close 'More Movies' block
 *
 * @param linkName  Id of link whose text to be changed.
 * @param cellName  Id of cell to open/close.
 */
function TAGS_toggleMoreMovies(linkName, cellName) {

	macthedNodes = document.getElementsByName(linkName);

	theNode = macthedNodes[0];

	if (theNode.innerHTML == "View...") {
		theNode.innerHTML = "Hide...";
	}
	else{
		theNode.innerHTML = "View...";
	}

	expandCell(cellName);
}

function titleKeyup(){
    var hasPhrase = document.search.searchPhrase.value.length > 0;
    /*
    alert("ph: " + document.search.searchPhrase.value
        + " len: " + document.search.searchPhrase.value.length
        + " hasPhrase: " + hasPhrase);
    */
	document.search.ExcludeRated.checked = !hasPhrase;
	document.search.ExcludeNoPred.checked = !hasPhrase;
}



function synchDomainBoxes() {
	if(document.search.domain.value!=""){
	    // Depending on the domain chosen, sometimes exclude ratings and no-preds.
	    // Set the hidden search parameters appropriately.
	    if ((document.search.domain.value == "Ratings")
	        || (document.search.domain.value == "Wishlist")
	        || (document.search.domain.value == "Hatelist")) {
	        document.search.ExcludeRated.checked = false;
	        document.search.ExcludeNoPred.checked = false;
	    }
	    else {
	        document.search.ExcludeRated.checked = true;
	        document.search.ExcludeNoPred.checked = true;
	    }
    }
    else {
        document.search.ExcludeRated.checked = true;
        document.search.ExcludeNoPred.checked = true;
    }
/*
    alert("ExRated: " + document.search.ExcludeRated.value +
          " ExNoPred: " + document.search.ExcludeNoPred.value +
          " domain: " + document.search.domain.value);
*/
}

/**
 *	Handles flagging of genre, date, and domain searches from the search bar.
 */
function genrePress(){
	if(document.search.domain.value!=""){
	    // DVD and VHS are formats, Foreign is a language
		if(document.search.domain.value == "DVD Releases"){
			document.search.format.setAttribute("value","DVD");
		}
		if(document.search.domain.value == "VHS Releases"){
			document.search.format.setAttribute("value", "VHS");
		}
		if(document.search.domain.value == "Foreign"){
			document.search.language.setAttribute("value", "Foreign");
		}
	}

	if (document.search.searchPhrase.value != "") {
	  document.search.sortBy.value = "TitleSimSort";
	}
	else {
	  document.search.sortBy.value = "RatePredSort";
	}
	//alert("d.s.s.v: " + document.search.sortBy.value);
	/*
        alert("ExRated: " + document.search.ExcludeRated.checked +
              " ExNoPred: " + document.search.ExcludeNoPred.checked +
              " domain: " + document.search.domain.value);
    */
}

// Used for debugging.
function formelements2string(form) {
  var ret = '(';
  if (form != null) {
    els = form.elements;
    if (els != null) {
      for (var i=0; i<els.length; i++) {
        if ('INPUT' == els[i].nodeName) {
          ret += els[i].name + " ";
          //var input = els[i].childNodes[0];
          //ret += input.nodeName + ':' + input.nodeValue + ' ';
        }
        else {
          ret += els[i].name + " ";
        }
      }
    }
  }
  ret += ')';
  return ret;
}

// Get the value from a widget with id ("previous" + widgetId).
// return value or 'null' if value was "<i>same</i>"
function getOldWidgetValue(widgetId) {
    //alert("get element id 'previous" + widgetId +"'");
    var prevElement = document.getElementById("previous" + widgetId);
    var divVal = prevElement.childNodes[0];

    var value = null;
    if (null == divVal) {
      // Div was empty
      value = '';
    }
    else if ("#text" == divVal.nodeName) {
      value = divVal.nodeValue;
    }
    else {
      // There's markup inside the node.  This is a special value
      //alert('nodename is ' + divVal.nodeName);
      if ("I" == divVal.nodeName) {
        var child = divVal.childNodes[0];
        if ("#text" == child.nodeName) {
          if ("blank" == child.nodeValue) {
              // <i>blank</i>
              value = '';
          }
          else {
            // Assume it was <i>same</i>, and leave value null
          }
        }
        else {
          // Completely unexpected.  What's in there and where did it come from?
        }
      }
      else {
          // Completely unexpected.  What's in there and where did it come from?
      }
    }
    return value;
}

/**
 * On the movieEdit screen, take the information from the previous movie
 * and put it in the edit boxes so one can save it.  This is a simple way to
 * revert.
 */
function loadPreviousMovieEditInfo() {
    var movieEditWidgets =
      new Array('title', 'lang', 'directedBy', 'starring', 'comment',
                'filmReleaseDate', 'vhsReleaseDate', 'dvdReleaseDate');

    for (var i = 0; i < movieEditWidgets.length; i++) {
        var widgetId = movieEditWidgets[i];
        var oldValue = getOldWidgetValue(widgetId);

        var element = document.getElementById(widgetId);
        if (null != oldValue)
            element.value = oldValue;
    }

    // Handle genre checkboxes specially
    var oldValue = getOldWidgetValue("genres");

    if (null != oldValue) {
        var form = document.getElementById('movieEditForm');
        // Split apart comma-separated genres, then check the right boxes
        var genreArray = oldValue.split(", ");

        // Check the right boxes
        for (var i = 0; i < form.genre.length; i++) {
            var genreName = form.genre[i].value;
            //alert ('genreName is ' + genreName);
            form.genre[i].checked = false;
            for (var j = 0; j < genreArray.length; j++) {
                if (genreName == genreArray[j]) {
                    // Match!
                    form.genre[i].checked = true;
                    break;
                }
            }
        }
    }
}

// Encapsulate the big actor search string.
function actorSearch(name) {
	self.location =
    	"/search?actorPhrase=" + name + "&sortBy=RatePredSort&action=newSearch"
}

// Encapsulate the big director search string.
function directorSearch(name) {
	self.location =
    	"/search?directorPhrase=" + name + "&sortBy=RatePredSort&action=newSearch"
}




/*************************************************************************
 * These functions are for buddystudy
 *************************************************************************/
/**
 * Submit a change in confidence.
 * Also, block out the "top 2 choices" checkbox if "I've seen it".
 * For buddystudy widget (radio buttons).
 * listNum is 1, 2, 3, corresponding to screens 2, 4, 6.
 */
function submitConfidenceChange(movieId, radioButton, ratingSource, listNum) {
    submitAction(movieId, 'rate', radioButton.value, 'buddystudy', listNum*2);

    var boxes = getNodesByTagAndNamePrefix(document.body, 'input', 'box' + movieId + '.');
    //alert('boxes[0] ' + boxes[0] + ' radioButton.value ' + radioButton.value);
    var seenIt = 5;
    if (seenIt == radioButton.value) {
        //alert('uncheck and gray out');
        if (boxes[0].checked) {
            boxes[0].checked = false;
            listId = (1*listNum) + 1000; // Contorted expression to get arithmetic +
            changeTack(movieId, listId, boxes[0]);
        }
    }

    boxes[0].disabled = (seenIt == radioButton.value);

    //alert('boxes[0].disabled ' + boxes[0].disabled);
}

function checkChoices() {
    // Check that everything is rated
    var rateDropdown = getNodesByTagAndNamePrefix(document.body, 'select', 'rate');
    for (var i = 0; i < rateDropdown.length; i++) {
      if (0 == rateDropdown[i].value) {
        alert('At least one movie has not been rated.  Please rate them all before going on.');
        return false;
      }
    }

    // Check all confidences
    var confDropdown = getNodesByTagAndNamePrefix(document.body, 'select', 'conf');
    for (var i = 0; i < confDropdown.length; i++) {
      if (0 == confDropdown[i].value) {
        alert('At least one rating confidence has not been selected.  Please select them all before going on.');
        return false;
      }
    }

    // Check that the right number of boxes is checked
    var boxes = getNodesByTagAndNamePrefix(document.body, 'input', 'box');
    var numChecked = 0;
    var numEnabled = 0;
    for (var i = 0; i < boxes.length; i++) {
        if (!boxes[i].disabled) numEnabled++;
        if (boxes[i].checked) numChecked++;
    }
    numRequired = 2;
    if (numEnabled < numRequired) numRequired = numEnabled;
    if (numChecked != numRequired) {
      alert("You have chosen " + numChecked + " movies.  Please choose " + numRequired
         + " by using the checkboxes along the right side of the screen.");
      return false;
    }
    return true;
}

// returns the array number of the selected radio button or -1 if no button is selected
function getSelectedRadio(buttonGroup) {
   // if the button group is an array (one button is not an array)
   if (buttonGroup[0]) {
      for (var i=0; i<buttonGroup.length; i++) {
         if (buttonGroup[i].checked) {
            return i
         }
      }
   } else {
      // if the one button is checked, return zero
      if (buttonGroup.checked) { return 0; }
   }
   // if we get to this point, no radio button is selected
   return -1;
}

function checkListSurvey(form) {
    var notSel = 0;
    for (var i=1; i<=2; i++) {
      notSel += (-1 == getSelectedRadio(eval('form.question' + i)));
    }
    if (notSel > 0) {
       alert("At least one of questions 1-2 is unanswered.  Please answer all questions.");
       return false;
    }
    return true;
}

function checkFinalSurvey(form, buddyarray) {
    //alert('hello');
    var notSel = 0;
    for (var i=1; i<=2; i++) {
      notSel += (-1 == getSelectedRadio(eval('form.question' + i)));
    }

    for (var i=3; i<=5; i++) {
      for (var b=0; b < buddyarray.length; b++) {
          //var radios = getNodesByTagAndNamePrefix(document.body, 'input', 'question' + i + '-' + buddyarray[b]);
          //alert(i + ' radios is ' + radios[0]);
          //var buttonGroupName = radios[0].name;
          var buttongroupName = 'question' + i + '_' + buddyarray[b];
          //alert('buttongroupName is ' + buttongroupName);
          var buttonGroup = eval('form.' + buttongroupName);
          //alert('buttonGroup is ' + buttonGroup);
          notSel += (-1 == getSelectedRadio(buttonGroup));
      }
    }

    if (notSel > 0) {
       alert("At least one of questions 1-5 is unanswered.  Please answer all questions.");
       return false;
    }
    return true;
}

/*************************************************************************
 * End functions for buddystudy
 *************************************************************************/

/**
 * Return true if the field contains too few characters.
 *
 * @param field An html element, probably a <textarea> to check for length
 * @param maxLen the minimum number of characters the field will accept
 */
function isTooShort(field, minLen) {
    if (field.value.length < minLen) {
        alert("Your message is too short. It must be " + minLen + " characters or more. It is currently "
            + field.value.length + " characters.");
        return true;
    }
    return false;
}

/**
 * Return true if the field contains too many characters.
 *
 * @param field An html element, probably a <textarea> to check for length
 * @param maxLen the maximum number of characters the field will accept
 */
function isTooLong(field, maxLen) {
    if (field.value.length > maxLen) {
        alert("Your message is too long. It must be " + maxLen + " characters or less. It is currently "
            + field.value.length + " characters.");
        return true;
    }
    return false;
}

/**
 * Clear an html form field (use with onclick())
 *
 * @param field An html element, probably a <textarea>
 * @param the default text to check for
 */
function clearField(field, defaulttext) {
    if (field.value == defaulttext) {
        field.value = "";
    }
}

/**
 * Restore an html form field (use with onblur())
 *
 * @param field An html element, probably a <textarea>
 * @param the default text to check for
 */
function restoreField(field, defaulttext) {
    if (field.value == "") {
        field.value = defaulttext;
    }
}

/**
* Revert html form field to original text. 
* 
* @param field An html element, probably a <textarea>
* @param the text used to repopulate the field (regardless of what text is 
*/
function revertField(field, defaulttext){ 
 if (field != null)
   field.value = defaulttext;
}
