//Copyright ©2009 Lat49 Media Inc. All rights reserved.
//Encloses the Lat49 namespace.
var Lat49 = {
	numAdHelpers : 0,
	adHelper_golems : {},
	cycleTimers : {},
	requests : {},

	//Use these global functions to initialize the ad helper and
	//to ask for ad updates by tile index or lat/lon.  If you want
	//to use the AdHelper based on pixel location, you should
	//get the object and call the geolocation setup functions.

	//This should be called before the other public functions are called,
	//for example when the body of the page loads.
	//The publisherID is for whoever should get the referral credit.
	//N.B. We removed the iepngfix URL as the second argument here.  If you
	//add another argument, then you MUST bump up the API version number.
	initAds : function(publisherID) {
		var h = new Lat49.AdHelper(publisherID);
		Lat49.fetchCSS();
		// This is now called at the bottom of the file because we're using
		// document.write to put the JS into the document. This is to
		// overcome an issue within the yahoo.util.event class re: IE.
		//Lat49.fetchJSDependencies();
	},

	fetchCSS : function()
	{
		// Put the ad templates CSS into the document.
		var head = document.getElementsByTagName('head')[0];
		var link = document.createElement("link");
		link.rel="stylesheet";
		link.type="text/css";
		link.href=Lat49.Ads.baseURL+"/lat49.css.php?serverURL="+Lat49.SERVER;
		head.appendChild(link);
	},

	fetchJSDependencies : function(usehead) {
		var basepath = Lat49.Ads.baseURL;
		var head = document.getElementsByTagName('head')[0];
		Lat49.fetchScript(basepath+"/lat49tile.js",usehead,head);
		// Use lat49-yahoo for YUI so that the YAHOO global object is put into the Lat49 namespace instead.
		// This avoids conflicts with publishers that use YUI.
		Lat49.fetchScript(basepath+"/userUtilities/lat49-yahoo/yui-2_5_2/yahoo-dom-event.js",usehead,head);
		Lat49.fetchScript(basepath+"/userUtilities/lat49-yahoo/yui-2_5_2/animation-min.js",usehead,head);
		Lat49.fetchScript(basepath+"/userUtilities/lat49adpopup.js",usehead,head);
	},

	fetchScript : function(src, usehead, head) {
		if (usehead)
		{
			if (!head)
				head = document.getElementsByTagName('head')[0];
			var script = document.createElement("script");
			script.type = "text/javascript";
			script.src = src;
			head.appendChild(script);
		}
		else
		{
			var script = "<script type='text/javascript' src='"+src+"'></script>";
			document.write(script);
		}
	},

	updateAdByLatLon : function(id, lat, lon, z) {
		if (this.adHelper_golems[0])
			this.adHelper_golems[0].updateAdByLatLon(id, lat, lon, z);
	},

	updateAdByTile : function(id, x, y, z) {
		if (this.adHelper_golems[0])
			this.adHelper_golems[0].updateAdByTile(id, x, y, z);
	},

	getAdHelper : function(id) {
		return this.adHelper_golems[id==undefined?0:id];
	},

	setAdHelper : function(id, helper) {
		this.adHelper_golems[id] = helper;
	},

	showPushPins : function(id, adDiv){
		this.adHelper_golems[id].showPushPin(adDiv);
	},

	trackPinClick : function(pinid, pubid){
	  this.adHelper_golems[id].trackPinClicked(pinid, pubid);
	},

	hidePushPins : function(id, adDiv){
		this.adHelper_golems[id].hidePushPin(adDiv);
	},

	onMouseOverShow : function(id){
		this.adHelper_golems[id].onMouseOverShow();
	},

	onMouseOutShow : function(id){
		this.adHelper_golems[id].onMouseOutShow();
	},

	onMouseOverHide : function(id){
		this.adHelper_golems[id].onMouseOverHide();
	},

	onMouseOutHide : function(id){
		this.adHelper_golems[id].onMouseOutHide();
	},

	publisherReferrer : function(id, pid){
		this.adHelper_golems[id].publisherRefer(pid);
	},

	requestAdResponse : function(params) {
		var req = this.requests[params.reqid];
		var templateid = params.template;
		var helperid = req.args.helperid;
		var adhelper = this.adHelper_golems[helperid];
		var adDivId = req.args.adcontainerid;
		var adDiv = document.getElementById(adDivId);
		var adpos = adhelper.getAdPos(adDiv);
		var ad = templateid?Lat49.Ads.create(templateid, params):document.createElement("div");
		var div;
		if (!templateid)
		{
			div = ad;
		}
		else
		{
			// Here we fetch the image url
			if (params.interactive_type == '1')     //image flyout
			{
				var imgurl = Lat49.SERVER + params.flyout_image;
				var popupimage  = Lat49AdPopup.createImagePopup(imgurl);
				var url = params.url;
				if (url.substring(0,17) == '/stw/stwgetad/hit')		//It's relative
					url = Lat49.SERVER+params.url;
				var popup = new Lat49AdPopup(ad,popupimage,adpos,url);

				div = popup.get();
			}
            else if (params.interactive_type == '2')    //form flyout
            {
				var imgurl = Lat49.SERVER + params.flyout_image;
                var url = params.url;
				var popupform  = Lat49AdPopup.createFormPopup(imgurl,url,params.interactive,params.publisherid,params.adid);
				/*
                var url = params.url;
				if (url.substring(0,17) == '/stw/stwgetad/hit')		//It's relative
					url = Lat49.SERVER+params.url;
                    */
                url = '';
				var popup = new Lat49AdPopup(ad,popupform,adpos,url);

                Lat49.YAHOO.util.Event.addListener("popupform"+params.adid, "click", function(){popup.popin(true);popup.clearIntAdFormFields();});

                popupform.onmouseout = function()
				{
				//override the onmouseout so popup doesn't close
				};
				div = popup.get();
                div.popup = popup;  //store popup object so we can call popin() to close in finalizeUpdateByAdTile
            }
			else if( params.interactive_type == '3')    //custom flyout
			{
				//Create the div for the custom flyout stuff
				if(params.custom_flyout)
				{
					var custompopup = Lat49AdPopup.createCustomPopup(params.custom_flyout);
					var popup = new Lat49AdPopup(ad, custompopup, adpos, url);
					div = popup.get();
				}
				else
					div = ad;
			}
			else
			{
				div = ad;
			}
		}

		if (req.args.callback)			//Pass the new ad to the provided callback
			req.args.callback(div);
		else {											//Provide the ad to the AdHelper
			var id = req.args.cacheid;
			div.id = id;
			div.name = id;
			div.style.display="none";
			div.style.position="absolute";
			div.className="lat49adwrapper";		// useless className. This is for MQ benefit (tagline).
			this.setPinnedPosition(div,adpos);

			if (div.innerHTML=="" && adhelper.getAdDebug(adDiv)) {
				var pattern = /(\d{14})/;
				pattern.test(id);
				var tileIndex = RegExp.$1;
				var z = parseInt(tileIndex.substring(0,2),10);
				var y = parseInt(tileIndex.substring(2,8),10);
				var x = parseInt(tileIndex.substring(8,14),10);
				div.innerHTML="No current ad for "+x+" "+y+" "+z;
				div.style.width = '226px';
				div.style.height = '58px';
			}

			if (params.lat != undefined) {
				div.lat = params.lat;
				div.lon = params.lon;
			}
			if (params.loc != undefined)
			{
				div.loc = params.loc;
			}
			if (params.headline != undefined)
			{
				div.headline = params.headline;
			}
			if (params.adid != undefined)
			{
				div.adid = params.adid;
			}
		  if (params.adaccount != undefined)
		  {
		    div.adaccount = params.adaccount;
		  }

			// This is to help get rid of the brokered ads flashing. They take a little bit of time fetch. So sometimes,
			// many can be fetched before the previously fetched ones return and get displayed. The result is that the old
			// one shows briefly, and then the new one comes in. In fact, they can even come in out of order. - jchong
			var displayAd = parseInt(params.reqid) == parseInt(Lat49.Ads.mostRecentRequest);
			adhelper.cacheAd(adDivId, id, div, displayAd);
		}

		// No reason to set the width, this is for MQ benefit (tagline).
		// Do this here so that offsetWidth is set by adding the div to the DOM (cacheAd).
		//div.style.width=ad.offsetWidth+"px";
		//   jchong - no longer do this, it actually causes a bug if the width gets set to 0.
		//            instead do something like this if we need to put it back in:
		//if (ad.offsetWidth > 0)
		//	div.style.width=ad.offsetWidth+"px";


		// remove <script> from head.
		var e = document.getElementById(id+"-script");
		if (e && e.parentNode) {
			if (e.timerId)
				clearTimeout(e.timerId);
			setTimeout(function(){e.parentNode.removeChild(e);},100);
		}

		this.removeRequestState(req.id);
	},

	setPinnedPosition:function(e,pos) {
		if (pos=='top-left' || pos=='top-right')
			e.style.top="0px";
		if (pos=='bottom-left' || pos=='bottom-right')
			e.style.bottom="0px";
		if (pos=='top-left' || pos=='bottom-left')
			e.style.left="0px";
		if (pos=='top-right' || pos=='bottom-right')
			e.style.right="0px";
	},

	addRequestState:function(args) {
		var r = new Lat49.RequestState(args);
		this.requests[r.id] = r;
		return r.id;
	},

	removeRequestState:function(reqid) {
		this.requests[reqid] = null;
		delete this.requests[reqid];
	}



};

