﻿/// <reference name="MicrosoftAjax.js"/>
/// <reference name="MapCommons.js"/>


Type.registerNamespace("AirQuestSite");

AirQuestSite.MapAreaControl = function(element) {

    this.initialSettings = {};
    this.mapIcons = {};
    this.sysImages = {};
    this.icons = {};

    AirQuestSite.MapAreaControl.initializeBase(this, [element]);

    // ensure unload
    if(!AirQuestSite.MapAreaControl.flagUnloadSet) {
        $addHandler(window, "unload", AirQuestSite.MapAreaControl.unloadGMaps);
        AirQuestSite.MapAreaControl.flagUnloadSet = true;
    }
}

AirQuestSite.MapAreaControl.prototype = {
    C_layerUrl: '',

    theMap: null,
    theMapContainer: null,
    initialSettings: null,
    mapIcons: null,
    sysImages: null,
    dataTag: '',
    mapLayerAirspaces: null,
    overlayAirspaces: null,
    mapNavControl: null,
    mapTypesControl: null,
    mapChanged$handler: null,
    markerClick$handler: null,
    onLoad$handler: null,
    googleEarth: null,
    earth$theNetLink: null,
    urlEarthAirspaceSvc: '',
    icons: null,
    bRequestMarkers: true,
    nodeInfoWindowContent: null,
    waitInfoWindowContent: null,
    containerInfoWindowContent: null,
    pendingInfoWindowRequest: null,
    theGeoCoder: null,
    onsubmit$handler: null,
    mapActionQueue: null,
    theAirspaceInspector: null,
    theAirspaceLayerSwitch: null,
    _partialUpdateEndRequestHandler: null,
    _theMarkerService: null,

    initialize: function() {
        AirQuestSite.MapAreaControl.callBaseMethod(this, 'initialize');

        this.mapActionQueue = new Array();

        this.mapLayerAirspaces = this.createAirspacesLayer("M0");

        var types = new Array();
        for (var i = 0; i < this.initialSettings.ml.length; ++i) {
            switch (this.initialSettings.ml.substring(i, i + 1)) {
                case 'N':
                    types.push(this.adjustMapType(google.maps.NORMAL_MAP, i));
                    break;
                case 'P':
                    types.push(this.adjustMapType(google.maps.PHYSICAL_MAP, i));
                    break;
                case 'S':
                    types.push(this.adjustMapType(google.maps.SATELLITE_MAP, i));
                    break;
                case 'H':
                    types.push(this.adjustMapType(google.maps.HYBRID_MAP, i));
                    break;
                case '3':
                    types.push(this.adjustMapType(google.maps.SATELLITE_3D_MAP, i));
                    break;
            }
        }

        var element = this.get_element();
        element.style.position = "relative";

        this.theMapContainer = document.createElement("div");
        this.theMapContainer.style.width = "100%";
        this.theMapContainer.style.height = "100%";
        this.theMapContainer.style.position = "absolute";
        element.appendChild(this.theMapContainer);


        this._theMarkerService = new AirQuestSite.MapMarkerManager();

        //////////////


        /*
        this._pageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
        if(this._pageRequestManager.get_isInAsyncPostBack()) {
        this._partialUpdateEndRequestHandler = Function.createDelegate(this, this._partialUpdateEndRequest);
        this._pageRequestManager.add_endRequest(this._partialUpdateEndRequestHandler);
        } else {*/
        this.onLoad$handler = Function.createDelegate(this, Function.createCallback(this.onLoad, types));
        Sys.Application.add_load(this.onLoad$handler);
        /*}*/

        //this.theMap.enableGoogleBar();

        for (var key in this.mapIcons) {
            var icoDef = this.mapIcons[key];
            var gico = new google.maps.Icon();
            gico.image = icoDef.icon;
            if (icoDef.size.Width != 0) {
                gico.iconSize = new google.maps.Size(icoDef.size.Width, icoDef.size.Height);
                gico.iconAnchor = new google.maps.Point(icoDef.iconAnchor.X, icoDef.iconAnchor.Y);
            } else {
                gico.iconSize = G_DEFAULT_ICON.iconSize;
                gico.iconAnchor = G_DEFAULT_ICON.iconAnchor;
            }
            if (icoDef.shadow) {
                if (icoDef.shadow == "-") {
                    gico.shadow = G_DEFAULT_ICON.shadow;
                    gico.shadowSize = G_DEFAULT_ICON.shadowSize;
                } else {
                    gico.shadow = icoDef.shadow;
                    gico.shadowSize = new google.maps.Size(icoDef.shadowSize.Width, icoDef.shadowSize.Height);
                }
            } else {
                gico.shadow = null;
            }
            if (icoDef.transparent) {
                if (icoDef.transparent == "-") {
                    gico.transparent = G_DEFAULT_ICON.transparent;
                } else {
                    gico.transparent = icoDef.transparent;
                }
            }
            if (icoDef.maxHeight != 0) {
                gico.maxHeight = icoDef.maxHeight;
            }

            this.icons[key] = gico;
        }

        // add default
        this.icons["default"] = G_DEFAULT_ICON;

        this.nodeInfoWindowContent = document.createElement("div");
        this.waitInfoWindowContent = document.createElement("div");
        this.containerInfoWindowContent = document.createElement("div");

        this.waitInfoWindowContent.style.textAlign = "center";
        var wImg = document.createElement("img");
        wImg.src = this.sysImages["wait_icon"];
        this.waitInfoWindowContent.appendChild(wImg);

    },

    _partialUpdateEndRequest: function(sender, endRequestEventArgs) {
        alert("Do not use");
        this._pageRequestManager.remove_endRequest(this._partialUpdateEndRequestHandler);
        this._partialUpdateEndRequestHandler = null;
    },

    postMapAction: function(mapDelegate) {

        // queue if needed
        if (!this.theMap) {
            this.mapActionQueue.push(mapDelegate);
        } else {
            mapDelegate(this.theMap);
        }
    },

    onLoad: function(sender, args, types) {
        Sys.Application.remove_load(this.onLoad$handler);
        this.onLoad$handler = null;

        // pospone it
        var cbk = new Function.createDelegate(this, function() { this.setupMap(types); });
        window.setTimeout(cbk, 0);
    },

    add_mapInitialized: function(handler) {
        var e = Function._validateParams(arguments, [{ name: "handler", type: Function}]);
        if (e) throw e;
        this.get_events().addHandler("mapinitialized", handler);
    },

    remove_mapInitialized: function(handler) {
        var e = Function._validateParams(arguments, [{ name: "handler", type: Function}]);
        if (e) throw e;
        this.get_events().removeHandler("mapinitialized", handler);
    },

    setupMap: function(types) {

        this.theMap = new google.maps.Map2(this.theMapContainer, { mapTypes: types });
        this.theMap.setCenter(new google.maps.LatLng(this.initialSettings.c.Lat, this.initialSettings.c.Lon), this.initialSettings.z);

        if (this.initialSettings.sa) {
            this.showAirspacesOverlay(true);
        }

        if (this.initialSettings.ed) {
            this.theMap.enableDragging();
        } else {
            this.theMap.disableDragging();
        }

        this.theMap.enableContinuousZoom();
        this.theMap.enableScrollWheelZoom();

        switch (this.initialSettings.mc) {
            case 1:
                this.mapNavControl = new google.maps.LargeMapControl();
                break;
            case 2:
                this.mapNavControl = new google.maps.SmallMapControl();
                break;
            case 3:
                this.mapNavControl = new google.maps.SmallZoomControl();
                break;
        }

        if (this.mapNavControl) {
            this.theMap.addControl(this.mapNavControl);
        }

        switch (this.initialSettings.mt) {
            case 1:
                this.mapTypesControl = new google.maps.MapTypeControl();
                break;
            case 2:
                this.mapTypesControl = new google.maps.MenuMapTypeControl();
                break;
        }

        if (this.mapTypesControl) {
            this.theMap.addControl(this.mapTypesControl);
        }

        if (this.initialSettings.ov) {
            this.theMap.addControl(new GOverviewMapControl());
        }

        this.theAirspaceInspector = new AirQuestSite.AirspaceInspector(this);
        this.theAirspaceLayerSwitch = new AirQuestSite.AirspaceLayerSwitch(this, Function.createDelegate(this, this.onAirLayerModeChanged));

        this.theMap.addControl(this.theAirspaceInspector);
        this.theMap.addControl(this.theAirspaceLayerSwitch);

        this.theMap.setMapType(types[this.initialSettings.ti]);

        this.mapChanged$handler = google.maps.Event.bind(this.theMap, "maptypechanged", this, this.onMapTypeChanged);

        this.onMapInitialized();
    },

    onMapInitialized: function() {

        // play the queue

        for (var i = 0; i < this.mapActionQueue.length; ++i) {
            this.mapActionQueue[i](this.theMap);
            this.mapActionQueue[i] = null;
        }
        var r = new Array();

        this.mapActionQueue = null;

        var handler = this.get_events().getHandler("mapinitialized");
        if (handler) {
            handler(this, Sys.EventArgs.Empty);
        }
    },

    get_map: function() {
        return this.theMap;
    },

    get_icons: function() {
        return this.icons;
    },

    get_waitInfoWindowContent: function() {
        return this.waitInfoWindowContent;
    },

    get_geoCoder: function() {
        if (!this.theGeoCoder) {
            this.theGeoCoder = new GClientGeocoder();
        }
        return this.theGeoCoder;
    },

    adjustMapType: function(baseType, strTypeCode) {
        var layers = new Array();
        var baseLayers = baseType.getTileLayers();
        for (var i = 0; i < baseLayers.length; ++i) {
            layers.push(baseLayers[i]);
        }
        //layers.push(this.mapLayerAirspaces);

        var mt = new GMapType(layers, baseType.getProjection(), baseType.getName(), { minResolution: 7 });
        mt.___typeindex = strTypeCode;
        return mt;
    },


    setInfoWindowContainer: function(node) {
        // clear current content
        while (this.containerInfoWindowContent.hasChildNodes() && this.containerInfoWindowContent.childNodes.length > 0) {
            this.containerInfoWindowContent.removeChild(this.containerInfoWindowContent.childNodes[this.containerInfoWindowContent.childNodes.length - 1]);
        }
        this.containerInfoWindowContent.appendChild(node);
    },



    //    onClickInfoMarker: function(sender, argd) {
    //        //this.setInfoWindowContainer(this.waitInfoWindowContent);

    //        var ad = sender.__apcontext;
    //        var svc = new AirQuest.AdInfoSvc();
    //        var This = this;
    //        var fcnOnOpen = function() { This.pendingInfoWindowRequest = svc.GetAirportInfo(ad.strName, Function.createDelegate(This, This.reply_GetAirportInfo), function() { This.theMap.closeInfoWindow(); }, argd.get_point()); }
    //        var fcnOnClose = function() { if(This.pendingInfoWindowRequest) { This.pendingInfoWindowRequest.get_executor().abort(); This.pendingInfoWindowRequest = null; }; };
    //        this.theMap.openInfoWindow(argd.get_point(), this.waitInfoWindowContent, { onOpenFn: fcnOnOpen, onCloseFn: fcnOnClose });
    //    },

    //    reply_GetAirportInfo: function(res, e) {
    //        this.pendingInfoWindowRequest = null;
    //        var wnd = this.theMap.getInfoWindow();
    //        this.nodeInfoWindowContent.innerHTML = res;
    //        if(!this.theMap.getInfoWindow().isHidden()) {
    //            var This = this;
    //            this.theMap.updateCurrentTab(function(tab) { tab.contentElem = This.nodeInfoWindowContent; });
    //        }
    //    },

    createAirspacesLayer: function(layMode) {
        var cpy = new google.maps.CopyrightCollection("@2010");
        cpy.addCopyright(new google.maps.Copyright(314, new google.maps.LatLngBounds(new GLatLng(45, 13), new GLatLng(55, 19)), 7, 'Pythagoras'));
        var tilelayer = new google.maps.TileLayer(cpy, 7, 15);
        var theLayerUrlBase = this.C_layerUrl;
        var theDataTag = this.dataTag;
        tilelayer.getTileUrl = function(pt, zf) { return theLayerUrlBase + "?z=" + zf.toString() + "&x=" + pt.x + "&y=" + pt.y + "&mode=" + layMode + "&tag=" + theDataTag; };
        tilelayer.isPng = function() { return true; };
        tilelayer.getOpacity = function() { return 1.0; }

        return tilelayer;
    },

    createOvelayedMap: function(map) {
        var lrs = map.getTileLayers();
        lrs.push(this.mapLayerAirspaces);
        var newMap = new google.maps.MapType(lrs, map.getProjection(), "Air" + map.getName());

        return newMap;
    },

    showAirspacesOverlay: function(bShow) {

        if (bShow) {
            if (!this.overlayAirspaces) {
                this.overlayAirspaces = new google.maps.TileLayerOverlay(this.mapLayerAirspaces);
                this.theMap.addOverlay(this.overlayAirspaces);
                if (this.theAirspaceLayerSwitch) {
                    Sys.UI.DomElement.setVisible(this.theAirspaceLayerSwitch.theControlFrame, true);
                }

            }
        } else {
            if (this.overlayAirspaces) {
                this.theMap.removeOverlay(this.overlayAirspaces);
                this.overlayAirspaces = null;
                if (this.theAirspaceLayerSwitch) {
                    Sys.UI.DomElement.setVisible(this.theAirspaceLayerSwitch.theControlFrame, false);
                }
            }
        }

    },


    onMapTypeChanged: function() {
        // load Earth stuff

        if (this.theMap.getCurrentMapType() == google.maps.SATELLITE_3D_MAP) {

            this.theMap.disableContinuousZoom();
            this.theMap.disableScrollWheelZoom();


            var This = this;
            this.theMap.getEarthInstance(function(ge) { This.loadEarthFeatures(ge); });
        } else {
            this.theMap.enableContinuousZoom();
            this.theMap.enableScrollWheelZoom();

            //this.bRequestMarkers = true;
            //this.forceMove();
        }
    },

    loadEarthFeatures: function(ge) {
        this.googleEarth = ge;

        if (!this.earth$theNetLink) {
            this.earth$theNetLink = ge.createNetworkLink("pth-airspaces");
            var theLink = ge.createLink("pth-airspaces-link");
            theLink.setHref(this.urlEarthAirspaceSvc);
            this.earth$theNetLink.set(theLink, true, false);
            var fts = this.googleEarth.getFeatures();
            this.googleEarth.getFeatures().appendChild(this.earth$theNetLink);
        }
    },

    onsubmit: function() {
        // save map state
        var state = {};
        if (this.theMap) {
            var c = this.theMap.getCenter();
            state.c = { lat: c.lat(), lon: c.lng() };
            state.z = this.theMap.getZoom();
            state.ti = this.theMap.getCurrentMapType().___typeindex;
        } else {
            state.c = { lat: this.initialSettings.c.Lat, lon: this.initialSettings.c.Lon };
            state.z = this.initialSettings.z;
            state.ti = 0;
        }
        $get(this.initialSettings.sf).value = Sys.Serialization.JavaScriptSerializer.serialize(state);
    },

    setMapCenter: function(center, zoom) {
        var action = Function.createDelegate(this, function(theMap) {
            this.theMap.setCenter(new GLatLng(center.lat, center.lon), zoom);
        });
        this.postMapAction(action);
    },

    requestAirspaceInfo: function(x, y) {
        var coords = this.theMap.fromContainerPixelToLatLng(new GPoint(x, y));

        this.theMap.openInfoWindow(coords, this.get_waitInfoWindowContent(), { onOpenFn: Function.createDelegate(this, Function.createCallback(this.requestAirspaceInfoContent, coords)) });
    },

    requestAirspaceInfoContent: function(coords) {
        this._theMarkerService.GetAirspaceInfo(coords.lat(), coords.lng(), Function.createDelegate(this, this.onGetAirspaceInfoResponse));
    },

    onGetAirspaceInfoResponse: function(resp, ctx) {
        var iw = this.theMap.getInfoWindow();
        if (!iw.isHidden()) {
            var tabs = new Array();
            var divCnt = document.createElement("div");
            divCnt.innerHTML = resp;
            tabs.push(new GInfoWindowTab("Informace o prostoru", divCnt));
            this.theMap.updateInfoWindow(tabs);
        }
    },

    onAirLayerModeChanged: function(sender) {
        this.showAirspacesOverlay(false);
        this.mapLayerAirspaces = this.createAirspacesLayer(this.theAirspaceLayerSwitch.getLayerType());
        this.showAirspacesOverlay(true);

    },

    dispose: function() {

        if (this.theAirspaceInspector) {
            this.theAirspaceInspector.dispose();
            this.theAirspaceInspector = null;
        }

        if (this.theAirspaceLayerSwitch) {
            this.theAirspaceLayerSwitch.dispose();
            this.theAirspaceLayerSwitch = null;
        }

        if (this.theMap) {
            google.maps.Event.removeListener(this.mapChanged$handler);

            var element = this.get_element();
            element.removeChild(this.theMapContainer);
            this.theMapContainer = null;
        }

        AirQuestSite.MapAreaControl.callBaseMethod(this, 'dispose');

    }
}

