
/**
 * @requires OpenLayers/Popup/Framed.js
 * @requires OpenLayers/Layer/Grid.js
 * @requires OpenLayers/Class.js
 * @requires OpenLayers/Util.js
 * $Workfile: atExtendOpenLayers.js $
 * $Revision: 35 $
 * $Modtime: 21/10/10 10:46 $
 * $Author: Aamir.afridi $ 
 */

/**
 * A class to provide an iShareMaps map as an OpenLayers layer
 */
OpenLayers.Layer.iShareMaps = OpenLayers.Class(OpenLayers.Layer.Grid, {

    DEFAULT_PARAMS: {
        'RequestType': 'OLMap',
		'MapID': -1,
		'ServiceAction': 'ZoomToLocation'
    },
    initialize: function(name, url, params, options) {
        var newArguments = [];
        newArguments.push(name, url, params, options);
        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);

        if (arguments.length > 0) {
            OpenLayers.Util.applyDefaults(
                           this.params,
                           this.DEFAULT_PARAMS
                           );
        }

        // unless explicitly set in options, if the layer is transparent, 
        // it will be an overlay
        if (options == null || options.isBaseLayer == null) {
            this.isBaseLayer = ((this.params.transparent != "true") && 
                                (this.params.transparent != true));
        }
    }, 
    /**
     * APIProperty: transitionEffect
     * {String} The transition effect to use when the map is panned or
     *     zoomed.  
     *
     * There are currently two supported values:
     *  - *null* No transition effect (the default).
     *  - *resize*  Existing tiles are resized on zoom to provide a visual
     *    effect of the zoom having taken place immediately.  As the
     *    new tiles become available, they are drawn over top of the
     *    resized tiles.
     */
    transitionEffect: 'resize',
    
    clone: function (obj) {
        if (obj == null) {
            obj = new OpenLayers.Layer.iShareMaps(this.name,
                                           this.url,
                                           this.params,
                                           this.options);
        }
        //get all additions from superclasses
        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);

        // copy/set any non-init, non-simple values here

        return obj;
    },
    addTile:function(bounds,position) {
        return new OpenLayers.Tile.Image(this, position, bounds, 
                                         null, this.tileSize);
    },
    redraw: function(  ) {
		if( this.params.layers && this.params.layers.length ) {
			if ( this.params.layers.length === 0) {
				this.setVisibility(false);
				for( var i = 0;  i < this.grid.length; i++ ) {
				
					for( var j = 0; j < this.grid[i].length; j++) {
						var tile = this.grid[i][j];
						if( tile.backBufferTile ) {
							//tile.backBufferTile.imgDiv.src = OpenLayers.Util.getImagesLocation() + "blank.gif";
						}
					}
				
				}
			}
			else {
				this.setVisibility(true);	
			}
		}
		OpenLayers.Layer.Grid.prototype.redraw.apply(
	        this, arguments
	    ); 
    },
    getURL: function (bounds) {
        bounds = this.adjustBounds(bounds);
		var centre = bounds.getCenterLonLat();
		
        var imageSize = this.getImageSize(); 
        this.view = {
					    mapwidth: imageSize.w,
						mapheight: imageSize.h,
					 	easting: centre.lon,
						northing: centre.lat,
						zoom: imageSize.w * this.map.getResolution()
					 }
        
        var url = this.getFullRequestString(this.view);
        
        return url;
    },
    getFullRequestString:function(newParams, altUrl) {
        // use layer's url unless altUrl passed in
        var url = (altUrl == null) ? this.url : altUrl;
        
        // create a new params hashtable with all the layer params and the 
        // new params together. then convert to string
        var allParams = OpenLayers.Util.extend({}, this.params);
        allParams = OpenLayers.Util.extend(allParams, newParams);
        var paramsString = OpenLayers.Util.getParameterString(allParams);
        
        // if url is not a string, it should be an array of strings, 
        // in which case we will deterministically select one of them in 
        // order to evenly distribute requests to different urls.
        if (url instanceof Array) {
            url = this.selectUrl(paramsString, url);
        }   
        
        // ignore parameters that are already in the url search string
        var urlParams = OpenLayers.Util.upperCaseObject(
                            OpenLayers.Util.getParameters(url));
        for(var key in allParams) {
            if(key.toUpperCase() in urlParams) {
                delete allParams[key];
            }
        }
        paramsString = OpenLayers.Util.getParameterString(allParams);
        
        // requestString always starts with url
        var requestString = url;        
     
        if (paramsString != "") {
            var lastServerChar = url.charAt(url.length - 1);
            if ((lastServerChar == "&") || (lastServerChar == "?")) {
                requestString += paramsString;
            } else {
                if (url.indexOf('?') == -1) {
                    //serverPath has no ? -- add one
                    requestString += '?' + paramsString;
                } else {
                    //serverPath contains ?, so must already have paramsString at the end
                    requestString += '&' + paramsString;
                }
            }
        }
        return requestString;
    },

    CLASS_NAME: "OpenLayers.Layer.iShareMaps"
});


