var fieldInfo = {
  "cat" : {
    "id" : "#cat",
    "field" : "categories",
    "allowMulti" : false
  },

  "vets" : {
    "id" : "#vets",
    "name" : "Vet Jobs",
    "field" : "specialties",
    "top" : -1
  },
    
  "jobsOutsideUK" : {
    "id" : "#jobsOutsideUK",
    "name" : "Jobs outside UK",
    "field" : "specialties"
  },
  
  "nursing" : {
    "id" : "#nursing",
    "name" : "Nursing Jobs",
    "field" : "specialties"
  },
  
  "practiceManagement" : {
    "id" : "#practiceManagement",
    "name" : "Practice Management Jobs",
    "field" : "specialties"
  },  

 "locumAgencies" : {
    "id" : "#locumAgencies",
    "name" : "Locum Agencies",
    "field" : "specialties",
    "searchType" : "locumAgencies"
  },
  
 "directory" : {
    "id" : "#directory",
    "name" : "Directory",
    "field" : "specialties",
    "top" : -5,
    "searchType" : "directory"
  },

 "coursesConfMeeting" : {
    "id" : "#coursesConfMeeting",
    "name" : "Education & Learning",
    "field" : "specialties",
    "searchType" : "coursesConfMeeting"
  },

  "notices" : {
    "id" : "#notices",
    "name" : "Notices",
    "field" : "specialties",
    "searchType" : "notices"
  },
  
  "reg" : {
    "id" : "#subregion",
    "name" : "Region(s)",
    "field" : "regions"
  },

  "grd" : {
    "id" : "#subgrade",
    "name" : "Grade",
    "field" : "grades"
  },

  "wp" : {
    "id" : "#subwpattern",
    "name" : "Work Pattern",
    "field" : "workpatterns"
  }
};

var categoryCodes = [
  "vets",  
  "nursing", 
  "practiceManagement",
  "jobsOutsideUK", 
  "locumAgencies",
  "directory",
  "coursesConfMeeting",
  "notices"
];

var cssClassesBySearchType = {
  notices: "notice",
  courses: "course",
  locumAgencies: "directory",
  directory: "directory"
};

var archiveOption;
// All fields visible, free choice of category.
function openAdmin(rootId)
{
  log("openAdmin");
  return initialiseForm(rootId, { isAdmin: true, searchType: "adminSearch" });
}

// Job search plus archive fields
function openArchive(rootId)
{
    log("openArchive");
    return initialiseForm(rootId, { searchType: "archive", showArchive: true });
}

// Free choice of job categories.
function openJobs(rootId, initialCategory)
{
  if (initialCategory)
    return initialiseForm(rootId, { category: initialCategory, searchType: "jobsearch" });
  else
    return initialiseForm(rootId, { searchType: "jobsearch" });
}

function openNotices(rootId)
{    
    return initialiseForm(rootId, { searchType: "notices", showArchive: false, fixedCategory: true, category: 8 });
}

function openCourses(rootId)
{
  return initialiseForm(rootId, { searchType: "courses", fixedCategory: false, showArchive: false });
}

function openCoursesSelectedCategory(rootId)
{
  return initialiseForm(rootId, { searchType: "coursesConfMeeting", showArchive: false, fixedCategory: true, category: 7 });
}

function openDirectory(rootId)
{
  return initialiseForm(rootId, { searchType: "directory", showArchive: false, fixedCategory: true, category: 6 });
}

function openLocumAgencies(rootId)
{
  return initialiseForm(rootId, { searchType: "locumAgencies", showArchive: false, fixedCategory: true, category: 5 });
}

/**
 * Given a set of options this sets up the initial
 * state of the search box, so it has the correct
 * items showing and appropriate behaviour.
 */