AirQuestSite.MapAreaControl.unloadGMaps = function() {

    if(GUnload) {
        GUnload();
    }
}

AirQuestSite.MapAreaControl.adDataCache = null;

AirQuestSite.MapAreaControl.registerClass('AirQuestSite.MapAreaControl', Sys.UI.Control);


/******************************* Airspace inspector **********************************/

AirQuestSite.AirspaceInspector = function(map) {
    this.mapControl = map;
    this.theMap = null;
    this.theControlFrame = null;
    this.ptDragStart = new Sys.UI.Point(0, 0);
    this.bMouseDown = false;
    this.bMouseDrag = false;
}

AirQuestSite.AirspaceInspector.prototype = new GControl();

AirQuestSite.AirspaceInspector.prototype.initialize = function(map) {
    this.theMap = map;    

    this.theControlFrame = document.createElement("div");
    this.theControlFrame.className = "airspaceinspector_back";
    this.theControlFrame.title = "Přetáhněte šipku na prostor, který Vás zajímá";

    this.theHomeIcon = document.createElement("div");
    this.theHomeIcon.className = "airspaceinspector_homeicon";
    this.theControlFrame.appendChild(this.theHomeIcon);

    this.thePointer = document.createElement("div");
    this.thePointer.className = "airspaceinspector_pointer";
    Sys.UI.DomElement.setVisible(this.thePointer, false);
    this.theControlFrame.appendChild(this.thePointer);


    this.theMap.getContainer().appendChild(this.theControlFrame);

    this.mouse$handler = Function.createDelegate(this, this.onmouse);
    $addHandler(this.theControlFrame, "mousedown", this.mouse$handler);
    $addHandler(document.body, "mousemove", this.mouse$handler);
    $addHandler(document.body, "mouseup", this.mouse$handler);


    return this.theControlFrame;
}

