function update_fp_type() {
  document.getElementById('os_form').style.display='none';
  document.getElementById('os_correction_form').style.display='none';
  document.getElementById('service_form').style.display='none';
  document.getElementById('service_correction_form').style.display='none';
  document.getElementById('email_submit_form').style.display='none';

  if (document.getElementById('submission_type').value == "new") {
    if (document.getElementById('fingerprint_type').value == "os")
      document.getElementById('os_form').style.display='inline';
    if (document.getElementById('fingerprint_type').value == "service")
      document.getElementById('service_form').style.display='inline';
  } else {
    if (document.getElementById('fingerprint_type').value == "os")
      document.getElementById('os_correction_form').style.display='inline';
    if (document.getElementById('fingerprint_type').value == "service")
      document.getElementById('service_correction_form').style.display='inline';
  }

  if (document.getElementById('fingerprint_type').value != "") {
    document.getElementById('email_submit_form').style.display='';
  }

  //scroll(0,0);
}


function update_service_choice(which) {
  var source, dest, i;

  if (which == "name") {
    source = document.getElementById('service_by_name_dropdown');
    dest = document.getElementById('service_by_pop_dropdown');
  } else {
    source = document.getElementById('service_by_pop_dropdown');
    dest = document.getElementById('service_by_name_dropdown');
  }

  document.getElementById('service_other').value = source.value;

  for (i=0; i<dest.options.length; i++) {
    if (source.value == dest.options[i].value) {
      dest.selectedIndex = i;
      return;
    }
  }
}



function follow_ostrie_path(trie, path) {
  var i, val, newpath;

  if (path.length == 0)
    return trie;

  val = document.getElementById(path[0]).value;

  newpath = new Array();
  for (i=1; i<path.length; i++) {
    newpath[i-1] = path[i];
  }

  for (i=1; i<trie.length; i++) {
    if (val == trie[i][0])
      return follow_ostrie_path(trie[i], newpath);
  }
}


function recurse_count(trie) {
  var i, c = 0, t = typeof trie;

  if (t == "number") return trie;
 
  for (i=1; i<trie.length; i++)
    c += recurse_count(trie[i]);

  return c;
}


function replace_branch(base, path, onchange) {
  var p, sel, inp, trie, skip;

  p = document.createElement('p');

  sel = document.createElement('select');
  sel.id = sel.name = (base + "_dropdown");
  sel.onchange = onchange;

  trie = follow_ostrie_path(ostrie, path);
  if (!trie) return; // selected unknown

  sel.options[0] = new Option("Unknown/Other (describe below)", "");

  for (i=1; i<trie.length; i++) {
    //var disp_len = trie[i].length-1;
    // If this is a leaf we want to give the number stored there, not the number of sub-branches
    //if (base == "os_class_devtype")
    //  disp_len = trie[i][1];
    disp_len = recurse_count(trie[i]);

    sel.options[i] = new Option(trie[i][0] + " (" + disp_len + ")", trie[i][0]);
  }
  p.appendChild(sel);

  document.getElementById(base + "_div").appendChild(p);

  // Special cases:

  // If we're replacing 'name and only choice is what was already in 'vendor we can skip the name. IE: Linux, OpenBSD
  if (base == "os_class_name"
      && sel.options.length == 2
      && document.getElementById("os_class_vendor_dropdown").value == sel.options[1].value)
    skip = 1;

  // If we're replacing 'family and value for 'name is "embedded" we can skip the family.
  if (base == "os_class_family"
      && document.getElementById("os_class_name_dropdown").value == "embedded")
    skip = 1;

  // If we're replacing 'family and only value for 'family is "" we can skip the family. IE: NetBSD
  if (base == "os_class_family"
      && sel.options.length == 2
      && document.getElementById("os_class_family_dropdown").value == "")
    skip = 1;

  // Allow people to enter their own trie leaves with an "other" textbox? Nah...
  //p.appendChild(document.createElement('br'));
  //inp = document.createElement('input');
  //inp.id = inp.name = base + "_other";
  //inp.onkeyup = function () { };
  //p.appendChild(inp);

  if (skip) {
    sel.selectedIndex = 1;
    onchange();
  } else {
    document.getElementById(base + "_fieldset").style.display='';
    //document.getElementById(base + "_div").focus();
  }
}


function nuke_path(path) {
  var i;

  for (i=0; i<path.length; i++) {
    var divel = document.getElementById(path[i] + "_div");

    if (divel.childNodes.length > 0)
      divel.removeChild(divel.childNodes[0]); // gc snip

    document.getElementById(path[i] + "_fieldset").style.display='none';
  }
}



var empty_re = new RegExp("^$");

var os_start_re = new RegExp("^[\r\n\t ]*OS:SCAN.V=[^\r\n\t ]+[\t ]*\r?\n");
var os_end_re = new RegExp("OS:[^\r\n\t ]+?[\r\n\t ]*$");
var os_unacceptable_re = new RegExp("%G=N%");
var os_has_xml_newlines_re = new RegExp("&#xa;");