Lat49.VERSION = "v0.10";
var theHead = document.getElementsByTagName('head')[0];
for(i=0; i< theHead.childNodes.length; i++) {
	if(theHead.childNodes[i].nodeName == 'SCRIPT') {
		//Search for (server URL)/lat49/(version+patchlevel)/lat49*.js
		var res = /(.*)\/lat49\/(v[^\/]+)\/lat49.*\.js/.exec(theHead.childNodes[i].src);
		if (res) {
			//Lat49.SERVER = res[1];
			Lat49.VERSION = res[2];
			break;
		}
	}
}
Lat49.SERVER = "http://adserver.lat49.com";

Lat49.RequestState = function(args)
{
	this.id = Lat49.RequestState.id++;
	this.args = args;
}

Lat49.RequestState.id = 0;

//Statics for supported projection types.
Lat49.projMercator = 0;
Lat49.projUnprojected = 1;

//Public functions for computing Lat49 tile geometry.
//The tile boundaries are the same as for VirtualEarth.

//A class for putting together the URLs for fetching ads.
Lat49.Ads = function(publisherID) {
	//This is the publisher that gets the credit when fetching ads.
	var publisher = publisherID || 1;

	this.getPublisherId = function()
	{
		return publisher;
	}
};

Lat49.Ads.prototype.requestAd = function(x, y, z, debug, args) {
	var head = document.getElementsByTagName('head')[0];
	var script = document.createElement("script");
	var pid = this.getPublisherId();
	script.type = "text/javascript";
	if (args.cacheid==null)
		args.cacheid = Lat49.Ads.hashTileIndices(x, y, z, "");
	var reqid = Lat49.addRequestState(args);
	Lat49.Ads.mostRecentRequest = reqid;
	script.id=args.cacheid+"-script";
	script.src = Lat49.Ads.serverURL+'/getad2?publisher='+pid+'&x='+x+'&y='+y+'&z='+z+'&reqid='+reqid+'&';
	if (debug)
		script.src += 'debug=1&';
	script.timerId = setTimeout('Lat49.Ads.cleanScript("'+script.id+'")', 30000);
	head.appendChild(script);
};

