// 郵便番号検索
function postalActionURI()
{
  return "/postal-search.php";
}

function postalSearchLoad(evt)
{
  var doc, fs, f, i, e, p, b, m, h;
  if ((doc = document) && doc.createElement &&
      (fs = snapElementsByTagName(doc, "FORM", null)))
  {
    for (i = 0; i < fs.length; ++i)
      if ((f = fs[i]) && (e = getNamedItem(f.elements, "postal_code") ||
          getNamedItem(f.elements, "postcode1") &&
          getNamedItem(f.elements, "postcode2")) &&
          (p = e.parentNode) && p.insertBefore &&
          (m = doc.createTextNode("郵便番号から住所を検索")) &&
          (b = doc.createElement("A")) && b.appendChild)
      {
        h = postalActionURI();
        b.href = h;
        b.className = "postal-search-button";
        b.appendChild(m);
        b.m_form = f;
        p.insertBefore(b, e.nextSibling);
        if (doc.createTextNode && (m = doc.createTextNode(" ")))
          p.insertBefore(m, b);
        pushEventListener(b, "click", postalSearchClick, false);
      }
    pushEventListener(doc, "mousedown", postalNoCadidateMouseDown, false);
    pushEventListener(doc, "keydown", postalNoCadidateMouseDown, false);
    postalSearchAddStyle(doc);
  }
  return;
}

// スタイルシートの新規作成
function doCreateStyleSheet(doc)
{
  var css, style, html, head, i;
  css = null;
  if (doc)
  {
    if (doc.createStyleSheet)
      css = doc.createStyleSheet();
    if (!css && doc.createElement && (html = doc.documentElement) &&
        html.childNodes && html.childNodes.item && 
        (style = doc.createElement("STYLE")))
    {
      style.type = "text/css";
      for (i = 0; i < html.childNodes.length; ++i)
        if ((head = html.childNodes.item(i)) && head.nodeType == 1 &&
            String(head.nodeName).toUpperCase() == "HEAD")
        {
          if (head.appendChild)
            head.appendChild(style);
          break;
        }
      css = style.sheet;
    }
  }
  return css;
}

function appendCSSRule(css, selectors, styles)
{
  var value, i, j;
  if (css && (rules = css.cssRules || css.rules) &&
      isObject(selectors) && isObject(styles))
  {
    if (css.addRule)
      for (i = 0; i < selectors.length; ++i)
      {
        for (j = 0; j < styles.length; ++j)
          css.addRule(selectors[i], styles[j], rules.length);
      }
    else
      if (css.insertRule)
      {
        value = selectors.join(" , ") + " { " + styles.join(" ; ") + " }";
        css.insertRule(value, rules.length);
      }
  }
  return;
}

// スタイルシートの追加
function postalSearchAddStyle(doc)
{
  var css, url;
  if ((css = doCreateStyleSheet(doc)))
  {
    url = postalActionURI();
    url = url.replace(/[^\/]+$/, "");
    appendCSSRule(css, [
            "a.postal-search-button:link",
            "a.postal-search-button:visited"
        ], [
            "display: inline-block !important",
            "background: url(\"" + url + "image/search/search-postcode-up.gif\") no-repeat !important",
            "color: #000000 !important",
            "text-decoration: none !important",
            "padding: 5px 20px 5px 8px !important",
            "font-family: \"MS UI Gothic\", sans-serif !important",
            "font-size: 9pt !important",
            "line-height: 1.0 !important"
        ]);
    appendCSSRule(css, [
            "a.postal-search-button:visited:active",
            "a.postal-search-button.down:link",
            "a.postal-search-button.down:visited"
        ], [
            "background: url(\"" + url + "image/search/search-postcode-down.gif\") no-repeat !important",
        ]);
    appendCSSRule(css, [
            "div#POSTAL-CANDIDATE-WINDOW select"
        ], [
            "min-width: 100%",
            "font-family: \"MS UI Gothic\", sans-serif",
            "font-size: 9pt"
        ]);
  }
  return;
}