/**
 * A class to provide an iShareMaps with background raster as an OpenLayers layer. 
 * Using old call to provide image with basemap and datamap combined.
 */
OpenLayers.Layer.iShareMaps.Combo = OpenLayers.Class(OpenLayers.Layer.iShareMaps, {

    DEFAULT_PARAMS: {
        'RequestType': 'Map'
    },

    CLASS_NAME: "OpenLayers.Layer.iShareMaps.Combo"
});

OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {                
	defaultHandlerOptions: {
	    'single': true,
	    'double': true,
	    'pixelTolerance': 0,
	    'stopSingle': false,
	    'stopDouble': false
	},
	initialize: function(options, callbacks) {
	    this.handlerOptions = OpenLayers.Util.extend(
	    	this.defaultHandlerOptions, options
	    );
		callbacks = OpenLayers.Util.extend(
			{'click': this.defaultClick, 'dblclick': this.defaultDoubleClick}, callbacks
		);
	    OpenLayers.Control.prototype.initialize.apply(
	        this, arguments
	    ); 
	    this.handler = new OpenLayers.Handler.Click(
	        this, 
			{
	            'click': callbacks.click,
	            'dblclick': callbacks.dblclick
	        }, 
			this.handlerOptions
	    );
	}, 
	defaultClick: function(evt) {
		//evt.xy is OpenLayers.Pixel
		var clickPixel = evt.xy;
		var clickLonLat = this.map.getLonLatFromPixel(clickPixel);
	    alert("Single click at: \n" + clickLonLat + " \n" + clickPixel);
	},
	defaultDoubleClick: function(evt) {  
		var clickPixel = evt.xy;
		var clickLonLat = this.map.getLonLatFromPixel(clickPixel);
	    alert("Double click at: \n" + clickLonLat + " \n" + clickPixel);
	}  
});


OpenLayers.Control.Hover = OpenLayers.Class(OpenLayers.Control, {                
    defaultHandlerOptions: {
        'delay': 500,
        'pixelTolerance': null,
        'stopMove': false
    },

    initialize: function(options, callbacks) {
        this.handlerOptions = OpenLayers.Util.extend(
            this.defaultHandlerOptions, options
        );		
		callbacks = OpenLayers.Util.extend(
			{'pause': this.defaultPause, 'move': this.defaultMove}, callbacks
		);
        OpenLayers.Control.prototype.initialize.apply(
            this, arguments
        ); 
        this.handler = new OpenLayers.Handler.Hover(
            this,
            {
				'pause': callbacks.pause,
				'move': callbacks.move
			},
            this.handlerOptions
        );
    }, 

    defaultPause: function(evt) {
		//evt.xy is OpenLayers.Pixel
        alert('pause ' + evt.xy);
       
    },

    defaultMove: function(evt) {
		//evt.xy is OpenLayers.Pixel
        // if this control sent an Ajax request when
        // the mouse pauses the onMove callback could
        //  be used to abort that request.
    }
});



OpenLayers.Control.Drag = OpenLayers.Class(OpenLayers.Control, {               
    defaultHandlerOptions: {
		'stopDown': false
    },

    initialize: function(callbacks) {
		callbacks = OpenLayers.Util.extend(
			{
				'move': function( pixel ) {
					// pixel - { Openlayers.Pixel }
					       
				},

				'done': function(pixel) {
					// pixel - { Openlayers.Pixel }
				},

				'down': function(pixel) {
					// pixel - { Openlayers.Pixel }
				},

				'up': function(pixel) {
					// pixel - { Openlayers.Pixel }
				},

				'out': function(pixel) {
					// pixel - { Openlayers.Pixel }
				}
			}, 
			callbacks
		);
        OpenLayers.Control.prototype.initialize.apply(
            this, arguments
        ); 
        this.handler = new OpenLayers.Handler.Drag(
            this,
            callbacks,
            this.defaultHandlerOptions
        );
    } 

   
});

