// -----------------------------------------------------------------------------
// rvsearch.js		(Copyright 2003 Rick Harvey)
//
// NS4: We don't support NS4 because it is old (only 1% of web now use it), 
//	buggy (CSS, DOM) and non-std (no getElementById, no style.display)
//
// NS6:  Added getAttribute() and trimHTML() - to remove <SP><TAB><LF> etc
// -----------------------------------------------------------------------------

var vSet = new Array()   // videos
var rSet = new Array()   // ruler (for display between video categories)
var bSet = new Array()   // breeds (no aliases)
var aSet = new Array()   // (breed) aliases
var sSet = new Array()   // subjects (no "-")
var groupAll = new Array() // groupAll[i]=option:code       // all "-"
var breedAll = new Array() // breedAll[i]=option:code:block // no "-"
var subjectAll = new Array() // subjectAll[i]=option:code // no "-"
var selectedBreed = "xx"
var duplicateBreeds = ""
var paddedCodes = ""
var breedLegendObj = null

// called after page has finished loading via <body onload="rvSearchInit()">
function rvSearchInit()
{
  if (rhOldBrowser() && oldBrowser)  	// oldBrowser is a global setup by rhlib
    return
  comboSearchMsg("------------- (loading) -------------")
  breedLegendObj = document.getElementById("breedLegend")
  showObjId("searchBox", true)
  showObjId("breedsAndSubjects", false)
  initSearchSets()
  comboGroupFill()
  comboBreedFill("-b0")
  comboSubjectFill()
  showBreedLegend(false)
  showSections()
}

function rvSearchByGroup(code)
{
  if (oldBrowser)
    return
  optionGroup(code)
}

function rvSearchByBreed(code)
{
  if (oldBrowser)
    return
  if (! code)
    optionGroup(selectedBreed)
  else
    optionBreed(code)
}

function rvSearchBySubject(code)
{
  if (oldBrowser)
    return
  optionSubject(code)
}

function rvSearchOldBrowserWarning()
{
  if (oldBrowser)
    document.write("Sorry, your browser is unable to run the JavaScript search functions.<br>")
}

function rvCheckDB()
{
  if (oldBrowser)
    return
  checkCodes()
  checkBreeds()
  checkSubjects()
  checkVideos()
}

// -----------------------------------------------------------------------------
// initialisation
// -----------------------------------------------------------------------------

function initSearchSets()
{
  var divSet = document.getElementsByTagName("div")
  for (i = 0; i < divSet.length; i++)
    initObj(divSet[i])
  breedAll.sort()
  subjectAll.sort()
}

function initObj(obj)
{
  initAttrs(obj)
  if (obj.video)
    addVideo(obj)
  else if (obj.breed)
    addBreed(obj)
  else if (obj.subject)
    addSubject(obj)
  else if (obj.ruler)
    addRuler(obj)
}

// getAttribute because of NS6
function initAttrs(obj)
{
  // video
  if (obj.video || obj.getAttribute("video"))
    obj.video = (obj.video) ? trimCode(obj.video) : trimCode(obj.getAttribute("video"));
  if (obj.subj || obj.getAttribute("subj"))
    obj.subj = (obj.subj) ? trimCode(obj.subj) : trimCode(obj.getAttribute("subj"));
  if (obj.many || obj.getAttribute("many"))
    obj.many = (obj.many) ? trimCode(obj.many) : trimCode(obj.getAttribute("many"));
  // breed
  if (obj.breed || obj.getAttribute("breed"))
    obj.breed = (obj.breed) ? trimCode(obj.breed) : trimCode(obj.getAttribute("breed"));
  if (obj.spec || obj.getAttribute("spec"))
    obj.spec = (obj.spec) ? trimCode(obj.spec) : trimCode(obj.getAttribute("spec"));
  if (obj.feat || obj.getAttribute("feat"))
    obj.feat = (obj.feat) ? trimCode(obj.feat) : trimCode(obj.getAttribute("feat"));
  if (obj.foot || obj.getAttribute("foot"))
    obj.foot = (obj.foot) ? trimCode(obj.foot) : trimCode(obj.getAttribute("foot"));
  if (obj.gen || obj.getAttribute("gen"))
    obj.gen = (obj.gen) ? trimCode(obj.gen) : trimCode(obj.getAttribute("gen"));
  // subject
  if (obj.subject || obj.getAttribute("subject"))
    obj.subject = (obj.subject) ? trimCode(obj.subject) : trimCode(obj.getAttribute("subject"));
  // all
  if (obj.block || obj.getAttribute("block"))
    obj.block = (obj.block) ? trimCode(obj.block) : trimCode(obj.getAttribute("block"));
  // ruler
  if (obj.ruler || obj.getAttribute("ruler"))
    obj.ruler = (obj.ruler) ? trimCode(obj.ruler) : trimCode(obj.getAttribute("ruler"));
}