AirQuestSite.AirspaceInspector.prototype.onmouse = function(e) {
    switch(e.type) {
        case "mousedown":
            if(e.button == 0) {
                this.bMouseDown = true;
                this.ptDragStart = new Sys.UI.Point(e.clientX, e.clientY);
                Sys.Debug.traceDump(this.ptDragStart);
                e.stopPropagation();
                e.preventDefault();
            }
            break;

        case "mousemove":
            if(this.bMouseDown && !this.bMouseDrag) {
                if(Math.abs(e.clientX - this.ptDragStart.x) > 2 || Math.abs(e.clientY - this.ptDragStart.y) > 2) {
                    this.bMouseDrag = true;
                    Sys.UI.DomElement.setVisible(this.theHomeIcon, false);
                    Sys.UI.DomElement.setVisible(this.thePointer, true);
                }
            }

            if(this.bMouseDrag) {
                var pel = this.thePointer.offsetParent;
                var posParent = Sys.UI.DomElement.getLocation(pel);
                //this.thePointer.style.top = (e.clientY - posParent.y - 25).toString() + "px";
                //this.thePointer.style.left = (e.clientX - posParent.x - 9).toString() + "px";

                var scrollX = 0;
                var scrollY = 0;

                while(pel && typeof(pel.scrollLeft) == "number") {
                    scrollX += pel.scrollLeft;
                    scrollY += pel.scrollTop;
                    pel = pel.parentNode;
                }

                Sys.UI.DomElement.setLocation(this.thePointer, e.clientX - posParent.x - 8 + scrollX, e.clientY - posParent.y - 24 + scrollY);
                e.stopPropagation();
                e.preventDefault();
            }

            break;

        case "mouseup":
            if(this.bMouseDown) {
                this.bMouseDown = false;
                e.stopPropagation();
            }

            if(this.bMouseDrag) {

                // dělěj něco užitečného                
                var posPointer = Sys.UI.DomElement.getLocation(this.thePointer);

                this.bMouseDrag = false;
                Sys.UI.DomElement.setVisible(this.theHomeIcon, true);
                Sys.UI.DomElement.setVisible(this.thePointer, false);

                var posMap = Sys.UI.DomElement.getLocation(this.theMap.getContainer());
                this.mapControl.requestAirspaceInfo(posPointer.x - posMap.x + 6, posPointer.y - posMap.y + 26);


            }

    }
}