/**
 * Class: OpenLayers.Popup.FramedCompact
 * 
 * Inherits from: 
 *  - <OpenLayers.Popup.Framed>
 */
OpenLayers.Popup.FramedCompact = 
  OpenLayers.Class(OpenLayers.Popup.Framed, {
 	/** 
     * Constructor: OpenLayers.Popup.FramedCompact
     * 
     * Parameters:
     * id - {String}
     * lonlat - {<OpenLayers.LonLat>}
     * contentSize - {<OpenLayers.Size>}
     * contentHTML - {String}
     * anchor - {Object} Object to which we'll anchor the popup. Must expose 
     *     a 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>) 
     *     (Note that this is generally an <OpenLayers.Icon>).
     * closeBox - {Boolean}
     * closeBoxCallback - {Function} Function to be called on closeBox click.
     */
    initialize: function(id, lonlat, contentSize, contentHTML, anchor, closeBox, 
                        closeBoxCallback, image) {

        //this.imageSrc = OpenLayers.Util.getImagesLocation() + 'Cloud-popup-relative.png'; Should Astun do something like this?
        this.imageSrc  = image;
        OpenLayers.Popup.Framed.prototype.initialize.apply(this, arguments);
        this.contentDiv.className = this.contentDisplayClass;
    },

    /** 
     * Property: displayClass
     * {String} The CSS class of the popup.
     */
    displayClass: "olPopup olFramedCompactPopup",
    
    /** 
     * Property: contentDisplayClass
     * {String} The CSS class of the popup content div.
     */
    contentDisplayClass: "olFramedCompactPopupContent",

    /**
     * Property: autoSize
     * {Boolean} FramedCompact is autosizing by default.
     */
    autoSize: true,

    /**
     * Property: panMapIfOutOfView
     * {Boolean} FramedCompact does pan into view by default.
     */
    panMapIfOutOfView: true,

    /**
     * Property: imageSize
     * {<OpenLayers.Size>}
     */
    imageSize: new OpenLayers.Size(676, 736),

    /**
     * Property: isAlphaImage
     * {Boolean} The FramedCompact does not use an alpha image (in honor of the 
     *     good ie6 folk out there)
     */
    isAlphaImage: false,

    /** 
     * Property: fixedRelativePosition
     * {Boolean} The FramedCompact popup works in just one fixed position.
     */
    fixedRelativePosition: false,
    

    /**
     * Property: positionBlocks
     * {Object} Hash of different position blocks, keyed by relativePosition
     *     two-character code string (ie "tl", "tr", "bl", "br")
     */
    positionBlocks: {
        "tl": {
            'offset': new OpenLayers.Pixel(0, 0),
            'padding': new OpenLayers.Bounds(5, 10, 10, 5),
            'blocks': [
                { // top-left
                    size: new OpenLayers.Size('auto', 'auto'),
                    anchor: new OpenLayers.Bounds(0, 10, 10, 0),
                    position: new OpenLayers.Pixel(0, 0)
                },
                { //top-right
                    size: new OpenLayers.Size(5, 'auto'),
                    anchor: new OpenLayers.Bounds(null, 10, 5, 0),
                    position: new OpenLayers.Pixel(-655, 0)
                },
                { //bottom-left
                    size: new OpenLayers.Size('auto', 5),
                    anchor: new OpenLayers.Bounds(0, 5, 10, null),
                    position: new OpenLayers.Pixel(0, -645)
                },
                { //bottom-right
                    size: new OpenLayers.Size(5, 5),
                    anchor: new OpenLayers.Bounds(null, 5, 5, null),
                    position: new OpenLayers.Pixel(-655, -645)
                },
                { // stem
                    size: new OpenLayers.Size(10, 10),
                    anchor: new OpenLayers.Bounds(null, 0, 0, null),
                    position: new OpenLayers.Pixel(-225, -712)
                }
            ]
        },
        "tr": {
            'offset': new OpenLayers.Pixel(0, 0),
            'padding': new OpenLayers.Bounds(10, 10, 5, 5),
            'blocks': [
                { // top-left
                    size: new OpenLayers.Size('auto', 'auto'),
                    anchor: new OpenLayers.Bounds(5, 10, 5, 0),
                    position: new OpenLayers.Pixel(0, 0)
                },
                { //top-right
                    size: new OpenLayers.Size(5, 'auto'),
                    anchor: new OpenLayers.Bounds(null, 10, 0, 0),
                    position: new OpenLayers.Pixel(-655, 0)
                },
                { //bottom-left
                    size: new OpenLayers.Size('auto', 5),
                    anchor: new OpenLayers.Bounds(5, 5, 5, null),
                    position: new OpenLayers.Pixel(0, -645)
                },
                { //bottom-right
                    size: new OpenLayers.Size(5, 5),
                    anchor: new OpenLayers.Bounds(null, 5, 0, null),
                    position: new OpenLayers.Pixel(-655, -645)
                },
                { // stem
                    size: new OpenLayers.Size(10, 10),
                    anchor: new OpenLayers.Bounds(0, 0, null, null),
                    position: new OpenLayers.Pixel(-215, -712)
                }
            ]
        },
        "bl": {
            'offset': new OpenLayers.Pixel(0, 0),
            'padding': new OpenLayers.Bounds(5, 5, 10, 10),
            'blocks': [
                { // top-left
                    size: new OpenLayers.Size('auto', 'auto'),
                    anchor: new OpenLayers.Bounds(0, 5, 10, 5),
                    position: new OpenLayers.Pixel(0, 0)
                },
                { //top-right
                    size: new OpenLayers.Size(5, 'auto'),
                    anchor: new OpenLayers.Bounds(null, 5, 5, 5),
                    position: new OpenLayers.Pixel(-655, 0)
                },
                { //bottom-left
                    size: new OpenLayers.Size('auto', 5),
                    anchor: new OpenLayers.Bounds(0, 0, 10, null),
                    position: new OpenLayers.Pixel(0, -645)
                },
                { //bottom-right
                    size: new OpenLayers.Size(5, 5),
                    anchor: new OpenLayers.Bounds(null, 0, 5, null),
                    position: new OpenLayers.Pixel(-655, -645)
                },
                { // stem
                    size: new OpenLayers.Size(10, 10),
                    anchor: new OpenLayers.Bounds(null, null, 0, 0),
                    position: new OpenLayers.Pixel(-225, -702)
                }
            ]
        },
        "br": {
            'offset': new OpenLayers.Pixel(0, 0),
            'padding': new OpenLayers.Bounds(10, 5, 10, 10),
            'blocks': [
                { // top-left
                    size: new OpenLayers.Size('auto', 'auto'),
                    anchor: new OpenLayers.Bounds(5, 5, 10, 5),
                    position: new OpenLayers.Pixel(0, 0)
                },
                { //top-right
                    size: new OpenLayers.Size(5, 'auto'),
                    anchor: new OpenLayers.Bounds(null, 5, 5, 5),
                    position: new OpenLayers.Pixel(-655, 0)
                },
                { //bottom-left
                    size: new OpenLayers.Size('auto', 5),
                    anchor: new OpenLayers.Bounds(5, 0, 10, null),
                    position: new OpenLayers.Pixel(0, -645)
                },
                { //bottom-right
                    size: new OpenLayers.Size(5, 5),
                    anchor: new OpenLayers.Bounds(null, 0, 5, null),
                    position: new OpenLayers.Pixel(-655, -645)
                },
                { // stem
                    size: new OpenLayers.Size(10, 10),
                    anchor: new OpenLayers.Bounds(0, null, null, 0),
                    position: new OpenLayers.Pixel(-215, -702)
                }
            ]
        }
    },

    /**
     * Property: minSize
     * {<OpenLayers.Size>}
     */
    minSize: new OpenLayers.Size(15, 15),

    /**
     * Property: maxSize
     * {<OpenLayers.Size>}
     */
    maxSize: new OpenLayers.Size(600, 660),

    /** 
     * Method: calculateRelativePosition
     * 
     * Parameters:
     * px - {<OpenLayers.Pixel>}
     * 
     * Returns:
     * {String} The relative position ("br" "tr" "tl" "bl") at which the popup
     *     should be placed. Also updates class of groupDiv accordingly.
     */
    calculateRelativePosition:function(px) {
        var quadrant = OpenLayers.Popup.Framed.prototype.calculateRelativePosition.apply(this, arguments);
        this.groupDiv.className = 'olQuadrant-' + quadrant;
        return quadrant;
    }, 
   
    /** 
     * Method: destroy
     */
    destroy: function() {
        OpenLayers.Popup.Framed.prototype.destroy.apply(this, arguments);
    },

    CLASS_NAME: "OpenLayers.Popup.FramedCompact"
});

