var m_MapMgrPrototypeDefined;
var m_PointsPrototypeDefined;

function MapMgr( objACGM, frmMain, txtX1, txtY1, txtX2, txtY2 ) {

  var m_objACGM = objACGM;
  var m_objOutput = null;
  var m_objMouseMoveHandlers = new Array();
  var m_CurrentValue = 0;
  var m_objOutput = null;
  var m_txtX1 = txtX1;
  var m_txtY1 = txtY1;
  var m_txtX2 = txtX2;
  var m_txtY2 = txtY2;
  var m_form = frmMain;
  var gOutput = "";

  // Set prototype method definitions
  if ( typeof(m_MapMgrPrototypeDefined) == 'undefined' ) {
    MapMgr.prototype.Measure = Measure;
    MapMgr.prototype.Navigate = NavigateMap;
    MapMgr.prototype.RegisterMouseMove = RegisterMouseMove;
    MapMgr.prototype.Digitize = Digitize;
    m_MapMgrPrototypeDefined = true;
  } // if
  
  function Digitize( strCommand ) {
  
    switch ( strCommand.toLowerCase() ) {
    
      case 'circle':
        DrawCircle( OutputPoints, false );
        break;
        
      case 'extents':
        DrawExtents( OutputPoints, false );
        break;
        
      case 'polygon':
        DrawLine( OutputPoints, true, false );
        break;
    } // switch
    
    return gOutput;
    
  } // Digitize
  
  function OutputPoints( pts ) {
    if ( pts == null ) {
    } else if ( pts.Count() == 0 ) {
      gOutput = "";
    } else {
      gOutput += pts.GetWorldX(pts.Count()) + " " + pts.GetWorldY(pts.Count()) + " ";
    } // if  
  } // OutputPoints()
  
  function Measure( strCommand, txtOutput ) {

    m_objOutput = txtOutput;

    switch ( strCommand.toLowerCase() ) {
      case 'distance':
        DrawLine( MeasureLineGetPoint, false, true );
        break;
      
      case 'area':
        DrawLine( MeasureAreaGetPoint, true, true );
        break;
      
    } // switch
    
  } // Measure()
  
  function RegisterMouseMove( fncHandler ) {
    m_objMouseMoveHandlers.Push( fncHandler );
  } // RegisterMouseMove()

  function DrawCircle( fncCallback, bErase ) {

    var strTemp;
      
    // Get Initial point
    strTemp = m_objACGM.MLCommand( 'addcircle -cp' );
    alert( strTemp );
    
    if ( bErase ) m_objACGM.MLCommand( 'delete -all' );
  } // DrawCircle()
  
  function DrawExtents( fncCallback, bErase ) {

  	var strBuf = m_objACGM.MLCommand( 'queryzoombox -limit' );
  	var arrBuf = strBuf.split(' ');
  	var dx, dy;
  	if ( arrBuf.length > 4 ) arrBuf = strBuf.split('  ');
  	if ( arrBuf.length == 4 ) {
  	  dx = 0.0; //parseFloat((arrBuf[2] - arrBuf[0])/75);
  	  dy = 0.0; // parseFloat((arrBuf[3] - arrBuf[1])/75);
  	  pts = new Points();
  	  fncCallback( pts );
  	  pts.AddPoint( parseFloat(arrBuf[0]) + dx, parseFloat(arrBuf[1]) + dy );
  	  fncCallback( pts );
  	  pts.AddPoint( parseFloat(arrBuf[0]) + dx, arrBuf[3]-dy );
  	  fncCallback( pts );
  	  pts.AddPoint( arrBuf[2]-dx, arrBuf[3]-dy );
  	  fncCallback( pts );
  	  pts.AddPoint( arrBuf[2]-dx, parseFloat(arrBuf[1])+dy );
  	  fncCallback( pts );
  	  pts.AddPoint( parseFloat(arrBuf[0]) + dx, parseFloat(arrBuf[1]) + dy );
  	  fncCallback( pts );
      pts.Draw( m_objACGM, false );  	  
  	  fncCallback( null );
  	  
      if ( bErase ) m_objACGM.MLCommand( 'delete -all' );
  	  pts.Clear();
    } // if
    
  } // DrawExtents()
  
  function DrawLine( fncCallback, bClose, bErase ) {

    var x, y;
    var strTemp;
    var pts;

    // Initialize
    pts = new Points();
    fncCallback( pts );
    
    // Get Initial point
    strTemp = m_objACGM.MLCommand( 'promptvector -force -point' );
    strTemp = strTemp.split('\n');
    if ( strTemp[0] == "1" ) {
      pts.AddPoint( strTemp[1].split(' ')[0], strTemp[1].split(' ')[1] );
      fncCallback( pts );

      while ( 1 ) {  
        strTemp = m_objACGM.MLCommand( 'promptvector -force -line -xy ' + pts.GetCgmX(pts.Count()) + ' ' + pts.GetCgmY(pts.Count()) );
        strTemp = strTemp.split('\n');
        if ( strTemp[0] != "2" ) {
          break;
        } else {
          x = strTemp[2].split(' ')[0];
          y = strTemp[2].split(' ')[1];
          
          if ( x == pts.GetCgmX(pts.Count()) && y == pts.GetCgmY(pts.Count()) ) {
            break;
          } else {
            pts.AddPoint( x, y );
            pts.Draw( m_objACGM, bClose );
            fncCallback( pts );
          } // if
        } // if
      } // while
    } // if
    fncCallback( null );
    
    if ( bErase ) m_objACGM.MLCommand( 'delete -all' );

    pts.Clear();
    
  } // DrawLine()

  function MeasureLineGetPoint( pts ) {

    var x1, y1;
    var x2, y2;

    if ( pts == null ) {
      // do nothing
      
    } else if ( pts.Count() == 0 ) {
      // initialize
      m_CurrentValue = 0;
      
    } else if ( pts.Count() > 1 ) {
      // Get last two points and calc their distance
      x1 = pts.GetWorldX(pts.Count());
      y1 = pts.GetWorldY(pts.Count());
      x2 = pts.GetWorldX(pts.Count()-1);
      y2 = pts.GetWorldY(pts.Count()-1);
      m_CurrentValue += Math.sqrt( Math.pow( x1-x2,2 ) + Math.pow( y1-y2,2 ) );
    } // if
    
    m_objOutput.value = "Distance: " + Math.round(m_CurrentValue*100)/100 + " " + gsLinearUOM;
    
  } // MeasureGetPoint
    
  function MeasureAreaGetPoint( pts ) {

    var x0, y0;
    var x1, y1;
    var x2, y2;
    var area = 0;
      
    if ( pts == null ) {
    } else if ( pts.Count() == 0 ) {
      m_CurrentValue = 0;
    } else if ( pts.Count() == 3 ) {
      x0 = pts.GetWorldX(1);
      y0 = pts.GetWorldY(1);
      x1 = pts.GetWorldX(2);
      y1 = pts.GetWorldY(2);
      x2 = pts.GetWorldX(3);
      y2 = pts.GetWorldY(3);
      
      m_CurrentValue = ((x0 * y1) - (x1*y0) + (x1*y2) - (x2*y1) + (x2*y0)-(x0*y2))/2;
      
    } else if ( pts.Count() > 3 ) {
      x0 = pts.GetWorldX(1);
      y0 = pts.GetWorldY(1);
      x1 = pts.GetWorldX(pts.Count()-1);
      y1 = pts.GetWorldY(pts.Count()-1);
      x2 = pts.GetWorldX(pts.Count());
      y2 = pts.GetWorldY(pts.Count());
      m_CurrentValue += ((x1 * y2) - (y1 * x2) + (x2*y0) - (x0*y2) -(x1*y0)+(x0*y1))/2;
    }
    
    area = Math.abs(m_CurrentValue);
    
    if ( gsLinearUOM == "ft" ) {
      if ( area > 43559.66 ) {
        area = Math.round(area / 435.5966)/100;
        m_objOutput.value = "Area: " + area + " acres";
      } else {
        m_objOutput.value = "Area: " + Math.round(area*100)/100 + " sq. ft";
      } // if
    } else {
        m_objOutput.value = "Area: " + Math.round(area*100)/100 + " sq. " + gsLinearUOM;    
    } // if
    
  } // MeasureGetPoint

  function NavigateMap( strType ) {

    if ( m_txtX1 == null || m_txtX2 == null || m_txtY1 == null || m_txtY2 == null || m_form == null ) return;
    
    var x1 = Math.round(m_txtX1.value);
    var x2 = Math.round(m_txtX2.value);
    var y1 = Math.round(m_txtY1.value);
    var y2 = Math.round(m_txtY2.value);
    var dX = (x2-x1);
    var dY = (y2-y1);
    var cX = x1 + dX/2;
    var cY = y1 + dY/2;
    var bSubmit = true;
    var pts;


    if( cX != x1 && cY != y1 ) {

	    switch ( strType.toLowerCase() ) {

	      case 'zoombox':
	        pts = new Points();
	        pts.AddPoints( m_objACGM.MLCommand( 'promptvector -rectangle -force' ) );
	        if ( pts.Count() == 2 ) {
            m_txtX1.value = pts.GetWorldX(1);
            m_txtY1.value = pts.GetWorldY(1);
            m_txtX2.value = pts.GetWorldX(2);
            m_txtY2.value = pts.GetWorldY(2);
          } else {
            bSubmit = false;
          } // if
          break;

  	    case 'zoomdisplay':
  	      var strBuf = objACGM.MLCommand( 'queryzoombox' );
  	      var arrBuf = strBuf.split(' ');
  	      if ( arrBuf.length > 4 ) arrBuf = strBuf.split('  ');
  	      if ( arrBuf.length == 4 ) {
  	        pts = new Points();
  	        pts.AddPoint( arrBuf[0], arrBuf[1] );
  	        pts.AddPoint( arrBuf[2], arrBuf[3] );
            m_txtX1.value = pts.GetWorldX(1);
            m_txtY1.value = pts.GetWorldY(1);
            m_txtX2.value = pts.GetWorldX(2);
            m_txtY2.value = pts.GetWorldY(2);
            
            
          } else {
            bSubmit = false;
          } // if
          break;

		    case 'zoomin':
		      m_txtX1.value = Math.round(cX - (dX * 0.33));
		      m_txtX2.value = Math.round(cX + (dX * 0.33));
		      m_txtY1.value = Math.round(cY - (dY * 0.33));
		      m_txtY2.value = Math.round(cY + (dY * 0.33));
		      break;

		    case 'zoomout':
		     
		      m_txtX1.value = Math.round(cX - (dX * 0.75));
		      m_txtX2.value = Math.round(cX + (dX * 0.75));
		      m_txtY1.value = Math.round(cY - (dY * 0.75));
		      m_txtY2.value = Math.round(cY + (dY * 0.75));
		      break;

		    case 'recenter':
			  pts = new Points();
			  m_objACGM.MLCommand( 'promptlocation' );
  			  var strPt = m_objACGM.MLCommand( 'querylocation'); 
  			  var arrPt = strPt.split('  ');
  			  //alert('Point:' + strPt);
  			  pts.AddPoint( arrPt[0], arrPt[1] );
  			  //alert(arrPt[0]);
  			  //alert(arrPt[1]);
  			  //alert('worldx:' + pts.GetWorldX(1));
  			  //alert('worldy:' + pts.GetWorldY(1));
  			  //alert('DX:' + dX);
  			  //alert('DY:' + dY);
  			  //alert(pts.GetWorldY(1) - dY * 0.5);
  			  //alert(pts.GetWorldY(1)+ dY * 0.5);
		      m_txtX1.value = Math.round(pts.GetWorldX(1) - (dX * 0.5));
		      m_txtX2.value = Math.round(pts.GetWorldX(1) + (dX * 0.5));
		      m_txtY1.value = Math.round(pts.GetWorldY(1) - (dY * 0.5));
		      m_txtY2.value = Math.round(pts.GetWorldY(1) + (dY * 0.5));
		    
			  //alert(m_txtY1.value);
			  //alert(m_txtY2.value);	
		      
		      break;
		      
        case 'pannw':
	        m_txtX1.value = x1 - dX*.75;
	        m_txtX2.value = x2 - dX*.75;
	        m_txtY1.value = y1 - dY*.75;
	        m_txtY2.value = y2 - dY*.75;
	        break;
	        
        case 'pann':
	        m_txtY1.value = y1 - dY*.75;
	        m_txtY2.value = y2 - dY*.75;
  	      break;
  	      
        case 'panne':
	        m_txtX1.value = x1 + dX*.75;
	        m_txtX2.value = x2 + dX*.75;
	        m_txtY1.value = y1 - dY*.75;
	        m_txtY2.value = y2 - dY*.75;
	        break;
	        
        case 'panw':
	        m_txtX1.value = x1 - dX*.75;
	        m_txtX2.value = x2 - dX*.75;
	        break;
	        
        case 'pane':
	        m_txtX1.value = x1 + dX*.75;
	        m_txtX2.value = x2 + dX*.75;
	        break;
	        
        case 'pansw':
	        m_txtX1.value = x1 - dX*.75;
	        m_txtX2.value = x2 - dX*.75;
	        m_txtY1.value = y1 + dY*.75;
	        m_txtY2.value = y2 + dY*.75;
	        break;
	        
        case 'pans':
	        m_txtY1.value = y1 + dY*.75;
	        m_txtY2.value = y2 + dY*.75;
	        break;
	        
        case 'panse':
	        m_txtX1.value = x1 + dX*.75;
	        m_txtX2.value = x2 + dX*.75;
	        m_txtY1.value = y1 + dY*.75;
	        m_txtY2.value = y2 + dY*.75;
	        break;
	        
	    } // switch
	    
	    if ( bSubmit ) {
  	    m_form.action='GenerateMap.aspx?RangeMode=NewRange';
  	    m_form.txtAction.value = 'MapByProfile';
  	    m_form.txtRangeMode.value = 'NewRange';
	      m_form.target='_self';
	      m_form.submit();
	    } // if
    } // if
    return;
    
  } // NavigateMap()
  
} // MapMgr

