// =============================================================================
// (c) 2008 MapJack.com
// Author: Bjorn Moren. bjorn@mapjack.com
// =============================================================================

var _dotOverlay = null;              // Dots overlay (google.maps.TileLayerOverlay)
var _dotOverlayVisible = true;
var _dotLayer = null
var _avatar = null;                  // Current position (google.maps.Marker)
var _beam = null;
var _beamDrag = null;
var _avatarImages = new Array();     // GIF images that makes up the avatar
//var _mapServer = "http://cpgimg.com/pano-tmp/dots/";
//var _localMapServer = "http://cpgimg.com/pano-tmp/dots/";
var _imageServer = "http://imfimg.com/images/pano/";
var _avatarLat = 0;
var _avatarLon = 0;
var _avatarHeading = 0;
var _beamAngle = 90;
var _markers = new Array();

var _beamLength = 30;
var _canDragMap = true;
var _isDraggingBeam = false;
var _beamDragDist = 10;

var _dotOpacityForSat = [7,7,7,7,7,7,7,5,5,5,6,6,6,6,6,8,10,10,10,10];      // Dot opacity for the zoom levels, 0 - 10
var _dotOpacityForMap = [4,4,4,4,4,4,6,6,6,6,6,6,6,7,7,7,8,8,8,8];

var _mapEncodeChars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789";

var crossIcon = "<div style='{position:relative;top:-20px;left:10px}' ><img src='/images/mapicon/shadow.png'></div>";
var beamImg = "<div class='avatarbeam'><img src='" + _imageServer + "BeamDrag.gif"  + "' /></div>";
var prevAvatarIcon;
var crossShape;
var currentShape;
var previousLoc = null;
var northBound = null;
var southBound = null;
var eastBound = null;
var westBound = null;

var _flagDrag = null;

function createAvatar(lat, lng, idx) {
    var avatarIcon = "<div class='avatar' ><img src='" + _avatarImages[idx].src  +"' /></div>";

	_avatar = MapLIB.addPushpin({pinHTML: avatarIcon,
							pinIMG: _avatarImages[idx].src,
							lat:lat,
							lng:lng,
		 					viewPoint: '',
							zIndex:2000,
		 					id:"AVATAR"});
}

function removeAvatar() {
	if(_avatar) {
		MapLIB.getMapInstance().DeleteShape(_avatar);
		_avatar = null;
	}
}

function createBeamDrag(lat, lng) {
	_beamDrag = MapLIB.addPushpin({pinHTML: beamImg,
							pinIMG: _imageServer + "BeamDrag.gif",
		 					viewPoint: '',
		 					id:"AVATAR_BEAM"});
}

function switchInit(initLat, initLng, code) {
	createAvatar(initLat, initLng, 0);
	
	zoomEndHandler();

   	if(code && code != "")
   		navigateToEncoded(code);
   	else
   		navigateTo(initLat, initLng);
}

function initAvatarIcons() {
	_startPos = mapDecodePosition("rZEsXa8NYFMD"); // don't remove it

    for (var i = 0; i < 8; i++) {
        var image = new Image();
        image.src = _imageServer + "Avatar" + i + ".gif";
        _avatarImages[_avatarImages.length] = image;
    }
}

function removePanOverlays() {
	removeAvatar();

	if(_beam) {
		map.DeleteShape(_beam);
		_beam = null;
	}
	_avatarImages = [];
}
/* ************************************************************************ */

function beamDragStartHandler() {
    _isDraggingBeam = true;
}

function beamDragEndHandler() {
	try {
		_beamDrag.Hide();
	} catch(e) {}

    _isDraggingBeam = false;
}

function beamDragHandler() {
    var beamPos = _beamDrag.GetPoints();
    var avatarPos = _avatar.GetPoints();
    var dragAng = 180 + 180 * Math.atan2(avatarPos[0].Longitude - beamPos[0].Longitude, avatarPos[0].Latitude - beamPos[0].Latitude) / Math.PI;

    _avatarHeading = dragAng;
    updateBeam();
    updateAvatar();

    turnTo(_avatarHeading);
}