/**
 * Class: OpenLayers.Popup.FramedMarker
 * 
 * Inherits from: 
 *  - <OpenLayers.Popup.FramedCompact>
 */
OpenLayers.Popup.FramedMarker = 
  OpenLayers.Class(OpenLayers.Popup.FramedCompact, {

    /**
     * Property: minSize
     * {<OpenLayers.Size>}
     */
    minSize: new OpenLayers.Size(25, 15),

    /** 
     * Property: displayClass
     * {String} The CSS class of the popup.
     */
    displayClass: "olPopup olFramedMarkerPopup",
    /** 
     * Property: contentDisplayClass
     * {String} The CSS class of the popup content div.
     */
    contentDisplayClass: "olFramedMarkerPopupContent",
    /**
     * Method: onclick
     * Ignore clicks, but allowing default browser handling
     * 
     * Parameters:
     * evt - {Event} 
     */
    onclick: function (evt) {
        if(jQuery) jQuery(this.contentDiv).trigger('popUpClicked',[evt]);
		OpenLayers.Event.stop(evt, true);
    },
    CLASS_NAME: "OpenLayers.Popup.FramedMarker"
});


/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Handler/Drag.js
 * @requires OpenLayers/Control/DragPan.js
 */

/**
 * Class: OpenLayers.Control.DragPanExt
 * The DragPan control pans the map with a drag of the mouse.
 *
 * Inherits from:
 *  - <OpenLayers.Control.DragPan>
 */