Lat49.Ads.prototype.trackmapit = function(adid)
{
	var head = document.getElementsByTagName('head')[0];
	var script = document.createElement("script");
	var pid = this.getPublisherId();
	script.type = "text/javascript";

	script.id='42';
	script.src = Lat49.Ads.serverURL+'/trackmapit?p='+pid+'&ad='+adid+'&key=a';
	script.timerId = setTimeout('Lat49.Ads.cleanScript("'+script.id+'")', 30000);
	head.appendChild(script);
};

Lat49.Ads.cleanScript = function(id) {
	var script = document.getElementById(id);
	if (script && script.parentNode)
		script.parentNode.removeChild(script);
}

Lat49.Ads.serverURL = Lat49.SERVER+"/stw/stwgetad";
Lat49.Ads.baseURL = Lat49.SERVER+"/lat49/"+Lat49.VERSION;

Lat49.Ads.TEXT_BANNER=6;
Lat49.Ads.IMAGE_BANNER=2;
Lat49.Ads.IMAGE_BUTTON=3;
Lat49.Ads.TEXT_IMAGE_BUTTON=5;
Lat49.Ads.TEXT_IMAGE_HORIZ=4;
Lat49.Ads.CUSTOM=8;

Lat49.Ads.create = function(templateid, params)
{
	var containerdiv = document.createElement("div");
	var imgroot = Lat49.SERVER;

	var ua=navigator.userAgent, m, iever=-1;
	m=ua.match(/MSIE\s([^;]*)/);
	if (m&&m[1])
		iever=parseFloat(m[1]);
	var isIe6 = iever>0 && iever<7;
	var src = "src='"+imgroot+params.image+"'";
	if (templateid != Lat49.Ads.TEXT_BANNER && isIe6 && params.image.substr(params.image.length-3).toLowerCase()=="png")
		src = "src='http://lat49.com/lat49/blank.gif' style='width:"+params.imagesize.w+"px;height:"+params.imagesize.h+"px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\""+imgroot+params.image+"\", sizingMethod=\"scale\")';";


	if (templateid == Lat49.Ads.TEXT_BANNER)
	{
		containerdiv.className = "container_text-h";
		containerdiv.innerHTML = "<div class='copy_text-h'><b><u>"+params.headline+"</span></u></b><br>"+params.message+"</div>";
	}
	else if (templateid == Lat49.Ads.IMAGE_BANNER)
	{
		containerdiv.className = "container_img-h";
		containerdiv.innerHTML = "<div class='container_img_img-h'><div class='center1_img-h'><div class='center2_img-h'><div class='center3_img-h'><img id='adimage' class='img-h' "+src+"/></div></div></div></div>";

	}
	else if (templateid == Lat49.Ads.IMAGE_BUTTON)
	{
		containerdiv.className = "container_img-sq";
		containerdiv.innerHTML = "<div class='container_img_img-sq'><div class='center1_img-sq'><div class='center2_img-sq'><div class='center3_img-sq'><img id='adimage' class='img-sq' "+src+"/></div></div></div></div>";
	}
	else if (templateid == Lat49.Ads.TEXT_IMAGE_BUTTON)
	{
		containerdiv.className = "container_textimg-sq";
		containerdiv.innerHTML = "<div class='container_img_textimg-sq'><div class='center1_textimg-sq'><div class='center2_textimg-sq'><div class='center3_textimg-sq'><img class='img_textimg-sq' id='adimage' "+src+"/></div></div></div></div><div class='copy_textimg-sq'><b><u>"+params.headline+"</u></b><br>"+params.message+"</div>";
	}
	else if (templateid == Lat49.Ads.TEXT_IMAGE_HORIZ)
	{
		containerdiv.className = "container_textimg-h";
		containerdiv.innerHTML = "<div class='container_img_textimg-h'><div class='center1_textimg-h'><div class='center2_textimg-h'><div class='center3_textimg-h'><img class='img_textimg-h' id='adimage' "+src+"/></div></div></div></div><div class='copy_textimg-h'><b><u>"+params.headline+"</u></b><br>"+params.message+"</div>";
	}
	else if (templateid == Lat49.Ads.CUSTOM)
	{
		var adClassSize = params.headline;		// class name was stored in headline.
		containerdiv.className = "container_"+adClassSize;
		containerdiv.innerHTML = "<div class='container_img_"+adClassSize+"'><div class='center1_"+adClassSize+"'><div class='center2_"+adClassSize+"'><div class='center3_"+adClassSize+"'>"+params.message+"</div></div></div></div>";
	}

	var newad = document.createElement("div");
	if (templateid == Lat49.Ads.CUSTOM)
		newad.appendChild(containerdiv);
	else
	{
		if (containerdiv.className != "")	{ // we've got a valid ad.
			var url = params.url;
			if (url.substring(0,17) == '/stw/stwgetad/hit')		//It's relative
				url = Lat49.SERVER+params.url;
			var a = document.createElement("a");
			a.href=url;
			a.target="_blank";
			a.style.textDecoration="none";
			a.appendChild(containerdiv);
			newad.appendChild(a);

			// IE doesn't follow the above HREF for some reason. I'm pretty sure this was broken somewhere
			// else because the change above has been in CVS since Jan 17. For a quick fix, we've added an
			// onclick to the newad div for IE only, but we should really find out what broke this in
			// the first place! - jchong - June 27,08
			var ua=navigator.userAgent, m, iever=-1;
			m=ua.match(/MSIE\s([^;]*)/);
			if (m)
				newad.onclick=function(){window.open(url).focus()};
		}
		else
			newad.appendChild(containerdiv);
	}

	return newad;
}

