/* Copyright (c) 2005, Kenn Hamm <kenn@aspeiro.net>.  All rights reserved. */

/* Perpetual, worldwide, royalty-free, non-exclusive license is granted to
 * Gradient Labs, LLC to use, distribute, sub-license, and create
 * derivative works of this software.  Kenn Hamm retains copyright in this
 * software and the right to license it to others. */

/* BEGIN: This code from <http://hacks.oreilly.com/pub/h/2127> */
var APOS = "'"; QUOTE = '"';
var ESCAPED_QUOTE = { };
ESCAPED_QUOTE[QUOTE] = '&quot;'
ESCAPED_QUOTE[APOS] = '&apos;'
   
  /*
	Format a dictionary of attributes into a string suitable
	for inserting into the start tag of an element.  Be smart
	about escaping embedded quotes in the attribute values.
  */
function formatAttributes(attributes) {
  var att_value;
  var apos_pos, quot_pos;
  var use_quote, escape, quote_to_escape;
  var att_str;
  var re;
  var result = '';
   
  for (var att in attributes) {
	att_value = attributes[att];
        
	// Find first quote marks if any
	apos_pos = att_value.indexOf(APOS);
	quot_pos = att_value.indexOf(QUOTE);
       
	// Determine which quote type to use around 
	// the attribute value
	if (apos_pos == -1 && quot_pos == -1) {
	  att_str = ' ' + att + "='" + att_value +  "'";
	  result += att_str;
	  continue;
	}
        
	// Prefer the single quote unless forced to use double
	if (quot_pos != -1 && quot_pos < apos_pos) {
	  use_quote = APOS;
	} else {
	  use_quote = QUOTE;
	}
   
	// Figure out which kind of quote to escape
	// Use nice dictionary instead of yucky if-else nests
	escape = ESCAPED_QUOTE[use_quote];
        
	// Escape only the right kind of quote
	re = new RegExp(use_quote,'g');
	att_str = ' ' + att + '=' + use_quote + 
	  att_value.replace(re, escape) + use_quote;
	result += att_str;
  }
  return result;
}
/* END: This code from <http://hacks.oreilly.com/pub/h/2127> */