function initialiseForm(rootId, options)
{

    var root = $(rootId);

    var options = $.extend({
        popup : true,
        searchType : "jobsearch",
        isAdmin : false,
        showArchive : false,
        fixedCategory : false,
        category : -1
    }, options || {});

  log("initialiseForm(%o, %o)", root, options);
  archiveOption = options.showArchive;

  
  // Set CSS class of form from search type.
  var css = options.searchType in cssClassesBySearchType ? cssClassesBySearchType[options.searchType] : "job";
  root.addClass(css);

  root.find("#close")
    .click(function() { $(this).removeClass(css); return true; }); 
  if(options.isAdmin)
  {
    root.find("#status-field, #cat-5, #cat-6, #cat-7, #cat-8").show();
  }else
  {
    root.find("#status-field, #cat-5, #cat-6, #cat-7, #cat-8").hide();
  }
  
  if(options.showArchive == true)
  {
   root.find("#archive").show();
  }
   else
  {
   root.find("#archive").hide();   
  }
  if(options.fixedCategory == false){
      if(options.searchType == "courses"){
         root.find("#cat-1, #cat-2, #cat-3, #cat-4").visible(false);
         root.find(" #cat-5, #cat-6, #cat-7, #cat-8").visible(true);   
      }
      if(options.searchType == "jobsearch"){
         root.find("#cat-1, #cat-2, #cat-3, #cat-4").show();
         root.find(" #cat-5, #cat-6, #cat-7, #cat-8").hide();   
      }
      if(options.searchType == "archive"){
         root.find("#cat-1, #cat-2, #cat-3, #cat-4").visible(true);
         root.find(" #cat-5, #cat-6, #cat-7, #cat-8").visible(false);   
      }      
  }
  if(options.searchType == "coursesConfMeeting"){
     root.find("#cat-1, #cat-2, #cat-3, #cat-4").visible(false);
     root.find(" #cat-5, #cat-6, #cat-7, #cat-8").visible(true);   
  }
  if (options.searchType == "notices")
  {
     root.find("#cat-1, #cat-2, #cat-3, #cat-4").visible(false);
     root.find(" #cat-5, #cat-6, #cat-7, #cat-8").visible(true);   
  }
  if (options.searchType == "directory")
  {
     root.find("#cat-1, #cat-2, #cat-3, #cat-4").visible(false);
     root.find(" #cat-5, #cat-6, #cat-7, #cat-8").visible(true);   
  }
  if (options.searchType == "locumAgencies")
  {
     root.find("#cat-1, #cat-2, #cat-3, #cat-4").visible(false);
     root.find(" #cat-5, #cat-6, #cat-7, #cat-8").visible(true);   
  }

  if (options.showArchive) 
  {       
    //root.find("#archive-subcat").visible(options.showArchive);
    root.find("#archive-subcat").show();
    root.find("#subcat").hide();
    
  }
  else
  {     
    root.find("#archive-subcat").hide();
    root.find("#subcat").show();
  }

    // Remove category dropdown and item delete buttons if we can't change category.
  if(options.fixedCategory == true)
  {
    root.find("#cat a.drop").hide();
  }else
  {
    root.find("#cat a.drop").show();  
  }
  // Set initial category, if any.
  setCategory(root, options.category, options.searchType);

  if (options.fixedCategory)
    $("#cat span.x").hide();

  // Show everything for admin search.
  if (options.isAdmin)
  {
    log("isAdmin show reg grd wp");
     root.find("#archive, #reg, #grd, #wp").show();
  }

  root.find("#searchType").val(options.searchType);
  root.find("#admin").val(options.isAdmin);

  // Show popup window now if we're not embedded.
  if (options.popup)
  {
    $.popupbox(root.attr("id"));
  }

  // Bind submit button to form.
  root.find("a.go").click(function()
  {
    root.find("form").submit();
  });

  log("initialiseForm done");

  return false;
}

/**
 * The category has changed, so clear fields and make
 * sure we're showing the right ones.
 */