OpenLayers.Control.DragPanExt = OpenLayers.Class(OpenLayers.Control.DragPan, {
    /**
     * Method: draw
     * Creates a Drag handler, using <panMap> and
     * <panMapDone> as callbacks.
     */    
    draw: function() {
        this.handler = new OpenLayers.Handler.Drag(this, {
                "move": this.panMap,
                "done": this.panMapDone
            }, {
                interval: this.interval,
                keyMask: this.keyMask
            }
        );
    },


    CLASS_NAME: "OpenLayers.Control.DragPanExt"
});


/**
 * Class: OpenLayers.Handler.RegularPolygonExtMoveCallback
 * Callback on mouse move
 * 
 * Inherits from:
 *  - <OpenLayers.Handler>
 */
OpenLayers.Handler.RegularPolygonExtMoveCallback = OpenLayers.Class(OpenLayers.Handler.RegularPolygon, {
    /**
     * Method: move
     * Respond to drag move events
     *
     * Parameters:
     * evt - {Evt} The move event
     */
    move: function(evt) {
        var maploc = this.map.getLonLatFromPixel(evt.xy);
        var point = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);
        if(this.irregular) {
            var ry = Math.sqrt(2) * Math.abs(point.y - this.origin.y) / 2;
            this.radius = Math.max(this.map.getResolution() / 2, ry);
        } else if(this.fixedRadius) {
            this.origin = point;
        } else {
            this.calculateAngle(point, evt);
            this.radius = Math.max(this.map.getResolution() / 2,
                                   point.distanceTo(this.origin));
        }
        this.modifyGeometry();
        if(this.irregular) {
            var dx = point.x - this.origin.x;
            var dy = point.y - this.origin.y;
            var ratio;
            if(dy == 0) {
                ratio = dx / (this.radius * Math.sqrt(2));
            } else {
                ratio = dx / dy;
            }
            this.feature.geometry.resize(1, this.origin, ratio);
            this.feature.geometry.move(dx / 2, dy / 2);
        }
        this.layer.drawFeature(this.feature, this.style);
		this.callback("point", [null, this.feature.geometry]);//This line added
    },
	callback: function (name, args) {
		if(name=='move' || name=='point')//This condition added
		{
        	OpenLayers.Handler.prototype.callback.apply(this, arguments);
			return;
		}
		if (this.callbacks[name]) { 
            this.callbacks[name].apply(this.control,
                                       [this.feature.geometry.clone()]);
        }
        if(!this.persist && (name == "done" || name == "cancel")) {
            this.clear();
        }
    },
    CLASS_NAME: "OpenLayers.Handler.RegularPolygonExtMoveCallback"
});



