//// Copyright 1999-2007 Maptuit Inc, All Rights Reserved
function HotSpotCanvas(nid, onetip) {
	this.HotSpotHover = new Object();
	this.HotSpotClick = new Object();
	this.HotSpotBoth = new Object();
	this.HotSpotIds = new Object();
	this.disableEvents = false;
	this.blobCounter = 0;
	this.installedCss = false;
	this.MyMap;
	this.MyCanvasId;
	this.id = nid;
	this.sta_tic = false;
	this.onetip = onetip ? (this.onetip = onetip) : false;
	this.lastTipID = null;
}

HotSpotCanvas.prototype.init = function (mydivId, damap) {
	this.MyMap = damap;
	this.MyCanvasId = mydivId;
	if (!this.installedCss) {
		var href = this.MyMap.csspath.replace(/nc.css$/, "canvases/CanvasHotspots.css");
		var l = document.createElement('LINK');
		l.type = 'text/css';
		l.rel = 'stylesheet';
		l.media = 'screen';
		l.href = href;
		document.getElementsByTagName('HEAD')[0].appendChild(l);
		this.installedCss = true;
	}
}

HotSpotCanvas.prototype.reInit = function (mydivId) {
	var xc;
	var yc;
	var i = 0;
	var hsc_tmp = this.HotSpotClick;
	var hsh_tmp = this.HotSpotHover;
	var hsb_tmp = this.HotSpotBoth;
	this.MyCanvasId = mydivId;
	this.ClearObj();
	this._reindex_collection("HotSpotClick", hsc_tmp, "Click");
	this._reindex_collection("HotSpotHover", hsh_tmp, "Hover");
	this._reindex_collection("HotSpotBoth", hsb_tmp, "Both");

	this.Redraw();
}

HotSpotCanvas.prototype.singleClickCallback = function (vpx, vpy, aidx) {
	if (this.disableEvents) {
		return true;
	}
	var tp = this.MyMap.xy_tray(vpx, vpy);
	if (!aidx) aidx = 0;
	var hotspot;
	hotspot = this._find_hotspot(this.HotSpotBoth, tp.x, tp.y, aidx);
	if (hotspot) {
		this._perform_click_action(hotspot);
		return false;
	}
	hotspot = this._find_hotspot(this.HotSpotClick, tp.x, tp.y, aidx);
	if (hotspot) {
		this._perform_click_action(hotspot);
		return false;
	}
	return true;
}

