function PegControl() {
	this.map = null;
	this.defaultposition = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(13, 7));

	this.peg = null;

	this.container = null;
}

PegControl.prototype = new GControl(true, false);

PegControl.prototype.initialize = function(map) {
	this.map = map;

	var container = document.createElement('div');

	container.style.width = '49px';
	container.style.height = '52px';
	container.style.background = 'url(images/scout_sprite.png) -49px -34px no-repeat';
	container.style.cursor = 'pointer';

	this.peg = new Peg();
	this.map.addOverlay(this.peg);

	GEvent.addListener(this.peg, 'dragstop', function(panorama) {
		if(panorama != null) {
			var yaw = 0;
			if(panorama.links.length != 0)
				yaw = panorama.links[0].yaw;

			this.startSettle(panorama.location.latlng, yaw);

			GEvent.trigger(self, 'panoramaselected', panorama, panorama.location.latlng, yaw);
		}
		else {
			this.rewindSettle();
		}
	});

	var self = this;

	GEvent.addDomListener(container, 'mouseover', function() {
		container.style.backgroundPosition = '-49px -313px';
	});

	GEvent.addDomListener(container, 'mouseout', function() {
		container.style.backgroundPosition = '-49px -34px';
	});

	this.peg.installDragListener(container);

	var img = document.createElement('img');

	img.src = 'images/void.gif';
	img.style.width = '49px';
	img.style.height = '52px';

	container.appendChild(img);

	this.container = container;

	this.map.getContainer().appendChild(this.container);

	return this.container;
}

PegControl.prototype.getDefaultPosition = function() {
	return this.defaultposition;
}

PegControl.prototype.unsetPegman = function() {
	this.peg.stopSettle();
}

PegControl.prototype.setPegman = function(point, yaw) {
	this.peg.startSettle(point, yaw);
}

PegControl.prototype.hide = function() {
	this.container.style.display = 'none';
}

PegControl.prototype.show = function() {
	this.container.style.display = '';
}

function Peg() {
	this.point = null;

	this.flying = {
		started: false,
		timeout: null,
		lastlng: 0,
		dir: 'right',
		width: 56,
		height: 92,
		div: null,
		target: null,
		peg: null
	};

	this.scouting = {
		yaw: 0,
		width: 46,
		height: 34,
		div: null,
		peg: null
	};

	this.settled = {
		inuse: false,
		yaw: 0,
		point: null,
		width: 49,
		height: 52,
		div: null,
		peg: null
	};

	this.scoutingSprites = [
		{x:  0, y: 150},		// N
		{x: 98, y:  52},		// NNE
		{x:  0, y:   0},		// NE
		{x:  0, y: 469},		// NEE
		{x: 76, y: 469},		// E
		{x: 30, y: 677},		// SEE
		{x: 46, y: 901},		// SE
		{x: 46, y: 763},		// SSE
		{x: 49, y:   0},		// S
		{x: 30, y: 503},		// SSW
		{x:  0, y:  86},		// SW
		{x: 49, y: 150},		// SWW
		{x:  0, y: 763},		// W
		{x: 92, y: 901},		// NWW
		{x:  0, y: 901},		// NW
		{x: 76, y: 503}			// NNW
	];

	this.settledSprites = [
		{x: 49, y: 711},		// N
		{x:  0, y:  34},		// NNE
		{x: 98, y: 711},		// NE
		{x: 98, y: 365},		// NEE
		{x:  0, y: 365},		// E
		{x: 98, y: 417},		// SEE
		{x: 98, y: 313},		// SE
		{x: 98, y: 797},		// SSE
		{x: 98, y: 150},		// S
		{x:  0, y: 711},		// SSW
		{x:  0, y: 417},		// SW
		{x: 98, y:   0},		// SWW
		{x: 49, y: 365},		// W
		{x: 49, y: 417},		// NWW
		{x: 49, y: 849},		// NW
		{x:  0, y: 849}			// NNW
	];

	this.map = null;
	this.mode = '';

	this.svOverlay = null;
	this.svClient = null;

	this.ev = null;
}

