﻿// 入力補助地図の表示に関するJavaScript
// 既存のサイトと同じ仕様で表示します。

/**
* クラス生成
*/
if (typeof (SupportMapArea) == 'undefined') SupportMapArea = function() { };

/**
* 定数クラス定義
*/
SupportMapArea.Const = function() { };

/** 地図から選択する 選択不可スタイル */
SupportMapArea.Const.MAP_SELECT_LINK_DISABLE = "disabletext mesh_unlink"
/** サブエリア 未選択項目 文字列 */
SupportMapArea.Const.SUB_AREA_NO_SELECTED_TEXT = "選択してください";
/** サブエリア 未選択項目 スタイル */
SupportMapArea.Const.SUB_AREA_NO_SELECTED_STYLE = "noselect";

/**
* Idを管理する連想配列オブジェクト
*/
SupportMapArea.idList = {};

/**
* SupportMapArea.Panel コンストラクタの定義
*/
SupportMapArea.Panel = function() {
    this.ken = SupportMapArea.idList["Ken"];
    this.subArea = SupportMapArea.idList["SubArea"];
    return this;
};

// SupportMapArea.Mapクラスのインスタンスをグローバル変数で保持。
// 地図更新は外から明示的に呼び出す。例：SupportMap.write();
var SupportMap;

/**
* SupportMapArea.Panel 初期化処理をおこないます。
*/
SupportMapArea.Panel.prototype.init = function() {
    var __this = this;
    SupportMap = new SupportMapArea.Map(
        "ImgMaps", this.ken, this.subArea, "MapSelectLink");
    SupportMap.init();

    SupportMap.write();

};

// 登録
addEvent(window, "load", function() {
    merge(SupportMapArea.idList, getMapIdList());
    var mapArea = new SupportMapArea.Panel();
    mapArea.init();
});