HotSpotCanvas.prototype.hoverCallback = function (vpx, vpy, aidx) {
	if (this.disableEvents) {
		return true;
	}
	var tp = this.MyMap.xy_tray(vpx, vpy);
	if (!aidx) aidx = 0;
	var hotspot;
	hotspot = this._find_hotspot(this.HotSpotBoth, tp.x, tp.y, aidx);
	if (hotspot) {
		this._perform_hover_action(hotspot);
		return false;
	}
	hotspot = this._find_hotspot(this.HotSpotHover, tp.x, tp.y, aidx);
	if (hotspot) {
		this._perform_hover_action(hotspot);
		return false;
	}
	return true;
}
HotSpotCanvas.prototype.doubleClickCallback = function (vpx, vpy) {
	return true;
}
HotSpotCanvas.prototype.trayMoveCallback = function (dx, dy) {
	return true;
}
HotSpotCanvas.prototype.resizeCallback = function (w, h) {
	return true;
}
HotSpotCanvas.prototype.showCallback = function (visi) {
	this.disableEvents = visi ? false : true;
	return true;
}
HotSpotCanvas.prototype.triggerClickEvent = function (id) {
	var hs, hsid;
	if ((hsid = this.HotSpotIds[id])) {
		if (hsid.type == "Click") {
			hs = this.HotSpotClick[hsid.x][hsid.y][hsid.i];
		} else if (hsid.type == "Both") {
			hs = this.HotSpotBoth[hsid.x][hsid.y][hsid.i];
		} else {
			return false;
		}
		this._perform_click_action(hs);
		return true;
	}
	return false;
}
HotSpotCanvas.prototype.CreateBothJS = function (id, lon, lat, img, imgw, imgh, scriptClick, scriptHover) {
	var myobj = this._create_hotspot_obj(id, lon, lat, img, imgw, imgh);
	myobj.scriptClick = scriptClick;
	myobj.scriptHover = scriptHover;
	this._add_to_collection("HotSpotBoth", myobj, "Both");
}
HotSpotCanvas.prototype.CreateBoth = function (id, lon, lat, img, imgw, imgh, divw, divh, html, cssClass, divwH, divhH, htmlH, cssClassH, oppressDraw) {
    
	var myobj = this._make_both(id, lon, lat, img, imgw, imgh, divw, divh, html, cssClass, divwH, divhH, htmlH, cssClassH);
	
	if (this.HotSpotAll === undefined) this.HotSpotAll = new Array();
	this.HotSpotAll.push(myobj);
    
    var overlappingHs = this._check_overlap(myobj);
    var hsToAdd;
    
    if (overlappingHs && overlappingHs.length > 0){
        hsToAdd = this._merge_hotspots(overlappingHs);
    } else {
        hsToAdd = myobj;
    }
    
    if(hsToAdd)
    {
        this._add_to_collection("HotSpotBoth", hsToAdd, "Both", oppressDraw);
    }
}

