
/**
 * @requires OpenLayers/Popup/Framed.js
 * @requires OpenLayers/Layer/Grid.js
 * @requires OpenLayers/Class.js
 * @requires OpenLayers/Util.js
 */

/**
 * A class to provide an iShareMaps map as an OpenLayers layer
 */
OpenLayers.Layer.iShareMaps = OpenLayers.Class(OpenLayers.Layer.Grid, { 

    DEFAULT_PARAMS: {
        'RequestType': 'Map',
		'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));
        }
    },
    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);
    },
    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.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"
});

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, style) {

        //this.imageSrc = OpenLayers.Util.getImagesLocation() + 'Cloud-popup-relative.png'; Should Astun do something like this?
        var imageStyle = style || 'astun';
        this.imageSrc  = 'includes/olmaps/_assets/images/'+imageStyle+'-popup-relative.png'
        OpenLayers.Popup.Framed.prototype.initialize.apply(this, arguments);
        this.contentDiv.className = this.contentDisplayClass;
    },

    /** 
     * Property: contentDisplayClass
     * {String} The CSS class of the popup content div.
     */
    contentDisplayClass: "olFramedCompactPopupContent",

    /**
     * Property: autoSize
     * {Boolean} FramedCompact is autosizing by default.
     */
    autoSize: false,

    /**
     * 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: true,
    /** 
     * Property: relativePosition
     * {String} The position for the popup relative to the base LonLat position.
     * See positionBlocks for allowed values.
     */
    relativePosition: 'tr',

    /**
     * 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(44, 0),
            'padding': new OpenLayers.Bounds(8, 40, 8, 9),
            'blocks': [
                { // top-left
                    size: new OpenLayers.Size('auto', 'auto'),
                    anchor: new OpenLayers.Bounds(0, 51, 22, 0),
                    position: new OpenLayers.Pixel(0, 0)
                },
                { //top-right
                    size: new OpenLayers.Size(22, 'auto'),
                    anchor: new OpenLayers.Bounds(null, 50, 0, 0),
                    position: new OpenLayers.Pixel(-638, 0)
                },
                { //bottom-left
                    size: new OpenLayers.Size('auto', 21),
                    anchor: new OpenLayers.Bounds(0, 32, 80, null),
                    position: new OpenLayers.Pixel(0, -629)
                },
                { //bottom-right
                    size: new OpenLayers.Size(22, 21),
                    anchor: new OpenLayers.Bounds(null, 32, 0, null),
                    position: new OpenLayers.Pixel(-638, -629)
                },
                { // stem
                    size: new OpenLayers.Size(81, 54),
                    anchor: new OpenLayers.Bounds(null, 0, 0, null),
                    position: new OpenLayers.Pixel(0, -668)
                }
            ]
        },
        "tr": {
            'offset': new OpenLayers.Pixel(0, 0),
            'padding': new OpenLayers.Bounds(10, 8, 5, 3),
            'blocks': [
                  { // top-left
                    size: new OpenLayers.Size('auto', 'auto'),
                    anchor: new OpenLayers.Bounds(4, 9, 5, 0),
                    position: new OpenLayers.Pixel(0, 0)
                },
                { //top-right
                    size: new OpenLayers.Size(5, 'auto'),
                    anchor: new OpenLayers.Bounds(null, 9, 0, 0),
                    position: new OpenLayers.Pixel(-655, 0)
                },
                { //bottom-left
                    size: new OpenLayers.Size('auto', 5),
                    anchor: new OpenLayers.Bounds(4, 4, 5, null),
                    position: new OpenLayers.Pixel(0, -645)
                },
                { //bottom-right
                    size: new OpenLayers.Size(5, 5),
                    anchor: new OpenLayers.Bounds(null, 4, 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(45, 0),
            'padding': new OpenLayers.Bounds(8, 9, 8, 40),
            'blocks': [
                { // top-left
                    size: new OpenLayers.Size('auto', 'auto'),
                    anchor: new OpenLayers.Bounds(0, 21, 22, 32),
                    position: new OpenLayers.Pixel(0, 0)
                },
                { //top-right
                    size: new OpenLayers.Size(22, 'auto'),
                    anchor: new OpenLayers.Bounds(null, 21, 0, 32),
                    position: new OpenLayers.Pixel(-638, 0)
                },
                { //bottom-left
                    size: new OpenLayers.Size('auto', 21),
                    anchor: new OpenLayers.Bounds(0, 0, 22, null),
                    position: new OpenLayers.Pixel(0, -629)
                },
                { //bottom-right
                    size: new OpenLayers.Size(22, 21),
                    anchor: new OpenLayers.Bounds(null, 0, 0, null),
                    position: new OpenLayers.Pixel(-638, -629)
                },
                { // stem
                    size: new OpenLayers.Size(81, 54),
                    anchor: new OpenLayers.Bounds(null, null, 0, 0),
                    position: new OpenLayers.Pixel(-101, -674)
                }
            ]
        },
        "br": {
            'offset': new OpenLayers.Pixel(-44, 0),
            'padding': new OpenLayers.Bounds(8, 9, 8, 40),
            'blocks': [
                { // top-left
                    size: new OpenLayers.Size('auto', 'auto'),
                    anchor: new OpenLayers.Bounds(0, 21, 22, 32),
                    position: new OpenLayers.Pixel(0, 0)
                },
                { //top-right
                    size: new OpenLayers.Size(22, 'auto'),
                    anchor: new OpenLayers.Bounds(null, 21, 0, 32),
                    position: new OpenLayers.Pixel(-638, 0)
                },
                { //bottom-left
                    size: new OpenLayers.Size('auto', 21),
                    anchor: new OpenLayers.Bounds(0, 0, 22, null),
                    position: new OpenLayers.Pixel(0, -629)
                },
                { //bottom-right
                    size: new OpenLayers.Size(22, 21),
                    anchor: new OpenLayers.Bounds(null, 0, 0, null),
                    position: new OpenLayers.Pixel(-638, -629)
                },
                { // stem
                    size: new OpenLayers.Size(81, 54),
                    anchor: new OpenLayers.Bounds(0, null, null, 0),
                    position: new OpenLayers.Pixel(-311, -674)
                }
            ]
        }
    },

    /**
     * Property: minSize
     * {<OpenLayers.Size>}
     */
    minSize: new OpenLayers.Size(15, 15),

    /**
     * Property: maxSize
     * {<OpenLayers.Size>}
     */
    maxSize: new OpenLayers.Size(600, 660),

   
    /** 
     * 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: contentDisplayClass
     * {String} The CSS class of the popup content div.
     */
    contentDisplayClass: "olFramedMarkerPopupContent",
    CLASS_NAME: "OpenLayers.Popup.FramedMarker"
});