function initModeHandler() {
}

function endPanHandler(e) {
	if(!mjStreetView.isStreetView)
		MapLIB.streetSceneButton();
}

function MetadataCallback(metaData) {
   alert("Imagery date range: " + metaData.DateRangeStart + " - " + metaData.DateRangeEnd);
}

function mouseDownHandler(e) {
	// if infobox is open, close it
	MapLIB.removeInfoBox();
	
	mjStreetView.downX = e.mapX;
	mjStreetView.downY = e.mapY;

	currentShape = map.GetShapeByID(e.elementID);

	if(e.elementID && currentShape._can_id == 'AVATAR') {
		avatarDragStartHandler();
		//crossShape = new VEShape(VEShapeType.Pushpin, map.PixelToLatLong(new VEPixel(e.mapX, e.mapY)));
		//crossShape.SetCustomIcon(crossIcon);
		//map.AddShape(crossShape);

		if(currentShape.GetType() == VEShapeType.Pushpin) {
		    mjStreetView.isAvatarMoving = true;
			preAvatarIcon = currentShape.GetCustomIcon().CustomHTML;
			var movingHTML = preAvatarIcon.replace('avatar', 'movingavatar');
		    currentShape.SetCustomIcon(movingHTML);
		    currentShape.SetPoints(map.PixelToLatLong(new VEPixel(e.mapX, e.mapY)));
		    map.vemapcontrol.EnableGeoCommunity(true);
		} 
		else {
		    currentShape = null;
		}
	} 
	else if(e.elementID && currentShape._can_id == 'AVATAR_BEAM') {
		MapLIB.vars.isClickedAvatarBeam = true;
	}
	else if(e.elementID && currentShape._can_id == 'FLAG') {
		_flagDrag = currentShape;	
	}

	MapLIB.vars.isMouseDown = true;
    MapLIB.vars.isCustomStartPan = false;
}

function mouseUpHandler(e) {
	if(mjStreetView.isAvatarMoving) {
		avatarDragEndHandler();

		mjStreetView.isAvatarMoving = false;
		currentShape.SetCustomIcon(preAvatarIcon);
		currentShape = null;
		map.vemapcontrol.EnableGeoCommunity(false);
	}

	// the same as endpan event
	if(MapLIB.vars.isMouseDown && MapLIB.vars.isCustomStartPan && !(mjStreetView.downX == e.mapX && mjStreetView.downY == e.mapY)) {
		if(mjStreetView.options.pageType == 'M' || mjStreetView.options.pageType == 'MS') {
			if(iMap.isRefreshMapOn) { 
				if(mjStreetView.options.pageType == 'MS' && (searchCriteria.sicCode != "" || searchCriteria.name != "")) {					
			    	searchCriteria.eventFired = 1;
			    	iMap.doIMapQuery(1);
				}
				else if(mjStreetView.options.pageType == 'M')
					iMap.doIMapQuery(1);
			}
			else if(!mjStreetView.isStreetView)
				Webcam.getWebcamMarkers();
		} 
		else if(mjStreetView.options.pageType == 'PS' || mjStreetView.options.pageType == 'RL') {
			flagDragEndHandler(e);			
			return false;// nothing
		}
		else {
			if(!mjStreetView.isStreetView)
				if(typeof Webcam !== 'undefined')
					Webcam.getWebcamMarkers();
		}

		setPanBounds();
	}
	
	// they should be reset here not inside of above block
	MapLIB.vars.isMouseDown = false;
    MapLIB.vars.isClickedAvatarBeam = false;   
    flagDragEndHandler(e);
}

function flagDragEndHandler(e) {
	if (_flagDrag!=null) {
		var newCenter = [];    
		newCenter[0] = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));			
		setTimeout(function() {
			map.PanToLatLong(new VELatLong(newCenter[0].Latitude, newCenter[0].Longitude));
		}, 500);
		
		if (searchCriteria!=null && searchCriteria!=undefined) {
			searchCriteria.eventFired = 0;
			searchCriteria.centerLat = newCenter[0].Latitude;
			searchCriteria.centerLng = newCenter[0].Longitude;
		}
    }    
	_flagDrag = null;
}