/**
* SupportMapArea.Map コンストラクタの定義
* @param mapElementId 地図表示エレメントID
* @param kenListId 県リストボックスエレメントID
* @param subAreaListId サブエリアリストボックスエレメントID
* @param linkButtonId 地図選択リンクのエレメントID
*/
SupportMapArea.Map = function(mapElementId, kenListId, subAreaListId, linkButtonId) {
    this.mapElementId = mapElementId;
    this.kenListId = kenListId;
    this.subAreaListId = subAreaListId;
    this.linkButtonId = linkButtonId;
    this.__dispelem = null;  // 地図表示欄エレメント
    this.__listelem = null;  // サブエリアリストエレメント
    this.disabled = false;  // 無効かされているかどうか
    this.kenCd = null;
    // タグのClickイベント等から呼び出せるように、
    // ルートに参照用変数を用意
    this.globalId = "__supportMap_" + this.kenListId;
    window[this.globalId] = this;
    this.mapImageId = "__map_image_" + this.mapElementId;
    return this;
};
/** zindexの定義 */
SupportMapArea.Map.prototype.zindex = 10;
/** イメージファイルのディレクトリprefix */
SupportMapArea.Map.prototype.mapImageDirPrefix = "/Search/images/map";
/** 閉じるボタンイメージURL */
SupportMapArea.Map.prototype.closeImage = "/Search/images/btn_top_favi_close.gif";
/** 地図を消すかどうかのフラグ */
SupportMapArea.Map.prototype.deleteflag = false;
/**
* ページ表示時の初期処理を行ないます。
*/
SupportMapArea.Map.prototype.init = function() {
    var __this = this;
    // ページ表示時のイベント登録
    // イベントを登録する
    var mapChoiceLink = getNode(this.linkButtonId);
    addEvent(mapChoiceLink, "click", function() {
        if (!__this.disabled) {
            __this.show();
        }
    });
    var mapdiv = this.getMapElement();
    // 地図の選択できない部分のクリックの挙動①
    addEvent(mapdiv, "mouseover", function() {
        __this.deleteflag = false;
    });
    // 地図の選択できない部分のクリックの挙動②
    addEvent(mapdiv, "mouseout", function() {
        __this.deleteflag = true;
    });
    // documentにマウス押下
    addEvent(document, "mousedown", function() {
        // 地図を消してもいいよフラグがtrueならば地図を消す
        if (__this.deleteflag == true) {
            __this.hide();
        }
    });

    // 画面の初期表示時用処理
    this.write();
    var subAreaNode = getNode(this.subAreaListId);
    if (subAreaNode.disabled) {
        this.disable();
    }
};
/**
* 地図表示欄のエレメントを返します。
*/
SupportMapArea.Map.prototype.getMapElement = function() {
    if (this.__dispelem) return this.__dispelem;
    this.__dispelem = getNode(this.mapElementId);
    return this.__dispelem;
};
/**
* サブエリアリストボックスのエレメントを返します。
*/
SupportMapArea.Map.prototype.getFormElement = function() {
    if (this.__listelem) return this.__listelem;
    this.__listelem = getNode(this.subAreaListId);
    return this.__listelem;
};
/**
* 地図表示欄を表示します。
*/
SupportMapArea.Map.prototype.show = function() {
    this.getMapElement().style.display = "";
    this.deleteflag = true;
};
/**
* 地図表示欄を即座に隠します。
*/
SupportMapArea.Map.prototype.hide = function() {
    this.getMapElement().style.display = "none";
    // 表示フラグを"0:非表示"に変更
    this.deleteflag = false;
};
/**
* 地図を描画します。
*/
SupportMapArea.Map.prototype.write = function() {
    //console.log("SupportMapArea.Map.prototype.write");
    var kenSelectNode = getNode(this.kenListId);
    // 未選択の場合はwriteしない
    if (kenSelectNode.value == "") {
        return;
    }
    this.getMapElement().innerHTML = "";
    // 県CD、サブエリアCDなどを取得する
    var conf = SupportMapArea.SubAreaConf.setting;
    // 県CDを取得
    this.kenCd = kenSelectNode.options[kenSelectNode.selectedIndex].value;
    // HTML作成用変数
    var closeButtonId = '__' + this.mapElementId + '_btn_close';
    var screenId = '__' + this.mapElementId + '_screen';
    var kenImageSrc = this.mapImageDirPrefix + "/" + this.kenCd + "/" + this.kenCd + ".gif";
    var areaMapId = "__area_map_" + this.kenCd + this.mapElementId;

    // HTMLソースを生成する
    // 地図の部分の生成
    var mapHtml = "";
    // z-indexをデフォルトの2倍にしておく。IEの場合iframeのより上にくる必要がある為の対応
    mapHtml += '<div id="' + screenId + '" style="position:relative;z-index:' + this.zindex * 2 + ';">';
    mapHtml += '<table class="supportMap">';
    mapHtml += '<tr>';
    //mapHtml += '  <td style=""><img id="' + closeButtonId + '" class="closeButton" src="' + this.closeImage + '" alt="閉じる"></td>'
    mapHtml += '  <td style="height:11px;text-align:right;"><div id="' + closeButtonId + '" class="closeButton"></td>'
    mapHtml += '</tr>';
    mapHtml += '<tr><td style="">';
    mapHtml += '<img id="' + this.mapImageId + '" class="mapImage" src="' + kenImageSrc + '" alt="入力補助地図" usemap="#' + areaMapId + '">';
    mapHtml += '<map id="' + areaMapId + '" name="' + areaMapId + '">';

    // エリア情報を設定する
    var targetKenCode = kenSelectNode.options[kenSelectNode.selectedIndex].value;
    for (var i = 0; i < conf.length; i++) {
        // 該当県のデータを取得 & SubArea名が空でないものを取得
        if (targetKenCode == conf[i].kenCode && conf[i].subAreaName != "") {
            var subCd = conf[i].subAreaCode;
            var coordsArray = conf[i].coords;
            // 座標データを使用し、Areaタグを作成する
            for (var j = 0; j < coordsArray.length; j++) {
                mapHtml +=
                    "<area "
                    + "value=\"" + subCd + "\" "
                    + "shape=\"poly\" "
                    + "coords=\"" + coordsArray[j] + "\" "
                    + "href=\"javascript:;\" "
                    + "onClick=\"" + this.globalId + ".selectMap(\'" + subCd + "\');\" "
                    + "onMouseOver=\"" + this.globalId + ".focusMap(\'" + subCd + "\');\" "
                    + "onMouseOut=\"" + this.globalId + ".blurMap();\" "
                    + "alt=\"" + conf[i].subAreaName + "\">";
            }
        }
    }
    mapHtml += '</map>';
    mapHtml += '</td></tr></table>';
    mapHtml += '</div>';

    // 地図を書き換える
    var mapNode = this.getMapElement();
    if (!mapNode) return;
    mapNode.style.position = "absolute";
    mapNode.style.display = "none";
    mapNode.innerHTML = mapHtml;

    // <select>への応急処置
    // カレンダーと全く同じサイズのIFRAMEを生成し、座標を一致させて下位レイヤに描画する
    // IFRAME対応が可能なバージョンのみ処置を施す
    var ua = navigator.userAgent;
    if (ua.indexOf("MSIE 5.5") >= 0 || ua.indexOf("MSIE 6") >= 0) {
        var screenHeight = "202px"; // 縦幅固定
        var screenWidth = "336px";  // 横幅固定
        
        var mapIFrameHtml = "";
        mapIFrameHtml += '<div style="position:absolute;z-index:' + this.zindex + ';top:0px;left:0px;">';
        mapIFrameHtml += '  <iframe src="javascript:false;" frameborder="0" scrolling="no" width="' + screenWidth + '" height="' + screenHeight + '"></iframe>';
        mapIFrameHtml += '</div>\n';
        // IFrameを挿入する
        mapNode.innerHTML = mapIFrameHtml + mapHtml;
    }

    // 閉じるボタン
    var __this = this;
    var closeButton = getNode(closeButtonId);
    addEvent(closeButton, "click", function() { __this.hide(); });
};
/**
* 地図のクリックした際の動作を処理します。
* 選択されたサブエリアの値でサブエリアプルダウンの値を変更し、地図を隠します。
* @param subCd 選択したサブエリアコード
*/
SupportMapArea.Map.prototype.selectMap = function(subCd) {
    var subAreaNode = getNode(this.subAreaListId);
    for (var j = 0; j < subAreaNode.length; j++) {
        if (subAreaNode[j].value == subCd) {
            subAreaNode.selectedIndex = j;
            break;
        }
    }
    this.hide();
    if (subAreaNode.onchange != null) {
        subAreaNode.onchange();
    }
    this.onSelected();
};
/**
* 指定されたエリアをハイライト表示します。
* @param subAreaCd サブエリアコード
*/
SupportMapArea.Map.prototype.focusMap = function(subAreaCd) {
    var mapImageNode = getNode(this.mapImageId);
    mapImageNode.src = this.mapImageDirPrefix + "/" + this.kenCd + "/" + subAreaCd + ".gif";
};
/**
* ハイライト表示されていない状態に戻します。
*/
SupportMapArea.Map.prototype.blurMap = function() {
    var mapImageNode = getNode(this.mapImageId);
    mapImageNode.src = this.mapImageDirPrefix + "/" + this.kenCd + "/" + this.kenCd + ".gif";
};
/**
* コントロールを使用不可に設定します。
*/
SupportMapArea.Map.prototype.disable = function() {
    this.hide();
    // 地図選択リンクのdisable化
    var mapSelectLinkNode = getNode(this.linkButtonId);
    addClass(mapSelectLinkNode, SupportMapArea.Const.MAP_SELECT_LINK_DISABLE);
    mapSelectLinkNode.removeAttribute("href");
    this.disabled = true;
};
/**
* コントロールを使用可能に設定します。
*/
SupportMapArea.Map.prototype.enable = function() {
    // 地図選択リンクのenable化
    var mapSelectLinkNode = getNode(this.linkButtonId);
    removeClass(mapSelectLinkNode, SupportMapArea.Const.MAP_SELECT_LINK_DISABLE);
    mapSelectLinkNode.setAttribute("href", "javascript:;");
    this.disabled = false;
};
/**
* 選択後イベント抽象メソッドです。
* <pre>
* 継承したクラスによってオーバーライドされることを想定しています
* exp)検索パネルで使用する場合：Ajax呼び出しを行う等
* </pre>
*/
SupportMapArea.Map.prototype.onSelected = function() {
    // デフォルトでは処理なし
};

