﻿var reasons = [];
//reasons[G_GEO_SUCCESS] = "Success";
//reasons[G_GEO_MISSING_ADDRESS] = "Missing Address: The address was either missing or had no value.";
//reasons[G_GEO_UNKNOWN_ADDRESS] = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
//reasons[G_GEO_UNAVAILABLE_ADDRESS] = "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
//reasons[G_GEO_BAD_KEY] = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
//reasons[G_GEO_TOO_MANY_QUERIES] = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
//reasons[G_GEO_SERVER_ERROR] = "Server error: The geocoding request could not be successfully processed.";
//reasons[403] = "Error 403: Probably an incorrect error caused by a bug in the handling of invalid JSON.";
var geo;
var points = "", addSplit = new Array();
function initGMapVariable() {
    //aFrame = document.getElementById("mapFrame");
    initIcon();
}
function isGMapScriptLoad() {
    try {
        GBrowserIsCompatible();
        return true;
    }
    catch (e) {
        return false;
    }
}
function UnloadGMap() {
    if (isGMapScriptLoad())
        GUnload();
}
function initGeocoder() {
    if (GBrowserIsCompatible() && geo == null) {
        geo = new GClientGeocoder();
        reasons[G_GEO_MISSING_ADDRESS] = "Missing Address";
        reasons[G_GEO_UNKNOWN_ADDRESS] = "Unknown Address";
        reasons[G_GEO_UNAVAILABLE_ADDRESS] = "Unavailable Address";
        reasons[G_GEO_TOO_MANY_QUERIES] = "Too Many Queries";
        reasons[G_GEO_SERVER_ERROR] = "Server error";
        reasons[403] = "Error 403";
    }
}
function StartGetAddressPoint(address) {
    initGeocoder();
    points = "";
    addSplit = address.split(";");
    DoGetAddressPoint();
}
function DoGetAddressPoint() {
    if (addSplit.length == 0) {
        slObj.content.GoogleMapTool.GetAddressPointHandler(points);
    }
    else {
        var address = addSplit[0];
        addSplit.splice(0, 1);
        setTimeout('GetAddressPoint("' + address + '");', 10);
    }
}
function GetAddressPoint(address) {
    geo.getLocations(address,
        function(result) {
            if (result.Status.code == G_GEO_SUCCESS) {
                var p = result.Placemark[0].Point.coordinates;
                var lat = p[1];
                var lng = p[0];
                if (points != "") points += ";";
                points += lat + "," + lng;
            }
            else {
                if (points != "") points += ";";
                //                if (_AddressError == "")
                //                    _AddressError = "Google Map Error\n";
                //                else
                //                    _AddressError += "\n";
                //                _AddressError += "  " + reasons[result.Status.code] + ": " + result.name;
            }
            DoGetAddressPoint();
        }
    );
}
//Div & iFrame
//var isHideMask = false;
var divList = new Array();
var mapList = new Array();
var GMapFrameList = new Array();
var _MarkerList = new Array();
var _MarkerManageList = new Dictionary();
var _CenterList = new Dictionary();
var _RangeValueList = new Dictionary();
var _GIcons = [];
var _VLine, _HLine;
var _CancelAddMarker = false;
//var aFrame = null;
function initIcon() {
    //    var icon = new GIcon();
    //    icon.iconSize = new GSize(32, 32);
    //    //G_DEFAULT_EARTH_ICON.shadowSize = new GSize(56, 32);
    //    icon.iconAnchor = new GPoint(16, 16);
    //    //G_DEFAULT_EARTH_ICON.infoWindowAnchor = new GPoint(16, 0);
    //    _GIcons["Center"] = new GIcon(icon, "http://maps.google.com/mapfiles/kml/pal2/icon2.png");
}
function initGMap(id, isRange, isClear) {
    isRange = isRange == "true";
    isClear = isClear == "true";
    if (GBrowserIsCompatible()) {
        if (!findItem(divList, id)) {
            //每個GoogleMap有獨立的iframe才不會造成新的GoogleMap產生前iframe出現在畫面上
            var frame = document.createElement("iframe");
            frame.setAttribute("id", id);
            frame.style.border = "0px";
            frame.style.position = "absolute";
            frame.style.display = "none";
            frame.style.zIndex = 0;
            document.body.appendChild(frame);
            GMapFrameList.push(frame);
            var div = document.createElement("div");
            div.setAttribute("id", id);
            div.style.position = "absolute";
            div.style.zIndex = 1;
            document.body.appendChild(div);
            divList.push(div);
            var map = new GMap2(div);
            map.id = id;
            //map.addControl(new GMapTypeControl());
            if (id == "GMapManage") {
                map.addControl(new GOverviewMapControl());
                map.addControl(new GLargeMapControl3D());
            }
            else if (id == "GMapLoc") {
                map.addControl(new GSmallZoomControl3D());
            }
            else
                map.addControl(new GLargeMapControl3D());
            //map.addControl(new GScaleControl(256));
            //map.addMapType(G_PHYSICAL_MAP);
            // 加入RangeControl
            if (isRange)
                map.addControl(new RangeControl());
            map.enableScrollWheelZoom();
            map._RangeList = new Dictionary();
            map._Circle = null;
            mapList.push(map);
            _MarkerList[id] = new Dictionary();
        }
        if (isClear)
            clearMarker(id);
        showGMap(id);
    }
}
function setGMapCenter(id, lat, lng, zoom) {
    var center = new GLatLng(eval(lat), eval(lng));
    _CenterList.Add(id, center);
    findItem(mapList, id).setCenter(center, eval(zoom));
    setTimeout(function() { setGMapCenter2(id, center, zoom) }, 300);
    if (id == "GMapLoc")
        initGMapForEditor(id);
    else {
        if (id == "GMapManage")
            initGMapManage(id);
        else
            initGMapRuntime(id);
        //showCenterIcon(id);
    }
}
function setGMapCenter2(id, center, zoom) {
    findItem(mapList, id).setCenter(center, eval(zoom));
}
function setCenterLine(map) {
    try {
        if (_HLine != null)
            map.removeOverlay(_HLine);
        if (_VLine != null)
            map.removeOverlay(_VLine);
    } catch (e) { }
    var bound = map.getBounds();
    var aLat = bound.getSouthWest().lat(), aLng = bound.getSouthWest().lng();
    var bLat = bound.getNorthEast().lat(), bLng = bound.getNorthEast().lng();
    var newLat = (bLat - aLat) / 2 + aLat, newLng = (bLng - aLng) / 2 + aLng;
    _HLine = new GPolyline([new GLatLng(newLat, aLng), new GLatLng(newLat, bLng)], "#ff0000", 2);
    _VLine = new GPolyline([new GLatLng(aLat, newLng), new GLatLng(bLat, newLng)], "#ff0000", 2);
    map.addOverlay(_HLine);
    map.addOverlay(_VLine);
}
function showCenterIcon(id) {
    if (_CenterList.Lookup(id) != null && id != "GMapManage" && id != "GMapLoc") {
        var center = _CenterList.Lookup(id);
        addMarker(id, 0, "__Center__", center.lat(), center.lng(), "", _GIcons["Center"], false, -1, -1);
    }
    //addMarker(id, 0, "__Center__", _Center.lat(), _Center.lng(), "", G_DEFAULT_ICON);
}
function moveGMap(id, x, y) {
    var div = findItem(divList, id);
    if (div == null) return;
    div.style.left = x + "px";
    div.style.top = y + "px";
    var frame = findItem(GMapFrameList, id);
    frame.style.left = x + "px";
    frame.style.top = y + "px";
    //getIFrame().style.left = x + "px";
    //getIFrame().style.top = y + "px";
}
function resizeGMap(id, w, h) {
    var div = findItem(divList, id);
    if (div == null) return;
    div.style.width = w + "px";
    div.style.height = h + "px";
    var frame = findItem(GMapFrameList, id);
    frame.style.width = w + "px";
    frame.style.height = h + "px";
    findItem(mapList, id).checkResize();
}
function refreshGMap(id, x, y, w, h) {
    moveGMap(id, x, y);
    resizeGMap(id, w, h);
}
//只能有一個GoogleMap顯示在畫面上，因為使用hideAllGMap導致第二個顯示時隱藏了前一個
function showGMap(id) {
    if (id == "" || !hasGMap()) return;
    hideAllGMap();
    findItem(divList, id).style.display = "block";
    findItem(GMapFrameList, id).style.display = "block";
    findItem(mapList, id).checkResize();
}
function hideGMap(id) {
    if (id == "" || !hasGMap()) return;
    findItem(divList, id).style.display = "none";
    findItem(GMapFrameList, id).style.display = "none";
}
function hideAllGMap() {
    hideList(divList);
    hideList(GMapFrameList);
    //getIFrame().style.display = "none";
}
function clearAllGMap() {
    clearList(divList);
    clearList(GMapFrameList);
    clearArray(mapList);
    clearArray(_MarkerList);
    _MarkerManageList.Clear();
    _MarkerManageList = new Dictionary();
    _CenterList.Clear();
    _CenterList = new Dictionary();
    _RangeValueList.Clear();
    _RangeValueList = new Dictionary();
}
function hasGMap() {
    return mapList.length > 0;
}
var _ProgressBar;
var _MaxNum, _Num = 0;
function addMarkers(id, range, ids, points, texts, imgs, imgPath, dragged, minZoom, maxZoom) {
    _CancelAddMarker = true;
    if (_ProgressBar != null) {
        setTimeout(function() { addMarkers(id, range, ids, points, texts, imgs, imgPath, dragged, minZoom, maxZoom) }, 10);
        return;
    }
    _CancelAddMarker = false;
    var map = findItem(mapList, id);
    if (_MarkerManageList[id] != null) {
        _MarkerManageList[id].clearMarkers();
        _MarkerManageList[id] = null;
    }
    _MarkerManageList[id] = new MarkerManager(map);
    GEvent.clearListeners(_MarkerManageList[id], "changed");
    GEvent.addListener(_MarkerManageList[id], "changed", function() {
        rangeRefresh(id);
    });
    _ProgressBar = new ProgressbarControl(map, { width: 150 });
    clearMarker(id);
    var mids = ids.split("#$#");
    var markers = points.split(";");
    var htmls = texts.split("#$#");
    var icons = imgs.split("#$#");
    _MaxNum = mids.length;
    _ProgressBar.start(_MaxNum);
    createMarker(id, range, mids, markers, htmls, icons, imgPath, dragged, eval(minZoom), eval(maxZoom));
}
function createMarker(id, range, mids, markers, htmls, icons, imgPath, dragged, minZoom, maxZoom) {
    if (_CancelAddMarker) {
        _Num = 0;
        _ProgressBar.remove();
        _ProgressBar = null;
        return;
    }
    if (mids[_Num] != "" && mids[_Num] != undefined) {
        var point = markers[_Num].split(",");
        var icon = null;
        if (icons[_Num] != "") {
            icon = new GIcon();
            icon.iconSize = new GSize(24, 24);
            icon.iconAnchor = new GPoint(8, 8);
            icon.infoWindowAnchor = new GPoint(8, 0);
            icon = new GIcon(icon, imgPath + icons[_Num]);
        }
        addMarker(id, eval(range), mids[_Num], point[0], point[1], htmls[_Num], icon, dragged, minZoom, maxZoom);
    }
    _Num++;
    _ProgressBar.updateLoader(1);
    if (_Num < _MaxNum) {
        setTimeout(function() { createMarker(id, range, mids, markers, htmls, icons, imgPath, dragged, minZoom, maxZoom) }, 10);
    } else {
        _Num = 0;
        _ProgressBar.remove();
        _ProgressBar = null;
        _MarkerManageList[id].refresh();
        //自動Focus第一筆Marker
        focusMarker(id, mids[0]);
    }
}