Peg.prototype = new GOverlay();

Peg.prototype.initialize = function(map) {
	this.map = map;

	this.initializeFlying();
	this.initializeScouting();
	this.initializeSettled();

	this.svOverlay = new GStreetviewOverlay();
	this.svClient = new GStreetviewClient();
}

Peg.prototype.initializeFlying = function() {
	this.flying.div = document.createElement('div');
	this.flying.div.style.width = this.flying.width + 'px';
	this.flying.div.style.height = this.flying.height + 'px';
	this.flying.div.style.position = 'absolute';
	this.flying.div.style.cursor = 'pointer';
	this.flying.div.style.zIndex = GOverlay.getZIndex(-90.0);
	this.flying.div.style.textAlign = 'center';

	// Pegman
	this.flying.peg = document.createElement('div');
	this.flying.peg.style.width = '49px';
	this.flying.peg.style.height = '52px';
	this.flying.peg.style.background = 'url(images/scout_sprite.png) -49px -797px no-repeat';
	
	var img = document.createElement('img');
	img.src = 'images/void.gif';
	img.style.width = '49px';
	img.style.height = '52px';
	
	this.flying.peg.appendChild(img);
	this.flying.div.appendChild(this.flying.peg);

	this.flying.target = document.createElement('div');
	this.flying.target.style.width = '56px';
	this.flying.target.style.height = '40px';
	this.flying.target.style.background = 'url(images/scout_sprite.png) 0px -184px no-repeat';

	img = document.createElement('img');
	img.src = 'images/target_locking.gif';
	img.style.width = '56px';
	img.style.height = '40px';

	this.flying.target.appendChild(img);
	this.flying.div.appendChild(this.flying.target);
}

Peg.prototype.initializeScouting = function() {
	this.scouting.div = document.createElement('div');
	this.scouting.div.style.width = this.scouting.width + 'px';
	this.scouting.div.style.height = this.scouting.height + 'px';
	this.scouting.div.style.position = 'absolute';
	this.scouting.div.style.cursor = 'pointer';
	this.scouting.div.style.zIndex = GOverlay.getZIndex(-90.0);

	var sprite = this.getScoutingSprite(this.scouting.yaw);

	// Pegman
	this.scouting.peg = document.createElement('div');
	this.scouting.peg.style.width = this.scouting.width + 'px';
	this.scouting.peg.style.height = this.scouting.height + 'px';
	this.scouting.peg.style.background = 'url(images/scout_sprite.png) -' + sprite.x + 'px -' + sprite.y + 'px no-repeat';
	
	var img = document.createElement('img');
	img.src = 'images/void.gif';
	img.style.width = this.scouting.width + 'px';
	img.style.height = this.scouting.height + 'px';
	
	this.scouting.peg.appendChild(img);
	this.scouting.div.appendChild(this.scouting.peg);
}

Peg.prototype.initializeSettled = function() {
	this.settled.div = document.createElement('div');
	this.settled.div.style.width = this.settled.width + 'px';
	this.settled.div.style.height = this.settled.height + 'px';
	this.settled.div.style.position = 'absolute';
	this.settled.div.style.cursor = 'pointer';
	this.settled.div.style.zIndex = GOverlay.getZIndex(-90.0);

	var sprite = this.getSettledSprite(this.settled.yaw);

	// Pegman
	this.settled.peg = document.createElement('div');
	this.settled.peg.style.width = this.settled.width + 'px';
	this.settled.peg.style.height = this.settled.height + 'px';
	this.settled.peg.style.background = 'url(images/scout_sprite.png) -' + sprite.x + 'px -' + sprite.y + 'px no-repeat';
	
	var img = document.createElement('img');
	img.src = 'images/void.gif';
	img.style.width = this.settled.width + 'px';
	img.style.height = this.settled.height + 'px';
	
	this.settled.peg.appendChild(img);
	this.settled.div.appendChild(this.settled.peg);
}

