/********************************************************************************
  Copyright, 2005, Intergraph Corporation. All Rights Reserved.
  The product licensee is granted permission to copy and distribute 
  this script only to support the product SVG output and licensee's 
  associated web sites, and to prepare derivative works solely for 
  internal use. All other rights reserved.
**********************************************************************************/

/*********************************************************/
//---  API FUNCTIONS  --- 
// Requires:
//   -global CORE FUNCTIONS object
//   -global BASIC MOUSE EVENTS object
//   -global BASIC FUNCTIONS object
/*********************************************************/


//--GLOBAL VARIABLES/CONSTANTS-----
// Error codes defined in CoreFunctions.js

//=========================================================
function _gwmAPIObject()
{
  this.iLoadFilePriority = 0; // used in loadFile processing
  this.iLoadMode = 0; // used in loadFile processing
  this.fZoomFactor = 2.0;
  this.sLoadFile = "";
  this.sLoadFileLayerName = "";
  this.UserEvtHandlerLoadFileComplete = null;
  this.sUserEvtInfoLoadFileComplete = null;
  this.UserEvtHandlerClick = null;
  this.sUserEvtInfoClick = null;
  this.UserEvtHandlerGeomCancel = null;
  this.sUserEvtInfoGeomCancel = null;
  
  // PMW 11/16/05 - add pan event handler stuff
  this.UserEvtHandlerPan = null;
  this.sUserEvtInfoPan = null;
  this.SVGEventTimeout = null;
  // PMW 11/17/05 - add zoom event handler stuff
  this.UserEvtHandlerSVGZoom = null;
  this.sUserEvtInfoSVGZoom = null;
  
  this.sCoordList = null;
  this.cmdCallback = null;
  this.sUserInfo   = ""; 

  this.bDynNav = false;
  this.iDynNavSteps = 7;
  
  //--PRIVATE Properties-------------------------
  // Dynamic Navigation (DN) and Zoom (DZ)
  this.iDNSteps  = 7; // default.
  this.iDNTLoop  = 0;
  this.bDNInProg = false;
  
  this.bDZIn     = false;
  this.bDZRect   = false;
  this.fDZRectX1 = 0.0;
  this.fDZRectY1 = 0.0;  
  this.fDZRectX2 = 0.0;
  this.fDZRectY2 = 0.0;
    
  this.fDNVRx1 = 0.0;  // Dyn, View Range, x1
  this.fDNVRy1 = 0.0;    
  this.fDNVRx2 = 0.0;  
  this.fDNVRy2 = 0.0;  
  
  this.fDNVRdx = 0.0;  // Dyn , View Range, delta in x
  this.fDNVRdy = 0.0;  // Dyn , View Range, delta in y
  
  this.fDNCntrX  = 0.0;
  this.fDNCntrY  = 0.0;
  this.fDNCntrDx = 0.0;  // Dyn Center, delta in x
  this.fDNCntrDy = 0.0;  // Dyn Center, delta in y
  
  this.DNFuncInWaiting = null;

  this.initAPI = _gwmInitAPI;
}
var _gwmAPI = new _gwmAPIObject();


//=======  FULL API FUNCTIONS  =======//

//=========================================================
function _gwmInitAPI( viewCtrl )
{
  //--File, Layer, Elements----------------------
  viewCtrl.getLayerEnabled = _gwmGetLayerEnabled;
  viewCtrl.setLayerEnabled = _gwmSetLayerEnabled;
  viewCtrl.getLayerVisible = _gwmGetLayerVisible;
  viewCtrl.setLayerVisible = _gwmSetLayerVisible;
  viewCtrl.getTooltipsEnabled = _gwmGetTooltipsEnabled;
  viewCtrl.setTooltipsEnabled = _gwmSetTooltipsEnabled;
  viewCtrl.getHotspotsEnabled = _gwmGetHotspotsEnabled;
  viewCtrl.setHotspotsEnabled = _gwmSetHotspotsEnabled;
  viewCtrl.getLayerNames = _gwmGetLayerNames;
  viewCtrl.getElementProperty = _gwmGetElementProperty;
  viewCtrl.setElementProperty = _gwmSetElementProperty;
  viewCtrl.getLayerPriority = _gwmGetLayerPriority;
  viewCtrl.setLayerPriority = _gwmSetLayerPriority;
  viewCtrl.unloadLayer = _gwmUnloadLayer;
  viewCtrl.displayElementTooltip = _gwmDisplayElementTooltip;
  viewCtrl.displayTooltip = _gwmDisplayTooltip;
  viewCtrl.eraseTooltip = _gwmEraseTooltip;
  viewCtrl.selectElement = _gwmSelectElement;
  viewCtrl.cmdSelectElement = _gwmCmdSelectElement;
  viewCtrl.highlightElement = _gwmSelectElement;
  viewCtrl.unselectElement = _gwmUnselectElement;
  viewCtrl.cmdUnselectElement = _gwmCmdUnselectElement;
  viewCtrl.unHighlightElement = _gwmUnselectElement;
  viewCtrl.unselectAllElements = _gwmUnselectAllElements;
  viewCtrl.unHighlightAllElements = _gwmUnselectAllElements;
  viewCtrl.getSelectStyle = _gwmGetSelectStyle;
  viewCtrl.setSelectStyle = _gwmSetSelectStyle;
  viewCtrl.getSelectedElements = _gwmGetSelectedElements;
  viewCtrl.getLayerStyleClass = _gwmGetLayerStyleClass;
  viewCtrl.setLayerStyleClass = _gwmSetLayerStyleClass;


  //--View Navigation------------------------------
  viewCtrl.refreshView            = _gwmRefreshView;
  viewCtrl.centerView             = _gwmCenterView;
  viewCtrl.cmdCenterView          = _gwmCmdCenterView;
  viewCtrl.setViewRange           = _gwmSetViewRange;
  viewCtrl.cmdZoomRectangleView   = _gwmCmdZoomRectangleView;
  viewCtrl.fitView                = _gwmFitView;
  viewCtrl.getViewRange           = _gwmGetViewRange;
  viewCtrl.zoomInView             = _gwmZoomInView;
  viewCtrl.cmdZoomInView          = _gwmCmdZoomInView;
  viewCtrl.zoomOutView            = _gwmZoomOutView;
  viewCtrl.cmdZoomOutView         = _gwmCmdZoomOutView;
  viewCtrl.shiftView              = _gwmShiftView;
  viewCtrl.cmdShiftView           = _gwmCmdShiftView;
  viewCtrl.fitElement             = _gwmFitElement;
  viewCtrl.cmdFitElement          = _gwmCmdFitElement;
  viewCtrl.setZoomFactor          = _gwmSetZoomFactor;
  viewCtrl.getZoomFactor          = _gwmGetZoomFactor;
  viewCtrl.cmdPanView             = _gwmCmdPanView; 
  viewCtrl.setDynamicNavigation   = _gwmSetDynamicNavigation;

  //--Geometry Capture------------------------------
  viewCtrl.cmdCapturePoint = _gwmCmdCapturePoint; 
  viewCtrl.cmdCaptureLine = _gwmCmdCaptureLine;
  viewCtrl.cmdCaptureRectangle = _gwmCmdCaptureRectangle; 
  viewCtrl.cmdCaptureCircle = _gwmCmdCaptureCircle;
  viewCtrl.cmdCapturePolyline = _gwmCmdCapturePolyline;
  viewCtrl.cmdCapturePolygon = _gwmCmdCapturePolygon;
  viewCtrl.cancelCmdCapture = _gwmCmdCaptureCancel;
  viewCtrl.getCoordinatePrecision = _gwmGetCoordinatePrecision;
  viewCtrl.setCoordinatePrecision = _gwmSetCoordinatePrecision;
  viewCtrl.getCoordinateUnits = _gwmGetCoordinateUnits; 
  viewCtrl.setCoordinateUnits = _gwmSetCoordinateUnits; 

  //--Miscellaneous------------------------------
  viewCtrl.getEventHandler = _gwmGetEventHandler;
  viewCtrl.setEventHandler = _gwmSetEventHandler;
  viewCtrl.loadFile = _gwmLoadFile;
  viewCtrl.loadString = _gwmLoadString;
  viewCtrl.loadRasterFile = _gwmLoadRasterFile;
  viewCtrl.enableMenuItem = _gwmEnableMenuItem;
  viewCtrl.displayMenuItem = _gwmDisplayMenuItem;
  viewCtrl.checkMenuItem = _gwmCheckMenuItem;
  viewCtrl.removeMenuItem = _gwmRemoveMenuItem;
  viewCtrl.insertMenuItem = _gwmInsertMenuItem;
  viewCtrl.getMetadata = _gwmGetMetadata;
  viewCtrl.removeAllMenuItems = _gwmRemoveAllMenuItems;
  viewCtrl.getViewerMenu = _gwmGetViewerMenu;
  
  //--Modes, Settings----------------------------
  viewCtrl.getAutoRepeatMode = _gwmGetAutoRepeatMode;
  viewCtrl.setAutoRepeatMode = _gwmSetAutoRepeatMode;
  viewCtrl.getListSeparator = _gwmGetListSeparator;
  viewCtrl.setListSeparator = _gwmSetListSeparator;
  viewCtrl.setDynamicLineStyle = _gwmSetDynamicLineStyle;
  viewCtrl.getDynamicLineStyle = _gwmGetDynamicLineStyle;
  viewCtrl.setDynamicShapeStyle = _gwmSetDynamicShapeStyle;
  viewCtrl.getDynamicShapeStyle = _gwmGetDynamicShapeStyle;
  viewCtrl.setTooltipTextStyle = _gwmSetTooltipTextStyle;
  viewCtrl.getTooltipTextStyle = _gwmGetTooltipTextStyle;
  viewCtrl.setTooltipRectStyle = _gwmSetTooltipRectStyle;
  viewCtrl.getTooltipRectStyle = _gwmGetTooltipRectStyle;
  
  //--Other/debugging/testing
  viewCtrl.DBGTEST = _gwmDBGTEST;
}

//=========================================================
function _gwmIsUnDef(d)
{
  //if (undefined == d || "" == d)
  if("undefined" == typeof(d)) return true;
  else return false;
}

//=========================================================
function _gwmIsNull(d)
{
  if(null == d || (("string"==typeof(d))&&""== d)) return true;
  else return false;
}