HotSpotCanvas.prototype._make_both = function(id, lon, lat, img, imgw, imgh, divw, divh, html, cssClass, divwH, divhH, htmlH, cssClassH){
    var myobj = this._create_hotspot_obj(id, lon, lat, img, imgw, imgh);
	myobj.divw = divw;
	myobj.divh = divh;
	myobj.html = html;
	if ((!cssClass) || (cssClass == '')) {
		myobj.className = '';
	} else {
		myobj.className = cssClass;
	}
	if (divwH && divhH && htmlH) {
		myobj.divwH = divwH;
		myobj.divhH = divhH;
		myobj.htmlH = htmlH;
		if ((!cssClassH) || (cssClassH == '')) {
			myobj.classNameH = '';
		} {
			myobj.classNameH = cssClassH;
		}
	}
	myobj.Type = "Both";
	myobj.Tp = this.MyMap.g2c(myobj.lon, myobj.lat);
    myobj.Bounds = this._get_bounding_rectangle(myobj);
    return myobj;
}
HotSpotCanvas.prototype._get_bounding_rectangle = function (myobj){
    var rect = new Object();
    rect.Center = this.MyMap.xy_skin(myobj.Tp.x, myobj.Tp.y);
    rect.Width = myobj.imgW;
    rect.Height = myobj.imgH;
    rect.Left = rect.Center.x - rect.Width / 2;
    rect.Right = rect.Left + rect.Width;
    rect.Top = rect.Center.y - rect.Height / 2;
    rect.Bottom = rect.Top + rect.Height;
    return rect;
}
HotSpotCanvas.prototype._check_overlap = function (myobj){
    if  (this.HotSpotIds === undefined) return;
    var retVal;
    var hs2delete = new Array();
    
    for (var index in this.HotSpotIds)
    {
        var hs = eval("this.HotSpot" + this.HotSpotIds[index].type)[this.HotSpotIds[index].x][this.HotSpotIds[index].y][this.HotSpotIds[index].i];
        if (myobj === hs) continue;
        if  (((myobj.Bounds.Left >= hs.Bounds.Left && myobj.Bounds.Left <= hs.Bounds.Right) && (myobj.Bounds.Top >= hs.Bounds.Top && myobj.Bounds.Top <= hs.Bounds.Bottom)) ||          // Bottom Right overlap
            ((myobj.Bounds.Right >= hs.Bounds.Left && myobj.Bounds.Right <= hs.Bounds.Right) && (myobj.Bounds.Bottom >= hs.Bounds.Top && myobj.Bounds.Bottom <= hs.Bounds.Bottom)) ||   // Top Left overlap
            ((myobj.Bounds.Left >= hs.Bounds.Left && myobj.Bounds.Left <= hs.Bounds.Right) && (myobj.Bounds.Bottom >= hs.Bounds.Top && myobj.Bounds.Bottom <= hs.Bounds.Bottom)) ||     // Top Right overlap
            ((myobj.Bounds.Right >= hs.Bounds.Left && myobj.Bounds.Right <= hs.Bounds.Right) && (myobj.Bounds.Top >= hs.Bounds.Top && myobj.Bounds.Top <= hs.Bounds.Bottom)))           // Bottom Leftoverlap
        {
            if (retVal === undefined)
            {
                retVal = new Array();
                retVal.push(myobj);
            }
            retVal.push(hs);
            hs2delete.push(this.HotSpotIds[index]);
        }
    }
    
    for (var i=hs2delete.length-1; i>=0; i--)
    {
        this._delete_hotspot(hs2delete[i].x, hs2delete[i].y, hs2delete[i].i, hs2delete[i].type);
    }
    
    return retVal;
}
HotSpotCanvas.prototype._delete_hotspot = function (x,y,i,type){
    var hotspots = eval("this.HotSpot" + type);
    
    var index = hotspots[x][y].splice(i, 1);
    index = index[0].id;
    
    if (hotspots[x][y].length <1)
    {
        delete hotspots[x][y];
        var isEmpty = true;
        for (var prop in hotspots[x])
        {
            if (hotspots[x].hasOwnProperty(prop))
            {
                isEmpty = false;
                break;
            }
        }
        if (isEmpty)
        {
            delete hotspots[x];
        }
    }
    delete this.HotSpotIds[index];
}
HotSpotCanvas.prototype._merge_hotspots = function (overlappingHs)
{
    var id = overlappingHs[0].id;
    var lon = overlappingHs[0].lon;
    var lat = overlappingHs[0].lat;
    var img = "http://www.trailerlifedirectory.com/images/icons/mapping/camperplus.gif";
    var imgw = 26;
    var imgh = 26;
    var divw = 100;
    var divh = 100;
    var html = HotSpotCanvas.prototype._zoom_to_hotspots;
    var cssClass = overlappingHs[0].className;
    var divwH = 100;
    var divhH = 30;
    var cssClassH = overlappingHs[0].classNameH;
    var numberOfHotspots = 1;
    
    for (var index = 1; index<overlappingHs.length; index++)
    {
        id += ";" + overlappingHs[index].id;
        lon += overlappingHs[index].lon;
        lat += overlappingHs[index].lat;
        numberOfHotspots++;
    }
    lon = lon / numberOfHotspots;
    lat = lat / numberOfHotspots;    
    var newHs = this._make_both (id, lon, lat, img, imgw, imgh, divw, divh, html, cssClass, divwH, divhH, "&nbsp;", cssClassH);
    var overlappingHs = this._check_overlap(newHs);
    if (overlappingHs && overlappingHs.length>0)
    {
        return this._merge_hotspots(overlappingHs);
    }
    else
    {
        newHs.Parent = this;
        return newHs;
    }
}
HotSpotCanvas.prototype._zoom_to_hotspots = function()
{
    if (this.Parent === undefined || this.Parent.HotSpotAll === undefined) return;
    
    var hotspotIds = this.id.split(';');
    var hotspotCollection = this.Parent.HotSpotAll;
    var boxPoints = new Array();
    
    for (var id in hotspotIds)
    {
        for(var c in hotspotCollection)
        {
            if (hotspotIds[id] == hotspotCollection[c].id)
            {
                boxPoints.push(hotspotCollection[c].lon+","+hotspotCollection[c].lat);
                break;
            }
        }
    }
    
    var box = this.Parent.MyMap.computebox(boxPoints);
    var S = new Object();
	S.Lon = (box.left + box.right)/2;
	S.Lat = (box.top + box.bottom)/2;
	S.Scale = this.Parent.MyMap.autoscale(box);
	this.Parent.MyMap.setState(S);
}
HotSpotCanvas.prototype.CreateClickJS = function (id, lon, lat, img, imgw, imgh, scriptClick) {
	var myobj = this._create_hotspot_obj(id, lon, lat, img, imgw, imgh);
	myobj.scriptClick = scriptClick;
	this._add_to_collection("HotSpotClick", myobj, "Click");
}
HotSpotCanvas.prototype.CreateClick = function (id, lon, lat, img, imgw, imgh, divw, divh, html, cssClass) {
	var myobj = this._create_hotspot_obj(id, lon, lat, img, imgw, imgh);
	myobj.divw = divw;
	myobj.divh = divh;
	myobj.html = html;
	if ((!cssClass) || (cssClass == '')) {
		myobj.className = '';
	} else {
		myobj.className = cssClass;
	}
	this._add_to_collection("HotSpotClick", myobj, "Click");
}
HotSpotCanvas.prototype.CreateHoverJS = function (id, lon, lat, img, imgw, imgh, scriptHover) {
	var myobj = this._create_hotspot_obj(id, lon, lat, img, imgw, imgh);
	myobj.scriptHover = scriptHover;
	this._add_to_collection("HotSpotHover", myobj, "Hover");
}
HotSpotCanvas.prototype.CreateHover = function (id, lon, lat, img, imgw, imgh, divw, divh, html, cssClass) {
	var myobj = this._create_hotspot_obj(id, lon, lat, img, imgw, imgh);
	myobj.divw = divw;
	myobj.divh = divh;
	myobj.html = html;
	if ((!cssClass) || (cssClass == '')) {
		myobj.className = '';
	} else {
		myobj.className = cssClass;
	}
	this._add_to_collection("HotSpotHover", myobj, "Hover");
}
HotSpotCanvas.prototype.ClearObj = function () {
	this.HotSpotClick = new Object();
	this.HotSpotHover = new Object();
	this.HotSpotBoth = new Object();
	this.HotSpotIds = new Object();
	return true;
}
HotSpotCanvas.prototype.ClearCanvas = function () {
	var cvs = $(this.MyCanvasId);
	while (cvs.firstChild) {
		cvs.removeChild(this.purge(cvs.firstChild));
	}
	this.MyMap.clearTips(this.id);
	this.ClearObj();
	return true;
}
HotSpotCanvas.prototype.Draw = function (xc, yc, i, datype) {
	var hd = $(this.MyCanvasId);
	if (hd) {
		var hs = this["HotSpot" + datype][xc][yc][i];
		this._draw_marker(hs, xc, yc, hd);
	}
}
HotSpotCanvas.prototype.Redraw = function () {
	var hd = $(this.MyCanvasId);
	var xc;
	var yc;
	var i = 0;
	while (hd.firstChild) {
		hd.removeChild(this.purge(hd.firstChild));
	}
	for (xc in this.HotSpotClick) {
		for (yc in this.HotSpotClick[xc]) {
			var hss = this.HotSpotClick[xc][yc];
			for (i = 0; i < hss.length; i++) {
				this._draw_marker(hss[i], xc, yc, hd);
			}
		}
	}
	for (xc in this.HotSpotHover) {
		for (yc in this.HotSpotHover[xc]) {
			var hss = this.HotSpotHover[xc][yc];
			for (var i = 0; i < hss.length; i++) {
				this._draw_marker(hss[i], xc, yc, hd);
			}
		}
	}
	for (xc in this.HotSpotBoth) {
		for (yc in this.HotSpotBoth[xc]) {
			var hss = this.HotSpotBoth[xc][yc];
			for (var i = 0; i < hss.length; i++) {
				this._draw_marker(hss[i], xc, yc, hd);
			}
		}
	}
}
HotSpotCanvas.prototype._find_hotspot = function (collection, x, y, aidx) {
	var xc, yc, idxx, idxy;
	for (xc in collection) {
		idxx = Math.abs(parseInt(xc) - x);
		if (idxx < 12) {
			for (yc in collection[xc]) {
				idxy = Math.abs(parseInt(yc) - y);
				if (idxy < 12) {
					return collection[xc][yc][aidx];
				}
			}
		}
	}
	return null;
}
HotSpotCanvas.prototype._perform_hover_action = function (hotspot) {
	if ('scriptHover' in hotspot) {
		if (typeof(hotspot.scriptHover) == 'function') {
			hotspot.scriptHover();
		} else {
			eval(hotspot.scriptHover);
		}
	} else {
		var width, height, cN, hot;
		if ('htmlH' in hotspot) {
			if (typeof(hotspot.htmlH) == 'function') {
				hot = hotspot.htmlH();
			} else {
				hot = document.createElement('DIV');
				hot.innerHTML = hotspot.htmlH;
			}
			width = hotspot.divwH;
			height = hotspot.divhH;
			cN = hotspot.classNameH;
		} else { if (typeof(hotspot.html) == 'function') {
				hot = hotspot.html();
			} else {
				hot = document.createElement('DIV');
				hot.innerHTML = hotspot.html;
			}
			width = hotspot.divw;
			height = hotspot.divh;
			cN = hotspot.className;
		}
		hot.style.width = width;
		hot.style.height = height;
		hot.style.background = '#FFFFFF';
		this.MyMap.toolTip(this.id + '_' + hotspot.id, 'hover', hotspot.lon, hotspot.lat, width, height, hot, cN);
	}
	return false;
}
HotSpotCanvas.prototype._perform_click_action = function (hotspot) {
	if ('scriptClick' in hotspot) {
		if (typeof(hotspot.scriptClick) == 'function') {
			hotspot.scriptClick();
		} else {
			eval(hotspot.scriptClick);
		}
	} else {
	    try
	    {
		    var hot;
		    if (typeof(hotspot.html) == 'function') {
			    hot = hotspot.html();
		    } else {
			    hot = document.createElement('DIV');
			    hot.innerHTML = hotspot.html;
		    }
		    hot.style.width = hotspot.divw;
		    hot.style.height = hotspot.divh;
		    hot.style.background = '#FFFFFF';
		    if (this.lastTipID && this.onetip) {
			    this.MyMap.closeTip(this.lastTipID);
		    }
		    this.lastTipID = this.MyMap.toolTip(this.id + '_' + hotspot.id, 'click', hotspot.lon, hotspot.lat, parseInt(hotspot.divw), parseInt(hotspot.divh), hot, hotspot.className);
		} catch (e){}
	}
}
HotSpotCanvas.prototype._allocate_in_collection = function (cname, x, y) {
	if (!this[cname]) this[cname] = new Object();
	if (!this[cname][x]) this[cname][x] = new Object();
	if (!this[cname][x][y]) this[cname][x][y] = new Array();
	return this[cname][x][y];
}
HotSpotCanvas.prototype._draw_marker = function (hotspot, x, y, domnode) {
	var nd = document.createElement('DIV');
	if (hotspot.premade) {
		nd = hotspot.blob;
	} else {
		nd.innerHTML = '<IMG src="' + hotspot.img + '" galleryimg="no" border="0">';
	}
	nd.id = this.MyMap.NAME + '_' + hotspot.id + '_marker';
	nd.style.position = 'absolute';
	nd.style.left = Math.round(parseInt(x) - (hotspot.imgW / 2)) + 'px';
	nd.style.top = Math.round(parseInt(y) - (hotspot.imgH / 2)) + 'px';
	domnode.appendChild(nd);
}
HotSpotCanvas.prototype._reindex_collection = function (cname, tempobj, type) {
    switch (cname){
        case "HotSpotBoth":
            delete this.HotSpotBoth;
        break;
        case "HotSpotClick":
            delete this.HotSpotClick;
        break;
        case "HotSpotHover":
            delete this.HotSpotHover;
        break;
    }
    
    for (var index=0; this.HotSpotAll && index<this.HotSpotAll.length; index++)
    {
        if (this.HotSpotAll[index].Type == type)
        {
            this.HotSpotAll[index].Tp = this.MyMap.g2c( this.HotSpotAll[index].lon, this.HotSpotAll[index].lat );
            this.HotSpotAll[index].Bounds = this._get_bounding_rectangle(this.HotSpotAll[index]);
            var overlappingHs = this._check_overlap(this.HotSpotAll[index]);
            var hsToAdd;
            if (overlappingHs && overlappingHs.length > 0)
            {
                hsToAdd = this._merge_hotspots(overlappingHs);
            } else {
                hsToAdd = this.HotSpotAll[index];
            }
            if (hsToAdd) this._add_to_collection(cname, hsToAdd, type, true);
        }
    }
}