// 検索ボタンをクリック
function postalSearchClick(evt)
{
  var b, es, v, s1, s2, m;
  if ((evt || (evt = window.event)) &&
      (b = getAncestorElement(evt.target || evt.srcElement, "A")) &&
      !classContains(b, "down"))
  {
    es = findFormElements(b.m_form, ["postcode1", "postcode2", "postal_code", "prefecture", "address"]);
    es.m_button = b;
    classAdd(b, "down");
    if (es.m_prefecture && es.m_address)
    {
      v = "";
      if (es.m_postal_code)
      {
        s1 = trim(es.m_postal_code.value);
        if ((m = s1.match(/([0-9]{3})-?([0-9]{0,4})/)))
          v = m[1] + (m[2] ? "-" + m[2] : "");
      }
      else
        if (es.m_postcode1 && es.m_postcode2)
        {
          s1 = trim(es.m_postcode1.value);
          s2 = trim(es.m_postcode2.value);
          if ((m = s1.match(/[0-9]{3}/)))
          {
            v = m[0];
            if ((m = s2.match(/[0-9]{1,4}/)))
              v += "-" + m[0];
          }
        }
      if (v)
        postalSearchDo(v, es);
      else
        postalSearchReqLoad(null, es);
    }
    if (evt.preventDefault)
      evt.preventDefault();
    else
      evt.returnValue = false;
  }
  return;
}

// 検索実行
function postalSearchDo(query, params)
{
  var url;
  url = postalActionURI() + "/" + encodeURI(query) + ".xml";
  sendHttpGetRequest(url, postalSearchReqLoad, params);
  return;
}

// 検索候補を表示するウィンドウを作る
function postalCreateCandidateWindow(doc)
{
  var win, w, s, t;
  win = null;
  if (isObject(doc))
  {
    if (!(win = takeUserData(doc, "postalCandidateWindow")) &&
        doc.createElement && doc.createTextNode &&
        (w = doc.createElement("DIV")) && (s = doc.createElement("SELECT")))
    {
      if ((t = doc.createTextNode("リストから該当する住所をクリックしてください")))
        w.appendChild(t);
      if ((t = doc.createElement("BR")))
        w.appendChild(t);
      w.id = "POSTAL-CANDIDATE-WINDOW";
      w.style.visibility = "hidden";
      w.style.position = "absolute";
      w.style.border = "1px solid #716F64";
      w.style.padding = "4px";
      w.style.background = "#ECE9D8";
      w.style.color = "#000000";
      w.style.fontFamily = "\"MS UI Gothic\", sans-serif";
      w.style.fontSize = "9pt";
      w.m_select = s;
      s.size = 12;
      s.m_div = w;
      w.appendChild(s);
      putUserData(doc, "postalCandidateWindow", w, null);
      pushEventListener(s, "blur", postalSelectBlur, false);
      pushEventListener(s, "click", postalSelectClick, false);
      pushEventListener(s, "keydown", postalSelectKeyDown, false);
      win = w;
    }
  }
  return win;
}

// 検索候補がないときに表示するウィンドウを作る
function postalCreateNoCandidateWindow(doc)
{
  var win, w, s;
  win = null;
  if (isObject(doc))
  {
    if (!(win = takeUserData(doc, "postalNoCadidateWindow")) &&
        doc.createElement && doc.createTextNode &&
        (w = doc.createElement("DIV")) && w.appendChild &&
        (s = doc.createTextNode("　")))
    {
      w.m_text = s;
      w.appendChild(s);
      w.id = "POSTAL-NO-CANDIDATE-WINDOW";
      w.style.visibility = "hidden";
      w.style.position = "absolute";
      w.style.border = "1px solid #000000";
      w.style.padding = "3px 3px 1px";
      w.style.background = "#FFFFE1";
      w.style.color = "#000000";
      w.style.fontSize = "9pt";
      w.style.fontFamily = "\"MS UI Gothic\", sans-serif";
      w.style.lineHeight = "1.0";
      putUserData(doc, "postalNoCadidateWindow", w, null);
      win = w;
    }
  }
  return win;
}

function postalNoCadidateMouseDown(evt)
{
  if ((evt || (evt = window.event)) &&
      (doc = evt.target || evt.srcElement) &&
      (doc = doc.ownerDocument || doc.document))
  {
    postalNoCadidateErase(takeUserData(doc, "postalNoCadidateWindow"));
  }
  return;
}

function postalNoCadidateErase(win)
{
  if (isObject(win))
  {
    if (win.m_timer)
      clearTimeout(win.m_timer);
    win.m_timer = 0;
    if (win.m_params && win.m_params.m_button)
    {
      classRemove(win.m_params.m_button, "down");
//      if (win.m_params.m_button.blur)
//        win.m_params.m_button.blur();
    }
    win.style.visibility = "hidden";
  }
  return;
}