function addVideo(obj)
{
  var vcode = obj.video
  vSet[vcode] = obj
}

function addBreed(obj)
{
  var bcode = obj.breed
  if (bcode.charAt(0) == "-")	// group
  {
    groupAll[groupAll.length] = trimHTML(obj.innerHTML) + ":" + bcode
    return
  }
  if (breedAttrs(obj))		// breed
  {
    if (bSet[bcode])
      duplicateBreeds = duplicateBreeds + bcode + " "
    else
      bSet[bcode] = obj
  }
  else				// alias
  {
    aSet[bcode] = obj
  }
  var block = (obj.block) ? obj.block : ""
  breedAll[breedAll.length] = trimHTML(obj.innerHTML) + ":" + bcode + ":" + block
}

function addSubject(obj)
{
  var scode = obj.subject
  if (scode.charAt(0) != "-")
  {
    sSet[scode] = obj
    subjectAll[subjectAll.length] = trimHTML(obj.innerHTML) + ":" + scode
  }
}

function addRuler(obj)
{
  var rcode = obj.ruler
  rSet[rcode] = obj
}

// -----------------------------------------------------------------------------
// selected option routines
// -----------------------------------------------------------------------------

function optionGroup(code)
{
  if (code.substr(0,3) == "-b0")
    showAllBreeds(code)
  else if (code.substr(0,2) == "-b")
    showBreedBlock(code)
  comboBreedFill(code)
  comboSubjectReset()
  showBreedLegend(false)
  showSections()
}

function optionBreed(code)
{
  showBreed(code)
  comboSubjectReset()
  showBreedLegend(true)
  showSections()
}

function optionSubject(code)
{
  showSubject(code)
  comboGroupReset()
  comboBreedReset()
  showBreedLegend(false)
  showSections()
}

// -----------------------------------------------------------------------------
// combo box routines
// -----------------------------------------------------------------------------

function comboGroupFill()
{
  var opt = document.searchForm.byGroup.options
  comboClear(opt)
  for (var i = 0; i < groupAll.length; i++)
  {
    var items = groupAll[i].split(":")
    opt[opt.length] = new Option(items[0], items[1])
  }
  opt.selectedIndex = 0;
}

function comboBreedFill(breedCode)
{
  if (breedCode == selectedBreed)
    return
  comboBreedMsg("----------- Select Breed -----------")
  if (breedCode.length > 2)
  {
    var opt = document.searchForm.byBreed.options
    var all = (breedCode.charAt(2) == "0")
    var previous = ""
    for (var i = 0; i < breedAll.length; i++)
    {
      var items = breedAll[i].split(":")
      if (all || breedCode == items[2])
      {
      	// some breeds can be in two groups (in two different countries)
      	if (items[0] != previous)
          opt[opt.length] = new Option(items[0], items[1])
        previous = items[0]
      }
    }
  }
  selectedBreed = breedCode
}

function comboSubjectFill()
{
  var opt = document.searchForm.bySubject.options
  comboClear(opt)
  comboSubjectMsg("----------- Select Subject -----------")
  for (var i = 0; i < subjectAll.length; i++)
  {
    var items = subjectAll[i].split(":")
    opt[opt.length] = new Option(items[0], items[1])
  }
  opt.selectedIndex = 0;
}

function comboGroupReset()
{
  document.searchForm.byGroup.options.selectedIndex = 0
  comboBreedFill("-b0")
}

function comboBreedReset()
{
  document.searchForm.byBreed.options.selectedIndex = 0  
}

function comboSubjectReset()
{
  document.searchForm.bySubject.options.selectedIndex = 0  
}

function comboSearchMsg(msg)
{
  comboGroupMsg(msg)
  comboBreedMsg(msg)
  comboSubjectMsg(msg)
}

function comboGroupMsg(msg)
{
  var combo = document.searchForm.byGroup
  comboMsg(combo, msg)
}