Peg.prototype.remove = function() {
	if(this.flying.div.parentNode != null)
		this.flying.div.parentNode.removeChild(this.flying.div);

	if(this.settled.div.parentNode != null) {
		this.settled.div.parentNode.removeChild(this.settled.div);

		this.settled.inuse = false;
	}
}

Peg.prototype.copy = function() {
	return new Peg();
}

Peg.prototype.redraw = function(force) {
	if(!force)
		return;

	if(this.mode == '')
		return;

	var p = this.map.fromLatLngToDivPixel(this.point);

	if(this.mode == 'flying') {
		this.flying.div.style.left = (p.x - this.flying.width / 2) + 'px';
		this.flying.div.style.top = (p.y - this.flying.height / 3) + 'px';
	}
	else if(this.mode == 'settled') {
		this.settled.div.style.left = (p.x - this.settled.width / 2) + 'px';
		this.settled.div.style.top = (p.y - 35) + 'px';
	}
}

Peg.prototype.getSettledSprite = function(yaw) {
	var d = 360.0 / this.settledSprites.length;
	var index = Math.floor((yaw + (d / 2.0)) / d) % this.settledSprites.length;

	return this.settledSprites[index];
}

Peg.prototype.getScoutingSprite = function(yaw) {
	var d = 360.0 / this.scoutingSprites.length;
	var index = Math.floor((yaw + (d / 2.0)) / d) % this.scoutingSprites.length;

	return this.scoutingSprites[index];
}

Peg.prototype.flyLeft = function() {
	this.flying.peg.style.backgroundPosition = '0px -313px';
}

Peg.prototype.flyRight = function() {
	this.flying.peg.style.backgroundPosition = '-49px -797px';
}

Peg.prototype.flyDisabled = function() {
	if(this.flying.dir == 'right')
		this.flying.peg.style.backgroundPosition = '0px -797px';
	else
		this.flying.peg.style.backgroundPosition = '-49px -184px';
}

Peg.prototype.getHotspot = function() {
	var p = this.map.fromLatLngToDivPixel(this.point);

	p.y += (72 - (this.flying.height / 3));

	return this.map.fromDivPixelToLatLng(p);
}

Peg.prototype.setScout = function(point, yaw) {
	this.flying.target.style.display = 'none';

	this.setScoutingYaw(yaw);

	this.map.getPane(G_MAP_MARKER_PANE).appendChild(this.scouting.div);

	var p = this.map.fromLatLngToDivPixel(point);

	this.scouting.div.style.left = (p.x - this.scouting.width / 2) + 'px';
	this.scouting.div.style.top = (p.y - this.scouting.height / 2) + 'px';
}

Peg.prototype.unsetScout = function() {
	if(this.scouting.div.parentNode != null) {
		this.scouting.div.parentNode.removeChild(this.scouting.div);

		this.flying.target.style.display = '';
	}
}

Peg.prototype.setYaw = function(yaw) {
	this.settled.yaw = yaw;
	var sprite = this.getSettledSprite(yaw);

	this.settled.peg.style.backgroundPosition = '-' + sprite.x + 'px -' + sprite.y + 'px';
}

Peg.prototype.setScoutingYaw = function(yaw) {
	this.scouting.yaw = yaw;
	var sprite = this.getScoutingSprite(yaw);

	this.scouting.peg.style.backgroundPosition = '-' + sprite.x + 'px -' + sprite.y + 'px';
}

Peg.prototype.setLatLng = function(point) {
	this.point = point;

	if(this.mode == 'settled')
		this.settled.point = point;
}

Peg.prototype.startSettle = function(point, yaw) {
	if(this.point == null && point == null)
		return;

	if(this.mode == 'flying')
		this.abortFlying();

	this.mode = 'settled';

	if(point == null)
		point = this.point;

	this.setLatLng(point);
	this.setYaw(yaw);

	if(this.settled.inuse == false) {
		this.map.getPane(G_MAP_MARKER_PANE).appendChild(this.settled.div);

		this.installDragListener(this.settled.div);

		this.settled.inuse = true;
	}

	this.redraw(true);
}