/**
* 連想配列オブジェクトをマージします
* される側とする側に同じデータがある場合、される側のデータは上書かれます。
* @param map1 mergeされるマップ情報
* @param map2 mergeするマップ情報
*/
function merge(map1, map2) {
    for (var key in map2) {
        map1[key] = map2[key];
    }
};

/**
* 指定したID 属性を検索してそのノードを返す。
* @param id ID
*/
function getNode(id) {
    return document.getElementById(id);
};

/**
* イベントを登録する際に使用する関数。
* @param elem イベントを登録するエレメント
* @param type イベント名
* @param func 登録する関数
*/
function addEvent(elem, type, func) {
    if (!elem) {
        return false;
    }
    if (elem.addEventListener) { // Safari, Firefox, Opera
        elem.addEventListener(type, func, false);
    } else if (elem.attachEvent) { // IE
        elem.attachEvent('on' + type, func);
    } else { // MacIE、Opera6、Netfront3.0、Netscape3
        return false;
    }
    return true;
};

/**
* 対象NodeのStyleClass指定に、新しいStyleClassを追加します
* @param node 対象node
* @param additionalClasses 追加するクラス
*/
function addClass(node, additionalClasses) {
    var classes = additionalClasses.split(" ");
    for (var i = 0; i < classes.length; i++) {
        if (classes[i] != "") {
            var reg = new RegExp("\\b" + classes[i] + "\\b");
            if (!node.className.match(reg)) {
                node.className += " " + classes[i];
            }
        }
    }
};
/**
* 対象NodeのStyleClass指定から、指定したStyleClassを取り除きます
* @param node 対象node
* @param removedClasses 取り除くクラス
*/
function removeClass(node, removedClasses) {
    var classes = removedClasses.split(" ");
    for (var i = 0; i < classes.length; i++) {
        if (classes[i] != "") {
            var reg = new RegExp("\\s?\\b" + classes[i] + "\\b");
            node.className = node.className.replace(reg, "");
        }
    }
};
