/* Zip.js
 * Copyright (c) 2008 Poturi, All Rights Reserved.
 * http://www.poturi.net/
 *
 * ソースコードの改変・再頒布は自由ですが、
 * その際はこのCopyrightを明記してください。
 * 商用利用は不可です。
 */

window.onload = function() {
    prepare_elements();
    form_description("show_zip");
    form_description("show_address");
}

// 住所を取得する
function get_address(num) {
    var url = '/gadgets/zip/zip.pl';
    var par = 'zip=' + num;

    var my_ajax = new Ajax.Request(
        url,
        {
            method: 'get',
            parameters: par,
            onCreate: show_spinner,
            onComplete: show_response
        });
}

// 郵便番号を取得する
function get_zip(str) {
    var url = '/gadgets/zip/zip.pl';
    var par = 'address=' + str;

    var my_ajax = new Ajax.Request(
        url,
        {
            method: 'get',
            parameters: par,
            onCreate: show_spinner,
            onComplete: show_response
        });
}

// 郵便番号が正当な値かどうかチェックする
// 同様のチェックをPerlスクリプト側でも再度行う
function check_zip() {
    form_description("hide_zip");
    var my_zip = $F('search_zip');
    my_zip = my_zip.replace(/-/, "");
    if (my_zip.match(/[^\d]/) || my_zip.length < 3 || my_zip.length > 7) {
        form_description("show_zip");
        $('error').firstChild.nodeValue = "3～7桁の半角数字を入力してください。";
        hide_all();
        $('error').show();
    }
    else {
        get_address(my_zip);
    }
}

// 住所が正当な値かどうかチェックする
function check_address() {
    form_description("hide_address");
    var my_addr = $F('search_address');
    if (!my_addr) {
        form_description("show_address");
        $('error').firstChild.nodeValue = "検索語を入力してください。";
        hide_all();
        $('error').show();
    }
    else if (my_addr.length > 20) {
        $('error').firstChild.nodeValue = "20文字以内で検索してください。";
        hide_all();
        $('error').show();
    }
    else {
        get_zip(my_addr);
    }
}

// 郵便番号が7桁になったら、自動的に検索する
function count_length() {
    var zip = $F('search_zip');
    zip = zip.replace(/-/, "");
    if (zip.length == 7) {
        check_zip();
    }
    else {
        hide_all();
    }
}

// 入力欄が説明文を表示/非表示する
function form_description(mode) {
    var zip = document.getElementById("search_zip");
    var zip_value = $F('search_zip');
    var zip_text = "郵便番号";
    var address = document.getElementById("search_address");
    var address_value = $F('search_address');
    var address_text = "住所の一部を入力してください";
    switch (mode) {
        case "show_zip":
            if (!zip_value || zip_value == zip_text) {
                set_form_style("weak_zip");
                zip.setAttribute("value", zip_text);
            }
            else { set_form_style("strong_zip"); }
            break;
        case "show_address":
            if (!address_value || address_value == address_text) {
                set_form_style("weak_address");
                address.setAttribute("value", address_text);
            }
            else { set_form_style("strong_address"); }
            break;
        case "hide_zip":
            if (zip_value == zip_text) {
                zip.setAttribute("value", "");
                set_form_style("strong_zip");
            }
            break;
        case "hide_address":
            if (address_value == address_text) {
                address.setAttribute("value", "");
                set_form_style("strong_address");
            }
            break;
        default:
            break;
    }
}

// フォームの表示スタイルを変更する
function set_form_style(mode) {
    var zip = document.getElementById("search_zip");
    var address = document.getElementById("search_address");
    switch (mode) {
        case "strong_zip":
            zip.style.height = "24px";
            zip.style.paddingTop = "1px";
            zip.style.fontWeight = "bold";
            zip.style.fontSize = "120%";
            zip.style.color = "#4b4641";
            break;
        case "weak_zip":
            zip.style.height = "20px";
            zip.style.paddingTop = "5px";
            zip.style.fontWeight = "normal";
            zip.style.fontSize = "90%";
            zip.style.color = "#7d7873";
            break;
        case "strong_address":
            address.style.color = "#4b4641";
            break;
        case "weak_address":
            address.style.color = "#7d7873";
            break;
        default:
            break;
    }
}

