// IE 用のラベルの動作修正
function fixLabelLoad(evt)
{
  var doc, labels, label, element, images, image, parent, next, i, j;
  if ((doc = document) && doc.getElementsByTagName &&
      (labels = nodeListToArray(doc.getElementsByTagName("LABEL"))))
    for (i = 0; i < labels.length; ++i)
      if ((label = labels[i]) && label.document)
      {
        // for 属性のないラベルを子のフォーム要素に関連づける
        if (!label.htmlFor&& (element = getLabelForElement(label)))
        {
          if (!element.id)
            element.id = "AUTO-GENERATED-ID-" + element.sourceIndex;
          label.htmlFor = element.id;
          // フォーム要素をラベルから追い出す
          if ((parent = label.parentNode) && parent.insertBefore)
          {
            next = label; // 前 <input><label>ラベル</label>
            for (image = label.firstChild; image && image != element;
                 image = image.nextSibling)
              if (image.nodeType == 1 || image.nodeType == 3 &&
                  !image.nodeValue.match(/^\s*$/))
              {
                next = label.nextSibling; // 後ろ <label>ラベル</label><input>
                break;
              }
            parent.insertBefore(element, next);
          }
        }
        // ラベルの子孫にイメージが含まれる場合にそれが反応しないバグを修正
        if (label.getElementsByTagName &&
           (images = nodeListToArray(label.getElementsByTagName("IMG"))))
          for (j = 0; j < images.length; ++j)
            if ((image = images[j]))
              for (parent = image.parentNode; parent; parent = parent.parentNode)
                if (parent == label)
                {
                  pushEventListener(child, "click", fixLabelImageClick, false);
                  break;
                }
                else
                  if (parent.nodeType == 1 &&
                      parent.nodeName.match(/^(A|APPLET|BUTTON|EMBED|IFRAME|LABEL|OBJECT)$/i))
                    break;
      }
  return;
}

// element がフォームエレメントでかつフォーカスを受け取れるなら true
function canFormElementFocus(element)
{
  if (element && element.nodeType == 1)
    switch (element.nodeName.toUpperCase())
    {
      case "INPUT":
        if (caseEqual(element.type, "hidden"))
          break;
      case "BUTTON":
      case "TEXTAREA":
      case "SELECT":
        return !element.disabled;
      case "OBJECT":
        return !caseEqual(element.name, "");
    }
  return false;
}

// ラベルの指しているフォーム要素を探す
function getLabelForElement(label)
{
  var doc, element, elements, i;
  if (label)
  {
    if ((doc = label.document) && label.htmlFor && doc.getElementById &&
        (element = doc.getElementById(label.htmlFor)))
      return element;
    if (label.getElementsByTagName && (elements = getAllElements(label)))
    {
      for (i = 0; i < elements.length; ++i)
        if ((element = elements[i]) && canFormElementFocus(element))
          return element;
    }
  }
  return null;
}

// ラベルの子孫のイメージがクリックされたときの動作
function fixLabelImageClick(evt)
{
  var label, element;
  if ((label = getTargetElement(evt, "LABEL")) &&
      (element = getLabelForElement(label)))
  {
    if (element.focus)
      element.focus();
    if (caseEqual(element.type, "checkbox"))
    {
      element.checked = !element.checked;
      element.fireEvent("click");
    }
    else
      if (caseEqual(element.type, "radio") && element.name &&
          !element.checked)
      {
        element.checked = true;
        element.fireEvent("click");
      }
  }
  return;
}

pushEventListener(this, "load", fixLabelLoad, false);