Lat49.Ads.hashTileIndices = function(x, y, z, name) {
	if (typeof(x) == "string")
		x = parseInt(x);		//y,z will be cast to numbers when they're multiplied.

	//Hopefully, x or y won't exceed 1,000,000
	var index = z*1000000000000 + y*1000000 + x;
	var indexStr = index.toString();
	if (z < 10)
		indexStr = '0' + indexStr;
	return "lat49ad" + '-' + name + "-" + indexStr;
}




//An internal class used for automatically cycling ads in the AdHelper class.
Lat49.CycleTimer = function(parent, divId) {
	var dad = parent;
	var id = divId;
	var x, y;		//Current tile indices
	var timer;
	var cycletime;

	this.updateNext = function() {
		//Quit if the ad DIV is gone.
		var adDiv = document.getElementById(id);
		if (adDiv == null) {
			timer = null;
			return;		//Quit showing ads for the deceased DIV.
		}

  		//Find a zoomlevel that we have ads for.
		var adzl = dad.getAdZoomLevel(dad.zoomlevel);

		if (adzl == -1)
			dad.clearAd(id);	//No ads to show, currently
		else {
			var x0 = Math.floor(Lat49.Tile.lonToXAtZ(dad.lonmin, adzl));
			var x1 = Math.floor(Lat49.Tile.lonToXAtZ(dad.lonmax, adzl));
			var y0 = Math.floor(Lat49.Tile.latToYAtZ(dad.latmax, adzl));
			var y1 = Math.floor(Lat49.Tile.latToYAtZ(dad.latmin, adzl));

 	  		if (x == null || x < x0)
				x = x0;
			else
				x++;

			if (y == null)
				y = y0;
			else if (x > x1) {
				y++;
				x = x0;
			}
			if (y < y0 || y > y1)
				y = y0;

			dad.updateAdByTile(id, x, y, adzl);
		}

		//Setup the next update
		var key = id+'-'+dad.num;
		timer = setTimeout('Lat49.cycleTimers["'+key+'"].updateNext()', cycletime*1000);
	}

	this.setCycleInterval = function(interval) {
		if (typeof(interval) == "string")
			interval = parseInt(interval);
		cycletime = interval;

		//Stop any existing timer.
		if (timer) {
			clearTimeout(timer);
			timer = null;
			dad.clearAd(id);
		}

		if (cycletime > 0)
			this.updateNext();
	}
};

//A convenient class for fetching ads based on pixel location or
//lat-lon.  Ads are cached internally for speedier access.

//The publisherID is for whoever should get the referral credit.
Lat49.AdHelper = function(publisherID) {
	//Variables used for converting pixel location to lat/lon/zoomlevel.
	this.screenWidth = 0;
	this.screenHeight = 0;
	this.latmin = 0;
	this.lonmin = 0;
	this.latmax = 0;
	this.lonmax = 0;
	this.zoomlevel = -1;

	//Variables used for caching ads.
	this.cache = {};
	this.cacheSize = 0;
	this.maxCacheSize = 100;

	//Variables used for adPanel
	this.hidepinflag = false; //enable/disable hide text
	this.showpinflag = true;  //enable/disable show text
	this.pid = publisherID;
  this.mapitClickedAds = new Array(); // array of ads where users has already clicked on mapit


	this.ads = new Lat49.Ads(publisherID);
	this.num = Lat49.numAdHelpers++;
	Lat49.setAdHelper(this.num, this);
};

//
// The following are the cache-related methods.
//

Lat49.AdHelper.prototype.setMaxCacheSize = function(max) {
	if (max < this.cacheSize)
		this.removeNCacheItems(this.cacheSize-max);
	this.maxCacheSize = max;
}

Lat49.AdHelper.prototype.removeFirstCacheItem = function() {
	this.removeNCacheItems(1);
}

Lat49.AdHelper.prototype.removeNCacheItems = function(n) {
	var j = 0;
	for (var eldest in this.cache) {
		if (j<n) {
			this.cache[eldest] = null;
			delete this.cache[eldest];	//XXXXXX might need more than delete for this.
			this.cacheSize--;
		}
		else
			break;
		j++;
	}
}


Lat49.AdHelper.prototype.ensureCacheSpace = function() {
	if (this.cacheSize >= this.maxCacheSize) {
		//Get rid of half of the cached items.
		var currentMaxCacheSize = this.maxCacheSize;
		this.setMaxCacheSize(Math.floor(currentMaxCacheSize/2));
		this.setMaxCacheSize(currentMaxCacheSize);
	}
}

Lat49.AdHelper.prototype.getAdPos = function(adDiv) {
	var pos = "top-left";		//the default
	var posAttr = adDiv.getAttribute("lat49adposition", false);
	if (posAttr) {
		if (posAttr.indexOf("centre")!=-1 || posAttr.indexOf("center")!=-1)
			pos = "top-left";		//Wrong, but meaningful.
			//pos = "centre";
		else {
			var right = posAttr.indexOf("right")!=-1;
			var bottom = posAttr.indexOf("bottom")!=-1 || posAttr.indexOf("lower")!=-1;
			pos = (bottom ? "bottom" : "top") + "-" + (right ? "right" : "left");
		}
	}

	return pos;
}

Lat49.AdHelper.prototype.getAdDebug = function(adDiv) {
	var debugAttr = adDiv.getAttribute("lat49debug", false);
	return (debugAttr!=null && debugAttr);
}