function flagDragHandler(e) {
	var x = e.mapX;
    var y = e.mapY;
    pixel = new VEPixel(x, y);
    var LL = map.PixelToLatLong(pixel);
    _flagDrag.SetPoints(LL);
}

function mouseMoveHandler(e) {
	// sometimes unhightbox doesn't work even with mouseout event so it remove hightlighted icon on mousemove event
	if(e.elementID == null && hShape != null) {
		unhighlightBox(highlightIndex);
	}
	
	if (_flagDrag!=null) {
	    flagDragHandler(e);
	    return true;
	}	
	
	// it plays role as a startpan event
    if(MapLIB.vars.isMouseDown && !MapLIB.vars.isCustomStartPan) {
    	if(!mjStreetView.autoPan && !mjStreetView.isStreetView) {
			mjStreetView.isTileDownloaded = false;
		} 
        MapLIB.vars.isCustomStartPan = true; // only once per pan.
    }
    
	if(!_avatar) {	
		return;
	}	


    //if(MapLIB.vars.isMouseDown && MapLIB.vars.isClickedAvatarBeam) {
    //	beamDragHandler();
    //}
	var loc = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
    var latVariance = 0;
    var longVariance = 0;
    var panAmount = 10;
    var movingDirection = '';

    if(mjStreetView.isAvatarMoving) {
        currentShape.SetPoints(loc);

        //determine direction
        if(previousLoc){
            latVariance = loc.Latitude - previousLoc.Latitude
            longVariance = loc.Longitude - previousLoc.Longitude

            if(latVariance > 0)
                movingDirection = 'north';
            else if(latVariance < 0)
            	movingDirection = 'south';

            if(longVariance > 0)
                movingDirection = 'east';
            else if(longVariance < 0)
                movingDirection = 'west';
        }

        //pan map
        if((loc.Latitude < southBound) && movingDirection == 'south') {
        	mjStreetView.autoPan = true;
        	map.Pan(0, panAmount);
        }
        if((loc.Latitude > northBound) && movingDirection == 'north') {
        	mjStreetView.autoPan = true;
        	map.Pan(0, panAmount * -1);
        }
        if((loc.Longitude < westBound) && movingDirection == 'west') {
        	mjStreetView.autoPan = true;
        	map.Pan(panAmount * -1, 0);
        }
        if((loc.Longitude > eastBound) && movingDirection == 'east') {
        	mjStreetView.autoPan = true;
        	map.Pan(panAmount, 0);
        }

        previousLoc = loc;
    }
}

function mouseOutHandler(e) {
	if(e.elementID != null) {
		var shape = map.GetShapeByID(e.elementID);

		// highlighted pin
		if(shape._can_type == 'H-PIN') {
			unhighlightBox(highlightIndex);
			clearTimeout(t);
		}
	}
}

function mouseOverHandler(e) {
	if(e.elementID != null) {
		var shape = map.GetShapeByID(e.elementID);

		// mouse might keep hovering until users move out mouse 
		if(hShape != null && hShape.GetID() == shape.GetID()) {
			return true;
		}
		else if(shape._can_type != 'PIN') {
			return true;
		}
		else {
			var pinIdx = shape._can_id;
			var letter = MapLIB.getPinLetter(pinIdx);
			
			var pinHTML = MapLIB.getPinHTML(letter, true);
			var pinIMG = MapLIB.getPinIMG(letter, true);					

			var ll = shape.GetPoints();

			try { 
				if(highlightIndex > 0) 
					unhighlightBox(highlightIndex);
			} 
			catch(e) {}

			hShape = MapLIB.addPushpin({
				lat: ll[0].Latitude,
				lng: ll[0].Longitude,
				beakOffsetX:shape._can_beakOffsetX,
				beakOffsetY:shape._can_beakOffsetY,				
				pinHTML: pinHTML,
			 	pinIMG: pinIMG,
			 	id: pinIdx,
			 	type:"H-PIN",
			 	viewPoint:shape._can_viewPoint,
			 	title: shape.GetTitle(),
			 	desc: shape.GetDescription()});
			
			//highlightIndex = pinIdx;
			// for mySask411, no auto showListingBox on mouseOver, show on mouse click instead
			if (getImpID()!=15){
				showListingBox(pinIdx);
			}
			highlightBox(pinIdx);
		}
		
		return true;  
	}
}