var sv_start_re = new RegExp("^[\r\n\t ]*SF-Port[^\r\n\t ]+[\t ]*\r?\nSF:");
var sv_end_re = new RegExp("SF:[^\r\n\t ]+?[\r\n\t ]*$");
var sv_mult_re = new RegExp("===NEXT SERVICE FINGERPRINT");


function os_fp_field_change() {
  var fpfield = document.getElementById('os_fp');
  var fpsfield = document.getElementById('os_fp_field_status');
  var font = document.createElement("font");
  var p;


  p = document.createElement("input");
  p.type = "button";
  p.value = "Check";
  font.appendChild(p);
  font.appendChild(document.createElement('br'));

  if (os_has_xml_newlines_re.exec(fpfield.value)) {
    fpfield.value = fpfield.value.replace(/[\r\n\t ]/g, "");
    fpfield.value = fpfield.value.replace(/&#xa;/g, "\n");
  }

  if (empty_re.exec(fpfield.value)) {
  } else if (sv_start_re.exec(fpfield.value)) {
    p = document.createTextNode("Oops! It looks like you're pasting a service scan fingerprint!");
    font.appendChild(p);
    font.style.color = "red";
  } else if (os_unacceptable_re.exec(fpfield.value)) {
    p = document.createTextNode("It looks as though network conditions were not ideal for this scan. To avoid polluting the database, we are unable to accept this fingerprint. Sorry!");
    font.appendChild(p);
    font.style.color = "red";
  } else if (os_start_re.exec(fpfield.value) && os_end_re.exec(fpfield.value)) {
    p = document.createTextNode("Fingerprint looks good!");
    font.appendChild(p);
    font.style.color = "green";
  } else {
    p = document.createTextNode("Fingerprint doesn't look good! Please check that it pasted OK.");
    font.appendChild(p);
    font.style.color = "red";
  }

  if (fpsfield.childNodes.length > 0)
    fpsfield.removeChild(fpsfield.childNodes[0]);

  fpsfield.appendChild(font);
}



function sv_fp_field_change() {
  var fpfield = document.getElementById('sv_fp');
  var fpsfield = document.getElementById('sv_fp_field_status');
  var font = document.createElement("font");
  var p;

  p = document.createElement("input");
  p.type = "button";
  p.value = "Check";
  font.appendChild(p);
  font.appendChild(document.createElement('br'));

  if (empty_re.exec(fpfield.value)) {
  } else if (os_start_re.exec(fpfield.value)) {
    p = document.createTextNode("Oops! It looks like you're pasting an OS scan fingerprint!");
    font.appendChild(p);
    font.style.color = "red";
  } else if (sv_mult_re.exec(fpfield.value)) {
    p = document.createTextNode("It appears you pasted multiple fingerprints! Please submit one at a time.");
    font.appendChild(p);
    font.style.color = "red";
  } else if (sv_start_re.exec(fpfield.value) && sv_end_re.exec(fpfield.value)) {
    p = document.createTextNode("Fingerprint looks good!");
    font.appendChild(p);
    font.style.color = "green";
  } else {
    p = document.createTextNode("Fingerprint doesn't look good! Please check that it pasted OK.");
    font.appendChild(p);
    font.style.color = "red";
  }

  if (fpsfield.childNodes.length > 0)
    fpsfield.removeChild(fpsfield.childNodes[0]);

  fpsfield.appendChild(font);
}

var uname_long_desc = 'The results of running the command "uname -a" on the target (feel free to remove the hostname before submitting)';

var extra_os_field_info = [
  // OS Name, Question title, Question instructions
  ['Windows', 'Winver', 'The results of running the command "winver" on the target'],
  ['AIX', 'uname -a', uname_long_desc],
  ['Linux', 'uname -a/distro', uname_long_desc + ' and the Linux distribution if not mentioned in the uname results'],
  ['HP-UX', 'uname -a', uname_long_desc],
  ['IRIX', 'uname -a', uname_long_desc],
  ['Mac OS X', 'uname -a', uname_long_desc],
  ['Solaris', 'uname -a', uname_long_desc],
  ['OpenBSD', 'uname -a', uname_long_desc],
  ['FreeBSD', 'uname -a', uname_long_desc],
  ['NetBSD', 'uname -a', uname_long_desc]];

function lookup_extra_info(os_name) {
  var i;

  for (i=0; i<extra_os_field_info.length; i++)
    if (os_name == extra_os_field_info[i][0])
      return extra_os_field_info[i];

  return null;
}


function setup_os_class_extra() {
  var os_name = document.getElementById('os_class_name_dropdown').value;
  var desc = document.getElementById('os_class_extra_desc_div');
  var field = document.getElementById('os_class_extra_div');

  if (desc.childNodes.length > 0)
    desc.removeChild(desc.childNodes[0]);

  if (field.childNodes.length > 0)
    field.removeChild(field.childNodes[0]);

  var info = lookup_extra_info(os_name);

  if (info) {
    var p = document.createElement('p');
    var b = document.createElement('b');
    b.appendChild(document.createTextNode(info[1]));
    p.appendChild(b);
    p.appendChild(document.createElement('br'));
    p.appendChild(document.createTextNode(info[2] + ":"));
    desc.appendChild(p);

    var f = document.createElement('input');
    f.name = 'os_class_extra_textfield';
    f.id = 'os_class_extra_textfield';
    f.size = 75;
    field.appendChild(f);

    document.getElementById("os_class_extra_fieldset").style.display='';
  }
}



function do_setup() {
  var sel, inp, i;

  document.getElementById('submission_type').selectedIndex = 0;
  document.getElementById('fingerprint_type').selectedIndex = 0;

  update_fp_type();


  // Ah if only we had macros this could be beautiful ;)
  replace_branch('os_class_vendor',
                 [],
                 function () {
    nuke_path(['os_class_name', 'os_class_family', 'os_class_devtype', 'os_class_extra']);

    replace_branch('os_class_name',
                   ['os_class_vendor_dropdown'],
                   function () {
      nuke_path(['os_class_family', 'os_class_devtype', 'os_class_extra']);

      setup_os_class_extra();

      replace_branch('os_class_family',
                     ['os_class_vendor_dropdown', 'os_class_name_dropdown'],
                     function () {
        nuke_path(['os_class_devtype']);

        replace_branch('os_class_devtype',
                       ['os_class_vendor_dropdown', 'os_class_name_dropdown', 'os_class_family_dropdown'],
                       function () {
            document.getElementById("os_class_devtype_div").focus(); }); }); }); });




  sel = document.createElement('select');
  sel.id = "service_by_name_dropdown";
  sel.name = "service_by_name_dropdown";
  sel.onchange = function () { update_service_choice("name"); };

  sel.options[0] = new Option("Services alphabetically", "");
  for (i=0; i<services_by_name.length; i++) {
    sel.options[i+1] = new Option(services_by_name[i][0] + " (" + services_by_name[i][1] + ")", services_by_name[i][0]);
  }
  document.getElementById('services_div').appendChild(sel);

  document.getElementById('services_div').appendChild(document.createElement('br'));

  sel = document.createElement('select');
  sel.id = "service_by_pop_dropdown";
  sel.name = "service_by_pop_dropdown";
  sel.onchange = function () { update_service_choice("pop"); };

  sel.options[0] = new Option("Services by popularity", "");
  for (i=0; i<services_by_pop.length; i++) {
    sel.options[i+1] = new Option(services_by_pop[i][0] + " (" + services_by_pop[i][1] + ")", services_by_pop[i][0]);
  }
  document.getElementById('services_div').appendChild(sel);

  document.getElementById('services_div').appendChild(document.createElement('br'));

  inp = document.createElement('input');
  inp.id = "service_other";
  inp.name = "service_other";
  inp.onkeyup = function () {
    var i, source, found, curval;

    found = -1;
    source = document.getElementById('service_by_pop_dropdown');
    curval = document.getElementById('service_other').value;

    for (i=1; i<source.options.length; i++) {
      if (curval == source.options[i].value) {
        found = i;
        break;
      }
    }

    if (found == -1) {
      document.getElementById('service_by_name_dropdown').selectedIndex = document.getElementById('service_by_pop_dropdown').selectedIndex = 0;
    } else {
      document.getElementById('service_by_pop_dropdown').selectedIndex = i;
      update_service_choice('pop');
    }
  };

  document.getElementById('services_div').appendChild(inp);



  sel = document.createElement('select');
  sel.id = "service_devices_dropdown";
  sel.name = "service_devices_dropdown";

  sel.options[0] = new Option("General Purpose/Unknown/Other", "");
  for (i=0; i<services_devices.length; i++) {
    sel.options[i+1] = new Option(services_devices[i][0] + " (" + services_devices[i][1] + ")", services_devices[i][0]);
  }
  document.getElementById('services_devices_div').appendChild(sel);


  sel = document.createElement('select');
  sel.id = "service_oses_dropdown";
  sel.name = "service_oses_dropdown";

  sel.options[0] = new Option("Unknown/Other", "");
  for (i=0; i<services_oses.length; i++) {
    sel.options[i+1] = new Option(services_oses[i][0] + " (" + services_oses[i][1] + ")", services_oses[i][0]);
  }
  document.getElementById('services_oses_div').appendChild(sel);


  document.getElementById('os_file_stats').appendChild(document.createTextNode(os_db_info));
  document.getElementById('service_file_stats').appendChild(document.createTextNode(service_info));


  document.getElementById('os_fp').onchange = os_fp_field_change; 
  document.getElementById('sv_fp').onchange = sv_fp_field_change; 


  var my_inputs = document.getElementById('main_form').getElementsByTagName('input');
  for (i=0; i<my_inputs.length; i++)
    if (my_inputs[i].type == 'text') my_inputs[i].value = '';

  my_inputs = document.getElementById('main_form').getElementsByTagName('textarea');
  for (i=0; i<my_inputs.length; i++)
    my_inputs[i].value = '';
  
  os_fp_field_change();
  sv_fp_field_change();

}