//Function for updating ads by tile indices.
Lat49.AdHelper.prototype.updateAdByTile = function(divId, x, y, z) {
	var adDiv = document.getElementById(divId);
	if (adDiv == null)
		return;
	var pos = this.getAdPos(adDiv);
	var debug = this.getAdDebug(adDiv);

	x = Lat49.Tile.normTileIndex(x, z);
	y = Lat49.Tile.normTileIndex(y, z);

	var frameId = Lat49.Ads.hashTileIndices(x, y, z, pos) + '-' + this.num;

	// no caching
	this.cache[frameId] = "waiting-for-request";
	this.ads.requestAd(x, y, z, debug, {helperid:this.num,cacheid:frameId,adcontainerid:divId});


// 	if (this.cache[frameId] == undefined) {
// 		this.cache[frameId] = "waiting-for-request";
// 		this.ads.requestAd(x, y, z, debug, {helperid:this.num,cacheid:frameId,adcontainerid:divId});
// 	}
// 	else if (this.cache[frameId] != "waiting-for-request")
// 		this.finalizeUpdateByAdTile(divId, frameId);
}

Lat49.AdHelper.prototype.finalizeUpdateByAdTile = function(divId, frameId)
{
	var adDiv = document.getElementById(divId);
	var newAd = this.cache[frameId];
	if ((adDiv == null) || (newAd == null))
		return;
	if (adDiv.popup) {
        adDiv.popup.popin(true);
        adDiv.popup.clearIntAdFormFields();
    }
	//First remove the old ad.
	var child = adDiv.firstChild;
	while (child) {
		var childID = child.id;
		if (childID && (childID.substring(0,7) == "lat49ad")) {
			if (childID == newAd.id) {
				newAd.style.display = "";

			  var showpinimg = document.getElementById('lat49showpinid' + this.num);
                          if(showpinimg != null)
			  {
			    this.showpinflag=adDiv.getAttribute('lat49locations',false) != null
			    if(this.showpinflag==true)
			      this.showpinflag = this.mapitClicked(adDiv);

			    this.enableShowImg(this.showpinflag, adDiv);
			    this.setPanelVisibility(adDiv);
			  }

				return; 	//Don't replace the old ad if it's the same one.
			}
			else {
                if (child.popup) {
                    child.popup.popin(true);
                    child.popup.clearIntAdFormFields();
                }
				child.style.display = "none";		//Stop displaying old ad first.
				adDiv.removeChild(child);
			}
		}
		child = child.nextSibling;
	}

	//Now append the new ad (replace doesn't seem to work).
	if(adDiv.firstChild && this.getAdPos(adDiv).substring(0,6) == 'bottom')
		adDiv.insertBefore(newAd,adDiv.firstChild);
	else
		adDiv.appendChild(newAd);

	newAd.style.display = "";

	//pushpin panel
	this.updateAdPanel(adDiv, frameId)

	//Exec the callback if it exists.
	var callbackAttr = adDiv.getAttribute("onlat49update", false);
	if (callbackAttr != null) {
		var contents = this.cache[frameId].innerHTML;
		var hasContents = !(contents == "" ||
				    contents.substring(0,17) == "No current ad for");
		var callback = callbackAttr+"("+hasContents+");";
		eval(callback);
	}
}



//Update the ad's show hide pushpin panel, or create it, if it doesn't exit
//adDiv: the container specified by the publisher
Lat49.AdHelper.prototype.updateAdPanel = function(adDiv, frameId)
{
	var showlink;
	var hidelink;
	var newAd = this.cache[frameId];
	var helperid = this.num;

	if (newAd.loc != undefined)
	{
		adDiv.setAttribute('lat49locations', newAd.loc);
		//adDiv.setAttribute('lat49headline', newAd.headline);
	  adDiv.setAttribute('lat49adaccount',newAd.adaccount);
		adDiv.setAttribute('lat49adid',newAd.adid);
	}
	else
	{
		adDiv.removeAttribute('lat49locations');
	}


	//check if publisher wants to use ad push pin feature
	var callbackAttr = adDiv.getAttribute("onlat49pushpin", false);
	if (callbackAttr != null)
	{
		var pushpindiv = document.getElementById('pushpindivid' + this.num);
		if(pushpindiv == null)
		{
			pushpindiv = this.createAdPanel(adDiv,showlink,hidelink);

			//Now append the ad panel
			if(this.getAdPos(adDiv).indexOf('right') != -1)
				pushpindiv.style.right = '0px';
			else
				pushpindiv.style.left = '0px';

			if(adDiv.firstChild && this.getAdPos(adDiv).substring(0,3) == 'top') {
				pushpindiv.style.top = '0px';

				adDiv.insertBefore(pushpindiv,adDiv.firstChild);
			}
			else {
				pushpindiv.style.bottom = '0px';
				adDiv.appendChild(pushpindiv);
			}
		}

		if(this.getAdPos(adDiv).substring(0,3) == 'top')
			newAd.style.top = '23px';
		else
			newAd.style.bottom = '23px';

		this.showpinflag = newAd.loc != undefined;  //check if we have an add
		 if(this.showpinflag==true)
		   this.showpinflag = this.mapitClicked(adDiv);

		this.enableHideImg(this.hidepinflag, adDiv);
		this.enableShowImg(this.showpinflag, adDiv);

		this.setPanelVisibility(adDiv);
	}
}

Lat49.AdHelper.prototype.createAdPanel = function(adDiv,showlink,hidelink)
{
	var pushpindiv = document.createElement('div');
	pushpindiv.id = 'pushpindivid' + this.num;
	pushpindiv.style.fontSize = "8pt";
	pushpindiv.style.backgroundColor = "transparent";
	pushpindiv.style.position = 'absolute';
	pushpindiv.style.width = '133px';
	pushpindiv.style.height = '23px';

	showlink = this.createAdPanelShowLink(adDiv, pushpindiv);
	hidelink = this.createAdPanelHideLink(adDiv, pushpindiv);
	//this.createAdPanelLocationText(pushpindiv);

	var helperid = this.num
	var pubid = this.pid;
	var logo = document.createElement('img')
	//logo.src = Lat49.SERVER+"/lat49/v0.10/img/lat49_60x28.png";
	this.filterPNG(logo, Lat49.SERVER+"/lat49/v0.10/img/lat49_58x23.png", '58px', '23px');
	logo.onclick = function(){Lat49.publisherReferrer(helperid, pubid);};
	logo.style.cursor = 'pointer';
	pushpindiv.appendChild(logo);

	return pushpindiv;
}