// Handles user clicks on the map
function mouseClickHandler(e) {
	var map = MapLIB.getMapInstance();

	// as map is moved by dragging map, click event is fired.
	// So in order to identify click and dragging, keep point as of mousedown event.
	if(mjStreetView.downX == e.mapX && mjStreetView.downY == e.mapY) {
		if(e.elementID != null) {
			var shape = map.GetShapeByID(e.elementID);	
			// show infobox for orange pins and webcams
			if(!mjStreetView.isStreetView && (shape._can_type == 'H-PIN' || shape._can_type.indexOf('WEBCAMS') >= 0)) {
				if(!e.leftMouseButton) {
					/*
					if(shape._can_type == 'WEBCAMS-M') {
						document.getElementById('baseCSS').href = '/css/style_traffic.css';
						map.ShowInfoBox(shape);
					} else {
						document.getElementById('baseCSS').href = '/css/style.css';
						map.ShowInfoBox(shape);
					}
					*/
				} else {
					//alert(e.elementID);
					MapLIB.showInfoBox(shape, e);				
				}
			}

			// don't move over traffic or web cameras
			if(shape._can_type.indexOf('WEBCAMS') >= 0) {
				return true;
			}
			
		    if(mjStreetView.isStreetView && e.leftMouseButton) {
		    	if(shape && shape._can_viewPoint) {
		    		navigateToEncoded(shape._can_viewPoint);
		    	}
		    	else if(shape) {
		    		var points = shape.GetPoints();
		    		mapNavigateTo(points[0].Latitude, points[0].Longitude);
		    	}
		    	else {
		        	var ll = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
		        	mapNavigateTo(ll.Latitude, ll.Longitude);
		    	}
		  	}
		}
		// for now, there is no 'Street Scene' for 'People Search', 'Reverse Lookup' and 'Traffic & Directions'. May 28, 2009
		else if(mjStreetView.options.pageType == 'PS' || mjStreetView.options.pageType == 'RL') {
			return true;
		}
		else if(mjStreetView.options.pageType == 'MS' && iMap.isSetCenterClicked) {	// Map Search
			mapNavMessage(orgSetCenterMsg);
			hideResult();
			hideListing();
			searchCriteria.sicCode = "";
			searchCriteria.name = "";
			iMap.clearMarkers(true);	// including flag shape
			
			var newCenter = [];
			newCenter[0] = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
				
			if(flagPushPin != null)
				map.DeleteShape(flagPushPin);

			panTo(newCenter[0].Latitude, newCenter[0].Longitude);
			//map.SetCenter(newCenter[0].Latitude, newCenter[0].Longitude);
			
			// flagPushPin is defined in bing_ms_v1.js 
			flagPushPin = MapLIB.addPushpin({pinHTML: flagShapeIcon,
				pinIMG: "http://imfimg.com/static/0/img/mapicon/icon_flag.png",
				lat:newCenter[0].Latitude,
				lng:newCenter[0].Longitude,
				id:"FLAG"});			

			iMap.isSetCenterClicked = false;
		}
		else if(mjStreetView.isStreetView) {
	    	var ll = map.PixelToLatLong(new VEPixel(e.mapX, e.mapY));
	    	mapNavigateTo(ll.Latitude, ll.Longitude);
		}
	}
}

// in IE, doublclick triggers mousemove event which must be bug.
function doubleClickHandler(e) {
	if(map.GetZoomLevel() == 19) {	// maixmum
		return true;
	}
	else {
		// there is a little time delay to remove beak completely 
		setTimeout(function(){MapLIB.removeInfoBox();}, 300);
	}
}

