﻿/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is VisKort.
*
* The Initial Developer of the Original Code is
* IT- og Telestyrelsen / Danish National IT and Telecom Agency.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):

* Lars Klindt Mogensen
* Morten Bødtkjer
* Niels Kinnerup
* Thomas Bergstedt
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

OpenLayers.Control.GetFeatures = OpenLayers.Class(OpenLayers.Control, {
    /**
    * Constant: EVENT_TYPES
    *
    * Supported event types:
    * featuresretrieved - Triggered when features are retrieved from the layers
    *  The event object has a features property with an array of features
    */
    EVENT_TYPES: ["featuresretrieved"],

    defaultHoverHandlerOptions: {
        'delay': 500,
        'pixelTolerance': null,
        'stopMove': false
    },

    /**
    * APIProperty: clickTolerance
    * {OpenLayers.Size} Tolerance for the BBOX query in pixels. Default is 5x5.
    */
    clickTolerance: new OpenLayers.Size(5, 5),

    layers: null,

    initialize: function(layers, options) {
        // concatenate events specific to vector with those from the base
        this.EVENT_TYPES =
            OpenLayers.Control.GetFeatures.prototype.EVENT_TYPES.concat(
            OpenLayers.Control.prototype.EVENT_TYPES
        );

        this.layers = layers;

        this.hoverHandlerOptions = OpenLayers.Util.extend(
                        {}, this.defaultHoverHandlerOptions
                    );
        OpenLayers.Control.prototype.initialize.apply(
                        this, [options]
                    );
        this.handler = new OpenLayers.Handler.Hover(
                        this,
                        { 'pause': this.onPause, 'move': this.onMove },
                        this.hoverHandlerOptions
                    );
    },

    onPause: function(evt) {
        var lonlat = this.map.getLonLatFromPixel(evt.xy);
        var bounds = this.pixelToBounds(evt.xy);
        var polygon = bounds.toGeometry();
        var features = [];

        for (var i = 0; i < this.layers.length; i++) {
        	if (this.layers[i].visibility && this.layers[i].features) {
                for (var j = 0; j < this.layers[i].features.length; j++) {
                    if (this.layers[i].features[j].geometry && polygon.intersects(this.layers[i].features[j].geometry)) {
                        features.push(this.layers[i].features[j]);
                    }
                }
            }
            //might implement functionality for non vector layers such as WMS
        }

        if (features.length > 0) {
            this.events.triggerEvent("featuresretrieved", { lonlat: lonlat, features: features });
        }
    },

    /**
    * Method: pixelToBounds
    * Takes a pixel as argument and creates bounds after adding the
    * <clickTolerance>.
    * 
    * Parameters:
    * pixel - {<OpenLayers.Pixel>}
    */
    pixelToBounds: function(pixel) {
        var llPx = pixel.add(-this.clickTolerance.w / 2, this.clickTolerance.w / 2);
        var urPx = pixel.add(this.clickTolerance.h / 2, -this.clickTolerance.h / 2);
        var ll = this.map.getLonLatFromPixel(llPx);
        var ur = this.map.getLonLatFromPixel(urPx);
        return new OpenLayers.Bounds(ll.lon, ll.lat, ur.lon, ur.lat);
    },

    onMove: function(evt) {
        // if this control sent an Ajax request (e.g. GetFeatureInfo) when
        // the mouse pauses the onMove callback could be used to abort that
        // request.
    }
});