Lat49.AdHelper.prototype.createAdPanelShowLink = function(adDiv,pushpindiv)
{
	var helperid = this.num

	var showlink = document.createElement('img');
	showlink.id = 'lat49showpinid' + this.num;
	showlink.onclick = function(){Lat49.showPushPins(helperid,adDiv);};
	showlink.style.cursor = 'pointer';
	showlink.onmouseover = function(){Lat49.onMouseOverShow(helperid);};
	showlink.onmouseout = function(){Lat49.onMouseOutShow(helperid);};
	showlink.src = ""
	pushpindiv.appendChild(showlink);

	return showlink;
}

Lat49.AdHelper.prototype.createAdPanelHideLink = function(adDiv,pushpindiv)
{
	var helperid = this.num

	var hidelink = document.createElement('img');
	hidelink.id = 'lat49hidepinid' + helperid;

	//src img gets set after div is created

	hidelink.onmouseover = function(){Lat49.onMouseOverHide(helperid);};
	hidelink.onmouseout = function(){Lat49.onMouseOutHide(helperid);};
	pushpindiv.appendChild(hidelink);

	return hidelink;
}

Lat49.AdHelper.prototype.createAdPanelLocationText = function(pushpindiv)
{
	var helperid = this.num

	var locationimg = document.createElement('img');
	locationimg.id = 'lat49loctextid' + this.num;
	locationimg.src = Lat49.SERVER+"/lat49/v0.10/locations_84x33.png";
	pushpindiv.appendChild(locationimg);
}

Lat49.AdHelper.prototype.filterPNG = function(img,png, w, h)
{
	var ua=navigator.userAgent, m, iever=-1;
	m=ua.match(/MSIE\s([^;]*)/);
	if (m&&m[1])
		iever=parseFloat(m[1]);

	var isIe6 = iever>0 && iever<7;
	if(isIe6)
	{
		img.src = Lat49.SERVER+"/lat49/blank.gif";
		img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\""+png+"\", sizingMethod=\"scale\")'"
	}
	else
		img.src = png;

	img.style.width = w;
	img.style.height = h;
}

Lat49.AdHelper.prototype.trackPinClicked = function(pinid,pubid)
{
  //alert('pinclicked' + pinid + pubid);

	var head = document.getElementsByTagName('head')[0];
	var script = document.createElement("script");
	script.type = "text/javascript";

	script.id='43';
	script.src = Lat49.Ads.serverURL+'/trackpinclicked?p='+pubid+'&pinid='+pinid;
	script.timerId = setTimeout('Lat49.Ads.cleanScript("'+script.id+'")', 30000);
	head.appendChild(script);

};

//check if ad viewed has already had its mapit button clicked
//if show, disable mapit.
//we simply add to an array of adids when mapit is clicked,
//and check if the ad is in the list .
//if it is in the list, mapit is disabled.
Lat49.AdHelper.prototype.mapitClicked = function(adDiv)
{
  var adaccount = adDiv.getAttribute("lat49adaccount",false);
  var enableMapit = true;

  for(var i=0; i<this.mapitClickedAds.length; i++)
  {
    if(adaccount == this.mapitClickedAds[i])
      enableMapit = false;
  }

  return enableMapit;
};

Lat49.AdHelper.prototype.showPushPin = function(adDiv)
{
	var adid = adDiv.getAttribute("lat49adid",false);
  var max = 20; // max number of pushpins returned to the publisher

	this.ads.trackmapit(adid);

	var callbackAttr = adDiv.getAttribute("onlat49pushpin", false);

	if (callbackAttr != null)
	{
		this.hidepinflag = true;
		this.enableHideImg(this.hidepinflag, adDiv);

		this.showpinflag = false;
		this.enableShowImg(this.showpinflag, adDiv)

		var loc = eval(adDiv.getAttribute('lat49locations',false));

		this.findDistanceToPin(loc, adDiv);

		loc.sort(this.sortByDistance);
	        loc.splice(max,loc.length-max);

	  // add pinurl;
	  var i=0;
	  for(i=0; i<loc.length; i++)
	  {
	    loc[i].pinurl = Lat49.SERVER + loc[i].pinurl;
	  }

		//var title = adDiv.getAttribute('lat49headline',false);
		if(loc.length > 0)
		{
		  var adaccount = adDiv.getAttribute("lat49adaccount",false);
		  this.mapitClickedAds.push(adaccount);
			var callback = callbackAttr+"(loc);";
			eval(callback);
		}
	}
}

Lat49.AdHelper.prototype.findDistanceToPin = function(pinLocArray, adDiv)
{
	var adx = null;
	var ady = null;
	var adz = null;

	var pinx = null;
	var piny = null;

	var child = adDiv.firstChild;
	while (child) {
		var childID = child.id;
		if (childID && (childID.substring(0,7) == "lat49ad"))
		{
			var pattern = /(\d{14})/;
			pattern.test(childID);
			var tileIndex = RegExp.$1;
			adz = parseInt(tileIndex.substring(0,2),10);
			ady = parseInt(tileIndex.substring(2,8),10);
			adx = parseInt(tileIndex.substring(8,14),10);
		}
		child = child.nextSibling;
	}

	for(var i=0; i<pinLocArray.length; i++)
	{
		pinx = Lat49.Tile.lonToXAtZ(pinLocArray[i].lon, adz);
		piny = Lat49.Tile.latToYAtZ(pinLocArray[i].lat, adz);
		pinLocArray[i].dist = this.getDistanceBetweenAdPin(adx, ady, pinx, piny);
	}
}

