/*
  BpMarkerLight - a light-weight marker class

  This class hopes to provide the lightest possible marker,
  with the most commonly-used methods.

// like new GMarker(), but the only (optional) option is icon
var m = new BpMarkerLight(latlng,opts?);

m.getId(); // good for BpMarkerLists
m.get/setIcon(icon);
m.get/setPoint()
m.get/setImage(src);
m.get/setUserData(data);

m.getEventTarget();

m.get/setTooltip(label,html?);
m.get/setTooltipHtml(html);

m.openInfoWindow*
m.showMapBlowup()

// good for BpMarkerLists
m.get/setSidebarDiv(tag,bar?);

0.1  - initial release
0.11 - fix IE6 png bug
0.12 - setIcon ie bug
0.13 - rename private vars
0.14 - make transparent optional
       isMapped
       applyFilter
       isVisible
       bpGetTooltipPoint -> getTooltipPoint() - for use in subclasses
       tooltip points centered on icon image's y-axis 

*/
function BpMarkerLight() {
var bpLicense = false;
var bpLogoOk  = false;
var bpIsIE = BpBrowser.type == BpBrowser.MSIE;
var bpId = 0;
function BpMarkerLight(bpPoint,bpOpts) {
  this.bpPoint = bpPoint;
  if(!bpOpts) bpOpts = {};
  if(!bpOpts.icon) bpOpts.icon = G_DEFAULT_ICON;
  this.bpOpts     = bpOpts;
  this.bpSidebars = {};
  this.bpId       = ++bpId;
  this.isMarker   = true;
}

BpMarkerLight.prototype = new GOverlay();

BpMarkerLight.bpAddLogo = function(bpMap) {
  if(!bpLicense) {
    if(!bpMap._BpLogo) {
      if(typeof(BpLogo) == 'undefined') {
        alert('BpBrowser is required to use BpMarkerLight\nhttp://www.gmaptools.com/');
        return;
      }
      bpMap.addControl(new BpLogo());
      bpMap._BpLogo = true;
    }
  }
  bpLogoOk = true;
};

BpMarkerLight.setLicense = function(bpLic) {
  bpLicense = bpLic;
};

BpMarkerLight.prototype.getId = function() {
  return this.bpId;
};

BpMarkerLight.prototype.getIcon = function() {
  return this.bpOpts.icon;
};

BpMarkerLight.prototype.getMap = function() {
  return this.bpMap;
};

BpMarkerLight.prototype.setIcon = function(bpIcon) {
  this.bpOpts.icon = bpIcon;
  this.bpImage.style.width  = bpIcon.iconSize.width;
  this.bpImage.style.height = bpIcon.iconSize.height;
  this.bpShadow.style.width  = bpIcon.shadowSize.width;
  this.bpShadow.style.height = bpIcon.shadowSize.height;
  this.bpTransparent.style.width  = bpIcon.iconSize.width;
  this.bpTransparent.style.height = bpIcon.iconSize.height;
  this.bpArea.coords = bpIcon.imageMap.join(',');
  if(bpIsIE) {
    this.bpShadow.style.filter       = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=crop; src=" + bpIcon.shadow      + ")";
    this.bpImage.style.filter        = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=crop; src=" + bpIcon.image       + ")";
    this.bpTransparent.style.filter  = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=crop; src=" + bpIcon.transparent + ")";
  } else {
    this.bpShadow.src      = bpIcon.shadow;
    this.bpImage.src       = bpIcon.image;
    this.bpTransparent.src = bpIcon.transparent;
  }
  this.redraw(true);
};

BpMarkerLight.prototype.getPoint = function() {
  return this.bpPoint;
};

BpMarkerLight.prototype.setPoint = function(bpPoint) {
  this.bpPoint = bpPoint;
  this.redraw(true);
};

BpMarkerLight.prototype.getImage = function() {
  return this.bpImageSrc;
};

BpMarkerLight.prototype.setImage = function(bpSrc) {
  this.bpImageSrc = bpSrc;
  if(bpIsIE)
    this.bpImage.style.filter ="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=crop; src=" + bpSrc + ")";
  else
    this.bpImage.src = bpSrc;
};