function setCategory(root, catVal, searchTypeVal)
{   
    var root = $(root);

    log("setCategory: %s", catVal);

    // Remove all current items, including from category.
    root.find(".field-items").empty();         
    if (archiveOption)
    {
      
        // Initially hide all other fields.
        root.find("#archive-notices, #archive-vets, #archive-practiceManagement, #archive-jobsOutsideUK, #archive-locumAgencies, #archive-coursesArchiveMeeting, #archive-nursing, #archive-directory, #archive-reg, #archive-grd, #archive-wp").hide();
        root.find("#archive-subcat-reg-down, #archive-subcat-wp-down").show();
        root.find("#archive-subcat-reg-down-more, #archive-subcat-wp-down-more").hide();      
        // Category picked, show appropriate fields.         
        if (catVal && catVal != -1)
        {    
             var catCode = categoryCodes[catVal - 1], fi = fieldInfo[catCode];                           
            log("setCategory: catval: %s, catcode: %s, fi[cc]: %o", catVal, catCode, fi);           
            // Add category item.
            addDirect(root, "cat", catVal, fi["name"]);
    
            // Show selected category's field and other sub-fields.            
            root.find("#archive-" + catCode).show();
            root.find("#archive-subcat-"+catCode+"-down").show();
            root.find("#archive-subcat-"+catCode+"-down-more").hide();
            
            if (catVal == 4) 
            {
                // jobs outside uk
                root.find("#archive-wp").show();
                root.find("#archive-subcat-wp-down").show();
                root.find("#archive-subcat-wp-down-more").hide();  
            }
            else if (catVal == 3 || catVal == 2)           
            {
                // nursing,practiceManagement
                root.find("#archive-reg, #archive-wp").show();
                root.find("#archive-subcat-reg-down, #archive-subcat-wp-down").show();
                root.find("#archive-subcat-reg-down-more, #archive-subcat-wp-down-more").hide();
            }
            else if (catVal == 1)    
            {
                // vets                
                root.find("#archive-reg, #archive-wp, #archive-grd").show();               
                root.find("#archive-subcat-reg-down, #archive-subcat-wp-down, , #archive-subcat-grd-down").show();
                root.find("#archive-subcat-reg-down-more, #archive-subcat-wp-down-more, #archive-subcat-grd-down-more").hide();
            } 
            else
            {
               $("#searchType").val(searchTypeVal);
            }             
        }
    }
    else
    {    
        root.find("#notices, #vets, #practiceManagement, #jobsOutsideUK, #locumAgencies, #coursesConfMeeting, #directory, , #nursing, #reg, #grd, #wp").hide(); 
        root.find("#subcat-reg-down, #subcat-wp-down, #subcat-grd-down").show();
        root.find("#subcat-reg-down-more, #subcat-wp-down-more, #subcat-grd-down-more").hide();       
        // Category picked, show appropriate fields.        
        if (catVal && catVal != -1)
        {
            var catCode = categoryCodes[catVal - 1], fi = fieldInfo[catCode];
            log("setCategory: catval: %s, catcode: %s, fi: %o", catVal, catCode, fi);
    
            // Add category item.
            addDirect(root, "cat", catVal, fi["name"]);
    
            // Show selected category's field and other sub-fields.
            root.find("#" + catCode).show();
            root.find("#subcat-"+catCode+"-down").show();
            root.find("#subcat-"+catCode+"-down-more").hide();
            
            if (catVal == 4)
            {
                // jobs outside uk
                root.find("#wp").show();   
                root.find("#subcat-wp-down").show();
                root.find("#subcat-wp-down-more").hide();  
            }
            if (catVal == 3 || catVal == 2)
            {
                // nursing,practiceManagement
                root.find("#reg, #wp").show();   
                root.find("#subcat-reg-down, #subcat-wp-down").show();
                root.find("#subcat-reg-down-more, #subcat-wp-down-more").hide(); 
                root.find("#subcat-"+catCode+"-down-more").hide();
            }

            else if (catVal == 1)  
            {
              // vets
              root.find("#reg, #wp, #grd").show();  
              root.find("#subcat-reg-down, #subcat-wp-down, #subcat-grd-down").show();
              root.find("#subcat-reg-down-more, #subcat-wp-down-more, #subcat-grd-down-more").hide();  
            } 
            else
            {
                $("#searchType").val(searchTypeVal);
            }                         
        }
    }    
  return false;
}