function comboBreedMsg(msg)
{
  var combo = document.searchForm.byBreed
  comboMsg(combo, msg)
}

function comboSubjectMsg(msg)
{
  var combo = document.searchForm.bySubject
  comboMsg(combo, msg)
}

function comboMsg(opt, msg)
{
  comboClear(opt)
  opt.options[0] = new Option(msg)
  opt.selectedIndex = 0;
}

function comboClear(opt)
{
  while (opt.length > 0)
    opt[opt.length-1] = null;

}

// -----------------------------------------------------------------------------
// display routines
// -----------------------------------------------------------------------------

function showSections()
{
  for (var r in rSet)
    rSet[r].show = false
  for (var v in vSet)
    if (objVisible(vSet[v]) && vSet[v].block)
      rSet[vSet[v].block].show = true
  var firstBlock = ""
  for (var r in rSet)
  {
    var visible = rSet[r].show
    var blockNum = parseInt(r.substr(2))
    showObj(vSet[r], visible)	// header
    showObj(rSet[r], visible)	// ruler
    if (visible)
      if (!firstBlock || blockNum < firstBlock)
        firstBlock = blockNum
  }
  if (firstBlock)	// don't show first ruler
    showObj(rSet["-v"+firstBlock], false)
}

function showBreed(code)
{
  var breedObj = bSet[code]
  if (! breedObj)
    return
  for (var v in vSet)
  {
    var style = ""
    if (codeInList(v, breedObj.spec))
      style = "rvSpecialty"
    else if (codeInList(v, breedObj.feat))
      style = "rvDescription"
    else if (codeInList(v, breedObj.foot))
      style = "rvFootage"
    else if (codeInList(v, breedObj.gen))
      style = "rvGeneral"
    showVideoBreed(vSet[v], style, style)
  }
}

function showSubject(code)
{
  for (var v in vSet)
    showVideoStyle(vSet[v], codeInList(code, vSet[v].subj), "")
}

function showBreedBlock(code)
{
  var videos = " "
  for (var b in bSet)
    if (bSet[b].block && code == bSet[b].block)
      videos = videos + getBreedCodes(bSet[b], videos)
  // alert("block="+code+".\r\nvideos="+videos+".")
  for (var v in vSet)
    showVideoBreed(vSet[v], codeInCodes(v, videos), "")
}

function showAllBreeds(code)
{
  for (var v in vSet)
    showVideoBreed(vSet[v], true, "")
}

function showAllSubjects(code)
{
  for (var v in vSet)
    showVideoStyle(vSet[v], (vSet[v].subj), "")
}

function showVideoBreed(obj, show, style)
{
  if (obj)
  {
    if (!show && codeInList("allbreeds", obj.many))
      show = true
    showVideoStyle(obj, show, style)
  }
}

function showVideoStyle(obj, show, style)
{
  if (obj)
  {
    obj.className = style
    showObj(obj, show)
  }
}

function showObjId(id, show)
{
  var obj = document.getElementById(id)
  showObj(obj, show)
}

function showBreedLegend(show)
{
  showObj(breedLegendObj, show)
}

function showObj(obj, show)
{
  if (obj)
    obj.style.display = (show) ? "block" : "none"
}

function objVisible(obj)
{
  if (obj && obj.style.display != "none")
    return true
  return false
}

// -----------------------------------------------------------------------------
// database checking routines
// -----------------------------------------------------------------------------

function checkCodes()
{
  if (paddedCodes)
    alert("CODES WITH EXTRA PADDING\r\n"+paddedCodes)
}

function checkBreeds()
{
  var badAliases = ""
  for (var a in aSet)
    if (! checkBreedAlias(a))
      badAliases = badAliases + a + " "
  if (badAliases)
    alert("BREEDS WITH NO VIDEOS\r\n" + badAliases)
  if (duplicateBreeds)
    alert("BREEDS DEFINED TWICE\r\n" + duplicateBreeds)
}

function checkBreedAlias(alias)
{
  for (var b in bSet)
    if (b == alias)
      if (breedAttrs(bSet[b]))
        return true
  return false
}
    
function checkSubjects()
{
  var subjects = " allbreeds "
  for (var s in sSet)
    subjects = subjects + s + " "
  // alert("Subjects:"+subjects)
  for (var v in vSet)
    if (vSet[v].subj && ! allOfListInCodes(vSet[v].subj, subjects))
      alert("VIDEO ("+vSet[v].video+") HAS BAD SUBJECT\r\n"+vSet[v].subj)
}