Peg.prototype.pauseSettle = function(reset) {
	this.mode = '';

	if(this.settled.div.parentNode != null) {
		this.settled.div.parentNode.removeChild(this.settled.div);

		this.settled.inuse = false;
	}
}

Peg.prototype.stopSettle = function() {
	this.pauseSettle();

	this.settled.yaw = 0;
	this.settled.point = null;
}

Peg.prototype.rewindSettle = function() {
	if(this.settled.point == null)
		return;

	this.startSettle(this.settled.point, this.settled.yaw);
}

Peg.prototype.startFlying = function() {
	var self = this;

	this.flying.started = false;

	this.ev = GEvent.addListener(this.map, 'mousemove', function(point) {
		if(self.flying.started == false) {
			self.startDrag(point);
			self.flying.started = true;

			return;
		}

		self.drag(point);
	});
}

Peg.prototype.stopFlying = function() {
	GEvent.removeListener(this.ev);

	if(this.flying.started == true)
		this.stopDrag(this.point, true);
}

Peg.prototype.abortFlying = function() {
	GEvent.removeListener(this.ev);

	this.abortDragListener();

	if(this.flying.started == true)
		this.stopDrag(this.point, false);
}

Peg.prototype.startDrag = function(point) {
	this.setLatLng(point);

	if(this.mode == 'settled')
		this.pauseSettle();

	this.map.getPane(G_MAP_MARKER_PANE).appendChild(this.flying.div);

	this.mode = 'flying';
	this.map.addOverlay(this.svOverlay);

	this.redraw(true);

	GEvent.trigger(this, 'dragstart', this.point);
}

Peg.prototype.stopDrag = function(point, findpanorama) {
	var self = this;

	if(this.flying.timeout != null) {
		clearTimeout(this.flying.timeout);
		this.flying.timeout = null;
	}

	this.setLatLng(point);

	this.map.removeOverlay(this.svOverlay);

	this.mode = '';

	this.unsetScout();
	this.flying.div.parentNode.removeChild(this.flying.div);

	if(findpanorama == true) {
		var hotspot = this.getHotspot();
		this.getPanorama(hotspot, function(panorama) {
			GEvent.trigger(self, 'dragstop', panorama);
		});
	}

	this.redraw(true);
}

Peg.prototype.drag = function(point) {
	var lng = point.lng();
	if(this.flying.lastlng < lng) {
		this.flying.dir = 'right';
		this.flyRight();
	}
	else {
		this.flyLeft();
		this.flying.dir = 'left';
	}
	this.flying.lastlng = lng;

	this.setLatLng(point);
	this.unsetScout();
	this.redraw(true);

	if(this.flying.timeout != null) {
		clearTimeout(this.flying.timeout);
		this.flying.timeout = null;
	}

	var self = this;

	this.flying.timeout = setTimeout(function() {
		var hotspot = self.getHotspot();
		self.getPanorama(hotspot, function(panorama) {
			if(panorama != null) {
				var yaw = 0;
				if(panorama.links.length != 0)
					yaw = panorama.links[0].yaw;

				self.setScout(panorama.location.latlng, yaw);
			}
			else
				self.flyDisabled();
		});
	}, 1000);

	GEvent.trigger(this, 'drag', this.point);
}

Peg.prototype.getPanorama = function(point, cb) {
	this.svClient.getNearestPanorama(point, function(data) {
		if(data.code == GStreetviewClient.ReturnValues.SUCCESS)
			cb(data);
		else
			cb(null);

		return;
	});
}

Peg.prototype.installDragListener = function(node) {
	var self = this;

	node.onmousedown = function(e) {
		var event = e || window.event;

		self.startFlying();

		document.onmousemove = function() {
			return false;
		}

		document.onmouseup = function() {
			self.stopFlying();

			document.onmousemove = function() {};
			document.onmouseup = function() {};

			return false;
		}

		if(event.stopPropagation)
			event.stopPropagation();
		else
			event.cancelBubble = true;

		return false;
	}

	return;
}

Peg.prototype.abortDragListener = function() {
	document.onmousemove = function() {};
	document.onmouseup = function() {};
}