/**
 * Called when setting values from user search objects
 * as we're bypassing the usual setup.
 */
function addDirect(root, fieldCode, id, text)
{
  var root = $(root);
  log("addDirect: root: %o, id: %s, t: %s, field: %s", root, id, text, fieldCode);
/*  
  showgrade = "sub-class-"+id;
  var grades = document.getElementsByTagName('li');
  for(i=0;i<grades.length;i++){
      grade = grades[i];      
      if(grade.id.match(/sub-class/g)){
          if(grade.id.match(showgrade)){
            grade.style.display = 'block';
          }else{
            grade.style.display = 'none';
          }
      }  
  }
  

 this is simpler and works in firefox but not in IE !!!
  showgrade = "sub-class-"+id;
  var grades = document.getElementsByTagName('sub-classification');
  for(i=0;i<grades.length;i++){
      grade = grades[i];
      if(grade.id == showgrade){
          grade.style.display = 'block';
      }else{
          grade.style.display = 'none';
      }   
  }

*/

  var divId = fieldCode + id;    
  if (root.find("#" + divId).length == 0)
  {
    var fi = fieldInfo[fieldCode];

    // Create new item containing the input tag for the form.    
    var newdiv = document.createElement('div');
    newdiv.setAttribute("id", divId);
    // Mantis ID: 0005884 Cannot remove selected category on Safari
    if (isSafari())     
    {           
        newdiv.innerHTML = fmt("<div id='%s' class='%s'>",fieldCode, fieldCode)+"<div class='search-word'><a class='tab' href='#' alt='Click here to remove' title='Click here to remove'><span><span><span><span>"
          + fmt("<input type='hidden' name='%s' value='%s'/>%s<span class='x'/>", fi["field"], id, text)
          + "</span></span></span></span></a></div></div>";
        
        var $items = $(root).find("#" + fieldCode + " div.field-items");      
        if (archiveOption) 
        {       
            if (fieldCode!='cat')
            {
                $items = $(root).find("#archive-" + fieldCode + " div.field-items");
            }               
        }
        
        // Initialise x button on new item and add the whole thing to the items div.
        $(newdiv)
          .find("span.x")
            .hover(
              function() { this.className = "x_hover" },
              function() { this.className = "x" })
            .click(function()
            {            
                $(newdiv).remove();                 
            setSubCatVisibility($items, fieldCode); 
            })
            .end()
      .appendTo($items);     
      setSubCatVisibility($items, fieldCode);   
    }
    else 
    {
         newdiv.innerHTML = fmt("<div id='%s' class='%s'>",fieldCode, fieldCode)+"<div class='search-word'><a class='tab' href='#' alt='Click here to remove' title='Click here to remove'><span><span><span><span>"
          + fmt("<input type='hidden' name='%s' value='%s'/>%s<span class='y'> </span>", fi["field"], id, text)
          + "</span></span></span></span></a></div>";
    
        // Find div for items.
        var $items = $(root).find("#" + fieldCode + " div.field-items");
        if (archiveOption) 
        {
            if (fieldCode!='cat')
            {
                $items = $(root).find("#archive-" + fieldCode + " div.field-items");                
            }   
        }
        // Initialise x button on new item and add the whole thing to the items div.
        $(newdiv)
          .find("span.y")
            .hover(
              function() { this.className = "y_hover" },
              function() { this.className = "y" })
            .click(function()
            {             
                $(newdiv).remove();             
        setSubCatVisibility($items, fieldCode);               
            })
            .end()
      .appendTo($items);                        
      setSubCatVisibility($items, fieldCode);   
    }
  }
  return false;
}

/**
 * Adds an element to the multi-select when the user
 * selects an option.
 */