function Points() {

  var m_objWorldPoints = new Array();
  var m_objCgmPoints = new Array();
  
  if ( typeof(m_PointsPrototypeDefined) == 'undefined' ) {
    Points.prototype.AddPoint = AddPoint;
    Points.prototype.AddPoints = AddPoints;
    Points.prototype.GetCgmX = GetCgmX;
    Points.prototype.GetCgmY = GetCgmY;
    Points.prototype.GetWorldX = GetWorldX;
    Points.prototype.GetWorldY = GetWorldY;
    Points.prototype.Count = GetCount;
    Points.prototype.Draw = Draw;
    Points.prototype.Clear = Clear;
    m_PointsPrototypeDefined = true;
  } // if
  
  function AddPoints( strBuf ) {
    var arrPoints = strBuf.split('\n');
    var iCount = arrPoints[0];

    if (iCount != "" && iCount > 0 ) {
      for ( i=1; i<=iCount; i++ ) {
        AddPoint( arrPoints[i].split(' ')[0], arrPoints[i].split(' ')[1] );
      } // for
    } // if
  } // AddPoints()

  function AddPoint( x, y ) {
    m_objCgmPoints.push( x );
    m_objCgmPoints.push( y );

    var wX = jTransXCoordACGMToStorage(x);
    var wY = jTransYCoordACGMToStorage(y);
    m_objWorldPoints.push( wX );
    m_objWorldPoints.push( wY );
  } // AddPoint()

  function GetWorldX( idx ) {
    return m_objWorldPoints[ 2*(idx-1) ];
  } // GetWorldX
  function GetWorldY( idx ) {
    return m_objWorldPoints[ 2*(idx-1)+1 ];
  } // GetWorldY()
  
  function GetCgmX( idx ) {
    return m_objCgmPoints[ 2*(idx-1) ];
  } // GetCgmX
  function GetCgmY( idx ) {
    return m_objCgmPoints[ 2*(idx-1)+1 ];
  } // GetCgmY()
  
  function GetCount() {
    return m_objWorldPoints.length/2;
  } // GetPointCount()
  
  function Clear() {
    m_objWorldPoints = new Array();
    m_objCgmPoints = new Array();
  } // Clear()

  function Draw( objACGM, bClose ) {  
    objACGM.MLCommand( 'delete -all' );
    objACGM.MLCommand( 'setredlineobject -mediumline' );
    for ( i=1; i<GetCount(); i++ ) {
      objACGM.MLCommand( 'addline -xy ' + GetCgmX(i) + ' ' + GetCgmY(i) + ' -xy ' + GetCgmX(i+1) + ' ' + GetCgmY(i+1) );
    } // for
    
    if (bClose && GetCount() > 2 ) {
      objACGM.MLCommand( 'setredlineobject -thinline' );
      objACGM.MLCommand( 'addline -xy ' + GetCgmX(1) + ' ' + GetCgmY(1) + ' -xy ' + GetCgmX(GetCount()) + ' ' + GetCgmY(GetCount()) );
    } // if        
  } // Draw()
} // Points