HotSpotCanvas.prototype._add_to_collection = function (cname, myobj, type, oppressDraw) {
    var numCampgrounds = myobj.id.split(';').length;
    if (numCampgrounds >1)
    {
        myobj.htmlH = "<b>" + numCampgrounds + " Campgrounds.<br/>Click icon to zoom.<b/>";
    }
    
	var tp = this.MyMap.g2c(myobj.lon, myobj.lat);
	var coll = this._allocate_in_collection(cname, tp.x, tp.y);
	coll.push(myobj);
	var hsid = this.HotSpotIds[myobj.id] = new Object();
	hsid.type = type;
	hsid.x = tp.x;
	hsid.y = tp.y;
	var i = hsid.i = coll.length - 1;
	if (oppressDraw === undefined || !oppressDraw){
	    this.Draw(tp.x, tp.y, i, type);
	}
}
HotSpotCanvas.prototype._create_hotspot_obj = function (id, lon, lat, img, imgw, imgh) {
	var myobj = new Object();
	myobj.id = id;
	myobj.lon = parseFloat(lon);
	myobj.lat = parseFloat(lat);
	if (typeof img === 'function') {
		myobj.blob = img();
		myobj.premade = true;
		if (myobj.blob.style.width && myobj.blob.style.height) {
			myobj.imgW = parseInt(myobj.blob.style.width);
			myobj.imgH = parseInt(myobj.blob.style.height);
		} else {
			myobj.imgW = imgw;
			myobj.imgH = imgh;
			myobj.blob.style.width = myobj.imgW + 'px';
			myobj.blob.style.height = myobj.imgH + 'px';
		}
	} else {
		myobj.img = img;
		myobj.imgW = imgw;
		myobj.imgH = imgh;
	}
	myobj.raised = false;
	return myobj;
}
HotSpotCanvas.prototype.CreateIndexedBlob = function (cssClass, index) {
	var newBlob = document.createElement('DIV');
	newBlob.className = cssClass;
	if (!index) {
		newBlob.innerHTML = this.blobCounter;
		this.blobCounter++;
	} else {
		newBlob.innerHTML = index;
	}
	return newBlob;
}
HotSpotCanvas.prototype.purge = function (d, childOnly) {
	var a = d.attributes,
	i, l, n;
	if (a && !childOnly) {
		l = a.length;
		for (i = 0; i < l; i += 1) {
			n = a[i].name;
			if (typeof d[n] === 'function') {
				d[n] = null;
			}
		}
	}
	a = d.childNodes;
	if (a) {
		l = a.length;
		for (i = 0; i < l; i += 1) {
			this.purge(d.childNodes[i]);
		}
	}
	return d;
}