// Handles mouse drags of avatar
// If Birds eye view style is selected, this is called 
function zoomEndHandler(e) {
	MapLIB.removeInfoBox();

	for(var i = 19; i >= 1; i--) {
		if(i == map.GetZoomLevel())
			jQuery('#zoomScale' + i).get(0).src = "/images/zoomstep_on.gif";
		else
			jQuery('#zoomScale' + i).get(0).src = "/images/zoomstep_off.gif";
	}	
	
	if(mjStreetView.options.pageType == 'PS' || mjStreetView.options.pageType == 'RL')
		return false;

	if((mjStreetView.options.pageType == 'M' || mjStreetView.options.pageType == 'MS') && !iMap.isZoomIgnored && !mjStreetView.toggling) {
		if(iMap.isRefreshMapOn && mjStreetView.options.pageType != 'D') {
			if(mjStreetView.options.pageType == 'MS' && (searchCriteria.sicCode != "" || searchCriteria.name != "")) { 
				searchCriteria.eventFired = 1;
				iMap.doIMapQuery(1);
			}
			else if(mjStreetView.options.pageType == 'M')
				iMap.doIMapQuery(1);
		}
		else if(!mjStreetView.isStreetView)
			Webcam.getWebcamMarkers();	
	} 
	else if(mjStreetView.options.pageType == 'D' && !mjStreetView.isStreetView) {
		if(typeof Webcam !== 'undefined')
			Webcam.getWebcamMarkers();
	}
	
	if(mjStreetView.isStreetView) {
	  var avatarPos = _avatar.GetPoints();
	  var pixPos = map.LatLongToPixel(avatarPos[0]);
	  var offsetPos = map.PixelToLatLong(new VEPixel(pixPos.x + _beamLength, pixPos.y));
	  _beamDragDist = MapLIB.veGetDistance(avatarPos, offsetPos, false);

	  updateBeam();
	}
	else {
		MapLIB.streetSceneButton();
	}
	
	if(mjStreetView.toggling)
		mjStreetView.toggling = false;
	
	//if(mjStreetView.options.pageType == 'M' && iMap.isInitZoomChanged)
	//	iMap.isInitZoomChanged = false;
	if(typeof iMap !== 'undefined' && iMap.isZoomIgnored)
		iMap.isZoomIgnored = false;
}

function setPanBounds() {
    var view = map.GetMapView();
    var topLeft = map.LatLongToPixel(view.TopLeftLatLong);
    var bottomRight = map.LatLongToPixel(view.BottomRightLatLong);
    
    var NBound = topLeft.x + 30;
    var SBound = bottomRight.x - 30;
    var EBound = bottomRight.y - 30;
    var WBound = topLeft.y + 30;
    
    var topLeftBound = map.PixelToLatLong(new VEPixel(NBound, WBound));
    var bottomRightBound = map.PixelToLatLong(new VEPixel(SBound, EBound));
    
    northBound = topLeftBound.Latitude;
    southBound = bottomRightBound.Latitude;
    westBound = topLeftBound.Longitude;
    eastBound = bottomRightBound.Longitude;
}

function showDots(show) {
    if (!_dotOverlay)
    	return false;

    if(show)
    	_dotOverlay.show(); 
    else 
    	_dotOverlay.hide();

    return true;
}

function updateMap(lat, lon, heading, viewAngle) {
    if (_isDraggingBeam) 
    	return false;
    /*
    if(!_avatar) {
		createAvatar(lat, lon, 0);
		createBeamDrag(lat, lon);
	}
	*/
    _avatarLat = lat;
    _avatarLon = lon;
    _avatarHeading = heading;
    _beamAngle = viewAngle;

    updateAvatar();
    updateBeam();

    return true;
}