AirQuestSite.AirspaceInspector.prototype.getDefaultPosition = function() {    

    return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 34));
}

AirQuestSite.AirspaceInspector.prototype.dispose = function() {
    $removeHandler(this.theControlFrame, "mousedown", this.mouse$handler);
    $removeHandler(document.body, "mousemove", this.mouse$handler);
    $removeHandler(document.body, "mouseup", this.mouse$handler);
}


/******************************* Airspace Layer Switch **********************************/

AirQuestSite.AirspaceLayerSwitch = function(map, notifyCall) {
    this.mapControl = map;
    this.notifyCall = notifyCall;
    this.theMap = null;
    this.theControlFrame = null;
}

AirQuestSite.AirspaceLayerSwitch.prototype = new GControl();

AirQuestSite.AirspaceLayerSwitch.prototype.initialize = function(map) {
    this.theMap = map;

    this.theControlFrame = document.createElement("div");
    this.theControlFrame.className = "airspacelayerswitch_back";
    this.theControlFrame.title = "Přepíná zobrazené prostory podle výšky, kam zasahují";

    this.theLabel = document.createElement("div");
    this.theLabel.appendChild(document.createTextNode("prostory do:"));
    this.theControlFrame.appendChild(this.theLabel);

    this.theSelect = document.createElement("select");
    var names = ["<FL50", "<FL95", "<FL195"];
    for (var idx = 0; idx < names.length; ++idx ) {
        var opt = document.createElement("option");
        opt.value = "0";        
        opt.appendChild(document.createTextNode(names[idx]));
        this.theSelect.appendChild(opt);
    }
    this.theSelect.selectedIndex = 0;

    this.theControlFrame.appendChild(this.theSelect);

    this.theMap.getContainer().appendChild(this.theControlFrame);

    this.change$handler = Function.createDelegate(this, this.onchange);
    $addHandler(this.theSelect, "change", this.change$handler);

    return this.theControlFrame;
}

AirQuestSite.AirspaceLayerSwitch.prototype.onchange = function(e) {
    this.notifyCall();
}

AirQuestSite.AirspaceLayerSwitch.prototype.getLayerType = function() {
    return "M" + this.theSelect.selectedIndex.toString();
}

AirQuestSite.AirspaceLayerSwitch.prototype.getDefaultPosition = function() {

    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(80, 5));
}

AirQuestSite.AirspaceLayerSwitch.prototype.dispose = function() {    
}



if(typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