function checkVideos()
{
  var videos = " "
  for (var v in vSet)
    videos = videos + v + " "
  //alert("Videos:"+videos)
  for (var b in bSet)
  {
    if (bSet[b].spec && ! allOfListInCodes(bSet[b].spec, videos))
      alert("BREED ("+bSet[b].breed+") HAS BAD SPECIALTY\r\n"+bSet[b].spec)
    if (bSet[b].feat && ! allOfListInCodes(bSet[b].feat, videos))
      alert("BREED ("+bSet[b].breed+") HAS BAD FEATURE\r\n"+bSet[b].feat)
    if (bSet[b].foot && ! allOfListInCodes(bSet[b].foot, videos))
      alert("BREED ("+bSet[b].breed+") HAS BAD FOOTAGE\r\n"+bSet[b].foot)
    if (bSet[b].gen && ! allOfListInCodes(bSet[b].gen, videos))
      alert("BREED ("+bSet[b].breed+") HAS BAD GENERAL\r\n"+bSet[b].gen)
  }
}

// -----------------------------------------------------------------------------
// string list routines
// -----------------------------------------------------------------------------

function breedAttrs(breedObj)
{
  return (breedObj.spec || breedObj.feat || breedObj.foot || breedObj.gen)
}

function getBreedCodes(breedObj, codes)
{
  var list = ""
  if (breedObj.spec)
    list = list + " " + breedObj.spec
  if (breedObj.feat)
    list = list + " " + breedObj.feat
  if (breedObj.foot)
    list = list + " " + breedObj.foot
  if (breedObj.gen)
    list = list + " " + breedObj.gen
  return getNewCodes(list, codes)
}

function getNewCodes(list, codes)
{
  var str = ""
  var listSet = list.split(" ")
  for (var i = 0; i < listSet.length; i++)
    if (listSet[i] && ! codeInCodes(listSet[i], codes))
      str = str + listSet[i] + " "
  return str
}

function anyOfListInCodes(list, codes)
{
  if (! list || ! codes)
    return false
  var listSet = list.split(" ")
  for (var i = 0; i < listSet.length; i++)
    if (codeInCodes(listSet[i], codes))
      return true
  return false
}

function allOfListInCodes(list, codes)
{
  if (! list)
    return true
  if (! codes)
    return false
  var listSet = list.split(" ")
  for (var i = 0; i < listSet.length; i++)
    if (listSet[i] && ! codeInCodes(listSet[i], codes))
      return false
  return true
}

function codeInCodes(code, codes)
{
  if (! code || ! codes)
    return false
  var codeDelimited = " " + code + " "
  return (codes.indexOf(codeDelimited) >= 0)
}

function itemInCodes(item, codes)
{
  if (! item || ! codes)
    return false
  var itemDelimited = " " + item + " "
  return (codes.indexOf(itemDelimited) >= 0)
}

function codeInList(code, list)
{
  if (! code || ! list)
    return false
  var codeDelimited = " " + code + " "
  var listDelimited = " " + list + " "
  return (listDelimited.indexOf(codeDelimited) >= 0)
}

// -----------------------------------------------------------------------------
// string routines
// -----------------------------------------------------------------------------

function trimCode(code)
{
  var txt = trimWhiteSpace(code)
  if (txt != code)
    paddedCodes = paddedCodes + "(" + code + ")"
  return txt.toLowerCase()
}

function trimHTML(code)
{
  var txt = unescapeHTML(code)
  txt = trimTags(txt)
  return trimWhiteSpace(txt)
}

// recursive!
function trimTags(txt)
{
  var start = txt.indexOf('<')
  var end = txt.indexOf('>')
  if (start >= 0 && end > start)
  {
    var str = txt.substring(0, start) + txt.substring(end+1)
    txt = trimTags(str)
  }
  return txt
}

function unescapeHTML(txt)
{
  return txt.replace(/&amp;/g, '&').replace(/&nbsp;/g, ' ')
}


function trimWhiteSpace(txt)
{
  // remove multiple internal spaces, leading spaces and trailing spaces
  return txt.replace(/\s\s+/g, ' ').replace(/^\s+/, '').replace(/\s+$/, '')
}

