  jQuery.fn.log = function (msg) {
      // Usage e.g. $("#myId").log("content of myId");
      // Usage e.g. $("#myId").log("content of myId before hide").hide();
      console.log("%s: %o", msg, this);
      return this;
  };
  
  // <!--  TROQ help -->
  $(document).ready(function() { 
      $('img.help').click(function(event) {
         // Get the event's target so we can accurately position the box.
         // The event x/y seems to be off by some set distance, so use
         // the target position.
    	 var mainPageElem = $(document);
    	 var target = $(this);
    	 var tpos = target.position();
         
         // close any open help
         $('.helptextbox').fadeOut();

         // See if the one clicked is hidden - if yes show it
         var helpDiv = $('#fieldhelp'+this.id+':hidden');
         if (helpDiv) {
        	   var leftVal = tpos.left + target.outerWidth();
        	   if (tpos.left + helpDiv.width() > mainPageElem.width()) {
        		   leftVal =  tpos.left - helpDiv.outerWidth();
        	   }

        	   var topVal =  tpos.top - helpDiv.outerHeight();
         
        	   helpDiv.animate({top:topVal,left:leftVal}, 10 );
        	   helpDiv.fadeIn();
         }
     });

     $('.helptextbox').click(function() {
         $(this).fadeOut();
         
     });
     
     $('.helptextbox').bind('mouseleave focusout',function(event) {
         $(this).fadeOut();
     });
    
     $(document).keyup(function(event) {
      if (event.keyCode == 27) {
          $('.helptextbox').fadeOut();
      }
     });
  });

  // CLEAR button
  $(document).ready(function() {
      $('#formClear').click(function(event) {
          $('input#currentClassificationId').val('');
          $('input#titleKeyWords').val('');
          $('select#qualificationType').val('');
          setLevel();
          $('select#qualificationLevel').val(''); 
          $('select#qualificationCredit').val('');
          $('select#qualificationStatus').val($('#statusCurrentValue').text());
          $('input#currentClassificationText').val($('#allOptionValue').text());
          event.preventDefault();
      });
  });

  // <!-- TROQ tree -->
  // This code expects that there be a div in the code that contains
  // nested ul's that describe the tree.
  // 
  var treeTime = 0;    
       
  $(document).ready(function() {

	  // Find the hidden ID number field
	  var idField = $('input#currentClassificationId');

      // Find the display-only field that should have been setup in the page
	  var idDisplayField = $('#currentClassificationText');
	  idDisplayField.show(); // Just in case the inline script failed to show it.
      idDisplayField.attr("readonly", "true");
      
      $('#subjectJavascriptHelp').hide();

      // Retrieve the current ID, if there is one,update the display text.
      var currentId = idField.val();
      var currentNode = (currentId == "") ? null : $('a.nodeText#id' + idField.val());
      var currentText = (currentId == "") ? $('#allDisplayValue').text() : computeSubjectTreeText(currentNode);

      idDisplayField.val(currentText);
      
      var subjectHelpPopup = $('#subjectHelpTreeBox');

      $('#subjectTree').children('ul').first().prepend('<li class="nodeItem"><a class="nodeText" id="idAll">' + $('#allDisplayValue').text()+ '</a></li>').focus();

      // On focus in the read-only display field, popup the tree (stored in a div).
      idDisplayField.bind('click focus select',function(event) {

    	  // Prevent event cascades (click, then focus) from popping the tree up/down
    	  var newTreeTime=(new Date()).getTime();      	  
    	  if (newTreeTime < treeTime + 500) {
    		    return true;
          }
          treeTime = newTreeTime;
          
          //alert(event.type);
          if (subjectHelpPopup.is(':visible')) {
              subjectHelpPopup.fadeOut();
          }
          else {
              // Pop up the tree near the input element
              var mainPageElem = $('#mainPage');
              var mainWidth = mainPageElem.width();
              var inputElem = $('#currentClassificationText');
              var inputElemPos = inputElem.position();
              var treeTopPos = inputElemPos.top  + inputElem.height() + 5;
              var treeLeftPos = inputElemPos.left ;
              subjectHelpPopup.animate({top:treeTopPos,left:treeLeftPos}, 10 );
              // popup the div
              subjectHelpPopup.fadeIn();
              subjectHelpPopup.bgiframe(); //IE6 selects show through popups - this fixes it
          }
          return false;      
      });

      // Need some way to close the popup if the input field changes.
      idDisplayField.bind('focusout blur',function(event) {         
   		  //subjectHelpPopup.fadeOut();
    	  return false;
      });

      // If they leave the popup, then close the popup window
      subjectHelpPopup.bind('focusout blur',function(event) {
          // Prevent event cascades (click, then focus) from popping the tree up/down
          var newTreeTime=(new Date()).getTime();         
          if (newTreeTime < treeTime + 500) {
                return true;
          }
          treeTime = newTreeTime;
          if (event.relatedTarget != $('#currentClassificationText')) {
        	  subjectHelpPopup.fadeOut();
          }
          return false;
      });

      // Allow escape to leave the popup
      $(document).keyup(function(event) {
         if (event.keyCode == 27) {
        	 subjectHelpPopup.fadeOut();
         }
         return false;
      }); 

      // Due to the order in which events occur, we have to catch
      // entry to other input elements and close the tree view when
      // this happens.
      $('input, select').each(function() {
          if ($(this).attr('id') != 'currentClassificationText') //XXXXX
          $(this).focus(function() {
        	  subjectHelpPopup.fadeOut();
          })
          return true;
      });
      
      // Find ul items representing sub-trees and for each
      // sub-tree add link that clicked to open/close it.
      $('#subjectTree li > ul').each(function() {
             // Find this list's parent list item.
             var parent_li = $(this).parent('li');

             // Prepend something clickable "<a>" that toggles the subordinate ul.
             var sub_ul = $(this);

             parent_li.addClass("nodeHasChildren");
             // Add text ref handle that can be used to open/close the tree node.
             var aref = $('<a class="treeControl treeControlClosed">&nbsp;</a>');
             aref.prependTo(parent_li);
             
             aref.click(function() {
                // Make the anchor toggle the leaf display.
                sub_ul.toggle();
                if (aref.hasClass("treeControlOpen")) {
                    aref.removeClass("treeControlOpen");
                    aref.addClass("treeControlClosed");
                }
                else {
                    aref.removeClass("treeControlClosed");
                    aref.addClass("treeControlOpen");
                }
                //subjectHelpPopup.show();
                //var inputElem = $('#currentClassificationText');
                //inputElem.focus();
                return false;
             });
             
          });
         
      // Hide all lists except the outermost. So all ul's under
      // the top level ul's will be hidden.
      $('#subjectTree ul ul').hide();

      // Show the current node and the path above it.
      if (currentNode != null) {
            // Open all parent ul's of the current node
    	    currentNode.parents('ul').each(function() {
    	    	   $(this).toggle();
    	    });
    	    // Highlight the current node.
    	    currentNode.addClass('nodeSelected');
      }
      
      // Add select-a-node handling to each node
      $('#subjectTree a.nodeText').each(function() {
             var a = $(this);

             if (!a.parent('li').hasClass('nodeHasChildren')) {
                 a.addClass('nodeLeafRef');
             }
             
          
             // Add select-a-node to set the hidden ID field.   
             a.click(function() {
                 var newNode = $(this);
                 // Find the old (current) ID
                 var idField = $('input#currentClassificationId');
                 var oldId = idField.val();
                 // Locate the old node and unhighlight it.
                 var oldNode = $('a.nodeSelected');
                 // Unhighlight the old current node
                 oldNode.removeClass('nodeSelected');
                 // Highlight the new current node
                 newNode.addClass('nodeSelected');

                 var pathText = computeSubjectTreeText(newNode);
                 var treeTextDisplayField = $('#currentClassificationText');                
                 treeTextDisplayField.val(pathText);
                           
                 // Copy the id from the current node ID attribute to the
                 // hidden field that stores the current ID.
                 idField = $('#currentClassificationId'); 
                 idField.val(newNode.attr("id").substr(2));
                 // Close the popup
                 $('#subjectHelpTreeBox').fadeOut();
             });
         });
         
   });

   function computeSubjectTreeText(newNode) {
	// Set the display text in the form.
       var text = "";
       var sep = "";
       var parentNode = newNode.parents('li.nodeItem').each( 
           function() {
              text =  $(this).children('a.nodeText').first().text() + sep + text;
              sep = " " + String.fromCharCode(0x00BB) + " "; //>>
           });
       return text;
   }
  
   function compareHyphenated(x,y){
	  // alert("x=" + x + ",y=" + y + ";");
	  // Compare hyphenated data columns.
	  // X or Y are either single values, e.g. 16, or hypenated pairs, e.g. 16-300
	  //
	  // The algorithm:
	  // X   Y       RESULT  NOTES
	  // -------------------------
	  // N   P     = N - P   
	  // N-P N     = -1      E.g. 10-20 > 10
	  // N   N-P   = 1       E.g. 10 < 10-20
	  // N   P     = N - P   
	  // N-P N-Q   = P - Q   
      var xParts = x.split('-');
      var yParts = y.split('-');
      var xValue = parseInt(xParts[0]); 
      var yValue = parseInt(yParts[0]);
      if (xValue != yValue) {
          return xValue - yValue;
      }
      if (xParts.length == 2) {
          if (yParts.length == 2) {
              xValue = parseInt(xParts[1]); 
              yValue = parseInt(yParts[1]);
              return xValue - yValue;                    
          }
          return 1;
      }
      else if (yParts.length == 2) {
          return -1;
      }
      return 0;
   }; 
   
   // <!-- TROQ table sorting -->
   $(document).ready(function() {
	   
	    jQuery.fn.dataTableExt.oSort['hyphenated-num-asc'] = function(x,y){
            return compareHyphenated(x,y);
        };
		jQuery.fn.dataTableExt.oSort['hyphenated-num-desc'] = function(x,y){
            return compareHyphenated(y,x);
		};

        $('#searchResults').dataTable({
            bPaginate:     false,
            bLengthChange: false,
            bFilter:       false,
            bSort:         true,
            aaSorting:     [], // Don't initially sort (hopefully) 
            bInfo:         false,
            bAutoWidth:    false,
            aoColumns:     [
                   { bSortable: false },
                   { sType: "html" },
                   { sType: "html" },
                   { sType: "html" },
                   { sType: "html" },
                   { sType: "hyphenated-num" },
                   { sType: "hyphenated-num" },
                   { sType: "html" }
                   // WARNING - do not end aoColumns [] with a comma or IE6 will
                   // error and report the following error to the user:
                   // "Datatable doesn't support rowspan/colspan in the table body"
             ]
         });
   });

   // <!-- TROQ Level filtering -->
   $(function () {
       if ($.browser.msie) {
          $('input:radio').click(function () {
              this.blur();
              this.focus();
          });
       }
    });
   
   function setLevel() {
       var typeField = $("select#qualificationType");
       var typeVal = typeField.val();
       //alert("." + typeVal + ".");
       var levelField = $('select#qualificationLevel');
       var levelVal = $('select#qualificationLevel').val();
       //alert(levelVal);
       var min = parseInt($('#qualLevelMin' + typeVal).text()); 
       var max = parseInt($('#qualLevelMax' + typeVal).text());
       var levelWord = $('#qualLevelText').text();
       var allWord = $('#qualLevelAllText').text();
                            
       //alert("type=" + typeVal + " min=" + min + " max=" + max + " levelVal=" + levelVal + " lvl" + levelField.val());
       levelField.empty('option');
       levelField.append('<option value="">' + allWord + '</option>');
       for (i = min; i <= max; i++) {
           levelField.append('<option value="' + i + '">' + levelWord  + ' ' + i + '</option>');
       }
       if (levelVal == 'All' || (parseInt(levelVal) >= min && parseInt(levelVal) <= max)) {
           levelField.val(levelVal);
       }
       else {
           levelField.val('');
       }
   }
   
   $(document).ready(function() {  
	    
        $('select#qualificationType').change(function() {
            setLevel();
        });
   });

   // <!-- TROQ Focus -->
   $(document).ready(function() {
	   $('input#titleKeyWords').focus(); $('input#titleKeyWords').select();
   });
       