// 検索結果の読み込み完了
function postalSearchReqLoad(req, params)
{
  var b, doc, win, win2, point, c, i, l, o;
  if (params && (b = params.m_button) &&
      (doc = b.ownerDocument || b.document) &&
      (win = postalCreateCandidateWindow(doc)) &&
      (win2 = postalCreateNoCandidateWindow(doc)) &&
      doc.body && doc.body.appendChild)
  {
    doc.body.appendChild(win);
    doc.body.appendChild(win2);
    point = { left: 0, top: 0 };
    getAbsoluteOrigin(b, point);
    win.style.left = point.left + "px";
    win.style.top = point.top + b.offsetHeight + 2 + "px";
    win2.style.left = point.left + "px";
    win2.style.top = point.top - win2.offsetHeight - (window.ActiveXObject ? 0 : 2) + "px";
    removeAllOptionsFromSelect(win.m_select);
    c = -1;
    if (req)
    {
      c = 0;
      if (req.responseXML && (xml = req.responseXML.documentElement) &&
          xml.childNodes)
      {
        for (i = 0; i < xml.childNodes.length; ++i)
          if ((l = xml.childNodes.item(i)) && l.nodeType == 1 &&
              (o = addOptionToSelect(win.m_select, getContentText(l))))
          {
            o.m_postcode1  = String(l.getAttribute("postcode1"));
            o.m_postcode2  = String(l.getAttribute("postcode2"));
            o.m_prefecture = Number(l.getAttribute("prefecture"));
            o.m_address    = String(l.getAttribute("address1"));
            ++c;
          }
      }
    }
    win.m_params = params;
    win2.m_params = params;
    if (c >= 1)
    {
      win.m_select.size = c <= 2 ? 2 : c <= 12 ? c : 12;
      if (win.m_select.options.item && (o = win.m_select.options.item(0)))
        o.selected = true;
      win.style.visibility = "visible";
      if (win.m_select.focus)
        win.m_select.focus();
      hideBackSelectElements(win);
    }
    else
    {
      win2.m_text.nodeValue = c == 0  ? "該当する住所が見つかりません" :
          "3桁、5桁または7桁の郵便番号を入力してください";
      win2.style.visibility = "visible";
      classRemove(b, "down");
      c = setTimeoutParam(postalNoCadidateErase, 3000, win2);
      win2.m_timer = c;
      if (b.blur)
        b.blur();
    }
  }
  return;
}

// フォーカスが外れたときに候補ウィンドウを隠す
function postalSelectBlur(evt)
{
  var win;
  if ((evt || (evt = window.event)) &&
      (win = getAncestorElement(evt.target || evt.srcElement, "DIV")))
  {
    win.style.visibility = "hidden";
    showBackSelectElements(win);
    if (win.m_params && win.m_params.m_button)
      classRemove(win.m_params.m_button, "down");
  }
  return;
}

// Enter→確定、Esc→キャンセル
function postalSelectKeyDown(evt)
{
  var flag;
  if (evt || (evt = window.event))
  {
    if (flag = evt.keyCode == 13)
      postalSelectClick(evt);
    else
      if (flag = evt.keyCode == 27)
        postalSelectBlur(evt);
    if (flag)
    {
      if (evt.preventDefault)
        evt.preventDefault();
      else
        evt.returnValue = false;
    }
  }
  return;
}

// 確定
function postalSelectClick(evt)
{
  var win, s, p, o;
  if ((evt || (evt = window.event)) &&
      (win = getAncestorElement(evt.target || evt.srcElement, "DIV")) &&
      (s = win.m_select) && (p = win.m_params) &&
      s.selectedIndex >= 0 && s.options && s.options.item &&
      (o = s.options.item(s.selectedIndex)))
  {
    if (p.m_postal_code)
      p.m_postal_code.value = o.m_postcode1 + "-" + o.m_postcode2;
    if (p.m_postcode1)
      p.m_postcode1.value = o.m_postcode1;
    if (p.m_postcode2)
      p.m_postcode2.value = o.m_postcode2;
    if (p.m_prefecture)
      selectOptionByValue(p.m_prefecture, o.m_prefecture);
    if (p.m_address)
    {
      p.m_address.value = o.m_address;
      if (p.m_address.focus)
        p.m_address.focus();
    }
  }
  return;
}

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