function jsEscapeLiteral(str) {
  rv = new String(str);
  rv = rv.replace(/(['"])/g, "\\$1");
  return rv;
}

function emulateEventHandlers(eventNames) {
  for (var i = 0; i < eventNames.length; i++) {
	document.addEventListener(eventNames[i], function (e) {
								window.event = e;
							  }, true); // using capture
  }
}

if (document.addEventListener) {
  emulateEventHandlers(["keypress", "keyup"]);
}

function strmatchlen(str1, str2) {
  var max = Math.max(str1.length, str2.length);

  for (var i = 0; i < max; i++) {
	if (str1[i] != str2[i]) {
	  return i;
	}
  }

  return max;
}

function MagicDropdown(name, width, vals, def) {
  this.name = name;
  this.width = width;
  this.vals = vals;
  this.def = def;
  this.selected = null;

  this.filterCount = this.vals.length;
}

MagicDropdown.prototype.show = function() {
  var elem = document.getElementById(this.prefix + "_dropdown");
  elem.style.display = "block";
}

MagicDropdown.prototype.hide = function() {
  var elem = document.getElementById(this.prefix + "_dropdown");
  elem.style.display = "none";
}

MagicDropdown.prototype.toggle = function() {
  var elem = document.getElementById(this.prefix + "_dropdown");
  if (elem.style.display != "block") {
	elem.style.display = "block";
  } else {
	elem.style.display = "none";
  }
}

MagicDropdown.prototype.step = function(incr) {
  var input = document.getElementById(this.prefix + "_text");
  if (this.selected == null) {
    this.selected = -1;
  } else {
	document.getElementById(this.prefix + "_dropdown_" + this.selected).style.backgroundColor =
	"white";
  }
	
  var count = 0;
  var element;

  while (count <= this.vals.length) {
	this.selected += incr;
	if (this.selected >= this.vals.length) {
	  this.selected = 0;
	} else if (this.selected < 0) {
	  this.selected = this.vals.length - 1;
	}

	element = document.getElementById(this.prefix + "_dropdown_" + this.selected);
	if (element != null && element.style.display != 'none') {
	  element.style.backgroundColor = "red";
	  break;
	}

	count++;
  }

  if (count < this.vals.length) {
	input.value = this.vals[this.selected];
  }
}

MagicDropdown.prototype.html = function() {
  var rv = { html: "", finish: null };
  this.prefix = "__dd__" + this.name;
  rv.html += "<div class='top'>";
  rv.html +=
  "<input type='text' style='width: " + this.width + "' name='" + this.name + "' " + 
  "id='" + this.prefix + "_text' value='" + this.def + "' " + 
  "onkeypress='return MagicDropdown.keypress(&quot;" + this.prefix + "&quot;)' " +
  "onkeyup='return MagicDropdown.keyup(&quot;" + this.prefix + "&quot;)' " +
  "onfocus='MagicDropdown.show(&quot;" + this.prefix + "&quot;)' " + 
  /* "onblur='MagicDropdown.hide(&quot;" + this.prefix + "&quot;)' " + */ " />";
  rv.html +=
  "<a href='javascript:MagicDropdown.toggle(&quot;" + this.prefix + "&quot;);'>" + 
  "<img border='0' style='position: relative; left: -22px; top: 2px' src='/images/siteimages/dropdown.gif' /></a>";
  rv.html += "<div style='position: relative; z-index: 100'>" +
  "<div class='dropdown' id='" + this.prefix + "_dropdown' style='position: absolute; left: 0; top: 0; display: none; width: " + this.width + "'>";

  for (var i = 0; i < this.vals.length; i++) {
	rv.html += "<a id='" + this.prefix + "_dropdown_" + i + "' " +
	  formatAttributes({href: "javascript:document.getElementById(&quot;" + this.prefix + "_text&quot;).value = " +
						   "&quot;" + jsEscapeLiteral(this.vals[i]) + "&quot;; MagicDropdown.hide(&quot;" + this.prefix + "&quot;);"}) + ">" +
	  "<div width='100%'>" + this.vals[i] + "</div></a>";
  }

  rv.html +=
  "</div></div></div>";
  
  var obj = this;
  rv.finish = function() {
	document.getElementById(obj.prefix + '_text').obj = obj;
  };
  return rv;
}

MagicDropdown.keyup = function(prefix) {
  var rv = true;

  if (window.event.keyCode == 37 || window.event.keyCode == 39) {
	// Don't repopulate the list on up/down arrow
	return;
  } else if (window.event.keyCode == 38 /* up arrow */) {
	MagicDropdown.prev(prefix);
  } else if (window.event.keyCode == 40 /* down arrow */) {
	MagicDropdown.next(prefix);
  } else if (window.event.keyCode == 13 /* enter */) {
	MagicDropdown.toggle(prefix);
	rv = false;
  } else {
	MagicDropdown.filter(prefix);
  }

  return rv;
}

MagicDropdown.keypress = function(prefix) {
  var rv = true;

  if (window.event.keyCode == 13 /* enter */) {
	rv = false;
  }

  return rv;
}

MagicDropdown.show = function(prefix) {
  var obj = document.getElementById(prefix + "_text").obj;
  obj.show();
}

MagicDropdown.hide = function(prefix) {
  var obj = document.getElementById(prefix + "_text").obj;
  obj.hide();
}

MagicDropdown.complete = function(prefix) {
  var obj = document.getElementById(prefix + "_text").obj;
  var val = document.getElementById(prefix + "_text").value;

  var completionPrefix;

  var i = 0;
  while (i < obj.vals.length) {
	if (obj.vals[i].indexOf(val) == 0) {
	  document.getElementById(prefix + '_dropdown_' + i).style.display = "block";
	  completionPrefix = obj.vals[i];
	  break;
	} else {
	  document.getElementById(prefix + '_dropdown_' + i).style.display = "none";
	}
	i++;
  }

  while (i < obj.vals.length) {
	if (obj.vals[i].indexOf(completionPrefix) == 0) {
	  document.getElementById(prefix + '_dropdown_' + i).style.display = "block";
	} else if (obj.vals[i].indexOf(val) == 0) {
	  document.getElementById(prefix + '_dropdown_' + i).style.display = "block";
	  completionPrefix = completionPrefix.substring(0, strmatchlen(completionPrefix, obj.vals[i]));
	} else {
	  document.getElementById(prefix + '_dropdown_' + i).style.display = "none";
	}
	i++;
  }

  if (typeof(completionPrefix) != "undefined") {
	document.getElementById(prefix + "_text").value = completionPrefix;
  }
}

MagicDropdown.filter = function(prefix) {
  var obj = document.getElementById(prefix + "_text").obj;
  var val = document.getElementById(prefix + "_text").value;

  /*  if (obj.filterCount == 0)
	  return; */
  obj.filterCount = 0;

  for (i = 0; i < obj.vals.length; i++) {
	if (obj.vals[i].indexOf(val) == 0) {
	  document.getElementById(prefix + '_dropdown_' + i).style.display = "block";
	  obj.filterCount++;
	} else {
	  document.getElementById(prefix + '_dropdown_' + i).style.display = "none";
	}
  }
}

MagicDropdown.toggle = function(prefix) {
  document.getElementById(prefix + "_text").obj.toggle();
}

MagicDropdown.hide = function(prefix) {
  document.getElementById(prefix + "_text").obj.hide();
}

MagicDropdown.prev = function(prefix) {
  document.getElementById(prefix + "_text").obj.step(-1);
}

MagicDropdown.next = function(prefix) {
  document.getElementById(prefix + "_text").obj.step(+1);
}