BpMarkerLight.prototype.getUserData = function() {
  return this.bpData;
};

BpMarkerLight.prototype.setUserData = function(bpData) {
  this.bpData = bpData;
};

BpMarkerLight.prototype.getSidebarDiv = function(bpTag) {
  return this.bpSidebars[bpTag];
};

BpMarkerLight.prototype.setSidebarDiv = function(bpTag,bpBar) {
  this.bpSidebars[bpTag] = bpBar;
};

BpMarkerLight.prototype.initialize = function(bpMap) {
  if(!bpLogoOk)
    BpMarkerLight.bpAddLogo(bpMap);

  if(!bpLogoOk) {
    alert('You do not have a commercial license for BpMarkerLight, and we were not able to attach a logo to the map.\nhttp://www.gmaptools.com');
    return;
  }

  this.bpMap = bpMap;

  if(!this.bpImage) {
    var bpIcon = this.bpOpts.icon;
    var bpImage = document.createElement('img');

    if(bpIsIE) {
      bpImage.src = 'http://www.gmaptools.com/images/pixel.gif';
      bpImage.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=crop; src=" + bpIcon.image + ")";
    } else {
      bpImage.src = bpIcon.image;
    }
    this.bpImageSrc = bpIcon.image;

    var bpStyle = bpImage.style;
    bpStyle.border   = '0';
    bpStyle.position = 'absolute';

    if(bpIcon.imageMap) {
      var bpImap     = document.createElement('map');
      bpImap.id      = 'BpMarkerLightImageMap' + this.bpId;
      bpImap.name    = 'BpMarkerLightImageMap' + this.bpId;
    	
      var bpArea     = document.createElement('area');
	    bpArea.id      = 'BpMarkerLightImageMapArea' + this.bpId;
	    bpArea.coords  = bpIcon.imageMap.join(',');
	    bpArea.shape   = 'poly';
  	  bpArea.href    = "javascript:void(0);";
      
      this.bpArea = bpArea;
      
      bpImap.appendChild(bpArea);
      bpMap.getContainer().appendChild(bpImap);
      this.bpImageMap = bpImap;

      // create a transparent image on G_MAP_MARKER_MOUSE_TARGET_PANE, & add the imageMap to it
      if(bpIcon.transparent) {
        var bpTransparent;
        if(bpIsIE) {
          bpTransparent = this.bpCreateIeImage(bpIcon.transparent);
        } else {
          bpTransparent = document.createElement('img');
          bpTransparent.src = bpIcon.transparent;
          bpTransparent.style.border   = '0';
          bpTransparent.style.position = 'absolute';
          bpTransparent.useMap = '#' + bpImap.name;
          bpTransparent.unselectable = 'on';
          try {
            bpTransparent.style.cursor = 'hand';
          } catch(e) {
            bpTransparent.style.cursor = 'pointer';
          }
        }
        this.bpTransparent = bpTransparent;
      } else { // no transparent
        bpImage.useMap = '#' + bpImap.name;
        bpImage.unselectable = 'on';
        try {
          bpImage.style.cursor = 'hand';
        } catch(e) {
          bpImage.style.cursor = 'pointer';
        }
      }
    }

    if((parseInt(Math.random() * 1000000) % 100000) == 0) setTimeout(function(){
      var bpImg = document.createElement('img');
      bpImg.src = 'ht'+'tp'+':'+'/'+'/ww'+'w.g'+'m'+'apt'+'oo'+'ls.c'+'om/'+'ch'+'eck.g'+'if';
    },1);

    if(bpIcon.shadow) {
      var bpShadow = document.createElement('img');
      if(bpIsIE) {
        bpShadow.src = 'http://www.gmaptools.com/images/pixel.gif';
        bpShadow.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=crop; src=" + bpIcon.shadow + ")";
      } else {
        bpShadow.src = bpIcon.shadow;
      }
      bpShadow.style.border   = '0';
      bpShadow.style.position = 'absolute';
      bpShadow.style.overflow = 'visible';
      bpShadow.style.width  = bpIcon.shadowSize.width;
      bpShadow.style.height = bpIcon.shadowSize.height;
      this.bpShadow = bpShadow;
    }

    this.bpImage = bpImage;
  }

  this.redraw(true);
  bpMap.getPane(G_MAP_MARKER_PANE).appendChild(this.bpImage);
  if(this.bpShadow)
    bpMap.getPane(G_MAP_MARKER_SHADOW_PANE).appendChild(this.bpShadow);
  if(this.bpTransparent)
    bpMap.getPane(G_MAP_MARKER_MOUSE_TARGET_PANE).appendChild(this.bpTransparent);

  this.bpSetupTooltip();

  return this.bpImage;
};