//=========================================================
function _gwmGetMetadata(name)
{
  try
  {
    return _gwmBas.getMetadata(name);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdUnselectElement()
{
  try
  {
    _gwmBas.cmdViewNavInit(_gwmBasME.GETELEMENT, _gwmCmdUnselectElementCallback, "");
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=======================================================
function _gwmCmdUnselectElementCallback(ele, userinfo)
{
  try
  {
    if (_gwmIsNull(ele)) return _gwm_E_GETELEMENT;
    var layer = _gwmBas.getLayerByName("gwmselected");
    if (_gwmIsNull(layer)) return _gwm_E_GETLAYER;
    layer.removeChild(ele);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdSelectElement()
{
  try
  {
    _gwmBas.cmdViewNavInit(_gwmBasME.GETELEMENT, _gwmCmdSelectElementCallback, "");
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=======================================================
function _gwmCmdSelectElementCallback(ele, userinfo)
{
  try
  {
    if (_gwmIsNull(ele)) return _gwm_E_GETELEMENT;
    var layer = _gwmBas.getEleLayer(ele);
    if (_gwmIsNull(layer)) return _gwm_E_GETLAYER;
    layer = layer.getAttribute("id");
    if (_gwmIsNull(layer)) return _gwm_E_GETLAYER;
    var eleid = ele.getAttribute("id");
    if (_gwmIsNull(eleid)) return gwm_E_ELEATTR;
    return _gwmSelectElement(layer, eleid);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
/**
Error values:
-1 : specified element is a symbol
-2 : couldn't find the selected layer
**/
//=======================================================
function _gwmSelectElement(layer, id)
{
  try
  {
    if (_gwmIsNull(layer) || _gwmIsNull(id))
      return _gwm_E_PARAMNULL;
    var ele = _gwmBas.getElement(layer, id);
    if (_gwmIsNull(ele))
      return _gwm_E_GETELEMENT; // TODO: throw exception?
    // cannot select symbols
    if (ele.nodeName == "use") return _gwm_E_GETELEMENT;
    var selele = ele.cloneNode(true);
    selele.setAttribute("id", layer + _gwmGetListSeparator() + id);
    selele.setAttribute("class", "");
    var newstyle = "";
    // check for linear element
    if (selele.nodeName == "path")
    {
      var path = selele.getAttribute("d");
      if (path.substr(path.length - 1, 1) != "z")
      {
        // we have a linear element, set fill to none
        newstyle += "fill:none;";
        selele.setAttribute("style", newstyle);
      }
    }
    
    var l = _gwmBas.getLayerByName("gwmselected");
    if (_gwmIsNull(l)) return _gwm_E_GETLAYER;
    l.appendChild(selele);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    // some unknown error
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmUnselectElement(layer, id)
{
  try
  {
    var ele = _gwmCore.svgDoc.getElementById(layer + _gwmGetListSeparator() + id);
    if (_gwmIsNull(ele))
      return _gwm_E_GETELEMENT;
    ele.parentNode.removeChild(ele);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmUnselectAllElements()
{
  try
  {
    var l = _gwmBas.getLayerByName("gwmselected");
    if (_gwmIsNull(l))
      return _gwm_E_GETLAYER;
    while(l.childNodes.length > 0)
      l.removeChild(l.firstChild);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetSelectedElements(layer)
{
  try
  {
    var l = _gwmBas.getLayerByName("gwmselected");
    if (_gwmIsNull(l))
      return _gwm_E_GETLAYER;
    var i = 0;
    var j = 0;
    var len = l.childNodes.length;
    var ele = null;
    var ret = "";
    for(i=0;i<len;i++)
    {
      ele = l.childNodes.item(i);
      if (ele.nodeType != 1) // skip if not an element
        continue;
      var id = ele.getAttribute("id");
      id = id.split(_gwmGetListSeparator());
      if (!_gwmIsNull(layer))
      {
        if (id[0] == layer)
        {
          j++;
          ret += id[0] + _gwmGetListSeparator() + id[1] + _gwmGetListSeparator();
        }
      }
      else
      {
        j++;
        ret += id[0] + _gwmGetListSeparator() + id[1] + _gwmGetListSeparator();
      }
    }
    if (len > 0)
      ret = j + _gwmGetListSeparator() + ret.substring(0, ret.length-1);
    else
      ret = "0";
    return ret;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetSelectStyle()
{
  try
  {
    var l = _gwmBas.getLayerByName("gwmselected");
    if (_gwmIsNull(l))
      return _gwm_E_GETLAYER;
    return l.getAttribute("style");
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetSelectStyle(style)
{
  try
  {
    var l = _gwmBas.getLayerByName("gwmselected");
    if (_gwmIsNull(l))
      return _gwm_E_GETLAYER; // TODO: throw exception?
    l.setAttribute("style", style);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}


//----------------------------------------------
/*** FILE, LAYERS, ELEMENTS ***/
//-----------------------------------------------


//=========================================================
function _gwmEraseTooltip()
{
  try
  {
    _gwmCore.clearTooltip();
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmDisplayTooltip(tt, x, y)
{
  try
  {
    if ( _gwmIsNull(tt) || _gwmIsUnDef(x) || _gwmIsUnDef(y) )
      return _gwm_E_PARAMNULL;
      
    var x2, y2;
    // translate the input coords to viewbox coords
    x2 = _gwmBas.transXCoordToViewer(x, _gwmBas.iCoordUnits);
    y2 = _gwmBas.transYCoordToViewer(y, _gwmBas.iCoordUnits);
    
    var root = _gwmCore.svgRoot;
    var pnt = _gwmBas.getPntViewCtrlPixDim();
    // get the pixel dimensions
    
    // viewbox to pixel ratios
    var rx =(_gwmCore.iViewW/pnt.x);
    var ry =(_gwmCore.iViewH/pnt.y);
    
    // convert the viewbox coords to pixel coords, which showTooltip needs
    x2 = x2/rx;
    y2 = y2/ry;
    pnt.x = x2;
    pnt.y = y2;
    _gwmCore.showTooltip(null, pnt, tt);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmDisplayElementTooltip(l, id, tt)
{
  try
  {
    if ( _gwmIsNull(l) || _gwmIsNull(id) )
      return _gwm_E_PARAMNULL;
      
    var ele = _gwmBas.getElement(l, id);
    if (null == ele)
      return _gwm_E_GETELEMENT;
    if (_gwmIsNull(tt))
      tt = _gwmCore.getTooltip(ele);
    
    var root = _gwmCore.svgRoot;
    var bb = _gwmGetBBox(ele);
    var x = bb.x + bb.width/2;
    var y = bb.y + bb.height/2;
    // get the pixel dimensions
    var pnt = _gwmBas.getPntViewCtrlPixDim();
    
    // viewbox to pixel ratios
    var rx =(_gwmCore.iViewW/pnt.x);
    var ry =(_gwmCore.iViewH/pnt.y);
    
    x = x/rx;
    y = y/ry;
    pnt.x = x;
    pnt.y = y;
    _gwmCore.showTooltip(null, pnt, tt);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetLayerPriority(sLayer)
{
  try
  {
    if (_gwmIsNull(sLayer)) return _gwm_E_PARAMNULL;
    var pri = _gwmBas.getLayerAttribute(sLayer, _gwmCore.ns + ":pri");
    if( null == pri ) return _gwm_E_GETLAYER;
    return pri;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetLayerNames(layerTypeMask)
{
  try
  {
    return ( _gwmBas.getLayerNames(layerTypeMask) );
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetLayerEnabled( sLyrName )
{
  try
  {
    if (_gwmIsNull(sLyrName)) return _gwm_E_PARAMNULL;
    var temp = _gwmBas.getLayerAttribute(sLyrName, _gwmCore.ns + ":layerenabled");
    if( null == temp ) return _gwm_E_GETLAYER;
    if ("" == temp || "true" == temp) return true;
    else return false;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetLayerEnabled( sLyrName, bEna )
{
  try
  {
    if (!_gwmIsNull(sLyrName))
      return(_gwmBas.setLayerAttribute(sLyrName, _gwmCore.ns + ":layerenabled", bEna));
    else
    {
      // apply to all layers
      var layers = _gwmBas.getLayerNames().split(_gwmGetListSeparator());
      var c = layers.length;
      if( c <= 0 ) return _gwm_E_GETLAYER;
      for(var i=0;i<c;i++)
      {
        _gwmBas.setLayerAttribute(layers[i], _gwmCore.ns + ":layerenabled", bEna);
      }
    }
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetTooltipsEnabled( sLyrName )
{
  try
  {
    if (_gwmIsNull(sLyrName)) return _gwm_E_PARAMNULL;
    var sEna = _gwmBas.getLayerAttribute(sLyrName, _gwmCore.ns + ":tooltipsenabled");
    if( null == sEna ) return _gwm_E_GETLAYER;
    if( sEna == "" || sEna == "true" ) return true;
    else return false;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetTooltipsEnabled( sLyrName, bEna )
{
  try
  {
    if (!_gwmIsNull(sLyrName))
      return(_gwmBas.setLayerAttribute(sLyrName, _gwmCore.ns + ":tooltipsenabled", bEna));
    else
    {
      // apply to all layers
      var layers = _gwmBas.getLayerNames().split(_gwmGetListSeparator());
      var c = layers.length;
      if( c <= 0 ) return _gwm_E_GETLAYER;
      for(var i=0;i<c;i++)
      {
        _gwmBas.setLayerAttribute(layers[i], _gwmCore.ns + ":tooltipsenabled", bEna);
      }
    }
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetHotspotsEnabled( sLyrName )
{
  try
  {
    if (_gwmIsNull(sLyrName)) return _gwm_E_PARAMNULL;
    var sEna = _gwmBas.getLayerAttribute(sLyrName, _gwmCore.ns + ":hotspotsenabled");
    if( null == sEna ) return _gwm_E_GETLAYER;
    if( sEna == "" || sEna == "true" ) return true;
    else return false;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetHotspotsEnabled( sLyrName, bEna )
{
  try
  {
    if (!_gwmIsNull(sLyrName))
      return(_gwmBas.setLayerAttribute(sLyrName, _gwmCore.ns + ":hotspotsenabled", bEna));
    else
    {
      // apply to all layers
      var layers = _gwmBas.getLayerNames().split(_gwmGetListSeparator());
      var c = layers.length;
      if( c <= 0 ) return _gwm_E_GETLAYER;
      for(var i=0;i<c;i++)
      {
        _gwmBas.setLayerAttribute(layers[i], _gwmCore.ns + ":hotspotsenabled", bEna);
      }
    }
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetLayerVisible( sLyrName )
{
  try
  {
    if (_gwmIsNull(sLyrName)) return _gwm_E_PARAMNULL;      
    var sVis = _gwmBas.getLayerAttribute(sLyrName, "visibility");
    if( null == sVis ) return _gwm_E_GETLAYER;
    if( sVis == "" || sVis == "visible" ) return true;
    else return false;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetLayerVisible( sLyrName, bVis )
{
  try
  {
    var vis;
    if (bVis)
    {
      vis = "visible";
    }
    else
    {
      vis = "hidden";
    }
    if (!_gwmIsNull(sLyrName))
    {
      return(_gwmBas.setLayerAttribute(sLyrName, "visibility", vis));
    }
    else
    {
      // apply to all layers
      var layers = _gwmBas.getLayerNames().split(_gwmGetListSeparator());
      var c = layers.length;
      if( c <= 0 ) return _gwm_E_GETLAYER;
      for(var i=0;i<c;i++)
      {
        _gwmBas.setLayerAttribute(layers[i], "visibility", vis);
      }
    }
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmUnloadLayer(sLayer)
{
  try
  {
    if (_gwmIsNull(sLayer))
    {
      // remove all layers
      var layers = _gwmGetLayerNames(63).split(_gwmGetListSeparator());
      var c = layers.length;
      if( c <= 0 ) return _gwm_E_GETLAYER;
      for(var i = 0;i<c;i++)
      {
        var layer = _gwmCore.svgDoc.getElementById(layers[i]);  
        layer.parentNode.removeChild(layer);
      }
      return _gwm_E_SUCCESS;
    }
      
    var lyr = _gwmBas.getLayerByName(sLayer);
    if (null == lyr)
    {
      return _gwm_E_GETLAYER;
    }
      
    lyr = lyr.parentNode.removeChild(lyr);
    if (null == lyr)
    {
      return _gwm_E_UNKNOWN;
    }
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetLayerPriority(sLayer, iPriority)
{
  try
  {
    iPriority = parseInt(iPriority);
    if ( _gwmIsNull(sLayer) || isNaN(iPriority) )
      return _gwm_E_PARAMINVALID;
  
    if (iPriority < 1 || iPriority > 65535)
      iPriority = 1000;
      
    var layer = _gwmBas.getLayerByName(sLayer);
    if (_gwmIsNull(layer))
      return _gwm_E_GETLAYER;
      
    var allgraphics = layer.parentNode;
    layer = allgraphics.removeChild(layer);
    _gwmBas.insertLayerWithPriority(layer, iPriority);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetElementProperty(iProperty, sLayer, sID)
{
  try
  {
    iProperty = parseInt(iProperty);
    if( isNaN(iProperty) || _gwmIsNull(sLayer) || _gwmIsNull(sID) )
      return _gwm_E_PARAMINVALID;
      
    var ele = _gwmBas.getElement(sLayer, sID);
    if (null == ele)
      return _gwm_E_GETELEMENT;
    
    switch (iProperty)
    {
      case 0: // tooltip
        ret = _gwmCore.getTooltip(ele);
        break;
      case 1: // visibility
        var style = ele.style;
        if (style.getPropertyValue("visibility") != "hidden")
        {
          ret = "true";
        }
        else
        {
          ret = "false";
        }
        break;
      case 2: // action
        ret = _gwmCore.getAction(ele);
        break;
      default: 
        return _gwm_E_PARAMINVALID;
    }
    return ret;     
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetElementProperty(iProperty, sLayer, sID, newval)
{
  try
  {
    iProperty = parseInt(iProperty);
    if ( isNaN(iProperty) || _gwmIsNull(sLayer) || _gwmIsNull(sID) )
      return _gwm_E_PARAMINVALID;
    
    var ele = _gwmBas.getElement(sLayer, sID);
    if (null == ele)
      return _gwm_E_GETELEMENT;
    
    switch (iProperty)
    {
      case 0: // tooltip
        _gwmCore.setTooltip(ele, newval);
        break;
      case 1: // visibility
        var sVis = "";
        if( newval.toLowerCase() == "true" ) sVis = "visible";
        else if( newval.toLowerCase() == "false" ) sVis = "hidden";
        if( sVis == "" ) return _gwm_E_PARAMINVALID;
        var style = ele.style;
        style.setProperty("visibility", sVis);
        break;
      case 2: // action
        _gwmCore.setAction(ele, newval);
        break;
      default:
        return _gwm_E_PARAMINVALID;
        break;
    }
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmLoadString(sSVG, sLyrName, iPriority, iLoadMode)
{
  try
  {
    if (_gwmIsNull(sSVG))
      return _gwm_E_PARAMNULL;
      
    // CDF 08/03/04 update to clear TTips b4 load
    _gwmEraseTooltip();
    
    // PMW 08/18/03 update for replacing all file content
    if (_gwmIsNull(iLoadMode))
    {
      iLoadMode = 0;
    }
    _gwmAPI.iLoadMode = parseInt(iLoadMode);
    if (isNaN(_gwmAPI.iLoadMode))
      _gwmAPI.iLoadMode = 0;
      
    iPriority = parseInt(iPriority);
    if (isNaN(iPriority))
      iPriority = 1000;
    if (iPriority <= 0 || iPriority > 65535)
      iPriority = 1000;
    _gwmAPI.iLoadFilePriority = iPriority;
    _gwmAPI.sLoadFileLayerName = sLyrName;
    // the SVG Viewer's getURL, when complete, will callback to our _gwmFileLoaded 
    _gwmFileLoaded(sSVG);
    return _gwm_E_SUCCESS; // NOTE: this does not mean the file was loaded successfully
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}
  
//=========================================================
function _gwmLoadFile(sFile, sLyrName, iPriority, iLoadMode)
{
  try
  {
    if (_gwmIsNull(sFile))
      return _gwm_E_PARAMNULL;
      
    // CDF 08/03/04 update to clear TTips b4 load
    _gwmEraseTooltip();
    
    // PMW 08/18/03 update for replacing all file content
    if(_gwmIsNull(iLoadMode)||_gwmIsUnDef(iLoadMode))
    {
      iLoadMode = 0;
    }
    _gwmAPI.iLoadMode = parseInt(iLoadMode);
    if (isNaN(_gwmAPI.iLoadMode))
      _gwmAPI.iLoadMode = 0;
      
    iPriority = parseInt(iPriority);
    if (isNaN(iPriority))
      iPriority = 1000;
    if (iPriority <= 0 || iPriority > 65535)
      iPriority = 1000;
    _gwmAPI.iLoadFilePriority = iPriority;
    _gwmAPI.sLoadFile = sFile; 
    _gwmAPI.sLoadFileLayerName = sLyrName;
    // the SVG Viewer's getURL, when complete, will callback to our _gwmFileLoaded 
    _gwmBas.viewCtrl.window.getURL(sFile, _gwmFileLoaded);
    return _gwm_E_SUCCESS; // NOTE: this does not mean the file was loaded successfully
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=======================================================
/**
Error values:
-1: file data was not loaded successfully
-2: file data could not be parsed as XML
-3: could not find root svg node in file
-4: could not find the all graphics group in file
-5: could not find all graphics group in destination
**/
//=========================================================
function _gwmFileLoaded(data)
{
  var status = 0;
  var bIsAsynch = false;
  try
  {
    //first get the xml string
    var string = "";
    if (typeof(data) == "object")
    {
      bIsAsynch = true;
      if(data.success)
      {
        string = data.content;
      }
      else
      {
        // The file data was not successfully loaded
        throw -1;
      }
    }
    else
    {
      string = data;
    }
    // PMW 3/17/04 - Fix for ASV6 - it doesn't like the XML tag at the beginning
    string = string.substr(string.indexOf("?>") + 2);
    // now parse it into a document
    var node = _gwmBas.viewCtrl.window.parseXML(string, _gwmCore.svgDoc);
    if (_gwmIsNull(node))
    {
      // error parsing the xml stream
      throw -2;
    }
    var svgroot = null;
    var len = node.childNodes.length;
    var i;
    // loop through the child nodes of the fragment, looking for the svg node
    for(i=0;i<len;i++)
    {
      if (node.childNodes.item(i).nodeName == "svg")
      {
        svgroot = node.childNodes.item(i);
        break;
      }
    }
    if (null == svgroot)
    {
      //Could not find root svg node in source file
      throw -3;
    }
    var newviewbox = svgroot.getAttribute("viewBox");
    var gwmmask = null;
    var bMaskFound = false;
    var bAllFound = false;
    var gall = null;
    // if we found the root svg node, loop through its children looking for the all graphics layer (id=_GWMAll)
    for(i=0;i<svgroot.childNodes.length&&!(bMaskFound&&bAllFound);i++)
    {
      if (svgroot.childNodes.item(i).id == "gwmmask")
      {
        gwmmask = svgroot.childNodes.item(i);
        bMaskFound = true;
      }
      else if (svgroot.childNodes.item(i).id == "_GWMAll")
      {
        gall = svgroot.childNodes.item(i);
        bAllFound = true;
      }
    }
    if (!bAllFound)
    {
      //Could not find the GWM all graphics layer in source file
      //just dump contents of svg file into specified layer name
      // build the layer element
      var layer = _gwmCore.svgDoc.createElementNS("http://www.w3.org/TR/svg", "g"); 
      layer.setAttribute("id", _gwmAPI.sLoadFileLayerName);
      layer.setAttribute(_gwmCore.ns + ":pri", _gwmAPI.iLoadFilePriority);
      layer.setAttribute(_gwmCore.ns + ":typ", "l");
      layer.appendChild(svgroot);
      // and finally, add and return the new layer
      var success = _gwmBas.insertLayerWithPriority(layer, _gwmAPI.iLoadFilePriority);
      if (success == null)
        status = _gwm_E_UNKNOWN;
    }
    else
    {
      //var gall = svgroot.childNodes.item(i);
     
      // first get allgraphics node
      var ginsert = _gwmBas.getAllGraphicsLayer();
      if (ginsert == null)
      {
        //Could not get the all graphics layer in target document
        throw -5;
      }
      
      if (_gwmAPI.iLoadMode == 1)
      {
        // replace all file content
        // update the viewBox
        svgroot = ginsert.parentNode;
        svgroot.setAttribute("viewBox", newviewbox);
        // update the mask
        var curmask = _gwmCore.svgDoc.getElementById("gwmmask"); 
        svgroot.replaceChild(gwmmask, curmask);
        // update the graphics
        svgroot.replaceChild(gall, ginsert);
        // now update the transformation params & logo
        _gwmCore.updateView();
        _gwmBas.initMeasure();
        _gwmCore.updateLogo();
      }
      else
      {
        for(i=0;i<gall.childNodes.length;i++)
        {
          if (gall.childNodes.item(i).nodeType != 1)
            continue;
          // don't add the logo, background rect, or anything with "BGROUND" in it
          node = gall.childNodes.item(i);
          var id = node.getAttribute("id");
          if (id== "_GWMMetadata" || id == "_GWMLogo" || id == "gwmbg" || (id.indexOf("BGROUND") >= 0) || id == "gwmselected")
          {
            continue;
          }
          if (id == "gwmstyles")
          {
            // styles, try to add to current style node
            var styles = _gwmCore.svgDoc.getElementById("gwmstyles");
            if (styles == null)
            {
              // no style node, so just append it
              ginsert.appendChild(node);
            }
            else
            {
              // add these styles to the current style node
              // this doesn't work??
              /*
              var styletext = node.firstChild.data + styles.firstChild.data;
              while (styles.hasChildNodes())
                styles.removeChild(styles.firstChild);
              var stylenode = _gwmCore.svgDoc.createTextNode(styletext);
              styles.appendChild(stylenode);
              */
              var newid = "gwmstyles";
              for(var j=0;j>-1;j++)
              {
                newid = "gwmstyles" + j;
                if (_gwmCore.svgDoc.getElementById(newid) == null) 
                  break;
              }
              node.setAttribute("id", newid);
              ginsert.appendChild(node);
            }
          }
          else if ("l" == node.getAttribute(_gwmCore.ns + ":typ"))
          {
            // if it has an id, check it
            if (!_gwmIsNull(id))
            {
              var existingnode = _gwmCore.svgDoc.getElementById(node.getAttribute("id"));  
              if (null != existingnode)
              {
                // an element with this id already exists, 1-up
                var newid = "";
                for(var j=0;j>-1;j++)
                {
                  newid = id + j;
                  if (_gwmCore.svgDoc.getElementById(newid) == null)  
                    break;
                }
                node.setAttribute("id", newid);
              }
            }
            _gwmBas.insertLayerWithPriority(node, _gwmAPI.iLoadFilePriority);
          }
          else if ("defs" == node.nodeName || "style" == node.nodeName)
          {
            // just append the defs & styles
            ginsert.appendChild(node);
          }// end element type
        }// end for all children in source file
      }// end if iLoadMode == 1...else...
    }// end if i == svgroot.childNodes.length {} else
  }// end try
  catch(e)
  {
    status = parseInt(e);
    if (isNaN(status))
      status = _gwm_E_UNKNOWN;
  }
  
  if (bIsAsynch)
  {
    if (_gwmAPI.UserEvtHandlerLoadFileComplete != null) //User's callback
    {
      _gwmAPI.UserEvtHandlerLoadFileComplete(_gwmAPI.sLoadFile,
                                            status,
                                            _gwmAPI.sUserEvtInfoLoadFileComplete);
    }
  }
  return status;
  
}// end function

//=========================================================
function _gwmLoadRasterFile(sFile, sLyrName, iPriority, xMin, yMin, xMax, yMax)
{
  try
  {
    // validate inputs
   if ( _gwmIsNull(sFile) ||
        _gwmIsUnDef(xMin) ||
        _gwmIsUnDef(xMax) ||
        _gwmIsUnDef(yMin) ||
        _gwmIsUnDef(yMax) )
      return _gwm_E_PARAMNULL;
      
    // check the layer name
    var layer = null;
    if (_gwmIsNull(sLyrName))
    {
      // if its missing, use _GWMRaster, and 1-up until we find an unused name
      sLyrName = "_GWMRaster";
      layer = _gwmBas.getLayerByName(sLyrName);
      var i = -1;
      while(!_gwmIsNull(layer))
      {
        i++;
        sLyrName = "_GWMRaster" + i;
        layer = _gwmBas.getLayerByName(sLyrName);
      }
    }
    else
    {
      // if the layer name was supplied, make sure it isn't used
      var layer = _gwmBas.getLayerByName(sLyrName);
      // if the layer name is already used, 1-up until we find an unused name
      var i = -1;
      while (!_gwmIsNull(layer))
      {
        i++;
        layer = _gwmBas.getLayerByName(sLyrName + i);
      }
      if (i > -1)
        sLyrName += i;
    }
    
    // check the priority, default to 999999 if not given
    iPriority = parseInt(iPriority);
    if (isNaN(iPriority))
      iPriority = 1000;
    else if (iPriority <= 0 || iPriority > 65535)
      iPriority = 1000;
    
    var xlinkns = "http://www.w3.org/1999/xlink";
    var svgns = "http://www.w3.org/2000/svg";
    var gwmns = "http://www.intergraph.com/GeoMedia/wmsvg";
    
    // translate the coords from the current coordinate unit to the viewer
    var xminv, xmaxv, yminv, ymaxv;
    xminv = _gwmBas.transXCoordToViewer(xMin, _gwmBas.iCoordUnits);
    xmaxv = _gwmBas.transXCoordToViewer(xMax, _gwmBas.iCoordUnits);
    yminv = _gwmBas.transYCoordToViewer(yMin, _gwmBas.iCoordUnits);
    ymaxv = _gwmBas.transYCoordToViewer(yMax, _gwmBas.iCoordUnits);
    
    // build the image tag
    var img = _gwmCore.svgDoc.createElementNS(svgns, "image"); 
    img.setAttributeNS(xlinkns, "xlink:href", sFile);
    img.setAttributeNS(null, "x", xminv);
    img.setAttributeNS(null, "y", yminv);
    img.setAttributeNS(null, "width", xmaxv - xminv);
    img.setAttributeNS(null, "height", ymaxv - yminv);
    // build the layer element
    layer = _gwmCore.svgDoc.createElementNS(svgns, "g"); 
    layer.setAttribute("id", sLyrName);
    layer.setAttribute(_gwmCore.ns + ":pri", iPriority);
    layer.setAttribute(_gwmCore.ns + ":typ", "l");
    layer.appendChild(img);
    // and finally, add and return the new layer
    var success = _gwmBas.insertLayerWithPriority(layer, iPriority);
    if (null != success)
      return _gwm_E_SUCCESS;
    else
      return _gwm_E_UNKNOWN;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//----------------------
/*** VIEW NAVIGATION ***/
//----------------------

//=========================================================
function _gwmCmdFitElement()
{
  try
  {
    _gwmBas.cmdViewNavInit(_gwmBasME.GETELEMENT, _gwmCmdFitElementCallback, "");
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdFitElementCallback(ele, userinfo)
{
  try
  {
    _gwmFitEle(ele);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//===========================================================
function _gwmGetBBox(ele)
{
  try
  {
    if (_gwmIsNull(ele))
      return _gwm_E_PARAMNULL;
    
    var bb = ele.getBBox();
    if (bb.x == 0 && bb.y == 0 && bb.width == 0 && bb.height == 0)
    {
      // must be a <use> tag (point)
      if (ele.nodeName == "use")
      {
        // a point element - get the def
        var def = ele.getAttribute("xlink:href");
        def = _gwmCore.svgDoc.getElementById(def.substr(1));
        bb = def.getBBox();
        bb.x += parseInt(ele.getAttribute("x"));
        bb.y += parseInt(ele.getAttribute("y"));
      }
    }
    return bb;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmFitEle(ele, zoomfactor)
{
  try
  {
    if (_gwmIsNull(ele))
      return _gwm_E_PARAMNULL;
      
    var bb = _gwmGetBBox(ele);
    var x1, y1, x2, y2;
    if (ele.nodeName == "use")
    {
      if (_gwmIsNull(zoomfactor)||_gwmIsUnDef(zoomfactor))
      {
        // if the user didn't specify a zoom factor, determine a new
        // one based on the relative size of the def
        var rx = bb.width / _gwmCore.iViewW;
        var ry = bb.height / _gwmCore.iViewH;
        if (rx > ry)
        {
          zoomfactor = .025/rx;
        }
        else
        {
          zoomfactor = .025/ry;
        }
      }
    }
    
    x1 = _gwmBas.transXCoordFromViewer(bb.x, _gwmBas.iCoordUnits);
    y1 = _gwmBas.transYCoordFromViewer(bb.y, _gwmBas.iCoordUnits);
    x2 = _gwmBas.transXCoordFromViewer(bb.x + bb.width, _gwmBas.iCoordUnits);
    y2 = _gwmBas.transYCoordFromViewer(bb.y + bb.height, _gwmBas.iCoordUnits);
    
    // check for points
      
    // get the zoomfactor
    if (_gwmIsNull(zoomfactor)||_gwmIsUnDef(zoomfactor))
      zoomfactor = _gwmAPI.fZoomFactor;
    else
      zoomfactor = parseFloat(zoomfactor);
    if (zoomfactor < 1.0)
      zoomfactor = 1.0;
    
    // update view range based on zoom factor
    if (1.0 != zoomfactor)
    {
      var widthadjustment = (zoomfactor*(x2-x1) - (x2-x1))/2;
      var heightadjustment = (zoomfactor*(y2-y1) - (y2-y1))/2;
      x1 -= widthadjustment;
      y1 -= heightadjustment;
      x2 += widthadjustment;
      y2 += heightadjustment;
    }
    return _gwmSetViewRange(x1,y1,x2,y2);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmFitElement(layer, id, zoomfactor)
{
  try
  {
    // check inputs
    if  ( _gwmIsNull(layer) || _gwmIsNull(id) )
      return _gwm_E_PARAMNULL;
    
    // get the element object, and verify it
    var ele = _gwmBas.getElement(layer, id);
    if (_gwmIsNull(ele))
      return _gwm_E_GETELEMENT;
      
    // if everything's ok, fit it
    _gwmFitEle(ele, zoomfactor);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmRefreshView()
{
  return _gwm_E_SUCCESS;
}

//=========================================================
function _gwmCmdPanView( UserCallback, sUserInfo )
{
  // NOTES:
  //  - due to poor performance of the SVG Viewers tested, 
  //    this command should only be used in well-tested, limited 
  //    situations where a performance issue is not apparent.
  try
  {
    _gwmBas.cmdPanInit(UserCallback,sUserInfo);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdShiftView()
{
  try
  {
    _gwmCmdCaptureLine(_gwmBas.shiftViewProcess, "", true);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCenterDynamicView(x,y)
{
  try
  {
    if( _gwmAPI.iDNTLoop == 0 )
    {
      // verify inputs
      if ( _gwmIsUnDef(x) || _gwmIsUnDef(y) ) return _gwm_E_PARAMNULL;
        
      _gwmAPI.bDNInProg = true;
            
      // convert inputs to numbers for ending center location
      var endCx = parseFloat(x);
      var endCy = parseFloat(y);   
      
      // get current view range (cvr)
      var viewcoords = _gwmBas.getViewRange();
      var coords = viewcoords.split(_gwmBas.sListSeparator);
      var x1 = parseFloat(coords[0]);
      var y1 = parseFloat(coords[1]);
      var x2 = parseFloat(coords[2]);
      var y2 = parseFloat(coords[3]);
      
      var curCx = x1 + ((x2 - x1)/2);
      var curCy = y1 + ((y2 - y1)/2);
      var dx = endCx - curCx;
      var dy = endCy - curCy;       
   
      // calc values to change dynamic center in incremental steps
      var dynCDx = dx / _gwmAPI.iDynNavSteps; 
      var dynCDy = dy / _gwmAPI.iDynNavSteps;   
      
      // global values to interate over
      _gwmAPI.fDNVRdx = dynCDx;
      _gwmAPI.fDNVRdy = dynCDy;
      
      // set starting point for centering
      _gwmAPI.fDNVRx1 = curCx;
      _gwmAPI.fDNVRy1 = curCy;
      
      // store starting point for later func calls
      _gwmAPI.fDNCntrX = curCx;
      _gwmAPI.fDNCntrY = curCy;   
    }

    if( _gwmAPI.iDNTLoop >= _gwmAPI.iDynNavSteps )
    {
      // All done.
      _gwmAPI.iDNTLoop = 0;
      _gwmAPI.bDNInProg = false;
      window.clearTimeout();

      if(_gwmIsValidFunction(_gwmAPI.DNFuncInWaiting))
      {
        //TO DO: if more than just the Zoom funcs use this, need to setup
        //  test for what nav process is in progress.
        _gwmAPI.DNFuncInWaiting( _gwmAPI.bDZIn, _gwmAPI.fDNCntrX, _gwmAPI.fDNCntrY );
      }   
      else
      {
        if( null != _gwmAPI.cmdCallback )
          _gwmAPI.cmdCallback(_gwmAPI.sCoordList, _gwmAPI.sUserInfo);
        _gwmAPI.cmdCallback = null;
        _gwmAPI.sCoordList  = null;      
      }
      return;
    }

    _gwmAPI.iDNTLoop += 1;  // increment timer loop counter
    _gwmAPI.fDNVRx1  += _gwmAPI.fDNVRdx;
    _gwmAPI.fDNVRy1  += _gwmAPI.fDNVRdy;

    _gwmCenterView( _gwmAPI.fDNVRx1, _gwmAPI.fDNVRy1 );

    window.setTimeout("_gwmCenterDynamicView()", 120);
  }
  catch(e)
  {
//window.alert("_gwmCenterDynamicView: CATCH ERROR e=" + e);     
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCenterView(x,y)
{
  try
  {
    // verify inputs
    if ( _gwmIsUnDef(x) || _gwmIsUnDef(y) )
      return _gwm_E_PARAMNULL;
      
    // If in dynamic mode, go there.
    if( _gwmAPI.bDynNav == true && _gwmAPI.bDNInProg == false )
    {
      _gwmAPI.iDNTLoop = 0;
      _gwmAPI.bDNInProg = true;
      _gwmAPI.DNFuncInWaiting = null;
      _gwmCenterDynamicView(x, y);
      return;
    }
    
    // convert inputs to numbers
    x = parseFloat(x);
    y = parseFloat(y);
    
    // get the pixel dimensions
    var root = _gwmCore.svgRoot;
    
    // pixel center
    var pixeldims = _gwmBas.getPntViewCtrlPixDim();
    var pixelCenter = root.createSVGPoint();
    pixelCenter.x = pixeldims.x / 2;
    pixelCenter.y = pixeldims.y / 2;
    
    // viewbox to pixel ratios
    var rx =(_gwmCore.iViewW/pixeldims.x);
    var ry =(_gwmCore.iViewH/pixeldims.y);
    
    // get the current scale
    var scale = root.currentScale;
    
    // translate the input coords to viewbox coords
    x = _gwmBas.transXCoordToViewer(x, _gwmBas.iCoordUnits);
    y = _gwmBas.transYCoordToViewer(y, _gwmBas.iCoordUnits);
    
    // calculate the current center of the map, in viewbox coords
    var matrix = _gwmCore.getSVGTransMatrix();
    var viewCenter;
    viewCenter = pixelCenter.matrixTransform(matrix);
    
    // calculate the shift
    var sx = ((viewCenter.x-x)/(rx/scale));
    var sy = ((viewCenter.y-y)/(ry/scale));

    // apply the shift
    root.currentTranslate.x += sx;
    root.currentTranslate.y += sy;
    return _gwm_E_SUCCESS;

  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdCenterView(UserCallback, sUserInfo)
{
  try
  {
    _gwmAPI.cmdCallback = null;
    if( _gwmBas.isValidFunction(UserCallback) )
      _gwmAPI.cmdCallback = UserCallback;
    _gwmAPI.sUserInfo = sUserInfo;  
    
    return _gwmCmdCapturePoint(_gwmCmdCenterViewCallback, "", true);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdCenterViewCallback(sCoords, sUserInfo)
{
  try
  {
    if (_gwmIsNull(sCoords))
      return _gwm_E_PARAMNULL;
      
    var coords = sCoords.split(_gwmGetListSeparator());
    var x = coords[1];
    var y = coords[2];
    
    if( _gwmAPI.bDynNav == true )
    {
      _gwmAPI.sCoordList = sCoords;         
      _gwmCenterDynamicView(x,y);
    }
    else
    {
      _gwmCenterView(x,y);
      if( null != _gwmAPI.cmdCallback )
        _gwmAPI.cmdCallback(sCoords, _gwmAPI.sUserInfo);
    }        
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdZoomInView(UserCallback, sUserInfo)
{
//_gwmBas.DBGTEXT = "";

  try
  {
    _gwmAPI.cmdCallback = null;
    if( _gwmBas.isValidFunction(UserCallback) )
      _gwmAPI.cmdCallback = UserCallback;
    _gwmAPI.sUserInfo = sUserInfo;
    
    return _gwmCmdCapturePoint(_gwmCmdZoomInViewCallback, "", true);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdZoomInViewCallback(sCoords, sUserInfo)
{

  try
  {
    if (_gwmIsNull(sCoords))
      return _gwm_E_PARAMNULL;      
    var coords = sCoords.split(_gwmGetListSeparator());
    var x = parseFloat(coords[1]);
    var y = parseFloat(coords[2]);
    
    if( _gwmAPI.bDynNav == true )
    {
      _gwmAPI.iDNTLoop = 0;
      _gwmAPI.bDZIn = true;
      _gwmAPI.sCoordList = sCoords;
      //set the func to callback after centering is done
      _gwmAPI.DNFuncInWaiting = _gwmZoomDynamicView;
      _gwmCenterDynamicView(x,y);
      //_gwmZoomDynamicView(true,x,y);
    }
    else
    {
      _gwmZoomInView(x,y);
      if( null != _gwmAPI.cmdCallback )
        _gwmAPI.cmdCallback(sCoords, _gwmAPI.sUserInfo);
    }
      
    return;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmZoomInView(x, y, zf)
{
  try
  {
    // determine the coords to center on - given (x,y) or the current center of the map
    var root = _gwmCore.svgRoot;
    var zoomFac = 1.0;
    
    if( _gwmIsUnDef(zf) ) 
      zoomFac = _gwmAPI.fZoomFactor;
    else
      zoomFac = zf;
    
    if( _gwmIsUnDef(x) || _gwmIsUnDef(y) )
    {
      var matrix = _gwmCore.getSVGTransMatrix();
      // one of the coords is empty, zoom on the center
      // get the pixel dimensions
      var pixeldims = _gwmBas.getPntViewCtrlPixDim();
      
      // pixel center
      var pixelCenter = root.createSVGPoint();
      pixelCenter.x =(pixeldims.x/2);
      pixelCenter.y =(pixeldims.y/2);
      
      // calculate the current center of the map
      var viewCenter = pixelCenter.matrixTransform(matrix);
      // now translate the view center coords to the current coord units
      x = _gwmBas.transXCoordFromViewer(viewCenter.x, _gwmBas.iCoordUnits);
      y = _gwmBas.transYCoordFromViewer(viewCenter.y, _gwmBas.iCoordUnits);
      
    }
    
    if( _gwmAPI.bDynNav == true && _gwmAPI.bDNInProg == false )
    {
      _gwmAPI.bDNInProg = true;
      _gwmZoomDynamicView(true, x, y);
    }
    else
    {
      // first zoom in
      root.currentScale *= zoomFac;
      // now re-center 
      return _gwmCenterView(x,y);
    }
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdZoomOutView(UserCallback, sUserInfo)
{
  try
  {
    _gwmAPI.cmdCallback = null;
    if( _gwmBas.isValidFunction(UserCallback) )
      _gwmAPI.cmdCallback = UserCallback;
    _gwmAPI.sUserInfo = sUserInfo;  
    
    return _gwmCmdCapturePoint(_gwmCmdZoomOutViewCallback, "", true);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdZoomOutViewCallback(sCoords, sUserInfo)
{
  try
  {
    if (_gwmIsNull(sCoords))
      return _gwm_E_PARAMNULL;
    var coords = sCoords.split(_gwmGetListSeparator());
    var x = coords[1];
    var y = coords[2];
    
    if( _gwmAPI.bDynNav )
    {
      _gwmAPI.iDNTLoop = 0;
      _gwmAPI.bDZIn = false;    
      _gwmAPI.sCoordList = sCoords;      
      //set the func to callback after dynamic centering is done
      _gwmAPI.DNFuncInWaiting = _gwmZoomDynamicView;
      _gwmCenterDynamicView(x,y);
      //_gwmZoomDynamicView(false,x,y);
    }      
    else
    {
      _gwmZoomOutView(x,y);
      if( null != _gwmAPI.cmdCallback )
        _gwmAPI.cmdCallback(sCoords, _gwmAPI.sUserInfo);      
    }      

    return;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmZoomOutView(x, y, zf)
{
  try
  {
    // determine the coords to center on - given (x,y) or the current center of the map
    var root = _gwmCore.svgRoot;
    var zoomFac = 1.0;
    
    if( _gwmIsUnDef(zf) ) 
      zoomFac = _gwmAPI.fZoomFactor;
    else
      zoomFac = zf;    
    
    if( _gwmIsUnDef(x) || _gwmIsUnDef(y) )
    {
      var matrix = _gwmCore.getSVGTransMatrix();
      // one of the coords is empty, zoom on the center
      // get the pixel dimensions
      var pixeldims = _gwmBas.getPntViewCtrlPixDim();
      
      // pixel center
      var pixelCenter = root.createSVGPoint();
      pixelCenter.x =(pixeldims.x/2);
      pixelCenter.y =(pixeldims.y/2);
      
      // calculate the current center of the map
      var viewCenter = pixelCenter.matrixTransform(matrix);
      // now translate the view center coords to the current coord units
      x = _gwmBas.transXCoordFromViewer(viewCenter.x, _gwmBas.iCoordUnits);
      y = _gwmBas.transYCoordFromViewer(viewCenter.y, _gwmBas.iCoordUnits);
    }
    
    if( _gwmAPI.bDynNav == true && _gwmAPI.bDNInProg == false )
    {
      _gwmAPI.bDNInProg = true;
      _gwmZoomDynamicView(false, x, y);
    }
    else
    {
      // first zoom out
      root.currentScale /= zoomFac;
      // now re-center
      return _gwmCenterView(x,y);
    }
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}


//=========================================================
function _gwmZoomDynamicView(zoomIn, x, y)
{
  
  try
  {
    if( _gwmAPI.iDNTLoop == 0 )
    {  

      if( (_gwmIsUnDef(zoomIn))==false ) _gwmAPI.bDZIn = zoomIn;
      
      // Center view on x, y [if not wanting DynCenterView, use this].
      //_gwmCenterView(x,y);
  
      // get current view range (cvr)
      var viewcoords = _gwmBas.getViewRange();
      var coords = viewcoords.split(_gwmBas.sListSeparator);
      var x1 = parseFloat(coords[0]);
      var y1 = parseFloat(coords[1]);
      var x2 = parseFloat(coords[2]);
      var y2 = parseFloat(coords[3]);
    
      var dx = Math.abs(x2 - x1);
      var dy = Math.abs(y2 - y1);
      
      // calculate dx, dy of final view range (fvr).
      if( _gwmAPI.bDZRect == false )
      {
        if( _gwmAPI.bDZIn == true )
        {
          var fvrDx = dx / _gwmAPI.fZoomFactor;
          var fvrDy = dy / _gwmAPI.fZoomFactor;
        }
        else
        {
          var fvrDx = dx * _gwmAPI.fZoomFactor;
          var fvrDy = dy * _gwmAPI.fZoomFactor;
        }   
      }
      else
      {
        var fvrDx = Math.abs(_gwmAPI.fDZRectX2 - _gwmAPI.fDZRectX1);
        var fvrDy = Math.abs(_gwmAPI.fDZRectY2 - _gwmAPI.fDZRectY1);
        _gwmAPI.bDZRect = false;
      }
      
      // calc values to change dynamic view range (dvr) in incremental steps
      var dvrDx = (Math.abs(dx-fvrDx)) / _gwmAPI.iDynNavSteps; 
      var dvrDy = (Math.abs(dy-fvrDy)) / _gwmAPI.iDynNavSteps; 
  
      // now, modify 'cause we want to change each side only 1/2 that amount, each time.
      dvrDx = dvrDx/2;
      dvrDy = dvrDy/2;
      
      // global settings to reuse during each step. 
  
  /***
      // Adjust for aspect ratio ??
      var ar = _gwmCore.iViewW/_gwmCore.iViewH;
  
      if( ar < 1.0 )
      {
        dvrDx = dvrDx * ar;
        dvrDy += + 1/ar;
      }
      else if( ar > 1.0 )
      {
        dvrDx += dvrDx * ar;
        dvrDy -= dvrDy * ar;    
      }
  ***/
  
      _gwmAPI.fDNVRdx = dvrDx;
      _gwmAPI.fDNVRdy = dvrDy;
      
      // start view range at current.
      _gwmAPI.fDNVRx1 = x1;  
      _gwmAPI.fDNVRy1 = y1;      
      _gwmAPI.fDNVRx2 = x2;  
      _gwmAPI.fDNVRy2 = y2;  
  
      _gwmAPI.bDNInProg = true; //in progress
    }
    
    if( _gwmAPI.iDNTLoop >= _gwmAPI.iDynNavSteps )
    {
      // All done.
      _gwmAPI.iDNTLoop = 0;
      _gwmAPI.bDNInProg = false;
      _gwmAPI.DNFuncInWaiting = null;
      window.clearTimeout();
      if( null != _gwmAPI.cmdCallback )
        _gwmAPI.cmdCallback(_gwmAPI.sCoordList, _gwmAPI.sUserInfo);
      _gwmAPI.cmdCallback = null;
      _gwmAPI.sCoordList  = null;
      return;
    }
    
    _gwmAPI.iDNTLoop += 1;  // increment timer loop counter
        
    if( _gwmAPI.bDZIn == true )
    {
      _gwmAPI.fDNVRx1 += _gwmAPI.fDNVRdx;  
      _gwmAPI.fDNVRy1 -= _gwmAPI.fDNVRdy;      
      _gwmAPI.fDNVRx2 -= _gwmAPI.fDNVRdx;  
      _gwmAPI.fDNVRy2 += _gwmAPI.fDNVRdy;  
    }
    else
    {
      _gwmAPI.fDNVRx1 -= _gwmAPI.fDNVRdx;  
      _gwmAPI.fDNVRy1 += _gwmAPI.fDNVRdy;      
      _gwmAPI.fDNVRx2 += _gwmAPI.fDNVRdx;  
      _gwmAPI.fDNVRy2 -= _gwmAPI.fDNVRdy;  
    }

    _gwmSetViewRange(_gwmAPI.fDNVRx1, _gwmAPI.fDNVRy1, 
                     _gwmAPI.fDNVRx2, _gwmAPI.fDNVRy2);

    window.setTimeout("_gwmZoomDynamicView()", 120);
  }
  catch(e)
  {
//window.alert("_gwmZoomDynamicView CATCH ERROR e=" + e);

    return _gwm_E_UNKNOWN;
  }
  
}

//=========================================================
function _gwmGetViewRange()
{
  return _gwmBas.getViewRange();
}

//=========================================================
function _gwmSetViewRange(x1, y1, x2, y2)
{

  try
  {
    // convert inputs to numbers and store for later use
    var ix1 = parseFloat(x1);
    var ix2 = parseFloat(x2);
    var iy1 = parseFloat(y1);
    var iy2 = parseFloat(y2);
    if (isNaN(ix1) || isNaN(ix2) || isNaN(iy1) || isNaN(iy2))
      return _gwm_E_PARAMNULL;
    
    // first update the scale.
    
    // translate the input coords to viewer
    x1 = _gwmBas.transXCoordToViewer(x1, _gwmBas.iCoordUnits);
    y1 = _gwmBas.transYCoordToViewer(y1, _gwmBas.iCoordUnits);
    x2 = _gwmBas.transXCoordToViewer(x2, _gwmBas.iCoordUnits);
    y2 = _gwmBas.transYCoordToViewer(y2, _gwmBas.iCoordUnits);
  
    var dx = Math.abs(x2 - x1);
    var dy = Math.abs(y2 - y1);
    var sx = dx/_gwmCore.iViewW;
    var sy = dy/_gwmCore.iViewH;
    if (sx > sy)
    {
      _gwmCore.svgRoot.currentScale = 1/sx;
    }
    else
    {
      _gwmCore.svgRoot.currentScale = 1/sy;
    }
    // now center the view on the center of the range
    var cx = 0, cy = 0;
    cx = ix1 + (ix2 - ix1)/2;
    cy = iy1 + (iy2 - iy1)/2;
    return _gwmCenterView(cx, cy);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdZoomRectangleView(UserCallback, sUserInfo)
{
//_gwmBas.DBGTEXT = "";

  try
  {
    _gwmAPI.cmdCallback = null;
    if( _gwmBas.isValidFunction(UserCallback) )
      _gwmAPI.cmdCallback = UserCallback;
    _gwmAPI.sUserInfo = sUserInfo;  
    
    return _gwmCmdCaptureRectangle(_gwmCmdZoomRectangleViewCallback, "", true);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdZoomRectangleViewCallback(sCoords, sUserInfo)
{

  try
  {
    if (_gwmIsNull(sCoords))
      return _gwm_E_PARAMNULL;
    var coords = sCoords.split(_gwmGetListSeparator());
    var x1 = coords[1];
    var y1 = coords[2];
    var x2 = coords[3];
    var y2 = coords[4];
    
    if( _gwmAPI.bDynNav == true )
    {
      // calc center point of rectangle
      var cx = parseFloat(x1) + ((parseFloat(x2) - parseFloat(x1))/2);
      var cy = parseFloat(y1) + ((parseFloat(y2) - parseFloat(y1))/2);
      
      _gwmAPI.iDNTLoop   = 0;
      _gwmAPI.bDZRect    = true;
      _gwmAPI.bDZIn      = true;
      _gwmAPI.sCoordList = sCoords; 
      _gwmAPI.fDZRectX1  = parseFloat(x1);
      _gwmAPI.fDZRectY1  = parseFloat(y1);  
      _gwmAPI.fDZRectX2  = parseFloat(x2);
      _gwmAPI.fDZRectY2  = parseFloat(y2);
  
      _gwmAPI.DNFuncInWaiting = _gwmZoomDynamicView;
      _gwmCenterDynamicView(cx,cy);
      //_gwmZoomDynamicView(true,cx,cy);
    }
    else   
    {
      _gwmSetViewRange(x1, y1, x2, y2);      
      if( null != _gwmAPI.cmdCallback )
        _gwmAPI.cmdCallback(sCoords, _gwmAPI.sUserInfo);      
    }
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}


//=========================================================
function _gwmFitView()
{
  try
  {
    var root = _gwmCore.svgRoot;
    root.currentTranslate.x = 0;
    root.currentTranslate.y = 0;
    root.currentScale = 1.0;
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetZoomFactor()
{
  try
  {
    return _gwmAPI.fZoomFactor;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetZoomFactor(zf)
{
  try
  {
    if (_gwmIsNull(zf)||_gwmIsUnDef(zf))
      return _gwm_E_PARAMNULL;
    _gwmAPI.fZoomFactor = parseFloat(zf);
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetDynamicNavigation( bOn, iSteps )
{
  if( _gwmIsNull(bOn) || _gwmIsUnDef(bOn) ) return _gwm_E_PARAMNULL;

  _gwmAPI.bDynNav = bOn;

  if( _gwmIsNull(iSteps) || _gwmIsUnDef(iSteps) )
  {
    return;
    //_gwmAPI.iDynNavSteps = _gwmAPI.iDNSteps;
  }
  else
    _gwmAPI.iDynNavSteps = iSteps;
}


//-----------------------
/*** GEOMETRY CAPTURE ***/
//-----------------------

//=========================================================
function _gwmCmdCapturePoint( fCallback, sUserInfo, bIgnorePrec )
{
  try
  {
    if( null == fCallback )
      return _gwm_E_PARAMNULL;
    else if ("function" != typeof(fCallback))
    	return _gwm_E_HANDLERNOTFUNCTION;
    if( bIgnorePrec != undefined )
      _gwmBas.bApplyCoordPrecision = !bIgnorePrec;
    _gwmBas.cmdCaptureInit(_gwmBasME.POINTMODE,fCallback,sUserInfo);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdCaptureLine( fCallback, sUserInfo, bIgnorePrec )
{
  try
  {
    if( null == fCallback )
      return _gwm_E_PARAMNULL;
    else if ("function" != typeof(fCallback))
    	return _gwm_E_HANDLERNOTFUNCTION;
    if( bIgnorePrec != undefined )
      _gwmBas.bApplyCoordPrecision = !bIgnorePrec;    
    _gwmBas.cmdCaptureInit(_gwmBasME.LINEMODE,fCallback,sUserInfo);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdCapturePolyline( fCallback, sUserInfo, bIgnorePrec )
{
  try
  {
    if( null == fCallback)
      return _gwm_E_PARAMNULL;
    else if ("function" != typeof(fCallback))
    	return _gwm_E_HANDLERNOTFUNCTION;
    if( bIgnorePrec != undefined )
      _gwmBas.bApplyCoordPrecision = !bIgnorePrec; 
    _gwmBas.cmdCaptureInit(_gwmBasME.POLYLINEMODE,fCallback,sUserInfo);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdCapturePolygon( fCallback, sUserInfo, bIgnorePrec )
{
  try
  {
    if( null == fCallback)
      return _gwm_E_PARAMNULL;
    else if ("function" != typeof(fCallback))
    	return _gwm_E_HANDLERNOTFUNCTION;
    if( bIgnorePrec != undefined )
      _gwmBas.bApplyCoordPrecision = !bIgnorePrec; 
    _gwmBas.cmdCaptureInit(_gwmBasME.POLYGONMODE,fCallback,sUserInfo);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdCaptureRectangle( fCallback, sUserInfo, bIgnorePrec )
{
  try
  {
    if( null == fCallback)
      return _gwm_E_PARAMNULL;
    else if ("function" != typeof(fCallback))
    	return _gwm_E_HANDLERNOTFUNCTION;
    if( bIgnorePrec != undefined )
      _gwmBas.bApplyCoordPrecision = !bIgnorePrec; 
    _gwmBas.cmdCaptureInit(_gwmBasME.RECTANGLEMODE,fCallback,sUserInfo);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmCmdCaptureCircle( fCallback, sUserInfo, bIgnorePrec )
{
  try
  {
    if( null == fCallback)
      return _gwm_E_PARAMNULL;
    else if ("function" != typeof(fCallback))
    	return _gwm_E_HANDLERNOTFUNCTION;
    if( bIgnorePrec != undefined )
      _gwmBas.bApplyCoordPrecision = !bIgnorePrec; 
    _gwmBas.cmdCaptureInit(_gwmBasME.CIRCLEMODE,fCallback,sUserInfo);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}


//========================================================
function _gwmCmdCaptureCancel()
{
  _gwmBas.cmdCaptureReset(true);
}

//=========================================================
function _gwmGetCoordinatePrecision()
{
  try
  {
    return _gwmBas.iCoordPrecision;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//==========================================================
function _gwmSetCoordinatePrecision( i )
{
  try
  {
    i = parseInt(i);
    if (isNaN(i)) return _gwm_E_PARAMINVALID;
    if (i < -1)
      _gwmBas.iCoordPrecision = 8;
    else
      _gwmBas.iCoordPrecision = i;
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetCoordinateUnits()
{
  try
  {
    return _gwmBas.iCoordUnits;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//===========================================================
function _gwmSetCoordinateUnits( i )
{
  try
  {
    i = parseInt(i);
    if (isNaN(i)) return _gwm_E_PARAMINVALID;
    _gwmBas.iCoordUnits = i;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}


//-----------------------
/*** MISCELLANEOUS ***/
//-----------------------

//======================================================
function _gwmGetViewerMenu()
{
  //implemented for the Adobe SVG Viewer 3.01 or greater
  return (_gwmBas.viewCtrl.window.printNode(contextMenu)); 
}

//=======================================================
function _gwmGetMenuItem(item)
{
  try
  {
    // check for adobe's contextMenu object
    if (typeof(contextMenu) == "undefined")
      return null;
  
    // get the menu item with id = "item"
    if (_gwmIsNull(item)) return null;
    var items = contextMenu.getElementsByTagName("item");
    var len = items.length;
    for(var i=0;i<len;i++)
    {
      if (items.item(i).getAttribute("id") == item)
      {
        return items.item(i);
      }
    }
    return null;
  }
  catch(e)
  {
    return null;
  }
}

//=========================================================
function _gwmEnableMenuItem(item, enabled)
{
  try
  {
    // check for adobe's contextMenu object
    if (typeof(contextMenu) == "undefined") return _gwm_E_VIEWERMENU;      
    if(_gwmIsNull(item)) return _gwm_E_PARAMNULL;
  
    var senabled = "no";
    if (enabled) senabled = "yes";
    
    // get the menu item, and set the "enabled" attribute if it exists
    var menuitem = _gwmGetMenuItem(item);
    if (null == menuitem) return _gwm_E_VIEWERMENUITEM;
    menuitem.setAttribute("enabled", senabled);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
  
}

//=========================================================
function _gwmDisplayMenuItem(item, display)
{
  try
  {
    // check for adobe's contextMenu object
    if (typeof(contextMenu) == "undefined") return _gwm_E_VIEWERMENU;
    if(_gwmIsNull(item)) return _gwm_E_PARAMNULL;
  
    var sDisplay = "none";
    if (display) sDisplay = "inline";
    
    // get the menu item, and set the "display" attribute if it exists
    var menuitem = _gwmGetMenuItem(item);
    if (null == menuitem) return _gwm_E_VIEWERMENUITEM;
    menuitem.setAttribute("display", sDisplay);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
  
}

//=======================================================
function _gwmCheckMenuItem(item, check)
{
  try
  {
    // check for adobe's contextMenu object
    if (typeof(contextMenu) == "undefined") return _gwm_E_VIEWERMENU;
    if(_gwmIsNull(item)) return _gwm_E_PARAMNULL;
  
    var sChecked = "no";
    if (check) sChecked = "yes";
    
    // get the menu item, and set the "display" attribute if it exists
    var menuitem = _gwmGetMenuItem(item);
    if (null == menuitem) return _gwm_E_VIEWERMENUITEM;
    menuitem.setAttribute("checked", sChecked);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
  
}

//===========================================================
function _gwmRemoveAllMenuItems()
{
  try
  {
    // check for adobe's contextMenu object
    if (typeof(contextMenu) == "undefined") return _gwm_E_VIEWERMENU;

    while(contextMenu.firstChild.childNodes.length > 0)
    {
      contextMenu.firstChild.removeChild(contextMenu.firstChild.childNodes.item(0));
    }  
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=======================================================
function _gwmRemoveMenuItem(item)
{
  try
  {
    // check for adobe's contextMenu object
    if (typeof(contextMenu) == "undefined") return _gwm_E_VIEWERMENU;    
    if (_gwmIsNull(item)) return _gwm_E_PARAMNULL;
      
    // try to remove
    var menuitem = _gwmGetMenuItem(item);
    if (null == menuitem) return _gwm_E_VIEWERMENUITEM;
    contextMenu.firstChild.removeChild(menuitem);
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=======================================================
function _gwmInsertMenuItem(id, label, action, type, beforeid)
{
  try
  {
    // check for adobe's contextMenu object
    if (typeof(contextMenu) == "undefined") return _gwm_E_VIEWERMENU;
    // check for a separator first
    var newitem;
    if (2 == type)
    {
      newitem = contextMenu.createElement("separator");
    }
    else
    {
      if (_gwmIsNull(label) || _gwmIsNull(id) || _gwmIsNull(action))
        return _gwm_E_PARAMNULL;
    
      if (_gwmGetMenuItem(id) != null)
        return _gwm_E_VIEWERMENUITEM; // can't add existing name
      
      // create the new item
      newitem = contextMenu.createElement("item");
      newitem.setAttribute("id", id);
      if (0 == type)
        newitem.setAttribute("onactivate", action);
      else if (1 == type)
        newitem.setAttribute("action", action);
      newitem.appendChild(contextMenu.createTextNode(label));
    }
    
    // if they gave a before item, try to find it
    if (!_gwmIsNull(beforeid))
    {
      var beforeitem = _gwmGetMenuItem(beforeid);
      // if the item exists, insert before it
      if (!_gwmIsNull(beforeitem))
      {
        contextMenu.firstChild.insertBefore(newitem, beforeitem);
      }
      // otherwise just append
      else
      {
        contextMenu.firstChild.appendChild(newitem);
      }
    }
    // otherwise just append
    else
    {
      contextMenu.firstChild.appendChild(newitem);
    }
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetEventHandler( iType )
{
  try
  {
    if ( null == iType || "number" != typeof(iType) )
    {
      return _gwm_E_PARAMINVALID;
    }
    if( iType == 0 ) //click
      return _gwmAPI.UserEvtHandlerClick;
    else if( iType == 100 ) //geometry cancel
      return _gwmAPI.UserEvtHandlerGeomCancel;
    else if( iType == 200 ) // loadFile
      return _gwmAPI.UserEvtHandlerLoadFileComplete;
    else if( iType == 300 ) // PMW 11/16/05 - SVGScroll/pan
      return _gwmAPI.UserEvtHandlerPan;
    else if( iType == 301 ) // PMW 11/18/05 - SVGZoom
      return _gwmAPI.UserEvtHandlerSVGZoom;
    else
    	return _gwm_E_PARAMINVALID; // iType is not a valid event id
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=======================================================
function _gwmEvtHandlerClick( ele, x, y )
{
var layer = null;
var sID   = null;
var retX  = null;
var retY  = null;

  /***********************************************************
  The Mouse Click event handler that we assign as the 
  BasicFunctions handler. That low-level handler gets called
  by BasicMouseEvents processing.
  
  Incoming X,Y is assumed to have had the SVGTransform Matrix
  applied.
  ***********************************************************/

  //_gwmBas.evtHandlerClick = null; // uncomment to reset click handler
  
  //--09/2004. New implementation for adding X,Y location to callback.
  
  if( !_gwmIsNull(ele) )
  {
    layer = _gwmBas.getEleLayer(ele);
    if( !_gwmIsNull(layer) )
    {
      layer = layer.getAttribute("id");
      sID   = ele.getAttribute("id");
    }
  }
  
  if( x && y )
  {
    var sBuf = "";
    sBuf = "1" + _gwmBas.sListSeparator + x + _gwmBas.sListSeparator + y;
    _gwmBas.setGlobalCoordArray( sBuf );
    _gwmBas.transGlobalPnts( false );
    retX = _gwmBas.ptArray[0].x;
    retY = _gwmBas.ptArray[0].y;
  }

  // Check for valid UserEvtHandler done in setEventHandler
  _gwmAPI.UserEvtHandlerClick( layer, sID, 
                               _gwmAPI.sUserEvtInfoClick, 
                               retX, retY );
}

//=======================================================
function _gwmEvtHandlerGeomCancel()
{
  // We're called back by BasicMouseEvents, now callback to UserCallback
  //_gwmBas.evtHandlerGeomCancel = null; // uncomment to reset click handler
  _gwmAPI.UserEvtHandlerGeomCancel( _gwmAPI.sUserEvtInfoGeomCancel );
}

//=======================================================
// PMW 11/16/05 - SVGScroll event handling
function _gwmEvtHandlerSVGScroll(evt)
{
  window.clearTimeout(_gwmAPI.SVGEventTimeout);
  _gwmAPI.SVGEventTimeout = window.setTimeout("_gwmEvtHandlerSVGScrollComplete()", 1000);
}

function _gwmEvtHandlerSVGScrollComplete()
{
  // PMW 11/17/05 - if the user has defined a callback, call it and pass the coords
  if (_gwmAPI.UserEvtHandlerPan)
  {
    var strNewViewRange = "2" + _gwmBas.sListSeparator + _gwmGetViewRange();
    //var coords = strNewViewRange.split("|");
    _gwmAPI.UserEvtHandlerPan(strNewViewRange, _gwmAPI.sUserEvtInfoPan);
  }
}

//=======================================================
// PMW 11/18/05 - SVGZoom event handling
function _gwmEvtHandlerSVGZoom(evt)
{
  window.clearTimeout(_gwmAPI.SVGEventTimeout);
  _gwmAPI.SVGEventTimeout = window.setTimeout("_gwmEvtHandlerSVGZoomComplete()", 100);
}
function _gwmEvtHandlerSVGZoomComplete()
{
  // PMW 11/18/05 - if the user has defined a callback, call it and pass the coords
  if (_gwmAPI.UserEvtHandlerSVGZoom)
  {
    var strNewViewRange = "2" + _gwmBas.sListSeparator + _gwmGetViewRange();
    //var coords = strNewViewRange.split("|");
    _gwmAPI.UserEvtHandlerSVGZoom(strNewViewRange, _gwmAPI.sUserEvtInfoSVGZoom);
  }
}


//=========================================================
/*
setEventHandler(int eventType, 
                String handlerFunctionName 
                [,String userInfo])
*/
/**
Error values:
-1: handler argument is not a function
**/
//=======================================================
function _gwmSetEventHandler(eventtype, handler, userinfo)
{
  try
  {
  	// validate inputs
    if( null == eventtype) return _gwm_E_PARAMNULL;
    eventtype = parseInt(eventtype);
    if (isNaN(eventtype)) return _gwm_E_PARAMINVALID;

    // handler can be null to turn off Event callback. If not null, it
    // has to be a valid function.
  	if(null != handler)
      if( !(_gwmBas.isValidFunction(handler)) ) return _gwm_E_HANDLERNOTFUNCTION;

    switch(eventtype)
    {
      // BasicFunction's handlers get called by BasicMouseEvents processing.
      // Set that handler to our API handler so we get called.
      
      case 0:
      
      	if (null == handler) 
          _gwmBas.evtHandlerClick = null;
      	else
	      	_gwmBas.evtHandlerClick = _gwmEvtHandlerClick;
      
	      _gwmAPI.UserEvtHandlerClick = handler;
        _gwmAPI.sUserEvtInfoClick   = userinfo;
        break;
      
      case 100:
      
      	if (null == handler) 
          _gwmBas.evtHandlerGeomCancel = null;
      	else
	      	_gwmBas.evtHandlerGeomCancel = _gwmEvtHandlerGeomCancel;

	      _gwmAPI.UserEvtHandlerGeomCancel = handler;
        _gwmAPI.sUserEvtInfoGeomCancel   = userinfo;
        break;
      
      case 200:
        
        _gwmAPI.UserEvtHandlerLoadFileComplete = handler;
        _gwmAPI.sUserEvtInfoLoadFileComplete   = userinfo;
        break;
      
      case 300: //pmw 11/16/05 - Pan event stuff
        
        if (null == handler)
          _gwmBas.evtHandlerSVGScroll = null;
        else
          _gwmBas.evtHandlerSVGScroll = _gwmEvtHandlerSVGScroll;
          
        // pan event handler signature should be:
        // handler(coords, userinfo)
        //   coords: array of 4 numbers (xmin, ymin, xmax, ymax) containing the view range after pan
        //   userinfo: passed through
        _gwmAPI.UserEvtHandlerPan = handler;
        _gwmAPI.sUserEvtInfoPan = userinfo;
        break;
        
      case 301: // pmw 11/18/05 - SVGZoom event

        if (null == handler)
          _gwmBas.evtHandlerSVGZoom = null;
        else
          _gwmBas.evtHandlerSVGZoom = _gwmEvtHandlerSVGZoom;
          
        // SVGZoom event handler signature should be:
        // handler(coords, userinfo)
        //   coords: array of 4 numbers (xmin, ymin, xmax, ymax) containing the view range after zoom
        //   userinfo: passed through
        _gwmAPI.UserEvtHandlerSVGZoom = handler;
        _gwmAPI.sUserEvtInfoSVGZoom = userinfo;
        break;
        
      default:
        return _gwm_E_PARAMINVALID;
        break;
    }        
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetListSeparator()
{
  try
  {
    return _gwmBas.sListSeparator;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetListSeparator( s )
{
  try
  {
    if(_gwmIsNull(s)||_gwmIsUnDef(s))
      return _gwm_E_PARAMNULL;
      
    if ("Newline" == s)
      s = "\n";
    if ("Tab" == s)
      s = "\t";
      
    _gwmBas.sListSeparator = s;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmGetAutoRepeatMode()
{
  try
  {
    return _gwmBas.bAutoRep;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=========================================================
function _gwmSetAutoRepeatMode( b )
{
  try
  {
    _gwmBas.bAutoRep = b;
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmGetDynamicLineStyle()
{
  try
  {
    return _gwmBas.getDynamicLineStyle();
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmSetDynamicLineStyle( style )
{
  try
  {
    if(_gwmIsNull(style)) return _gwm_E_PARAMNULL;
    return( _gwmBas.setDynamicLineStyle(style) );
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmGetDynamicShapeStyle()
{
  try
  {
    return _gwmBas.getDynamicShapeStyle();
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmSetDynamicShapeStyle( style )
{
  try
  {
    if (_gwmIsNull(style)) return _gwm_E_PARAMNULL;
    return( _gwmBas.setDynamicShapeStyle( style ) );
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmSetTooltipTextStyle( style )
{
  try
  {
    if(_gwmIsNull(style)) return _gwm_E_PARAMNULL;
    return( _gwmCore.setTooltipTextStyle( style ) );
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmGetTooltipTextStyle()
{
  try
  {
    return _gwmCore.getTooltipTextStyle();
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmSetTooltipRectStyle( style )
{
  try
  {
    if(_gwmIsNull(style)) return _gwm_E_PARAMNULL;
    return( _gwmCore.setTooltipRectStyle(style) );
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmGetTooltipRectStyle()
{
  try
  {
    return _gwmCore.getTooltipRectStyle();
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmGetLayerStyleClass( sLyrName, bHiCls )
{
  //--22-Mar-2006: CDF: mods for change in 6.0 that puts StyleClass on
  //  Layer subgroup(s).
  
  try
  { 
    if( _gwmIsNull(sLyrName) ) return _gwm_E_PARAMNULL;

    var ele = _gwmGetLayerFirstSubGroup(sLyrName);
    if( null == ele ) return _gwm_E_GETELEMENT;
  
    bHi = false;
    if( null != bHiCls 
       && 'undefined' != bHiCls 
       && "" != bHiCls ) bHi = bHiCls;
        
    if( !bHi ) 
    {
      //var sCls = _gwmBas.getLayerAttribute(sLyrName, 'class');
      var sCls = ele.getAttribute('class');
      if( null == sCls ) return _gwm_E_GETELEMENT;
      else return sCls;
    }

    //process for highlight class
    //var hClass = _gwmBas.getLayerAttribute(sLyrName, _gwmCore.ns + ":hi"); 
    var hClass = ele.getAttribute(_gwmCore.ns + ":hi");
    
    if( !hClass ) return "";

    var classes = hClass.split(" ");
    if( classes.length > 1 ) return classes[1];
    else return "";

    return _gwm_E_UNKNOWN;
  }
  catch(e)
  {  
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmSetLayerStyleClass( sLyrName, sClsID, sHiClsID )
{
  //--22-Mar-2006: CDF: mods for change in 6.0 that puts StyleClass on
  //  Layer subgroup(s).
      
  try
  { 
    if( _gwmIsNull(sLyrName) ) return _gwm_E_PARAMNULL;
  
    var bCls = false;
    var bHiCls = false;
    
    if( !(_gwmIsNull(sClsID)) ) bCls = true;
    if( !(_gwmIsNull(sHiClsID)) ) bHiCls = true;

    if( !bCls && !bHiCls ) return _gwm_E_PARAMNULL;

    var sCls = "";
    var sHiCls = "";
    var sNewHi = "";
    var ele = null;
    
    if( bCls )
    {
      //if( (_gwmBas.setLayerAttribute(sLyrName, 'class', sClsID)) < 0 ) return _gwm_E_GETELEMENT;
      ele = _gwmGetLayerFirstSubGroup(sLyrName);
      if( null == ele ) return _gwm_E_GETELEMENT; 
      ele.setAttribute('class', sClsID);        
      sCls = sClsID;
    }
    else if( bHiCls )
    {
      //sCls = _gwmBas.getLayerAttribute(sLyrName, 'class'); 
      ele = _gwmGetLayerFirstSubGroup(sLyrName);
      if( null == ele ) return _gwm_E_GETELEMENT;  
      sCls = ele.getAttribute('class');
      if( null == sCls ) return _gwm_E_GETELEMENT;         
    }
    
    if( null == ele ) return _gwm_E_GETELEMENT;  
    
    if( bHiCls ) sHiCls = sHiClsID;
    var classes = "";
    //var hClass = _gwmBas.getLayerAttribute(sLyrName, _gwmCore.ns + ":hi"); 
    var hClass = ele.getAttribute(_gwmCore.ns + ":hi");

    if( (bCls && hClass) || bHiCls )
    {
      // set the gwm:hi value      
      if( hClass ) 
      {
        classes = hClass.split(" ");      
        if( !bHiCls ) sHiCls = classes[1];
      }
      if( sCls == "" || sHiCls == "" ) return _gwm_E_UNKNOWN;
      sNewHi = sCls + " " + sHiCls;
      //_gwmBas.setLayerAttribute(sLyrName, _gwmCore.ns + ":hi", sNewHi);
      ele.setAttribute(_gwmCore.ns + ":hi", sNewHi);    
    }
    
    return _gwm_E_SUCCESS;
  }
  catch(e)
  {
    return _gwm_E_UNKNOWN;
  }
}

//=================================================
function _gwmDBGTEST()
{
  //Implement for whatever debugging/testing you need to do
  
  //window.alert(_gwmBas.DBGTEXT);
  return _gwmBas.DBGTEXT;

}