/**
 * Class: OpenLayers.Handler.PolygonExtMoveCallback
 * Callback on mouse move
 * 
 * Inherits from:
 *  - <OpenLayers.Handler>
 */
OpenLayers.Handler.PolygonExtMoveCallback = OpenLayers.Class(OpenLayers.Handler.Polygon, {
	mousemove: function (evt) {
        if(this.drawing) {
            if(this.mouseDown && this.freehandMode(evt)) {
                this.addPoint(evt.xy);
            } else {
                this.modifyFeature(evt.xy);
				this.callback("point", [this.point.geometry, this.getGeometry()]);//Line added
            }
        }
        return true;
    },
	
    CLASS_NAME: "OpenLayers.Handler.PolygonExtMoveCallback"
});

/**
 * Class: OpenLayers.Handler.PathExtMoveCallback
 * Callback on mouse move
 * 
 * Inherits from:
 *  - <OpenLayers.Handler>
 */
OpenLayers.Handler.PathExtMoveCallback = OpenLayers.Class(OpenLayers.Handler.Path, {
	mousedown: function(evt) {
        // ignore double-clicks
        if (this.lastDown && this.lastDown.equals(evt.xy)) {
            return false;
        }
        if(this.lastDown == null) {
            if(this.persist) {
                this.destroyFeature();
            }
            this.createFeature(evt.xy);
        } else if((this.lastUp == null) || !this.lastUp.equals(evt.xy)) {
            this.addPoint(evt.xy);
        }
        this.mouseDown = true;
        this.lastDown = evt.xy;
        this.drawing = true;
		//jQuery('#'+astun.mapWrapper.mapElement.id).trigger('pointAdded',evt);
        return false;
    },
	mousemove: function (evt) {
        if(this.drawing) {
            if(this.mouseDown && this.freehandMode(evt)) {
                this.addPoint(evt.xy);
            } else {
                this.modifyFeature(evt.xy);
				this.callback("point", [this.point.geometry, this.getGeometry()]);//Line added
            }
        }
        return true;
    },
    CLASS_NAME: "OpenLayers.Handler.PathExtMoveCallback"
});


/**
 * Class: OpenLayers.Control.ModifyFeature
 * Control to modify features.  When activated, a click renders the vertices
 *     of a feature - these vertices can then be dragged.  By default, the
 *     delete key will delete the vertex under the mouse.  New features are
 *     added by dragging "virtual vertices" between vertices.  Create a new
 *     control with the <OpenLayers.Control.ModifyFeature> constructor.
 *
 * Inherits From:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.ModifyFeatureBeforeDragEvt = OpenLayers.Class(OpenLayers.Control.ModifyFeature, {
	
	dragStart: function(feature, pixel) {
		var targetFeature = this.feature;
		//jQuery('#'+astun.mapWrapper.mapElement.id).trigger('hideFeaturePopups',targetFeature);
		astun.featureDragingStarted = true;
        // only change behavior if the feature is not in the vertices array
        if(feature != this.feature && !feature.geometry.parent &&
           feature != this.dragHandle && feature != this.radiusHandle) {
            if(this.feature) {
                // unselect the currently selected feature
                this.selectControl.clickFeature.apply(this.selectControl,
                                                      [this.feature]);
            }
            // check any constraints on the geometry type
            if(this.geometryTypes == null ||
               OpenLayers.Util.indexOf(this.geometryTypes,
                                       feature.geometry.CLASS_NAME) != -1) {
                // select the point
                this.selectControl.clickFeature.apply(this.selectControl,
                                                      [feature]);
                /**
                 * TBD: These lines improve workflow by letting the user
                 *     immediately start dragging after the mouse down.
                 *     However, it is very ugly to be messing with controls
                 *     and their handlers in this way.  I'd like a better
                 *     solution if the workflow change is necessary.
                 */
                // prepare the point for dragging
                this.dragControl.overFeature.apply(this.dragControl,
                                                   [feature]);
                this.dragControl.lastPixel = pixel;
                this.dragControl.handlers.drag.started = true;
                this.dragControl.handlers.drag.start = pixel;
                this.dragControl.handlers.drag.last = pixel;
            }
        }
    },

	dragComplete: function(vertex) {
        this.resetVertices();
        this.setFeatureState();
        this.onModification(this.feature);
        this.layer.events.triggerEvent("featuremodified", {feature: this.feature});
		targetFeature = this.feature;
		astun.featureDragingStarted = false;
		//jQuery('#'+astun.mapWrapper.mapElement.id).trigger('showFeaturePopups',targetFeature);
    }
});



