function Scope(center, opt_color, opt_direction, opt_angle) {
  this.center_ = center;
  this.color_ = opt_color || "#FFFF00";
  this.direction_ = opt_direction || 0;
  this.angle_ = opt_angle || 90;
  this.jg_ = null;
  this.div_ = null;
  this.dragging_ = false;
  this.c1 = null;
  this.functionToCallWhenTurned = null;
  this.functionToCallWhenMouseUp = null;
}
Scope.prototype = new GOverlay();

// Creates the DIV representing this Scope.
Scope.prototype.initialize = function(map) {
  // Create the DIV representing our Scope
  var div  = document.createElement("div");
  div.style.position = "absolute";
  div.className = "scope";

  this.jg_ = new jsGraphics(div);
  this.jg_.setColor(this.color_);

  // Our Scope is flat against the map, so we add our selves to the
  // MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
  // below the marker shadows)
  map.getPane(G_MAP_MAP_PANE).appendChild(div);

  GEvent.bindDom(div,"mousedown",this,this.onMouseDown);
  GEvent.bindDom(div,"mousemove",this,this.onMouseMove);
  GEvent.bindDom(div,"mouseup",this,this.onMouseUp);

  this.map_ = map;
  this.div_ = div;

  this.c1 = this.map_.fromLatLngToDivPixel(this.center_);
}

Scope.prototype.recalculateCenter = function() {
  this.c1 = this.map_.fromLatLngToDivPixel(this.center_);
  this.redraw(true);
}

Scope.prototype.registerTurnListener = function(functionToCall) {
  this.functionToCallWhenTurned = functionToCall;
}

Scope.prototype.registerMouseUpListener = function(functionToCall2) {
  this.functionToCallWhenMouseUp = functionToCall2;
}

Scope.prototype.onMouseDown = function(a) {
  this.dragging_ = true;

  if ( typeof(this.div_.setCapture) != 'undefined' ) {
  	this.div_.setCapture();
  }
  if (navigator.appName.indexOf('Microsoft') != -1) {
	window.event.cancelBubble=true;
	window.event.returnValue=false
  } else {

	a.cancelBubble=true;
        a.preventDefault();
        a.stopPropagation();
  }
}

Scope.prototype.onMouseMove = function(e) {

  if ( !this.dragging_ ) return;

  if( !e ) {
    if( window.event ) {
      //Internet Explorer
      e = window.event;
    } else {
      //total failure, we have no way of referencing the event
      
      return;
    }
  }
  if( typeof( e.pageX ) == 'number' ) {
    //most browsers
    var xcoord = e.pageX;
    var ycoord = e.pageY;
  } else if( typeof( e.clientX ) == 'number' ) {
    //Internet Explorer and older browsers
    //other browsers provide this, but follow the pageX/Y branch
    var xcoord = e.clientX;
    var ycoord = e.clientY;
    var badOldBrowser = ( window.navigator.userAgent.indexOf( 'Opera' ) + 1 ) ||
     ( window.ScriptEngine && ScriptEngine().indexOf( 'InScript' ) + 1 ) ||
     ( navigator.vendor == 'KDE' )
    if( !badOldBrowser ) {
      if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        //IE 4, 5 & 6 (in non-standards compliant mode)
        xcoord += document.body.scrollLeft;
        ycoord += document.body.scrollTop;
      } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
        //IE 6 (in standards compliant mode)
        xcoord += document.documentElement.scrollLeft;
        ycoord += document.documentElement.scrollTop;
      }
    }
  } else {
    //total failure, we have no way of obtaining the mouse coordinates

    return;
  }

  xcoord = xcoord - this.map_.getContainer().offsetLeft;
  ycoord = ycoord - this.map_.getContainer().offsetTop;

  var TlcLatLng = this.map_.fromContainerPixelToLatLng(new GPoint(0,0),true);
  var TlcDivPixel = this.map_.fromLatLngToDivPixel(TlcLatLng);
  var pointContainerPixel = subGPoints(this.c1, TlcDivPixel); 
  var dir = GetAngleFromPoint(pointContainerPixel.x,pointContainerPixel.y,xcoord,ycoord) + 180;

  if (dir > 360) dir = dir - 360;
  if ( this.functionToCallWhenTurned != null ) {
	this.functionToCallWhenTurned(dir);
  }
}

Scope.prototype.onMouseUp = function(a) {
  this.dragging_ = false;
  if ( typeof(this.div_.releaseCapture) != 'undefined' ) {
  	this.div_.releaseCapture();
  }
  if (navigator.appName.indexOf('Microsoft') != -1) {
	window.event.cancelBubble=true;
	window.event.returnValue=false
  } else {
	a.cancelBubble=true;
        a.preventDefault();
        a.stopPropagation();
  }
  if ( this.functionToCallWhenMouseUp != null ) {
	this.functionToCallWhenMouseUp();
  }
}

Scope.prototype.setDirection = function(dir) {
	if ( dir < 0 ) dir = dir + 360;
	else if ( dir > 360 ) dir = dir - 360;
	
	this.direction_ = dir;
	this.redraw(true);
}

Scope.prototype.getDirection = function() {
	return this.direction_;
}

Scope.prototype.setAngle = function(angle) {
	
	if ( angle < 0 ) angle = angle + 360;
	else if ( angle > 360 ) angle = angle - 360;

	this.angle_ = angle;
	this.redraw(true);
}

Scope.prototype.getAngle = function() {
	return this.angle_;
}

// Remove the main DIV from the map pane
Scope.prototype.remove = function() {
  this.div_.parentNode.removeChild(this.div_);
}

// Copy our data to a new Scope
Scope.prototype.copy = function() {
  return new Scope(this.point_, this.weight_, this.color_,
                       this.backgroundColor_, this.opacity_);
}

// Redraw the Scope based on the current projection and zoom level
Scope.prototype.redraw = function(force) {
  // We only need to redraw if the coordinate system has changed
  if (!force) return;

  // Calculate the DIV coordinates of two opposite corners of our bounds to
  // get the size and position of our Scope
  

  // Now position our DIV based on the DIV coordinates of our bounds
  this.div_.style.width = "220px";
  this.div_.style.height = "220px";
  this.div_.style.left = (this.c1.x - 110) + "px";
  this.div_.style.top = (this.c1.y - 110) + "px";

  this.jg_.clear();
  
  var dir = this.direction_ + 90 - this.angle_/2;
  this.jg_.fillArc(15, 15, 190, 190, dir , dir + this.angle_);
  this.jg_.paint();
}

function GetAngleFromPoint(x1,y1,x2,y2) {
	var m = 0.0;
			
	if (x1 == 0) {
		if (y1 > y2)
			m = Math.PI/2;
		else
			m = - Math.PI/2;
	} else {
		m = (y1 - y2) / (x1 - x2);
		m =  Math.atan(m);
	}

	if (x1 < x2)
		m = Math.PI + m;

	//ã‚Í0‹
	m = (Math.PI*2 - (m + Math.PI/2));
	m = (m * 360) / (Math.PI*2);
	return m;
}

function subGPoints(a,b) {
	return new GPoint(a.x-b.x, a.y-b.y);
}