// Called by the panorama when position or heading has changed
function updateAvatar() {
    if (!_avatar) 
    	return;

    MapLIB.updatePushpin({
    		shape: _avatar,
    		lat: _avatarLat,
    		lng: _avatarLon,
    		pinHTML: "<div class='avatar'><img src='" + _avatarImages[Math.round(_avatarHeading / 45) % 8].src  + "'></div>", 
    		pinIMG: _avatarImages[Math.round(_avatarHeading / 45) % 8].src});
    
    panVisible(_avatarLat, _avatarLon);
    setPanBounds();
}

//Makes sure a position is visible on the map
function panVisible(lat, lon) {
	var view = MapLIB.getMapInstance().GetMapView();
	
	var latDelta = (view.TopLeftLatLong.Latitude - view.BottomRightLatLong.Latitude) / 4;
	var lngDelta = (view.BottomRightLatLong.Longitude - view.TopLeftLatLong.Longitude) / 6;
	
	if (lat < view.BottomRightLatLong.Latitude + latDelta || lat > view.TopLeftLatLong.Latitude - latDelta ||
	     lon < view.TopLeftLatLong.Longitude + lngDelta || lon > view.BottomRightLatLong.Longitude - lngDelta) {
		MapLIB.getMapInstance().SetCenter(new VELatLong(lat, lon));
	}
}

function updateBeam() {
    if (!_avatar || (_avatarLat == 0 && _avatarLon == 0)) {
    	return;
    }

    if (_beam) 
    	map.DeleteShape(_beam);
    
    _beam = null;
    
    /*if (map.getZoom() <= 12) 
    	return;  */
    var roundNess = parseInt(_beamAngle / 10);
    if (roundNess < 2) 
    	roundNess = 2;

    var avatarPoint = (_avatar.GetPoints())[0];
    var center = map.LatLongToPixel(avatarPoint);//map.fromLatLngToDivPixel(_avatar.getPoint());
    var beamAngle = _beamAngle * Math.PI / 180;
    var heading = _avatarHeading * Math.PI / 180;
    var points = [] ;// new Array();
    points.push(avatarPoint);
    for (var i = 0; i <= roundNess; i++)  {
        var ang = heading + (beamAngle * i / roundNess) - (beamAngle / 2);
        var x = Math.sin(ang) * _beamLength;
        var y = -Math.cos(ang) * _beamLength;
        var p = map.PixelToLatLong(new VEPixel(x + center.x, y + center.y)); //map.fromDivPixelToLatLng(new GPoint(x + center.x, y + center.y));
        points.push(p);
    }
    points.push(avatarPoint);

    _beam = MapLIB.addPolygon({
    	points:points,
    	lineColor:{opacity:1,R:102,G:102,B:255},
    	fileColor:{opacity:0.1,R:170,G:170,B:170},
    	lineWidth:1
    });
}

// Calls the panorama application to move to a coordinate
function mapNavigateTo(lat, lon) {
    navigateTo(lat, lon, true);
}

// Handles mouse drags of avatar
function avatarDragStartHandler() {
    if (_beam) 
    	map.DeleteShape(_beam);
    
    _beam = null;
}

// Handles mouse drags of avatar
function avatarDragEndHandler() {
    var point = _avatar.GetPoints();
    mapNavigateTo(point[0].Latitude, point[0].Longitude);
}

function mapDecodePosition(code) {
  if (code == null || code.length < 10) return null;
	var result = new Object();
	
	var latVal = mapDecodeInt(code.substr(0, 5));
	result.lat = (latVal / 1000000.0) - 180.0;

	var lonVal = mapDecodeInt(code.substr(5, 5));
	result.lon = (lonVal / 1000000.0) - 180.0;

	return result;
}

function mapDecodeInt(code) {
	var result = 0;
	for (var i = code.length - 1; i >= 0; i--)
	{
		var charNo = _mapEncodeChars.indexOf(code.substr(i, 1));
		if (charNo < 0 || charNo >= _mapEncodeChars.length) return 0;
		result = result * _mapEncodeChars.length + charNo;
	}
	return result;
} 

function getImpID(){
	return document.getElementById('iMap_imp').innerHTML;
}