Lat49.AdHelper.prototype.getDistanceBetweenAdPin = function(x,y,px,py)
{
	var d = ((x+0.5)-(px))*((x+0.5)-(px)) + ((y+0.5)-(py))*((y+0.5)-(py))

	return d;
}

Lat49.AdHelper.prototype.sortByDistance = function(a, b)
{
	var x = a.dist;
	var y = b.dist;
	return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

Lat49.AdHelper.prototype.hidePushPin = function(adDiv)
{
	var callbackAttr = adDiv.getAttribute("onlat49hidepushpin", false);

  this.mapitClickedAds = null;
  this.mapitClickedAds = new Array();

	if (callbackAttr != null)
	{
		this.showpinflag=adDiv.getAttribute('lat49locations',false) != null
		this.enableShowImg(this.showpinflag, adDiv);

		this.hidepinflag = false;
		this.enableHideImg(this.hidepinflag, adDiv);

		this.setPanelVisibility(adDiv);

		var callback = callbackAttr+"();";
		eval(callback);
	}
}

Lat49.AdHelper.prototype.onMouseOverShow = function()
{
	if(this.showpinflag){
		var showimg = document.getElementById('lat49showpinid'+ this.num);
		//showimg.src = Lat49.SERVER+"/lat49/v0.10/img/mapit_47x28_hover.png";
		this.filterPNG(showimg, Lat49.SERVER+"/lat49/v0.10/img/mapit_40x23_hover.png", '40px', '23px');
	}
}

Lat49.AdHelper.prototype.onMouseOutShow = function()
{
	if(this.showpinflag){
		var showimg = document.getElementById('lat49showpinid'+ this.num);
		//showimg.src = Lat49.SERVER+"/lat49/v0.10/img/mapit_47x28_on.png";
		this.filterPNG(showimg, Lat49.SERVER+"/lat49/v0.10/img/mapit_40x23_on.png", '40px', '23px');
	}
}

Lat49.AdHelper.prototype.onMouseOverHide = function()
{
	if(this.hidepinflag){
		var hideimg = document.getElementById('lat49hidepinid'+ this.num);
		//hideimg.src = Lat49.SERVER+"/lat49/v0.10/img/clear_35x28_hover.png";
		this.filterPNG(hideimg, Lat49.SERVER+"/lat49/v0.10/img/clear_35x23_hover.png", '35px', '23px');
	}
}

Lat49.AdHelper.prototype.onMouseOutHide = function()
{
	if(this.hidepinflag){
		var hideimg = document.getElementById('lat49hidepinid'+ this.num);
		//hideimg.src = Lat49.SERVER+"/lat49/v0.10/img/clear_35x28_on.png";
		this.filterPNG(hideimg, Lat49.SERVER+"/lat49/v0.10/img/clear_35x23_on.png", '35px', '23px');
	}
}

Lat49.AdHelper.prototype.publisherRefer = function(pid)
{
	window.open("http://lat49.com/index.php?pubid="+pid);
}


Lat49.AdHelper.prototype.isAdVisible = function(adDiv)
{
        var advisible = true;

        if (adDiv != null)
        {
                var child = adDiv.firstChild;

                while (child) {
                        var childID = child.id;
                        if (childID && (childID.substring(0,7) == "lat49ad")) {
                                if (child.style.display == 'none')
                                        advisible = false;
                        }
                        child = child.nextSibling;
                }
        }

        return advisible;
}


Lat49.AdHelper.prototype.setPanelVisibility = function(adDiv)
{
	var showpinimg = document.getElementById('lat49showpinid' + this.num);
	var hidepinimg = document.getElementById('lat49hidepinid' + this.num);
	//var locationsimg = document.getElementById('lat49loctextid' + this.num);

  if (this.showpinflag && this.isAdVisible(adDiv))
	{
		var loc = eval(adDiv.getAttribute('lat49locations',false));
		if(loc)
		{
			if (loc.length <= 0) //ad not associated with any push pins
			{
				this.showpinflag = false;
				this.enableShowImg(this.showpinflag);
			}
		}
	}
  else
  {
    this.showpinflag = false;
    this.enableShowImg(this.showpinflag);
  }


	//keep panel visible all the time
	/*
  if(this.showpinflag || this.hidepinflag)
  {
    showpinimg.style.visibility = 'visible';
    hidepinimg.style.visibility = 'visible';
    locationsimg.style.visibility = 'visible';
  }
  else
  {
    showpinimg.style.visibility = 'hidden';
    hidepinimg.style.visibility = 'hidden';
    locationsimg.style.visibility = 'hidden';
  }
*/
}

Lat49.AdHelper.prototype.enableShowImg = function(enable, adDiv)
{
	var helperid = this.num;
	var showimg = document.getElementById('lat49showpinid' + helperid);

	if(enable)
	{
		//showimg.src = Lat49.SERVER+"/lat49/v0.10/img/mapit_47x28_on.png";
		this.filterPNG(showimg, Lat49.SERVER+"/lat49/v0.10/img/mapit_40x23_on.png", '40px', '23px');
		showimg.style.cursor = 'pointer';
		showimg.onclick = function(){Lat49.showPushPins(helperid,adDiv);};
	}
	else
	{
		//showimg.src = Lat49.SERVER+"/lat49/v0.10/img/mapit_47x28_off.png";
		this.filterPNG(showimg, Lat49.SERVER+"/lat49/v0.10/img/mapit_40x23_off.png", '40px', '23px');
		showimg.style.cursor = 'default';
		showimg.onclick = function(){return false;};
	}
}

Lat49.AdHelper.prototype.enableHideImg = function(enable, adDiv)
{
	var helperid = this.num;
	var hideimg = document.getElementById('lat49hidepinid' + helperid);

	if(enable)
	{
		//hideimg.src = Lat49.SERVER+"/lat49/v0.10/img/clear_35x28_on.png";
		this.filterPNG(hideimg, Lat49.SERVER+"/lat49/v0.10/img/clear_35x23_on.png", '35px', '23px');
		hideimg.style.cursor = 'pointer';
		hideimg.onclick = function(){Lat49.hidePushPins(helperid, adDiv);};
	}
	else
	{
		//hideimg.src = Lat49.SERVER+"/lat49/v0.10/img/clear_35x28_off.png";
		this.filterPNG(hideimg, Lat49.SERVER+"/lat49/v0.10/img/clear_35x23_off.png", '35px', '23px');
		hideimg.style.cursor = 'default';
		hideimg.onclick = function(){return false;};
	}
}

Lat49.AdHelper.prototype.cacheAd = function(container, id, adobject, finalizeUpdate)
{
	if (finalizeUpdate == null)
		finalizeUpdate = true;

	this.ensureCacheSpace();
	this.cache[id] = adobject;
	this.cacheSize++;
	if (finalizeUpdate)
		this.finalizeUpdateByAdTile(container, id);
}

Lat49.AdHelper.prototype.clearAd = function(divId) {
	//Stop displaying any ads in the DIV.
	var adDiv = document.getElementById(divId);
	if (adDiv == null)
		return;
	var child = adDiv.firstChild;
	while (child) {
		var childID = child.id;
		if (childID && (childID.substring(0,7) == "lat49ad")) {
			child.style.display = "none";
		}
		child = child.nextSibling;
	}
}

Lat49.AdHelper.prototype.normLon = function(lon) {
	while (lon < -180)
		lon += 360;
	while (lon >= 180)
		lon -= 360;
	return lon;
}

//Function for finding the zoom level with offered ads given some input
//zoom level.  Returns "-1" if there is no appropriate level.
Lat49.AdHelper.prototype.getAdZoomLevel = function(z) {
	//Should round up to 7, 10, 13 or 16.  4 or less get no ads.
	var adzl = 7 + 3*Math.floor((z-5)/3);
	if (adzl > 16)
		adzl = 16;
	else if (adzl < 7)
		adzl = -1;

	return adzl;
}

//Function for updating ads by lat/lon location.
Lat49.AdHelper.prototype.updateAdByLatLon = function(divId, lat, lon, z) {
	//Make sure that longitudes are within +/-180 degrees (for caching).
	lon = this.normLon(lon);

	//Find a zoomlevel that we have ads for.
	var adzl = this.getAdZoomLevel(z);
	if (adzl == -1) {
		this.clearAd(divId);		//Don't show any ads when we're zoomed out passed BRAND scale.


	  var showpinimg = document.getElementById('lat49showpinid' + this.num);
	  if(showpinimg != null)
          {
	    var adDiv = document.getElementById(divId);
	    this.showpinflag=adDiv.getAttribute('lat49locations',false) != null
	    if(this.showpinflag==true)
	      this.showpinflag = this.mapitClicked(adDiv);

	    this.enableShowImg(this.showpinflag, adDiv);
	    this.setPanelVisibility(adDiv);
	  }

		return;
	}

	var x = Math.floor(Lat49.Tile.lonToXAtZ(lon, adzl));
	var y = Math.floor(Lat49.Tile.latToYAtZ(lat, adzl));

	this.updateAdByTile(divId, x, y, adzl);
}

//
// The following are the pixel-space/geospace transform-related methods.
//

Lat49.AdHelper.prototype.setScreenSpace = function(width, height) {
	this.screenWidth = width;
	this.screenHeight = height;
	this.computeZoomLevel();
}

Lat49.AdHelper.prototype.setLatLonSpace = function(latmin, lonmin, latmax, lonmax, proj) {
	this.latmin = latmin;
	this.lonmin = lonmin;
	this.latmax = latmax;
	this.lonmax = lonmax;
	while (this.lonmin > this.lonmax)
		this.lonmin -= 360;
	if (proj == undefined)
		this.proj = Lat49.projMercator;
	else
		this.proj = proj;

	this.computeZoomLevel();
}

Lat49.AdHelper.prototype.computeZoomLevel = function() {
	if ((this.screenWidth <= 0) || (this.lonmax <= this.lonmin))
		this.zoomlevel = -1;
	else {
		var lat = (this.latmin + this.latmax)/2.0;
		this.zoomlevel = Lat49.Tile.computeZoomLevel(lat, this.lonmin, lat, this.lonmax, this.screenWidth);
	}
}

Lat49.AdHelper.prototype.updateAdByPixel = function(divId, x, y) {
	if (zoomLevel != -1) {
		var lat, lon;
		switch (this.proj) {
		case Lat49.projMercator: {
			lon = this.lonmin + (this.lonmax-this.lonmin)*x/this.screenWidth;
			var yymin = Lat49.Tile.latToYAtZ(this.latmax, zoomLevel);
			var yymax = Lat49.Tile.latToYAtZ(this.latmin, zoomLevel);
			var yy = yymin + (yymax-yymin)*y/this.screenHeight;
			lat = Lat49.Tile.yToLatAtZ(yy, zoomLevel);
			break;
	}
		case Lat49.projUnprojected:
			lon = this.lonmin + (this.lonmax-this.lonmin)*x/this.screenWidth;
			lat = this.latmax + (this.latmin-this.latmax)*y/this.screenHeight;
			break;
		default:	//Unsupported projections.
			return;
		}
		this.updateAdByLatLon(divId, lat, lon, this.zoomlevel);
	}
}

Lat49.AdHelper.prototype.cycleAdsForScreen = function(divId, interval) {
	var key = divId+'-'+this.num;
	if (Lat49.cycleTimers[key] == undefined) {
		Lat49.cycleTimers[key] = new Lat49.CycleTimer(this, divId);
	}

	Lat49.cycleTimers[key].setCycleInterval(interval);
}

// See note in Lat49.initAds()
Lat49.fetchJSDependencies();

