﻿/// <reference name="MicrosoftAjax.js"/>
/// <reference assembly="ESRI.ArcGIS.ADF.Web.UI.WebControls" name="ESRI.ArcGIS.ADF.Web.UI.WebControls.Runtime.JavaScript.references.js"/>

// Register the namespace for the control.
Type.registerNamespace('ADF.Samples.Hyperlink');

ADF.Samples.Hyperlink.Callout = function(map, toolbar, hyperlinkToolID, calloutID, hyperlinkGraphicGroupID) {
    ADF.Samples.Hyperlink.Callout.initializeBase(this);
    this._mapID = map || 'tomsMap';
    this._toolbarID = toolbar || 'Toolbar1';
    this._hyperlinkToolID = hyperlinkToolID || 'Hyperlink';
    this._calloutID = calloutID || 'HyperlinkCallout';
    this._hyperlinkGroupID = hyperlinkGraphicGroupID || 'HyperlinkGraphicsGroup';
    this._calloutMapX = null;
    this._calloutMapY = null;
    this._selectedTool = null;
    this._map = null;
    this._toolbar = null;
    this._hyperlinkGraphicsGroup = null;
    this._processingImageFile = null;
    this._processingImageWidth = null;
    this._processingImageHeight = null;
}

ADF.Samples.Hyperlink.Callout.prototype = {
    initialize: function() {
        ADF.Samples.Hyperlink.Callout.callBaseMethod(this, 'initialize');

        if (this._mapID != null) {
            this._map = $find(this._mapID);
            this._toolbar = $find(this._toolbarID);
            var mapElement = $get(this._mapID);

            if (this._map) {
                // Add an event that fires whenever the map extent changes or is changing.
                this._map.add_extentChanged(Type.createDelegate(this, this.mapExtentChange));
                this._map.add_extentChanging(Type.createDelegate(this, this.mapExtentChange));
                // Add an event that fires whenever the map sends a request to the server.
                this._map.add_onServerRequest(Type.createDelegate(this, this.mapServerRequest));
            }
            // Add an event handler that fires whenever a tool on the toolbar is selected.
            if (this._toolbar) {
                this._toolbar.add_onToolSelected(Type.createDelegate(this, this.toolbarToolSelected));
            }
        }
    },

    dispose: function() {
        ADF.Samples.Hyperlink.Callout.callBaseMethod(this, 'dispose');
        if (this._map) {
            this._map.remove_extentChanged(Type.createDelegate(this, this.mapExtentChange));
            this._map.remove_extentChanging(Type.createDelegate(this, this.mapExtentChange));
            this._map.remove_onServerRequest(Type.createDelegate(this, this.mapServerRequest));
        }
        if (this._toolbar) {
            this._toolbar.remove_onToolSelected(Type.createDelegate(this, this.toolbarToolSelected));
        }
    },

    displayCallout: function(featureXCoOrd, featureYCoOrd, contentHtml, headerHtml) {
        this._calloutMapX = featureXCoOrd;
        this._calloutMapY = featureYCoOrd;
        if (!this._map) { return; }

        var myCallout = $find(this._calloutID);
        if (myCallout == null) {
            myCallout = $create(ESRI.ADF.UI.Callout, { "id": this._calloutID, "parent": this._map.get_element(), "animate": true, "autoHide": false }, null);

            var template = String.format('<div style="background-color:#fff;border: solid 1px #ddd;padding: 0px; margin:0;"><div style="background:#eee; margin:0; height: 22px; width:200px"><table style="height:12px;width:100%"><tr><td>{{@header}}</td><td align="right"><span style="cursor: pointer;" onclick="$find(\'{0}\').hide();">X</span></td></tr></table></div><div style="padding:0;">{{@content}}</div></div>', this._calloutID);
            myCallout.set_template(template);
            myCallout.set_calloutBuffer(0);
        }

        myCallout.setContent({ "content": String.format("<DIV style='width:200px;'>{0}</DIV>", contentHtml), "header": headerHtml });
        this.positionCallout(myCallout);
        myCallout.show();
    },
    
    RemoveAllCalloutGraphics: function(){
        if(this._hyperlinkGraphicsGroup){
            this._hyperlinkGraphicsGroup.clear();
        }
    },

    mapExtentChange: function() {
        var currentCallout = $find(this._calloutID);
        if (currentCallout) {
            this.positionCallout(currentCallout);
        }
    },

    positionCallout: function(callout) {
        if (callout == null) { return; }

        var mapBounds = Sys.UI.DomElement.getBounds(this._map.get_element());
        var screenPoint = this._map.toScreenPoint(new ESRI.ADF.Geometries.Point(this._calloutMapX, this._calloutMapY));

        callout.setPosition(screenPoint.offsetX, screenPoint.offsetY);

        var mapCenterX = mapBounds.x + (mapBounds.width / 2);
        var mapCenterY = mapBounds.y + (mapBounds.height / 2);
        var calloutPoint = callout.getPosition();
        var calloutXinScreenCoords = mapBounds.x + calloutPoint[0];
        var calloutYinScreenCoords = mapBounds.y + calloutPoint[1];
        if (calloutXinScreenCoords > mapCenterX && calloutYinScreenCoords > mapCenterY) {
            callout.set_anchorPoint(ESRI.ADF.UI.AnchorPoint.BottomRight);
        }
        else if (calloutXinScreenCoords > mapCenterX && calloutYinScreenCoords < mapCenterY) {
            callout.set_anchorPoint(ESRI.ADF.UI.AnchorPoint.TopRight);
        }
        else if (calloutXinScreenCoords < mapCenterX && calloutYinScreenCoords > mapCenterY) {
            callout.set_anchorPoint(ESRI.ADF.UI.AnchorPoint.BottomLeft);
        }
        else if (calloutXinScreenCoords < mapCenterX && calloutYinScreenCoords < mapCenterY) {
            callout.set_anchorPoint(ESRI.ADF.UI.AnchorPoint.TopLeft);
        }
        callout.checkPosition();
    },

    // Fires when a tool on Toolbar1 is selected
    toolbarToolSelected: function(toolbarObject, activeToolInfo) {
        // Store a reference to the seleceted tool
        this._selectedTool = activeToolInfo.tool;
    },

    // Fires when the map sends a request to the server
    mapServerRequest: function(mapObject, inputArgument) {
        // Check whether the custom tool is the currently selected tool
        if (this._selectedTool && this._selectedTool.name == this._hyperlinkToolID) {

            var pnt = mapObject.graphicsEditor._geometry;
            if (pnt == null) { return; }

            var screenPnt = mapObject.toScreenPoint(pnt);
            var markerGraphicSizeX = this._processingImageWidth;
            var markerGraphicSizeY = this._processingImageHeight;
            var graphicPoint = mapObject.toMapPoint(screenPnt.offsetX + (markerGraphicSizeX / 2), screenPnt.offsetY + (markerGraphicSizeY / 2))
            //var graphicPoint = new ESRI.ADF.Geometries.Point(pnt.get_x() + 8, pnt.get_y() + 8, pnt.get_spatialReference());

            var defaultSymbol = null;
            defaultSymbol = new ESRI.ADF.Graphics.MarkerSymbol(this._processingImageFile, markerGraphicSizeX, markerGraphicSizeY, 'cross');
            defaultSymbol.set_width(markerGraphicSizeX);
            defaultSymbol.set_height(markerGraphicSizeY);

            // Try retrieving the graphicFeatureGroup (i.e. layer) with the ID corresponding to the current 
            // geometry type.  If the group is not found, create it.
            if (!this._hyperlinkGraphicsGroup) {
                //Try to get the graphics group by ID
                this._hyperlinkGraphicsGroup = $find(this._hyperlinkGroupID);
                if (!this._hyperlinkGraphicsGroup) {
                    // Create the graphic feature group with the ID, symbols, and mapTips.  Also, wire the
                    // onMouseOverGraphics and onMouseOutGraphics to the group's mouseOver and mouseOut events    
                    this._hyperlinkGraphicsGroup = $create(ESRI.ADF.Graphics.GraphicFeatureGroup, { "id": this._hyperlinkGroupID,
                        "symbol": defaultSymbol
                    });

                    // Add the new graphic feature group to the map
                    mapObject.addGraphic(this._hyperlinkGraphicsGroup);
                }
            }
            
            //Clear any existing activity indicators
            this._hyperlinkGraphicsGroup.clear();

            // Create the graphic feature with a unique ID made up of the hyperlinkGroupID and the graphicCount; 
            // the passed-in geometry; and the attributes object that specifies the valueInTextbox attribute
            var graphicFeature = $create(ESRI.ADF.Graphics.GraphicFeature, { "id": "customID", "geometry": graphicPoint });

            // Add the graphic to the group
            this._hyperlinkGraphicsGroup.add(graphicFeature);
        }
    },

    ///
    /// accessors for properties
    ///
    get_mapID: function() {
        return this._mapID;
    },
    set_mapID: function(value) {
        this._mapID = value;
    },
    get_toolbarID: function() {
        return this._toolbarID;
    },
    set_toolbarID: function(value) {
        this._toolbarID = value;
    },
    get_hyperlinkToolID: function() {
        return this._hyperlinkToolID;
    },
    set_hyperlinkToolID: function(value) {
        this._hyperlinkToolID = value;
    },
    get_calloutID: function() {
        return this._calloutID;
    },
    set_calloutID: function(value) {
        this._calloutID = value;
    },
    get_hyperlinkGroupID: function() {
        return this._hyperlinkGroupID;
    },
    set_hyperlinkGroupID: function(value) {
        this._hyperlinkGroupID = value;
    },
    ///Read only properties
    get_calloutMapX: function() {
        return this._calloutMapX;
    },
    get_calloutMapY: function() {
        return this._calloutMapY;
    },
    get_map: function() {
        return this._map;
    },
    set_map: function(value) {
        this._map = value;
    },
    get_toolbar: function() {
        return this._toolbar;
    },
    get_selectedTool: function() {
        return this._selectedTool;
    },
    get_hyperlinkGraphicsGroup: function(){
        return this._hyperlinkGraphicsGroup;
    },
    set_hyperlinkGraphicsGroup: function(value){
        this._hyperlinkGraphicsGroup = value;
    },
    get_processingImageFile: function() {
        return this._processingImageFile;
    },
    set_processingImageFile: function(value) {
        this._processingImageFile = value;
    },
    get_processingImageWidth: function() {
        return this._processingImageWidth;
    },
    set_processingImageWidth: function(value) {
        this._processingImageWidth = value;
    },
    get_processingImageHeight: function() {
        return this._processingImageHeight;
    },
    set_processingImageHeight: function(value) {
        this._processingImageHeight = value;
    }
} //End ADF.Samples.Hyperlink.Callout.prototype definition

ADF.Samples.Hyperlink.Callout.registerClass('ADF.Samples.Hyperlink.Callout', Sys.Component);