function addElement(root, source, fieldCode)
{   
    var id = source.href.split("#")[1], text = source.innerHTML;    
    return addDirect(root, fieldCode, id, text);
}

/**
 * Positions the element underneath the dropdown button.
 */
function positionList($button, fieldCode)
{
    var $menu = $button.next();    
    log("positionList(%s, %s)", fieldCode, fieldInfo[fieldCode]["top"]);
    var offset = $button.height() + (fieldInfo[fieldCode]["top"] ? fieldInfo[fieldCode]["top"] : 5);

    $menu.css("margin-top", offset);
   
  // For IE 6.
    if ($menu.css("left") == "auto")
      $menu.css("margin-left", -$button.width());
}

/**
   * Detects if the cookies are disable or not,
   * if they are disable warns users the search will not work with disable cookies.
   */
function detectCookies()
{
  var h = window.location.host;
  h = h.substring(h.indexOf(".") + 1);

  $.cookie('the_cookie', 'the_value', { path: '/' }); // set cookie
  if(!($.cookie('the_cookie'))){
     /*alert('Your browser is not accepting cookies. In order to use the search you must allow cookies.\n\n To allow cookies in IE go to: tools>internet options >privacy and change privacy to medium. \n To allow cookies in Firefox go to: tools>options>privacy and tick \'accept cookies from sites\'.\n To allow cookies in Safari go to: Safari>Preferences>Security and tick \'accept cookies: only from sites I navigate to\'');     }
    */

     $.popupbox("cookiebox");
     return true;
  }
  return false;
}

/**
 * Causes the dropdown list for the given field to
 * dropdown below the source element.
 */
function openList(source, fieldCode)
{  
  var menuDiv = $(source).next();  
  log("openList src: %o, code: %s, next: %o", source, fieldCode, menuDiv);
  positionList($(source), fieldCode); 
  $(document).mouseup(function()
  {
    $(document).click(function(e)
    {    
      menuDiv.hide();
      $(document).unbind("click");
      return false;
    });
    $(document).unbind("mouseup"); 
    return false;
  });

  $(menuDiv).show();   
  return false;
}

/**
 * Causes the dropdown list for the given field to
 * dropdown below the source element.
 * only applicable to sub category
 */
function openSubList(source, fieldCode)
{  
  var $items = $(document).find("#" + fieldCode + " div.field-items");
  var menuDiv = $(source).next();  
  log("openSubList src: %o, code: %s, next: %o", source, fieldCode, menuDiv);
  positionList($(source), fieldCode);   
  $(document).mouseup(function()
  {  
    $(document).click(function(e)
    {    
      menuDiv.hide();
      $(document).unbind("click");   
      if (archiveOption) 
      {
        $items = $(document).find("#archive-" + fieldCode + " div.field-items");        
        setSubCatVisibility($items, fieldCode);
      }
      else
      {        
        setSubCatVisibility($items, fieldCode);         
      }     
      return false;
    });
    $(document).unbind("mouseup"); 
    return false;
  });
  $(menuDiv).show();   
  return false;
}

/**
*   set sub category 'Add another xxx' button visibility
*/
function setSubCatVisibility(items, fieldCode)
{
    if (items.find("#"+fieldCode).length > 0)
    {
        if (archiveOption)
        {           
            var divId = "#archive-subcat-"+fieldCode+"-down";
            $(document).find(divId).hide();
            $(document).find(divId+"-more").show();
        }
        else
        {   
            var divId = "#subcat-"+fieldCode+"-down";
            $(document).find(divId).hide();
            $(document).find(divId+"-more").show(); 
        }
        
    }
    else
    {
        if (archiveOption)
        {           
            var divId = "#archive-subcat-"+fieldCode+"-down";
            $(document).find(divId).show();
            $(document).find(divId+"-more").hide();
        }
        else
        {   
            var divId = "#subcat-"+fieldCode+"-down";
            $(document).find(divId).show();
            $(document).find(divId+"-more").hide(); 
        }
    }
}