
//var log = log4javascript.getDefaultLogger();

var log;


function MaidenheadOverlay() {
    if (log) {
        log.debug("Instaniating new Overlay");
    }
}


MaidenheadOverlay.prototype = new GOverlay();

(function () {

var alpha = "ABCDEFGHIJKLMNOPQRSTUVWX";
var lalpha = "abcdefghijklmnopqrstuvwx";
var digit = "0123456789";

var scales = [alpha, digit, lalpha, digit, lalpha];

var rounding = 1;

var lldiv = new Array();

for (var i in scales) {
    rounding = rounding * scales[i].length;
    lldiv.push(rounding);
}

function getgrid(level, pos) {
    var lat = get1grid(1, pos.lat());
    var lng = get1grid(2, pos.lng());

    var obj = new Object();

    obj.grid = result;
    obj.bnds = new GLatLngBounds(
	new GLatLng(Math.floor(lat.v / 240 * lldiv[level-1]) * 240 / lldiv[level - 1],
                         Math.floor(lng.v / 480 * lldiv[level-1]) * 480 / lldiv[level - 1]),
	new GLatLng((Math.floor(lat.v / 240 * lldiv[level-1]) + 1) * 240 / lldiv[level - 1],
                         (Math.floor(lng.v / 480 * lldiv[level-1]) + 1) * 480 / lldiv[level - 1])
    		);

    var result = '';
    while (level-- >= 0) {
	result = lng.str.charAt(level) + lat.str.charAt(level) + result;
    }

    obj.grid = result;

    return obj;
}

function get1grid(scale, v) {
    var ov = v;
    v = v / scale;
    v = v + 90;

    if (v >= 179.99998) {
	v -= 180;
    }

    v = v / 240;

    var result = '';
    var r = new Object();

    v += 0.5 / rounding;

    r.v = ((v * 240) - 90) * scale

    for (var i in scales) {
        v = v * scales[i].length;

        result = result + scales[i].charAt(Math.floor(v));
        v = v - Math.floor(v);
    }

    r.str = result;

    return r;
}


MaidenheadOverlay.prototype.initialize = function (map) {

    var div = document.createElement("div");
    div.style.position = "absolute";
    div.style.top = "0px";
    div.style.left = "0px";
    div.style.zIndex = GOverlay.getZIndex(90);
    map.getPane(G_MAP_MARKER_PANE).appendChild(div);

    this.map = map;
    this.div = div;

    this.have = new Object();

};

MaidenheadOverlay.prototype.remove = function () {
    this.map.getPane(G_MAP_MARKER_PANE).removeChild(this.div);
    while (this.div.firstChild) {
	  this.div.removeChild(this.div.firstChild);
    }
    this.have = new Object();
};

MaidenheadOverlay.prototype.copy = function () {
    if (log) {
        log.debug("copy called");
    }
};

MaidenheadOverlay.prototype.getBox = function (level, b) {
    var div = document.createElement("div");
    div.style.position = "absolute";
    div.style.borderTopStyle = 'solid';
    div.style.borderLeftStyle = 'solid';
    div.style.borderWidth = '1px';
    div.style.borderColor = '#808080';
    div.style.color = '#808080';

    var pt = this.map.fromLatLngToDivPixel(b.bnds.getSouthWest());
    var pt2 = this.map.fromLatLngToDivPixel(b.bnds.getNorthEast());

    div.style.left = pt.x + "px";
    div.style.top = pt2.y + "px";

    div.style.width = (pt2.x - pt.x) + "px";
    div.style.height = (pt.y - pt2.y) + "px";

    var t = document.createTextNode(b.grid);
    div.appendChild(t);

    return div;
};


MaidenheadOverlay.prototype.appendBox = function (lat, lng, level) {
    var ll = new GLatLng(lat, lng);
    var b = getgrid(level, ll);
    var pt = this.map.fromLatLngToDivPixel(b.bnds.getSouthWest());
    var uniq = '' + pt;
    if (!this.have[uniq]) {
	var box = this.getBox(level, b);
	box.bnds = b.bnds;
	this.have[uniq] = box;
	this.div.appendChild(box);
    }
};

MaidenheadOverlay.prototype.redraw = function (force) {
    if (force) {
	while (this.div.firstChild) {
	      this.div.removeChild(this.div.firstChild);
	}
	this.have = new Object();
    }

    var view = this.map.getBounds();

    var zoom = this.map.getZoom();

    if (zoom <= 2) {
	return;
    }

    var level = 1;

    // Figure out the level
    for (level = 4; level > 1; level--) {
	var center = getgrid(level, this.map.getCenter());

	var pt = this.map.fromLatLngToDivPixel(center.bnds.getSouthWest());
	var pt2 = this.map.fromLatLngToDivPixel(center.bnds.getNorthEast());
	var width = (pt2.x - pt.x);
	var height = (pt.y - pt2.y);

	//log.debug("width=" + width + " height=" + height);

	if (width > 60 &&
	    height > 50) {
	    break;
	}
    }

    // get limits of ll for this viewport
    var sw = getgrid(level, view.getSouthWest());
    var ne = getgrid(level, view.getNorthEast());

    var bnds = new GLatLngBounds(
	sw.bnds.getSouthWest(),
	ne.bnds.getNorthEast()
    	);

    var latincr = 240 / lldiv[level - 1] - 0.000001;
    var lngincr = 480 / lldiv[level - 1] - 0.000001;

    var latmax = bnds.getNorthEast().lat();
    var lngmax = bnds.getNorthEast().lng();
    var lngmin = bnds.getSouthWest().lng();

    for (var lat = bnds.getSouthWest().lat(); lat <= latmax; lat += latincr) {
	if (lngmin > lngmax) {
	    for (var lng = lngmin; lng < 180; lng += lngincr) {
		this.appendBox(lat, lng, level);
	    }
	    for (var lng = -180; lng <= lngmax; lng += lngincr) {
		this.appendBox(lat, lng, level);
	    }
	}
	for (var lng = lngmin; lng <= lngmax; lng += lngincr) {
	    this.appendBox(lat, lng, level);
	}
    }
    // We really should delete boxes outside the viewport
};

}());