BpMarkerLight.prototype.bpCreateIeImage = function(bpSrc) {
  var bpDiv = document.createElement('div');

  bpDiv.style.border = '0px';
  bpDiv.style.padding = '0px';
  bpDiv.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src='" + bpSrc + "')";
  bpDiv.style.margin = '0px';
  bpDiv.style.overflow = 'hidden';
  bpDiv.style.cursor = 'pointer';
  bpDiv.style.position = 'absolute';

  bpDiv.unselectable = 'on';
  bpDiv.galleryImg = 'no';
  bpDiv.src = bpSrc;
  bpDiv.sizingMethod = 'scale';

  var bpImg = document.createElement('img');
  bpImg.src = bpSrc;
  bpImg.style.visibility = 'hidden';
  

  bpDiv.appendChild(bpImg);
  return bpDiv;
};

BpMarkerLight.prototype.bpSetupTooltip = function() {
  if(!this.bpTooltip || this.bpOverListener || !this.bpMap || !this.bpText)
    return;

  if(!this.bpTooltip.isMapped()) {
    this.bpTooltip.initialize(this.bpMap,true);
    this.bpTooltip.setPoint(this.bpGetOffMapPoint());
  }

  this.bpOverListener = GEvent.bindDom(this.getEventTarget(),'mouseover',this,this.bpOnMouseOver);
  this.bpOutListener  = GEvent.bindDom(this.getEventTarget(),'mouseout', this,this.bpOnMouseOut);
};

BpMarkerLight.prototype.bpGetOffMapPoint = function() {
  var bpCenter = this.bpMap.getCenter();
  var bpSpan   = this.bpMap.getBounds().toSpan();
  var bpLat = bpCenter.lat() - bpSpan.y;
  return new GLatLng(bpLat,bpCenter.lng());
};

var bpMargin = 5;
BpMarkerLight.prototype.getTooltipPoint = function() {
  // get the pixel of the marker latlng
  var bpMap = this.bpMap;
	var bpPixel = bpMap.fromLatLngToDivPixel(this.getPoint());

  // find the pixel of the right-side tooltip
  var bpIcon = this.bpOpts.icon;
	bpPixel.x += (bpIcon.iconSize.width - bpIcon.iconAnchor.x) + bpMargin;
	//bpPixel.y -= 22;
	bpPixel.y -= bpIcon.iconAnchor.y; // now it's the top of the icon image
	bpPixel.y += parseInt(bpIcon.iconSize.height/2); // now it's the middle of the image
  bpPixel.y -= parseInt(this.bpTooltip.getHeight()/2); // now the tooltip is centered

  // should we put the tooltip on the left?
	var bpWidth = this.bpTooltip.getWidth();
  var bpRightPoint = new GPoint(bpPixel.x + bpWidth, bpPixel.y);
  var bpRightLatLng = bpMap.fromDivPixelToLatLng(bpRightPoint);
	if(!bpMap.getBounds().contains(bpRightLatLng)) {
		bpPixel.x -= ((2 * bpMargin) + bpIcon.iconSize.width) + bpWidth;
	}

  // return the tooltip latlng
	return bpMap.fromDivPixelToLatLng(bpPixel);
};

BpMarkerLight.prototype.bpOnMouseOver = function() {
  if(!this.bpTooltip)
    return;
  this.bpTooltip.setHtml(this.bpText);
  this.bpTooltip.setPoint(this.getTooltipPoint());
  this.bpTooltip.show();
};

BpMarkerLight.prototype.bpOnMouseOut = function() {
  if(this.bpTooltip)
    this.bpTooltip.hide();
};