function addMarker(id, range, mid, lat, lng, html, icon, dragged, minZoom, maxZoom) {
    if (!hasGMap()) return;
    dragged = dragged == "true";
    var point = new GLatLng(lat, lng);
    var center = findItem(mapList, id).getCenter();
    //var center = _CenterList.Lookup(id);
    if (range != 0) {
        if (center.distanceFrom(point) > range) return;
    }
    var marker = new GMarker(point, { icon: icon, draggable: dragged });
    marker.html = html;
    if (dragged) {//GoogleMapTool專用
        GEvent.clearListeners(marker, "click");
        GEvent.addListener(marker, "click", function() {
            if (marker.html)
                marker.openInfoWindowHtml(marker.html);
            slObj.content.GoogleMapTool.SelectRow(mid);
        });
        GEvent.clearListeners(marker, "dragend");
        GEvent.addListener(marker, "dragend", function(latlng) {
            slObj.content.GoogleMapTool.UpdateMarker(mid, latlng.lat(), latlng.lng());
        });
    }
    else {//GoogleMap專用
        GEvent.clearListeners(marker, "click");
        GEvent.addListener(marker, "click", function() {
            if (marker.html) {
                //Close時Focus Map
                GEvent.clearListeners(marker, "infowindowclose");
                GEvent.addListener(marker, "infowindowclose", function() {
                    setGoogleMapRuntimeFocus(id);
                });
                marker.openInfoWindowHtml(marker.html);
            }
            slObj.content.GoogleMap.SelectRow(id, mid);
        });
    }
    _MarkerList[id].Add(mid, marker);
    if (minZoom != 0 && maxZoom != 0 && _MarkerManageList[id])
        _MarkerManageList[id].addMarker(marker, minZoom - 1, maxZoom - 1);
    else
        findItem(mapList, id).addOverlay(marker);
}
function rangeMarker(id, range) {
    range = eval(range);
    _RangeValueList[id] = range;
    var map = findItem(mapList, id);
    map.closeInfoWindow();
    var center = map.getCenter();
    if (range <= 0) {
        clearCircle(map);
        _RangeValueList.Delete(id);
        if (range == -1) {
            for (var i = map._RangeList.Keys.length - 1, len = 0; i >= len; i--) {
                var name = map._RangeList.Keys[i];
                var poly = map._RangeList.Index(i);
                map.removeOverlay(poly);
                map._RangeList.Delete(name);
            }
        }
    }
    else if (range > 0)
        drawCenterCircle(map, center, range / 1000, 36);
    //    if (id == "GMapManage")
    //        center = map.getCenter();
    //    else
    //        center = _CenterList.Lookup(id);
    var ids = "";
    var dict = _MarkerList[id];
    for (var i = 0, len = dict.Keys.length; i < len; i++) {
        var mid = dict.Keys[i];
        var marker = dict.Index(i);
        var latlng = marker.getLatLng();
        var isContain = true;
        for (var j = 0, count = map._RangeList.Keys.length; j < count; j++) {
            var bound = map._RangeList.Index(j).getBounds();
            if (bound == null) continue;
            isContain = bound.containsLatLng(latlng);
            if (isContain) break;
        }
        var hidden = marker.isHidden();
        if (isContain) {
            if (range > 0 && center.distanceFrom(marker.getLatLng()) > range) {
                if (!hidden)
                    marker.hide();
            }
            else {
                if (hidden)
                    marker.show();
                if (ids != "") ids += "#$#";
                ids += mid;
            }
        }
        else {
            if (!hidden && !latlng.equals(center))
                marker.hide();
        }
    }
    showGMap(id);
    if (isRunTimeMap(id)) {
        slObj.content.GoogleMap.RangeChanged(id, ids);
    }
    else if (id == "GMapManage")
        slObj.content.GoogleMapTool.RangeMarkerHandler(ids);
}
//重新整理篩選範圍
function rangeRefresh(id) {
    if (_RangeValueList.Lookup(id) == null) return;
    rangeMarker(id, _RangeValueList[id]);
}
//清空篩選範圍
function rangeClear(id) {
    var map = findItem(mapList, id);
    if (map == null) return;
    clearCircle(map);
    if (_RangeValueList.Lookup(id) != null)
        _RangeValueList.Delete(id);
    for (var i = map._RangeList.Keys.length - 1, len = 0; i >= len; i--) {
        var name = map._RangeList.Keys[i];
        var poly = map._RangeList.Index(i);
        map.removeOverlay(poly);
        map._RangeList.Delete(name);
    }
}
function focusMarker(id, mid) {
    if (id == "") return;
    var marker = _MarkerList[id].Lookup(mid);
    if (marker == null || marker.isHidden()) return;
    var point = marker.getLatLng();
    findItem(mapList, id).panTo(point);
    if (marker.html)
        marker.openInfoWindowHtml(marker.html);
    //GEvent.trigger(marker, "click", point);
}
function clearMarker(id) {
    clearAllMarker(id);
    //showCenterIcon(id);
}
function clearAllMarker(id) {
    if (!hasGMap()) return;
    if (id == "") return;
    var map = findItem(mapList, id);
    _MarkerList[id].Clear();
    //_MarkerManageList[id] = new GMarkerManager(map);
    //_MarkerManageList[id].refresh();
    map.clearOverlays();
}
function removeGMap(id) {
    if (!hasGMap()) return;
    if (id == "") return;
    var n = indexOfList(divList, id);
    if (n > -1) {
        clearAllMarker(id);
        var div = findItem(divList, id);
        div.style.display = "none";
        document.body.removeChild(div);
        divList.remove(n);
        mapList.remove(n);
        var frame = findItem(GMapFrameList, id);
        frame.style.display = "none";
        document.body.removeChild(frame);
        GMapFrameList.remove(n);
        //getIFrame().style.display = "none";
    }
}
function findItem(list, id) {
    var n = indexOfList(list, id);
    if (n > -1)
        return list[n];
    else
        return null;
}
function indexOfList(list, id) {
    for (var i = 0; i < list.length; i++) {
        if (list[i].id == id)
            return i;
    }
    return -1;
}
function hideList(list) {
    for (var i = 0; i < list.length; i++) {
        list[i].style.display = "none";
    }
}
function clearList(list) {
    for (var i = list.length - 1; i >= 0; i--) {
        var frame = list[i];
        frame.src = "";
        frame.style.display = "none";
        document.body.removeChild(frame);
        list.remove(i);
        frame = null;
    }
    list = new Array();
}
function clearArray(list) {
    for (var i = list.length - 1; i >= 0; i--) {
        list[i] = null;
        list.remove(i);
    }
    list = new Array();
}
function clearDictionary(list) {
}
function initGMapRuntime(id) {
    //執行中頁面專用，地圖工具的移動及縮放時取得焦點
    var map = findItem(mapList, id);
    GEvent.clearListeners(map, "move");
    GEvent.addListener(map, "move", function() {
        setCenterLine(map);
    });
    GEvent.clearListeners(map, "moveend");
    GEvent.addListener(map, "moveend", function() {
        setGoogleMapRuntimeFocus(id);
    });
    GEvent.clearListeners(map, "zoomend");
    GEvent.addListener(map, "zoomend", function() {
        setGoogleMapRuntimeFocus(id);
    });
}
function initGMapForEditor(id) {
    var map = findItem(mapList, id);
    GEvent.clearListeners(map, "move");
    GEvent.addListener(map, "move", function() {
        setCenterLine(map);
    });
    GEvent.clearListeners(map, "dragend");
    GEvent.addListener(map, "dragend", function() {
        setGoogleMapLocation(map);
    });
    GEvent.clearListeners(map, "zoomend");
    GEvent.addListener(map, "zoomend", function() {
        setGoogleMapLocation(map);
    });
}
function initGMapManage(id) {
    var map = findItem(mapList, id);
    GEvent.clearListeners(map, "move");
    GEvent.addListener(map, "move", function() {
        setCenterLine(map);
    });
    GEvent.clearListeners(map, "moveend");
    GEvent.addListener(map, "moveend", function() {
        setGoogleMapManageFocus();
    });
    GEvent.clearListeners(map, "zoomend");
    GEvent.addListener(map, "zoomend", function() {
        setGoogleMapManageFocus();
    });
}
function setGoogleMapRuntimeFocus(id) {
    try { slObj.content.GoogleMap.FocusMap(id); }
    catch (e) { }
}
function setGoogleMapLocation(map) {
    slObj.content.GoogleMapLocation.SetLocation(map.getCenter().lat(), map.getCenter().lng(), map.getZoom());
}
function setGoogleMapManageFocus() {
    slObj.content.GoogleMapManage.FocusMap();
}
function getIFrame(id) {
    var aFrame = findItem(GMapFrameList, id);
    if (aFrame == null) return null;
    if (aFrame.frameElement)
        return aFrame.frameElement;
    else//Firefox
        return aFrame;
}
function isRunTimeMap(id) {
    return id != "GMapLoc" && id != "GMapManage";
}
//function getIFrame() {
//    if (aFrame.frameElement)
//        return aFrame.frameElement;
//    else//Firefox
//        return aFrame;
//}