/**
 * Move a popup with a drag.
 * 
 * @author Matt Walker
 * @class
 */
OpenLayers.Control.DragPopup = OpenLayers.Class(OpenLayers.Control, {

    down: false,

    popPnt: null,

    mapPnt: null,

    popup: null,

    docMouseUpProxy: null,

    /**
     * Constructor: OpenLayers.Control.DragPopup
     * Create a new control to drag a popup.
     *
     * Parameters:
     * @param {OpenLayers.Popup} popup
     * @param {Object} options
     */
    initialize: function(popup, options) {
        OpenLayers.Control.prototype.initialize.apply(this, [options]);
        this.popup = popup;
        this.popup.events.register('mousedown', this, this.mouseDown);
        this.popup.events.register('mouseup', this, this.mouseUp);
        this.popup.events.register('mousemove', this, this.mouseMove);
        // Define a function bound to this used to listen for
        // document mouseout events
        this.docMouseUpProxy = OpenLayers.Function.bind(this.mouseUp, this);
    },

    /**
     * Method: setMap
     * Set the map property for the control.
     *
     * Parameters: 
     * map - {<OpenLayers.Map>} The control's map.
     */
    setMap: function(map) {
        OpenLayers.Control.prototype.setMap.apply(this, [map]);
        this.map.events.register('mousemove', this, this.mouseMove);
    },

    mouseDown: function(evt) {
        //console.log('mouseDown');
        this.down = true;
        this.popPnt = this.popup.events.getMousePosition(evt);
        OpenLayers.Event.observe(document, 'mouseup', this.docMouseUpProxy);
        OpenLayers.Event.stop(evt);
    },

    mouseUp: function(evt) {
        //console.log('mouseUp');
        this.down = false;
        OpenLayers.Event.stopObserving(document, 'mouseup', this.docMouseUpProxy);
        OpenLayers.Event.stop(evt);
    },

    mouseOut: function(evt) {
        //console.log('map.mouseOut');
        this.down = false;
        OpenLayers.Event.stop(evt);
    },

    mouseMove: function(evt) {
        //console.log('mouseMove');
        if (this.down) {
            var mapPntPx = this.map.events.getMousePosition(evt);
            mapPntPx = mapPntPx.add((this.popPnt.x * -1), (this.popPnt.y * -1));
            this.popup.lonlat = this.map.getLonLatFromViewPortPx(mapPntPx);
            this.popup.updatePosition();
        }
        OpenLayers.Event.stop(evt);
    },

    destroy: function() {
        // Remove listeners
        this.popup.events.unregister('mousedown', this, this.mouseDown);
        this.popup.events.unregister('mouseup', this, this.mouseUp);
        this.popup.events.unregister('mousemove', this, this.mouseMove);
        this.map.events.unregister('mousemove', this, this.mouseMove);
        // Clear object references
        this.popup = null;
        this.popPnt = null;
        // allow our superclass to tidy up
        OpenLayers.Control.prototype.destroy.apply(this, []);
    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Control.DragPopup"
});



// If baseURL is set (which happens in FileIncluderJS.aspx),
// override the OpenLayers function that returns the location
// of CSS and images.
if (window.baseURL) {
	OpenLayers._getScriptLocation = function () {
		return baseURL + 'js/lib/OpenLayers/';
	}
}