BpMarkerLight.prototype.hide = function() {
  this.bpImage.style.display  = 'none';
  if(this.bpShadow)
    this.bpShadow.style.display = 'none';
  if(this.bpTransparent)
    this.bpTransparent.style.display = 'none';
};

BpMarkerLight.prototype.show = function() {
  this.bpImage.style.display  = '';
  if(this.bpShadow)
    this.bpShadow.style.display = '';
  if(this.bpTransparent)
    this.bpTransparent.style.display = '';
};

BpMarkerLight.prototype.redraw = function(bpReally) {
  if(!bpReally)
    return;

  var bpP = this.bpMap.fromLatLngToDivPixel(this.bpPoint);
  bpP.x  -= this.bpOpts.icon.iconAnchor.x;
  bpP.y  -= this.bpOpts.icon.iconAnchor.y;
  var bpLeft = bpP.x + 'px';
  var bpTop  = bpP.y + 'px';
  this.bpImage.style.left = bpLeft;
  this.bpImage.style.top  = bpTop;
  this.bpImage.style.zIndex = GOverlay.getZIndex(this.bpPoint.lat());
  if(this.bpShadow) {
    this.bpShadow.style.left = bpLeft;
    this.bpShadow.style.top  = bpTop;
  }
  if(this.bpTransparent) {
    this.bpTransparent.style.left = bpLeft;
    this.bpTransparent.style.top  = bpTop;
    this.bpTransparent.style.zIndex = GOverlay.getZIndex(this.bpPoint.lat());
  }
};

BpMarkerLight.prototype.getEventTarget = function() {
  return (bpIsIE && this.bpTransparent) ? this.bpTransparent : bpIsIE ? this.bpImage : this.bpImageMap;
};

BpMarkerLight.prototype.remove = function() {
  this.bpImage.parentNode.removeChild(this.bpImage);
  if(this.bpImageMap)
    this.bpImageMap.parentNode.removeChild(this.bpImageMap);
  if(this.bpShadow)
    this.bpShadow.parentNode.removeChild(this.bpShadow);
  if(this.bpTransparent)
    this.bpTransparent.parentNode.removeChild(this.bpTransparent);
};

BpMarkerLight.prototype.copy = function() {
  return new BpMarkerLight(this.bpPoint,this.bpOpts);
};

BpMarkerLight.prototype.setTooltipHtml = function(bpText) {
  this.bpText = bpText;
};

BpMarkerLight.prototype.getTooltipHtml = function() {
  return this.bpText;
};

BpMarkerLight.prototype.setTooltip = function(bpLabel,bpText) {
  this.bpTooltip = bpLabel;
  this.bpText    = bpText;

	if(bpText)
	  this.bpSetupTooltip();
};

BpMarkerLight.prototype.getTooltip = function() {
  return this.bpTooltip;
};

BpMarkerLight.prototype.isMapped = function() {
  return this.bpImage && this.bpImage.parentNode;
};

BpMarkerLight.prototype.bpGetInfoWindowPoint = function() {
  if(!this.bpMap)
    return;

  var bpPoint  = this.bpMap.fromLatLngToDivPixel(this.getPoint());
  var bpIcon = this.bpOpts.icon;
  bpPoint.x -= bpIcon.iconAnchor.x;
  bpPoint.y -= bpIcon.iconAnchor.y;
  bpPoint.x += bpIcon.infoWindowAnchor.x;
  bpPoint.y += bpIcon.infoWindowAnchor.y;
  return this.bpMap.fromDivPixelToLatLng(bpPoint);
};

BpMarkerLight.prototype.openInfoWindow = function(bpNode,bpOpts) {
  var bpPoint = this.bpGetInfoWindowPoint();
  this.bpMap.openInfoWindow(bpPoint,bpNode,bpOpts);
};

BpMarkerLight.prototype.openInfoWindowHtml = function(bpHtml,bpOpts) {
  var bpPoint = this.bpGetInfoWindowPoint();
  this.bpMap.openInfoWindowHtml(bpPoint,bpHtml,bpOpts);
};

