
/**
 * @requires OpenLayers/Control.js
 */

/**
 * Class: OpenLayers.Control.CoordBorders
 * Show coordinates at the border of the map.
 *
 * Inherits from:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.CoordBorders = OpenLayers.Class(OpenLayers.Control, {

    /**
     * APIProperty: showMinorMeasures
     * {Integer} Measures for tenth of minutes will be shown only if a minute is at least this amount of pixels.
     */
    showMinorMeasures: 50,

    /**
     * APIProperty: showHalfMinuteMeasures
     * {Integer} Measures for half minutes will be shown only when a minute is at least this amount of pixels.
     */
	showHalfMinuteMeasures: 20,

    /**
     * APIProperty: showMeasures
     * {Integer} Measures will be shown only when a minute is at least this amount of pixels.
     */
	showMeasures: 5,

    /**
     * APIProperty: div
     * {Element} Optional DOM element to become the container for the coordinate
     *     borders.  If not provided, one will be created.
     */
    div: null,

    /**
     * Constructor: OpenLayers.Control.CoordBorders
     * Create a new coordinate borders instance.
     *
     * Parameters: 
     * options - {Object} Optional object whose properties will be set on this
     *     object.
     */
    initialize: function(options) {
        OpenLayers.Control.prototype.initialize.apply(this, [options]);
        if (!document.styleSheets) {
            this.limitedStyle = true;
        }
        if (this.limitedStyle) {
            this.appliedStyles = OpenLayers.Util.extend({}, this.defaultStyles);
            OpenLayers.Util.extend(this.appliedStyles, this.customStyles);
        }
    },

    /**
     * APIMethod: destroy
     * Destroy the control.
     */
    destroy: function() {
        this.map.events.unregister('moveend', this, this.onMoveend);
        this.div.innerHTML = "";
        OpenLayers.Control.prototype.destroy.apply(this);
    },

    /**
     * Method: draw
     */
    draw: function() {
        OpenLayers.Control.prototype.draw.apply(this, arguments);

        this.map.events.register('moveend', this, this.onMoveend);
        this.update();
        return this.div;
    },

    /**
     * Method: onMoveend
     * Registered as a listener for "moveend".
     */
    onMoveend: function() {
        this.update();
    },

    /**
     * APIMethod: update
     * Update the coordinate border after modifying properties.
     */
    update: function() {
        if (this.map.baseLayer == null || !this.map.getExtent() || !this.map.getSize()) {
            return;
        }
        // clean out any old content from containers
        this.div.innerHTML = "";
		// create bar
		var projWGS84 = new OpenLayers.Projection("EPSG:4326");
		var extent = this.map.getExtent();
		var size = this.map.getSize();
		extent.transform(this.map.projection, projWGS84);
		
		// Top
		var pxPerMinute = size.w / ((extent.right - extent.left) * 60);
		if (pxPerMinute > this.showMeasures) {
			this.div.appendChild(this.createElement(
					"Bar1", "Top", new OpenLayers.LonLat(extent.left, extent.top), size.w
			));
			this.div.appendChild(this.createElement(
					"Bar2", "Top", new OpenLayers.LonLat(extent.left, extent.top), size.w
			));

			var begin = Math.floor(extent.left * 60) * 10;
			var end   = Math.ceil(extent.right * 60) * 10;
	
			for (var x = begin; x <= end; x += 20) {
				var coord = new OpenLayers.LonLat(x / 600, extent.top);
				this.div.appendChild(this.createElement(
					"Bar", "Top", coord, pxPerMinute
				));
			}
			for (var x = begin; x <= end; x += 1) {
				if ((x % 10) == 0 || (pxPerMinute > this.showHalfMinuteMeasures && (x % 5) == 0)) {
					var coord = new OpenLayers.LonLat(x / 600, extent.top);
					this.div.appendChild(this.createElement(
						"MarkerMajor", "Top", coord
					));
				} else if (pxPerMinute > this.showMinorMeasures) {
					var coord = new OpenLayers.LonLat(x / 600, extent.top);
					this.div.appendChild(this.createElement(
						"MarkerMinor", "Top", coord
					));
				}
			}
		}

		// Left
		pxPerMinute = size.h / ((extent.top - extent.bottom) * 60);
		if (pxPerMinute > this.showMeasures) {
			this.div.appendChild(this.createElement(
					"Bar1", "Left", new OpenLayers.LonLat(extent.left, extent.top), size.h
			));
			this.div.appendChild(this.createElement(
					"Bar2", "Left", new OpenLayers.LonLat(extent.left, extent.top), size.h
			));
	
			begin = Math.floor(extent.bottom * 60) * 10;
			end   = Math.ceil(extent.top * 60) * 10;
	
			for (var y = begin; y <= end; y += 20) {
				var coord = new OpenLayers.LonLat(extent.left, y / 600);
				this.div.appendChild(this.createElement(
					"Bar", "Left", coord, pxPerMinute
				));
			}
			for (var y = begin; y <= end; y += 1) {
				if ((y % 10) == 0 || (pxPerMinute > this.showHalfMinuteMeasures && (y % 5) == 0)) {
					var coord = new OpenLayers.LonLat(extent.left, y / 600);
					this.div.appendChild(this.createElement(
						"MarkerMajor", "Left", coord
					));
				} else if (pxPerMinute > this.showMinorMeasures) {
					var coord = new OpenLayers.LonLat(extent.left, y / 600);
					this.div.appendChild(this.createElement(
						"MarkerMinor", "Left", coord
					));
				}
			}
		}
    },

    /**
     * Method: createElement
     * Create a coordinate border element. These should be absolutely positioned
     *     using stylesheets.
     *
     * Parameters:
     * cls - {String} Class name suffix.
     * location - {String} Which border this is, is used to determine what properties to set and will be part of the class name.
     * coord - {OpenLayers.LonLat} Left or top offset is used depending on the location.
     * size - {Float} Optional width or height, depending on the location.
     * 
     * Returns:
     * {Element} A coordinate border element.
     */
    createElement: function(cls, location, coord, size) {
		coord.transform(projWGS84, this.map.projection);
		var px = this.map.getPixelFromLonLat(coord);
        var element = document.createElement("div");
        element.className = this.displayClass + cls + location;
		var style;
		if (location == "Top") style = { left: px.x + "px" };
		if (location == "Right") style = { top: px.y + "px" };
		if (location == "Bottom") style = { left: px.x + "px" };
		if (location == "Left") style = { top: px.y + "px" };
        OpenLayers.Util.extend(element.style, style);
        if (size) {
			if (location == "Top" || location == "Bottom") {
				element.style.width = Math.round(size) + "px";
			} else {
				element.style.height = Math.round(size) + "px";
			}
		}
        return element;
    },

    CLASS_NAME: "OpenLayers.Control.CoordBorders"

});