// resultコンテナ内に生成する要素
function prepare_elements() {
    // 読み込み中に表示するimg要素 id="spinner"
    var my_img = document.createElement("img");
    my_img.setAttribute("id", "spinner");
    my_img.setAttribute("src", "/gadgets/zip/img/loading.gif");
    my_img.setAttribute("width", "100");
    my_img.setAttribute("height", "20");
    my_img.setAttribute("alt", "Loading");
    my_img.style.display = "none";
    $('result').appendChild(my_img);

    // エラー表示用のp要素 id="error"
    var my_p = document.createElement("p");
    my_p.setAttribute("id", "error");
    var message_text = ""
    var message_node = document.createTextNode(message_text);
    my_p.style.display = "none";
    my_p.appendChild(message_node);
    $('result').appendChild(my_p);

    // 住所一覧用のselect要素 id="address_list"
    var my_select = document.createElement("select");
    my_select.setAttribute("id", "address_list");
    my_select.style.display = "none";
    my_select.onchange = function() { set_address(); };
    $('result').appendChild(my_select);

    // 地図検索用のa要素とimg要素 id="map_button"
    var map_a = document.createElement("a");
    map_a.setAttribute("id", "map_link");
    map_a.setAttribute("href", "");
    map_a.setAttribute("target", "_blank");
    map_a.style.display = "none";
    var map_button = document.createElement("img");
    map_button.setAttribute("src", "/gadgets/zip/img/map_off.png");
    map_button.setAttribute("width", "90");
    map_button.setAttribute("height", "25");
    map_button.setAttribute("alt", "地図を表示");
    map_button.onmouseover = function() { this.src="/gadgets/zip/img/map_on.png" };
    map_button.onmouseout = function() { this.src="/gadgets/zip/img/map_off.png" };
    map_a.appendChild(map_button);
    $('result').appendChild(map_a);

    // 住所データ保持用のdiv要素 id="address_data"
    var my_data = document.createElement("div");
    my_data.setAttribute("id", "address_data");
    my_data.style.display = "none";
    $('result').appendChild(my_data);
}

function hide_all() {
    $('spinner').hide();
    $('error').hide();
    $('address_list').hide();
    $('map_link').hide();
}

function show_spinner() {
    hide_all();
    $('spinner').show();
}

function show_response(originalRequest) {
    var my_xml = originalRequest.responseXML;

    if (my_xml.getElementsByTagName("error")) {
        var error = my_xml.getElementsByTagName("error");
    }

    if (my_xml.getElementsByTagName("zip")) {
        var zip = my_xml.getElementsByTagName("zip");
        var address = my_xml.getElementsByTagName("addr");
    }

    if (error.length > 0) {
        $('error').firstChild.nodeValue = error[0].firstChild.nodeValue;

        hide_all();
        $('error').show();
    }

    else if (zip.length == 1) {
        set_form_style("strong_zip");
        set_form_style("strong_address");
        var zip_text = zip[0].firstChild.nodeValue;
        var pattern = /(\d{3})(\d{4})/;
        var match = zip_text.match(pattern);
        zip_text = match[1] + "-" + match[2];
        var address_text = address[0].firstChild.nodeValue;
        hide_all();
        $('search_zip').value = zip_text;
        $('search_address').value = address_text;
        set_map(address_text);
        $('map_link').show();
    }

    else if (zip.length > 1) {
        // address_listの子ノードをすべて消去する
        while ($('address_list').hasChildNodes()) {
            $('address_list').removeChild($('address_list').firstChild);
        }
        // address_dataの子ノードをすべて消去する
        while ($('address_data').hasChildNodes()) {
            $('address_data').removeChild($('address_data').firstChild);
        }

        var count_text = zip.length + "件見つかりました";
        var count_node = document.createTextNode(count_text);
        var my_option = document.createElement("option");
        my_option.appendChild(count_node);
        $('address_list').appendChild(my_option);

        for (var i = 0; i < zip.length; i++) {
            var data_id = "data" + i;
            var address_text = address[i].firstChild.nodeValue;

            var address_node = document.createTextNode(address_text);
            var my_option = document.createElement("option");
            my_option.setAttribute("value", data_id);
            my_option.appendChild(address_node);
            $('address_list').appendChild(my_option);

            // 住所データ保持用のinput要素
            var zip_text = zip[i].firstChild.nodeValue;
            var pattern = /(\d{3})(\d{4})/;
            var match = zip_text.match(pattern);
            zip_text = match[1] + "-" + match[2];
            var full_address_text = zip_text + "@" + address_text;
            var hidden_data = document.createElement("input");
            hidden_data.setAttribute("id", data_id);
            hidden_data.setAttribute("type", "hidden");
            hidden_data.setAttribute("value", full_address_text);

            $('address_data').appendChild(hidden_data);
        }

        hide_all();
        $('address_list').show();
    }
}

function set_address() {
    set_form_style("strong_zip");
    set_form_style("strong_address");
    var selected = $F('address_list');
    var full_address_text = $F(selected);

    var pattern = /^(\d{3}-\d{4})@(.+)/;
    var match = full_address_text.match(pattern);
    var zip_text = match[1];
    var address_text = match[2];
    $('search_zip').value = zip_text;
    $('search_address').value = address_text;
    hide_all();
    set_map(address_text);
    $('map_link').show();
}

function set_map(str) {
    var encoded_address = encodeURIComponent(str);
    my_url = "http://maps.google.co.jp/maps?f=q&hl=ja&geocode=&ie=UTF8&z=15&iwloc=addr&q=" + encoded_address;
    $('map_link').setAttribute("href", my_url);
}