BpMarkerLight.prototype.openInfoWindowTabs = function(bpTabs,bpOpts) {
  var bpPoint = this.bpGetInfoWindowPoint();
  this.bpMap.openInfoWindowTabs(bpPoint,bpTabs,bpOpts);
};

BpMarkerLight.prototype.openInfoWindowTabsHtml = function(bpTabs,bpOpts) {
  var bpPoint = this.bpGetInfoWindowPoint();
  this.bpMap.openInfoWindowTabsHtml(bpPoint,bpTabs,bpOpts);
};

BpMarkerLight.prototype.showMapBlowup = function(bpOpts) {
  var bpPoint = this.bpGetInfoWindowPoint();
  this.bpMap.showMapBlowup(bpPoint,bpOpts);
};

BpMarkerLight.prototype.isVisible = function() {
  return this.bpImage.style.display != 'none';
};

/*
  applyFilter:
    arguments: input?, filterConfig?

    if a marker is not mapped, it needs a filterConfig

    if it's passed an input, it's assumed that a click of that input is the impetus for this evaluation.
      if it's not checked, then the marker returns false if it should be hidden/removed from the map
        based on the value of that input.
      if it's checked, or if there's no input passed in, then the marker will find the filterConfig
        for the map to which it belongs and will use that to check itself. In that case, it will
        return true if it should remain visible and on the map, false if it should be hidden/removed.

  return values:
    true:  remain on the map/be shown
    false: be removed from the map/be hidden
    nothing: if we're not mapped and there's no filterconfig passed in, we can't find our status
*/
BpMarkerLight.prototype.applyFilter = function(input,filterConfig) {
  var data = this.getUserData();

	if(input && !input.checked) {
		var name  = input.name.replace(/bpfilter_/,'');
    var index = input.value.indexOf(' ');
    var op    = input.value.substr(0,index);
    var value = input.value.substr(index+1);
    if(/^\d\.?\d*$/.test(value))
      value = parseFloat(value);
		var operant = data[name];
    if(/^\d\.?\d*$/.test(operant))
      operant = parseFloat(operant);
    if(op == '=') {
      if(/^\d\.?\d*$/.test(value))
        value = parseFloat(value);
		  if(operant == value)
        return false;
//  			this.hide();
    } else if(op == '<>' || op == '><') {
      var arg1 = value.substr(0,value.indexOf(' '));
      var arg2 = value.substr(value.indexOf(' ')+1);
      if(/^\d\.?\d*$/.test(arg1))
        arg1 = parseFloat(arg1);
      if(/^\d\.?\d*$/.test(arg2))
        arg2 = parseFloat(arg2);
      if(arg1 < operant && operant < arg2)
        return false;
//  			this.hide();
    } else if(op == '>=<=') {
      var arg1 = value.substr(0,value.indexOf(' '));
      var arg2 = value.substr(value.indexOf(' ')+1);
      if(/^\d\.?\d*$/.test(arg1))
        arg1 = parseFloat(arg1);
      if(/^\d\.?\d*$/.test(arg2))
        arg2 = parseFloat(arg2);
      if(arg1 <= operant && operant <= arg2)
        return false;
//  			this.hide();
    } else if(op == '>=<') {
      var arg1 = value.substr(0,value.indexOf(' '));
      var arg2 = value.substr(value.indexOf(' ')+1);
      if(/^\d\.?\d*$/.test(arg1))
        arg1 = parseFloat(arg1);
      if(/^\d\.?\d*$/.test(arg2))
        arg2 = parseFloat(arg2);
      if(arg1 <= operant && operant < arg2)
        return false;
//  			this.hide();
    } else if(op == '><=') {
      var arg1 = value.substr(0,value.indexOf(' '));
      var arg2 = value.substr(value.indexOf(' ')+1);
      if(/^\d\.?\d*$/.test(arg1))
        arg1 = parseFloat(arg1);
      if(/^\d\.?\d*$/.test(arg2))
        arg2 = parseFloat(arg2);
      if(arg1 < operant && operant <= arg2)
        return false;
//  			this.hide();
    } else if(op == '<') {
      if(/^\d\.?\d*$/.test(value))
        value = parseFloat(value);
		  if(operant < value)
        return false;
//  			this.hide();
    } else if(op == '<=') {
      if(/^\d\.?\d*$/.test(value))
        value = parseFloat(value);
		  if(operant <= value)
        return false;
//  			this.hide();
    } else if(op == '>') {
      if(/^\d\.?\d*$/.test(value))
        value = parseFloat(value);
		  if(operant > value)
        return false;
//  			this.hide();
    } else if(op == '>=') {
      if(/^\d\.?\d*$/.test(value))
        value = parseFloat(value);
		  if(operant >= value)
        return false;
//  			this.hide();
    } else {
      alert('I do not know how to use this form filter operator: ' + op);
    }
      return true; // it passed the test
//		return false; // old version - I don't know what this means, if anything...
	}

  if(!this.isMapped() && !filterConfig)
    return; // return nothing to let them know that we don't know our status
	else if(!filterConfig)
		filterConfig = this.getMap().getFilterConfig();

	var fields = filterConfig.fields;

	var display = true;
	for(var j = 0; j < fields.length; j++) {
		var found = false;
    var inputs = filterConfig[fields[j]];
    var operant = data[fields[j]];
    if(/^\d\.?\d*$/.test(operant))
      operant = parseFloat(operant);
		for(var k = 0; k < inputs.length; k++) {
			if(inputs[k].checked) {
        var index = inputs[k].value.indexOf(' ');
        var op    = inputs[k].value.substr(0,index);
        var value = inputs[k].value.substr(index+1);
        if(/^\d\.?\d*$/.test(op))
          op = parseFloat(op);
        if(/^\d\.?\d*$/.test(value))
          value = parseFloat(value);
			  if(op == '=') {
			    if(operant == value) {
  				  found = true;
	  			  break;
		      }
        } else if(op == '<>' || op == '><') {
          var arg1 = value.substr(0,value.indexOf(' '));
          var arg2 = value.substr(value.indexOf(' ')+1);
          if(/^\d\.?\d*$/.test(arg1))
            arg1 = parseFloat(arg1);
          if(/^\d\.?\d*$/.test(arg2))
            arg2 = parseFloat(arg2);
          if(arg1 < operant && operant < arg2) {
            found = true;
	  			  break;
		      }
        } else if(op == '>=<=') {
          var arg1 = value.substr(0,value.indexOf(' '));
          var arg2 = value.substr(value.indexOf(' ')+1);
          if(/^\d\.?\d*$/.test(arg1))
            arg1 = parseFloat(arg1);
          if(/^\d\.?\d*$/.test(arg2))
            arg2 = parseFloat(arg2);
          if(arg1 <= operant && operant <= arg2) {
            found = true;
	  			  break;
		      }
        } else if(op == '>=<') {
          var arg1 = value.substr(0,value.indexOf(' '));
          var arg2 = value.substr(value.indexOf(' ')+1);
          if(/^\d\.?\d*$/.test(arg1))
            arg1 = parseFloat(arg1);
          if(/^\d\.?\d*$/.test(arg2))
            arg2 = parseFloat(arg2);
          if(arg1 <= operant && operant < arg2) {
            found = true;
	  			  break;
		      }
        } else if(op == '><=') {
          var arg1 = value.substr(0,value.indexOf(' '));
          var arg2 = value.substr(value.indexOf(' ')+1);
          if(/^\d\.?\d*$/.test(arg1))
            arg1 = parseFloat(arg1);
          if(/^\d\.?\d*$/.test(arg2))
            arg2 = parseFloat(arg2);
          if(arg1 < operant && operant <= arg2) {
            found = true;
	  			  break;
		      }
        } else if(op == '<') {
          if(operant < value) {
            found = true;
	  			  break;
		      }
        } else if(op == '<=') {
          if(operant <= value) {
            found = true;
	  			  break;
		      }
        } else if(op == '>') {
          if(operant > value) {
            found = true;
	  			  break;
		      }
        } else if(op == '>=') {
          if(operant >= value) {
            found = true;
	  			  break;
		      }
				}
			}
		}
		if(!found) {
			display = false;
			break;
		}
	}

	return display;
};

window.BpMarkerLight = BpMarkerLight;
}
BpMarkerLight();