///////////// SA Setup ///////////////////////////////////////////
var API_HOST_URL = "http://maps.afrigis.co.za/msjsapi111/";
var MS_GATEWAY = "http://maps.afrigis.co.za/msjsapi111/IISGateway.aspx";
var MARBIL_GATEWAY = "http://maps.afrigis.co.za/msjsapi111/MarbilGateway.aspx";
var DD_GATEWAY = "http://maps.afrigis.co.za/services/MapServerUtils/DDHTMLGateway.aspx";
var MAP_LAYERS = "AG_PROVINCES,AG_SUBURBS,AG_TOWNS_CENTROID,AG_STREETS";
var MAP_STYLES = "Mapstyle3,Dineke1,Point_SCHEME,Mapstyle3";
var INIT_BB = "15.46345732,-29.8445173,34.08369661,-25.80449264";
var ROUTE_LAYER = "AG_STREETS";
var ROUTE_PARAM = "TRAVELTIME";


/////////////////////////////////////////////////////////////////////////////////////////////////////////////

var IMAGERY_BASE_URLS = "0-4|http://196.35.231.56/getTile?dataset=AfriGIS;5-7|http://196.35.231.56/getTile?dataset=AfriGIS;8-12|http://196.35.231.56/getTile?dataset=AfriGIS";                   


var DEFAULT_DD_CSS_FILE_NAME = "css/DefaultDDStyle.css";

var ADVERTISE_DURATION = 30; // 30 sec
var TOTAL_NO_OF_ZOOMBAR = 5;

// define constants
var NOT_REQUESTED = "Not Requested";
var REQUESTED = "Requested";
var RESPONSE_SUCCESSFUL = "Response Succeeful";
var RESPONSE_ERROR = "Error In Response";

// events - all are in UpperCase
var EVENTS = new Array("ZOOM","RIGHTBUTTONCLICK","LEFTBUTTONCLICK", "DOUBLECLICK", "SHOWROUTING", "CLEARROUTING", "RESETBBOX", "PAN");

var NO_ROW = 3;
var NO_COL = 3;
var MAX_TILE = 100;
var zoombarNumber = 0;
var DEFAULT_ZOOMBAR = 1;
var ANI_IMAGE_NAME = "LoadingGIF01_grey.gif";

// Satellite image
var MAX_SAT_TILE = 50;

// Capabilities Layers
var bCapabilitiesRequested = false;
var strCapabilitiesStatus = NOT_REQUESTED;
var arrAllLayers = new Array();

var bMapRequestOn = false;


var AGGlobalsArray = new Array();


var myLocation = location.href;

var qIndex1 = myLocation.indexOf("GetTiledMapInfoAG");
var qIndex2 = myLocation.indexOf("GetMapInfoAG");
var qIndex3 = myLocation.indexOf("GetCapabilitiesAG");
var qIndex4 = myLocation.indexOf("GetAdvertNow");
var qIndex5 = myLocation.indexOf("GetMarbilUser");

var UrlManager = {
    RequestQueryStringUrlEncoded : function (Url, ParamName)
	{
		var regexS = "[\\?&#]"+ParamName+"=([^&#]*)";
		var regex = new RegExp( regexS );
		var results = regex.exec( Url );
		if( results == null )
			return "";
		else
			return results[1];
	}
};

if (qIndex1 >=0 || qIndex2 >=0 || qIndex3>=0 || qIndex4>=0 || qIndex5>=0)
{   
	var myLocation = location.href;
    location.href = API_HOST_URL + "Dummy.htm";
    top.xxxx(myLocation);
}

function xxxx(url)
{
    var qIndex = url.indexOf("?");
    if(qIndex<0)
        return;
    
    var urlParams = "";
    var parentDivId = "";
    var response = ""
    try
    {
        urlParams = url.substring(qIndex+1);
        var parentParamIndex = urlParams.lastIndexOf("&Parent=");
        if(parentParamIndex < 0)
        {
            alert("no parent");
            return;
        }
        response = urlParams.substring(0,parentParamIndex);
        parentDivId = urlParams.substring(parentParamIndex+8, urlParams.length);
    }
    catch(err)
    {   
        return;
    }
    
    var qIndex = -1;
    if ( (qIndex = urlParams.indexOf("GetTiledMapInfoAG")) >= 0 )
    {   
        res = UrlEncoderDecoder.decode(urlParams);
        var temp = getElementsByTagName(res, "<token>", "</token>");

        if(temp.length>0)
            AGGlobalsArray[parentDivId].CallBackGetToken(temp[0])
        else
            AGGlobalsArray[parentDivId].MakeBusyForRequest();
    }
    else if ( (qIndex = urlParams.indexOf("GetCapabilitiesAG")) >= 0 )
    {
        var strCapabilities = UrlManager.RequestQueryStringUrlEncoded(url, "GetCapabilitiesAG");
        CallBackGetCapabilities(strCapabilities);
    }
    else if((qIndex = urlParams.indexOf("GetAdvertNow")) >= 0)
    {
        var strAdvert = UrlEncoderDecoder.decode( UrlManager.RequestQueryStringUrlEncoded(url, "GetAdvertNow") );
        AGGlobalsArray[parentDivId].CallBackGetAdvertise(strAdvert);
    }
    else if((qIndex = urlParams.indexOf("GetMarbilUser")) >= 0)
    {
        var strUserInfo = UrlEncoderDecoder.decode( UrlManager.RequestQueryStringUrlEncoded(url, "GetMarbilUser") );
        AGGlobalsArray[parentDivId].CallBackGetMarbilUser(strUserInfo);
    }
}

function CallBackGetCapabilities(strCapabilities)
{   
    if(strCapabilities.toLowerCase().indexOf('error') == 0)
    {
        strCapabilitiesStatus = RESPONSE_ERROR;
        return;
    }
    
    var layers = strCapabilities.split("*"); // '*' is the Layer-Separator]
    arrAllLayers = new Array();
    for(var l=0; l<layers.length; l++)
    {
        var layer = layers[l];
        var layerProperties = layer.split("|"); 
        if(layerProperties.length >= 3)
        {
            var layerName = layerProperties[0];
            var layerStyles = layerProperties[1].split(",");
            var routable = false;
            var routeParam = new Array();
            if(layerProperties[2] == "t")
                routable = true;
            if(routable && layerProperties.length >= 4)
                routeParam = layerProperties[3].split(",");
            
            arrAllLayers.push(new Layer(layerName, layerStyles, routable, routeParam));
        }
    }
    
    strCapabilitiesStatus = RESPONSE_SUCCESSFUL;
}

function getElementsByTagName(inputStr, startTag, endTag)
{   
    
    var listContents = new Array();
    var startIndex = 0;
    var endIndex=-1;
    
    // as different browsers gives different tag names (cases are different)
    var lowerInputStr = inputStr.toLowerCase();
    startTag = startTag.toLowerCase();
    endTag = endTag.toLowerCase();
    
    while(true)
    {
        startIndex = lowerInputStr.indexOf(startTag, startIndex);
        if(startIndex < 0)
            break;
        startIndex = startIndex + startTag.length;
        endIndex = lowerInputStr.indexOf(endTag, startIndex);
        if(endIndex < 0)
            break;
        var content = inputStr.substring(startIndex, endIndex)
        listContents.push(content);
    }
    return listContents;
}


var UrlEncoderDecoder = {

	// public method for url encoding
	encode : function (string) {
		return escape(this._utf8_encode(string));
	},

	// public method for url decoding
	decode : function (string) {
		return this._utf8_decode(unescape(string));
	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}
		return string;
	}
}

function AGMap(mapCanvasDiv, uid, zoombar_no, boolEnablePan)
{
    this.m_strParentDivID = mapCanvasDiv.id;
    mapCanvasDiv.style.overflow = "hidden"; // required for IE, otherwise div can't be make smaller than its content
    this.m_strUid = uid;
    
    if(typeof zoombar_no =="NaN" || typeof zoombar_no =="undefined" || Math.floor(zoombar_no) != zoombar_no || zoombar_no <1 || zoombar_no> TOTAL_NO_OF_ZOOMBAR)
        zoombar_no = DEFAULT_ZOOMBAR;
    
    // sometimes history remains in browsers. so some objects get inserted twice. 
    // here problem occurs & busy image is not removed. so the provided div needs to be cleared first.
    var prevObject = document.getElementById(this.m_strParentDivID);
    if(prevObject != null)
        prevObject.innerHTML = "";
    else
        return;
    
    AGGlobalsArray[this.m_strParentDivID] = new AGMapGlobals(API_HOST_URL, mapCanvasDiv, this.m_strParentDivID);
    
    AGGlobalsArray[this.m_strParentDivID].zoombarNumber = zoombar_no;
    AGGlobalsArray[this.m_strParentDivID].m_LocalDomain = location.href;
    AGGlobalsArray[this.m_strParentDivID].m_hostURL = API_HOST_URL;
    if(typeof boolEnablePan == "boolean")
        AGGlobalsArray[this.m_strParentDivID].m_bEnablePan = boolEnablePan;
    else
        AGGlobalsArray[this.m_strParentDivID].m_bEnablePan = true;
    
    AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas = new MapCanvas(mapCanvasDiv,this.m_strParentDivID,zoombar_no);
    AGGlobalsArray[this.m_strParentDivID].m_ptImgBasePointShift = new Point(0,0);

    this.m_strMSGateway = MS_GATEWAY;
    this.m_iNoOfRow = NO_ROW;
    this.m_iNoOfCol = NO_COL;
    this.m_iMaxNoOfTile = MAX_TILE;
    this.m_strMapLayers = MAP_LAYERS;
    this.m_strMapStyles = MAP_STYLES;
    this.m_strInitialBoundingBox = INIT_BB;
        
    this.m_strRouteLayer = ROUTE_LAYER;
    this.m_strRouteParam = ROUTE_PARAM;

    this.bInitialize = false;
    
    this.IsLoading = function()
    {
     if (AGGlobalsArray[this.m_strParentDivID].m_iRequestCount > 0)
     {
        return true;
     }
    }
        
    this.InitializeMap = function()
    {
        AGGlobalsArray[this.m_strParentDivID].m_bDocumentLoaded = true;
        this.InitMapComponent(this.m_strMSGateway, this.m_iNoOfRow, this.m_iNoOfCol, this.m_iMaxNoOfTile, this.m_strMapLayers, this.m_strMapStyles, this.m_strInitialBoundingBox, this.m_strRouteLayer, this.m_strRouteParam);
        this.bInitialize=true;
    }
    
    this.GetCapabilities = function()
    {
        return arrAllLayers;
    }
    
//    this.SetLayers = function(strLayerDef)
//    {
//        var arrLayerDefDivisions = strLayerDef.split(";");
//        var iDivisionLen = arrLayerDefDivisions.length;
//        if(iDivisionLen < 3)
//            return false;   // at least one layer|style, one RouteLayer, one RouteParam
//        
//        var strRouteParam = arrLayerDefDivisions[iDivisionLen-1];
//        var iRouteLayerIndex = -1;
//        try
//        {
//            iRouteLayerIndex = parseInt(arrLayerDefDivisions[iDivisionLen-2],10);   // index must be an integer
//        }
//        catch(err)
//        {
//            return false;
//        }
//        
//        if(iRouteLayerIndex<0 || iRouteLayerIndex>=(iDivisionLen-2))    // index must be between 0~GivenLayerCount
//            return false;
//        
//            
//        var givenLayers = "";
//        var givenStyles = "";
//        var arrLayers = this.GetCapabilities();
//        for(var i=0; i<iDivisionLen-2; i++)
//        {
//            var arrLayerDefPart = arrLayerDefDivisions[i].split("|");
//            if(arrLayerDefPart.length != 2)
//                return false;
//            var strLayerName = arrLayerDefPart[0];
//            var strStyleName = arrLayerDefPart[1];
//            
//            var bLayerFound = false;
//            for(var j=0; j<arrLayers.length; j++)
//            {   
//                if(arrLayers[j].GetLayerName() == strLayerName)
//                {
//                    // layer found at index j
//                    bLayerFound = true;
//                    if(arrLayers[j].ContainsStyle(strStyleName))
//                    {
//                        // given style of layer is valid
//                        if(iRouteLayerIndex == i && !arrLayers[j].ContainsRouteParameter(strRouteParam))
//                        {
//                            return false;   // this layer is given routable layer, but invalid route param
//                        }
//                    }
//                    else
//                        return false;   // style does not match with layer
//                }
//            }
//            
//            if(!bLayerFound)
//                return false;
//            
//            givenLayers += strLayerName + ",";
//            givenStyles += strStyleName + ",";
//        }
//        
//        if(givenLayers.length > 0)  // then givenStyles.length must be > 0
//        {
//            givenLayers = givenLayers.substring(0,givenLayers.length-1);    
//            givenStyles = givenStyles.substring(0,givenStyles.length-1);
//            
//            // everything ok, set layers and return true
//            AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.layers = givenLayers;
//            AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.styles = givenStyles;
//            AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.routableParameter = strRouteParam;
//            AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RedrawCurrentArea();
//            return true;
//        }
//        else
//            return false;
//    }
//    
//    this.GetLayers = function()
//    {
//        var arrLayers = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.layers.split(",");
//        var arrStyles = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.styles.split(",");
//        var strRoutableLayer = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.routableLayer;
//        var strRouteParam = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.routableParameter;
//        
//        var iRouteLayerIndex = -1;
//        for(var i=0; i<arrLayers.length; i++)
//        {
//            if(arrLayers[i] == strRoutableLayer)
//            {
//                iRouteLayerIndex = i;
//                break;
//            }
//        }
//        
//        if(iRouteLayerIndex >=0)
//        {
//            if(arrLayers.length != arrStyles.length)
//                return "";
//                
//            var strLayerDef = "";
//            for(var i=0; i<arrLayers.length; i++)
//                strLayerDef += arrLayers[i] + "|" + arrStyles[i] + ";";
//            strLayerDef += iRouteLayerIndex + ";" + strRouteParam;
//            return strLayerDef;
//        }
//        else
//            return "";
//    }

//    this.SetLayers = function(strLayerDef)
//    {
//        var arrLayerDefDivisions = strLayerDef.split(";");
//        var iDivisionLen = arrLayerDefDivisions.length;
//        if(iDivisionLen < 1)
//            return false;   // at least one layer|style, one RouteLayer, one RouteParam
//            
//        var givenLayers = "";
//        var givenStyles = "";
//        var arrLayers = this.GetCapabilities();
//        for(var i=0; i<iDivisionLen; i++)
//        {
//            var arrLayerDefPart = arrLayerDefDivisions[i].split("|");
//            if(arrLayerDefPart.length != 2)
//                return false;
//            var strLayerName = arrLayerDefPart[0];
//            var strStyleName = arrLayerDefPart[1];
//            
//            var bLayerFound = false;
//            for(var j=0; j<arrLayers.length; j++)
//            {   
//                if(arrLayers[j].GetLayerName() == strLayerName)
//                {
//                    // layer found at index j
//                    bLayerFound = true;
//                    if(arrLayers[j].ContainsStyle(strStyleName))
//                    {
//                        // given style of layer is valid
////                        if(iRouteLayerIndex == i && !arrLayers[j].ContainsRouteParameter(strRouteParam))
////                        {
////                            return false;   // this layer is given routable layer, but invalid route param
////                        }
//                    }
//                    else
//                        return false;   // style does not match with layer
//                        
//                    break;
//                }
//            }
//            
//            if(!bLayerFound)
//                return false;
//            
//            givenLayers += strLayerName + ",";
//            givenStyles += strStyleName + ",";
//        }
//                
//        
//        if(givenLayers.length > 0)  // then givenStyles.length must be > 0
//        {
//            givenLayers = givenLayers.substring(0,givenLayers.length-1);    
//            givenStyles = givenStyles.substring(0,givenStyles.length-1);
//            
//            // everything ok, set layers and return true
//            var objMapInfo = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject;
//            //AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.layers = givenLayers;
//            //AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.styles = givenStyles;
//            objMapInfo.layers = givenLayers;
//            objMapInfo.styles = givenStyles;
//            
//            AGGlobalsArray[this.m_strParentDivID].SetRoutingLayerConsistency(objMapInfo.layers, objMapInfo.routableLayer);
//            AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RedrawCurrentArea();
//            return true;
//        }
//        else
//            return false;
//    }

/*********************************
SetLayers() - Coded By Iaan Roux 27 May 2008
*/
    this.SetLayers = function(strLayerDef)
    {
        var arrLayerDefDivisions = strLayerDef.split(";");
        var iDivisionLen = arrLayerDefDivisions.length;
        if(iDivisionLen < 1)
            return false;   // at least one layer|style, one RouteLayer, one RouteParam
            
        var givenLayers = "";
        var givenStyles = "";
        
        //var arrLayers = this.GetCapabilities();
        for(var i=0; i<iDivisionLen; i++)
        {
            var arrLayerDefPart = arrLayerDefDivisions[i].split("|");
            if(arrLayerDefPart.length != 2)
                return false;
            givenLayers = givenLayers + arrLayerDefPart[0] + ",";
            givenStyles = givenStyles + arrLayerDefPart[1] + ",";
        }
        if(givenLayers.length > 0)  // then givenStyles.length must be > 0
        {
            givenLayers = givenLayers.substring(0,givenLayers.length-1);    
            givenStyles = givenStyles.substring(0,givenStyles.length-1);
            
            // everything ok, set layers and return true
            var objMapInfo = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject;
            objMapInfo.layers = givenLayers;
            objMapInfo.styles = givenStyles;
            return true;
        }
        else
            return false;
    }

    
    this.GetLayers = function()
    {
        var arrLayers = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.layers.split(",");
        var arrStyles = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.styles.split(",");
        
        if(arrLayers.length != arrStyles.length)
            return "";
            
        var strLayerDef = "";
        for(var i=0; i<arrLayers.length; i++)        
            strLayerDef += arrLayers[i] + "|" + arrStyles[i] + ";";
        
        if(strLayerDef.length > 0)        
            strLayerDef = strLayerDef.substring(0,strLayerDef.length-1);    
        
        return strLayerDef;
    }
    
    this.SetRouteLayer = function(RouteableLayerName,RouteParameter)
    {
        var arrLayers = this.GetCapabilities();
        
        for(var i=0;i<arrLayers.length;i++)
        {
            if(arrLayers[i].GetLayerName() == RouteableLayerName)
            {
                if(arrLayers[i].ContainsRouteParameter(RouteParameter))
                {
                    var objMapInfo = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject;
                    //AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.routableLayer = RouteableLayerName;
                    //AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.routableParameter = RouteParameter;
                    objMapInfo.routableLayer = RouteableLayerName;
                    objMapInfo.routableParameter = RouteParameter;
                    
                    AGGlobalsArray[this.m_strParentDivID].SetRoutingLayerConsistency(objMapInfo.layers, objMapInfo.routableLayer);

                    return true;
                }
            }
        }
        return false;
    }

    this.GetRouteLayer = function()
    {
        var objMapInfo = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject;
        return objMapInfo.routableLayer + "," + objMapInfo.routableParameter;
    }
    
    this.InitializaionFromConfiguration = function(strMSGateway, iNoOfRow, iNoOfCol, iMaxNoOfTile, strMapLayers, strMapStyles, strRouteLayer, strRouteParam)
    {
        AGGlobalsArray[this.m_strParentDivID].m_iTileRow = iNoOfRow;
        AGGlobalsArray[this.m_strParentDivID].m_iTileCol = iNoOfCol;
        AGGlobalsArray[this.m_strParentDivID].m_iMaxNoOfTile = iMaxNoOfTile;
        
		imageElement = document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MAPTILES_DIV_ID);
        imageElement.style.position = 'absolute';
        imageElement.innerHTML="";
        
        var bAddIEDiv = (BrowserDetect.browser=="Explorer" && BrowserDetect.version < 7 && BrowserDetect.version >= 5.5);

        for (var imgNo = 0; imgNo < AGGlobalsArray[this.m_strParentDivID].m_iMaxNoOfTile; imgNo++)
        {
            imgId = AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.TILE_IMAGE_ID+imgNo;
            if(bAddIEDiv)
            {
                var divId = AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.TILE_IMAGE_DIV_ID+imgNo;
                imageElement.innerHTML+='<img  id="'+ imgId +'" alt="" galleryimg="no" style="visibility:hidden; position:absolute; left:-10000px; top:-10000px; z-index:4; " onload="AGGlobalsArray[\''+this.m_strParentDivID+'\'].SetPos(\'' + imgNo + '\')" posLeft="-10000" posTop=-"10000" zoom="0" />';
                imageElement.innerHTML+='<div  id="'+ divId +'" alt="" galleryimg="no" style="position:absolute; left:-10000px; top:-10000px; z-index:4; " />';
            }
            else
                imageElement.innerHTML+='<img  id="'+ imgId +'" alt="" galleryimg="no" style="position:absolute; left:-10000px; top:-10000px; z-index:4; " onload="AGGlobalsArray[\''+this.m_strParentDivID+'\'].SetPos(\'' + imgNo + '\')" posLeft="-10000" posTop=-"10000" zoom="0" />';
        }
        
        // satellite image init
        var satImgElem = document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.SATELLITE_MAPTILES_DIV_ID);
        satImgElem.innerHTML="";
        for (var imgNo = 0; imgNo < AGGlobalsArray[this.m_strParentDivID].m_iMaxNoOfSatTile; imgNo++)
        {
            var satImgId = AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID + imgNo;
            satImgElem.innerHTML+='<img  id="'+ satImgId +'" src="'+API_HOST_URL+'Images/transparentpixel.gif" alt="" galleryimg="no" style="position:absolute; z-index:2; left:-1000000px; top:-1000000px; " level="-1"  xVal="-1" yVal="-1" posLeft="-1000000" posTop="-1000000" zoom="0" onload="AGGlobalsArray[\''+this.m_strParentDivID+'\'].satTileHandler.SetPos(\'' + imgNo + '\')" />';
        }
        
    }
    
    this.InitMapComponent = function(strMSGateway, iNoOfRow, iNoOfCol, iMaxNoOfTile, strMapLayers, strMapStyles, strInitialBoundingBox, strRouteLayer, strRouteParam)
    {
        this.InitializaionFromConfiguration(strMSGateway, iNoOfRow, iNoOfCol, iMaxNoOfTile, strMapLayers, strMapStyles, strRouteLayer, strRouteParam);
        this.InitMainMap(strMapLayers, strMapStyles, strInitialBoundingBox, strRouteLayer, strRouteParam, AGGlobalsArray[this.m_strParentDivID].m_JSFunc, AGGlobalsArray[this.m_strParentDivID].m_LocalDomain, this.m_strUid, this.m_strParentDivID);
        
        // moving container
        AGGlobalsArray[this.m_strParentDivID].m_objMovingContainer = new MovingContainer(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MOVIMG_CONTAINER_DIV_ID);
        AGGlobalsArray[this.m_strParentDivID].m_objMovingContainer.RemoveAllObjectsFromMap();
        this.SetCrossHairAtMidPosition(AGGlobalsArray[this.m_strParentDivID].m_iTileRow,AGGlobalsArray[this.m_strParentDivID].m_iTileCol,AGGlobalsArray[this.m_strParentDivID].m_iTileWidth,AGGlobalsArray[this.m_strParentDivID].m_iTileHeight);
        this.SetLoadingImageAtMidPosition(AGGlobalsArray[this.m_strParentDivID].m_iTileRow,AGGlobalsArray[this.m_strParentDivID].m_iTileCol,AGGlobalsArray[this.m_strParentDivID].m_iTileWidth,AGGlobalsArray[this.m_strParentDivID].m_iTileHeight);
        AGGlobalsArray[this.m_strParentDivID].ActivateMouseEvents();
    }
    
    this.SetCrossHairAtMidPosition = function(tileRowCount, tileColCount, tileWidth, tileHeight)
    {
        var crossHairImageWidth = parseInt((document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.CROSS_HAIR_DIV_ID).offsetWidth), 10);        
        var crossHairImageHeight = parseInt((document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.CROSS_HAIR_DIV_ID).offsetHeight), 10);
        var obCrossHair = document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.CROSS_HAIR_DIV_ID);        
        obCrossHair.style.left = Math.round(((tileRowCount-1) * tileWidth)/2 - crossHairImageWidth/2) + 'px';
        obCrossHair.style.top = Math.round(((tileColCount-1) * tileHeight)/2 - crossHairImageHeight/2)+ 'px';
    }        
    
    this.SetLoadingImageAtMidPosition = function(tileRowCount, tileColCount, tileWidth, tileHeight)
    {
        var loadingImageWidth = parseInt((document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.ANI_IMAGE_DIV_ID).offsetWidth), 10);
        var loadingImageHeight = parseInt((document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.ANI_IMAGE_DIV_ID).offsetHeight), 10);
        
        var iniImg = document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.ANI_IMAGE_DIV_ID);
        iniImg.style.left = Math.round(((tileRowCount-1) * tileWidth)/2 - loadingImageWidth/2) + 'px';
        iniImg.style.top = Math.round(((tileColCount-1) * tileHeight)/2 - loadingImageHeight/2)+ 'px';
    }

    this.ResizeMapContent = function ()
    {   
        var parDiv = document.getElementById(this.m_strParentDivID);
        AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.style.width = (parseInt(parDiv.offsetWidth) ) +"px";      // why -3 ????
        
        if(AGGlobalsArray[this.m_strParentDivID].m_bShowAdvertising == null || AGGlobalsArray[this.m_strParentDivID].m_bShowAdvertising == true) 
        {
            // calculate advertise div height
            AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.AdvertisingDiv.style.overflow = "hidden";
            
            var iAdDivHeight =  parseInt( 0.15 * AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MyMapDivId.offsetHeight); // 15 percent of whole div
            iAdDivHeight = (iAdDivHeight < 20) ? 20 : iAdDivHeight;
            
            if(iAdDivHeight < 30)
            {
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertWidth = 200;
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertHeight = 20;
            }
            else if(iAdDivHeight < 40)
            {
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertWidth = 300;
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertHeight = 30;
            }
            else if(iAdDivHeight < 60)
            {
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertWidth = 400;
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertHeight = 40;
            }
            else if(iAdDivHeight < 70)
            {
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertWidth = 600;
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertHeight = 60;
            }
            else
            {
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertWidth = 700;
                AGGlobalsArray[this.m_strParentDivID].m_iAdvertHeight = 70;
            }
            
            AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.style.height = (parseInt(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MyMapDivId.offsetHeight)) +"px";
            //AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.AdvertisingDiv.style.left = "0px";
            //AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.AdvertisingDiv.style.bottom = "0px";
            //AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.AdvertisingDiv.style.top = (-iAdDivHeight) + "px";
            AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.AdvertisingDiv.style.width = AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.style.width;
            AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.AdvertisingDiv.style.height = iAdDivHeight + "px";
            //AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.AdvertisingDiv.style.height = "20px";
            
            
            
        }
        else
        {
            AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.style.height = (parseInt(parDiv.offsetHeight) -2) +"px";
        }
        
        // Set Copyright Div position
        //AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.CopyrightDiv.style.top =  (parseInt(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.offsetHeight) - 16)+"px";
    }
    
    this.InitMainMap = function (layers, styles, bbox, routableLayer, routableParameter, jSFunc, localDomain, userId, parentDivId)
    {
        this.ResizeMapContent();    
        
        AGGlobalsArray[this.m_strParentDivID].m_iTileRow = parseInt(AGGlobalsArray[this.m_strParentDivID].m_iTileRow,10);
        AGGlobalsArray[this.m_strParentDivID].m_iTileCol = parseInt(AGGlobalsArray[this.m_strParentDivID].m_iTileCol,10);
        
        var map_width = parseInt((AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.offsetWidth), 10);
        var map_height = parseInt((AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.offsetHeight), 10);
        
		map_width = (map_width/AGGlobalsArray[this.m_strParentDivID].m_iTileCol) * (AGGlobalsArray[this.m_strParentDivID].m_iTileCol+1);
		map_height =(map_height/AGGlobalsArray[this.m_strParentDivID].m_iTileRow) * (AGGlobalsArray[this.m_strParentDivID].m_iTileRow+1);
		
		AGGlobalsArray[this.m_strParentDivID].m_iTileCol = parseInt(AGGlobalsArray[this.m_strParentDivID].m_iTileCol,10) + parseInt(1,10);
		AGGlobalsArray[this.m_strParentDivID].m_iTileRow = parseInt(AGGlobalsArray[this.m_strParentDivID].m_iTileRow,10) + parseInt(1,10);
		
        AGGlobalsArray[this.m_strParentDivID].m_iTileHeight =  Math.round(map_height/AGGlobalsArray[this.m_strParentDivID].m_iTileRow);
        AGGlobalsArray[this.m_strParentDivID].m_iTileWidth =  Math.round(map_width/AGGlobalsArray[this.m_strParentDivID].m_iTileCol);
        
        var FORMAT = "image/png";
        var VERSION = "1.0.0" ;
        var CRS = "EPSG:4326" ;
        var EXCEPTION = "INIMAGE";                
       
        var mapinfo = new MapInfo( bbox, Math.round(AGGlobalsArray[this.m_strParentDivID].m_iTileWidth*AGGlobalsArray[this.m_strParentDivID].m_iTileCol), Math.round(AGGlobalsArray[this.m_strParentDivID].m_iTileHeight*AGGlobalsArray[this.m_strParentDivID].m_iTileRow), FORMAT, layers, styles, EXCEPTION, routableLayer, routableParameter );
        
        var RM = new RequestManager(this.m_strMSGateway, VERSION, CRS, mapinfo, jSFunc, localDomain, userId, parentDivId);
        AGGlobalsArray[this.m_strParentDivID].m_objMainMap = new MainMap(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.TILE_IMAGE_ID, RM);
    }
    
    this.SetMap = function (BBoxString)
    {   
        if(!this.bInitialize)
            alert("First you must have to initialize the map by calling InitializeMap() function");
        AGGlobalsArray[this.m_strParentDivID].m_objMainMap.ZoomToBoundingBox(BBoxString);
    }
    
    this.AddObject = function(HTMLObject,latitude,longitude,horisontalOffset,verticalOffset)
    {
        if(typeof horisontalOffset == 'undefined' || typeof horisontalOffset == 'NaN')
            horisontalOffset = 0;
        if(typeof verticalOffset=='undefined' || typeof verticalOffset == 'NaN')
            verticalOffset = 0;
        
        AGGlobalsArray[this.m_strParentDivID].m_objMovingContainer.AddObjectToMap(HTMLObject,latitude,longitude,horisontalOffset,verticalOffset);
    }
    
    this.Pan = function(x, y)
    {
        AGGlobalsArray[this.m_strParentDivID].m_objMainMap.Pan2(x,y);
    }
    
    this.CentreAndScale = function(midLat,midLng, ZoomLevel)
    {
        //alert(typeof ZoomLevel);
        if(typeof ZoomLevel != "number")   
            return;
        
        if(!this.bInitialize)
            alert("First you must have to initialize the map by calling InitializeMap() function");
         
        if( AGGlobalsArray[this.m_strParentDivID].m_ptIniMap.x == 0 &&  AGGlobalsArray[this.m_strParentDivID].m_ptIniMap.y == 0 )
        {
            this.SetInitialMapLocation(midLat,midLng,ZoomLevel);
        }
            
        if(ZoomLevel >= AGGlobalsArray[this.m_strParentDivID].m_arrZoomScale.length)
            ZoomLevel = AGGlobalsArray[this.m_strParentDivID].m_arrZoomScale.length-1;
        else if(ZoomLevel < 0)
            ZoomLevel = 0;
        
        try
        {
            ZoomLevel = parseInt(ZoomLevel,10);
        }
        catch(err)
        {
            ZoomLevel = 0;
        }
        
        var zoomScale = AGGlobalsArray[this.m_strParentDivID].m_arrZoomScale[ZoomLevel];
        AGGlobalsArray[this.m_strParentDivID].m_iCurZoomLevel = ZoomLevel;
        AGGlobalsArray[this.m_strParentDivID].m_objMainMap.ZoomToLocation(midLng, midLat, zoomScale);
    }
    
    this.GetLatLongFromPixel = function(x,y)
    {  
        var pt= AGGlobalsArray[this.m_strParentDivID].GetVisibleLatLongFromPixel(new Point(x,y));
        return {Long:pt.x, Lat:pt.y};
    }
    
    this.AddPoint =function( imgSrc, imgID, lat, lng, xOffset, yOffset, header, Description)
    {
        var imgObj=document.createElement("img");
	    imgObj.src=imgSrc;
	    imgObj.id = imgID;
	    imgObj.parentId = this.m_strParentDivID;
	    AGGlobalsArray[this.m_strParentDivID].m_objMovingContainer.AddObjectToMap(imgObj, lat, lng, xOffset, yOffset);
	    
	    imgObj.onclick = function(ev)
	    { 
            var parentId = this.parentId;
            AGGlobalsArray[parentId].AddUserPointWithText(lat, lng, header, Description, parentId, this.id);
            return false;
	    }

    }
    
    this.RemovePointByID = function(id)
    {
        try
        {
            var obj = document.getElementById(id);
            AGGlobalsArray[this.m_strParentDivID].m_objMovingContainer.RemoveObjectFromMap(obj);
            
            var objBubble = document.getElementById(this.m_strParentDivID + "_callout1");
            if(objBubble && objBubble.PointID && objBubble.PointID == id)
            {   
                AGGlobalsArray[this.m_strParentDivID].m_objMovingContainer.RemoveObjectFromMap(objBubble);
            }
            return true;
        }
        catch(err)
        {
            return false;
        }
    }
    
    this.RemoveAllObjects = function()
    {
        try
        {
            AGGlobalsArray[this.m_strParentDivID].m_objMovingContainer.RemoveAllObjectsFromMap();
            return true;
        }
        catch(err)
        {
            return false;
        }
    }
    
    this.RemoveObject = function(obj)
    {
        try
        {
            AGGlobalsArray[this.m_strParentDivID].m_objMovingContainer.RemoveObjectFromMap(obj);
            return true;
        }
        catch(err)
        {
            return false;
        }
    }
    
    this.RemoveObjectById = function(objId)
    {
        var obj = document.getElementById(objId);
	    return this.RemoveObject(obj);
    }
    
    this.GetScale = function()
    {
        return (AGGlobalsArray[this.m_strParentDivID].m_iCurZoomLevel);
    }
    
    this.GetBoundingBox = function()
    {
        return (AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.GetMapBoundingBox());
    }

	this.ResetMap = function() 
	{
		AGGlobalsArray[this.m_strParentDivID].m_objMainMap.ZoomToLocation(AGGlobalsArray[this.m_strParentDivID].m_ptIniMap.x,AGGlobalsArray[this.m_strParentDivID].m_ptIniMap.y, AGGlobalsArray[this.m_strParentDivID].m_arrZoomScale[AGGlobalsArray[this.m_strParentDivID].m_iniMapZoomLevel]);
	};
	
	this.AddExecutingFunction = function(strFuncName)
    {
        // search if the function contains already
        for(var i=0; i<AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions.length; i++)
        {
            if(AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions[i] == strFuncName)
                return true;
        }
        AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions.push(strFuncName);
        return true;
    }
    
    this.InsertExecutingFunction = function(strFuncName, iIndex)
    {
        if(iIndex < 0)
            return false;
        
        if(iIndex > AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions.length)
            iIndex = AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions.length;
            
        for(var i=AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions.length-1; i>=iIndex; i--)
            AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions[i+1] = AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions[i];
        AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions[iIndex] = strFuncName;
        return true;
    }
    
    this.RemoveExecutingFunction = function(strFuncName)
    {
        var tempArray = AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions;
        AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions = new Array();
        for(var i=0; i<tempArray.length; i++)
        {
            if(tempArray[i] != strFuncName)
                AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions.push(tempArray[i]);
        }
    }
    
    this.RemoveAllExecutingFunctions = function()
    {
        AGGlobalsArray[this.m_strParentDivID].m_arrExecutingFunctions = new Array();
    }

    this.GetCoordinateFromMap = function(boolSinglePoint, CallBackFunctionName)
	{
	    if(boolSinglePoint)
	        AGGlobalsArray[this.m_strParentDivID].m_UserClickOption = AGGlobalsArray[this.m_strParentDivID].SINGLE_POINT;
	    else
	        AGGlobalsArray[this.m_strParentDivID].m_UserClickOption = AGGlobalsArray[this.m_strParentDivID].MULTIPLE_POINTS;
	        
	    
        AGGlobalsArray[this.m_strParentDivID].m_UserClickedPoints = new Array();
        AGGlobalsArray[this.m_strParentDivID].m_UserClickedLatLongs = new Array();
	    
	    if(typeof CallBackFunctionName != "undefined")
	        AGGlobalsArray[this.m_strParentDivID].m_UserCallBackFunction = CallBackFunctionName;
	    else
	        AGGlobalsArray[this.m_strParentDivID].m_UserCallBackFunction = null;
        
	    AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.UserLayer.style.visibility = "visible";
	}
	
	this.GetClickedPoints = function()
	{
	    return AGGlobalsArray[this.m_strParentDivID].m_UserClickedPoints;
	}
	
	this.GetClickedCoordinates = function()
	{
	    return AGGlobalsArray[this.m_strParentDivID].m_UserClickedLatLongs;
	}
	
	this.CancelCoordinateFromMap = function()
	{
	    AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.UserLayer.style.visibility = "hidden";
	}
	
	this.GetCurrentMapArea = function()
	{
	    return AGGlobalsArray[this.m_strParentDivID].m_objMainMap.GetVisibleMainMapBoundingBox2();
	}
	
	this.SetInitialMapLocation = function(Latitude, Longitude, ZoomLevel)
	{   
        AGGlobalsArray[this.m_strParentDivID].m_ptIniMap.x = parseFloat(Longitude);
        AGGlobalsArray[this.m_strParentDivID].m_ptIniMap.y = parseFloat(Latitude);
        AGGlobalsArray[this.m_strParentDivID].m_iniMapZoomLevel = parseInt(ZoomLevel);
	}
	
	this.DisplayZoomBar = function(boolDisplay)
	{
	    if(boolDisplay)
	        AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.ZoomBarContainer.style.visibility = "visible";
	    else
	        AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.ZoomBarContainer.style.visibility = "hidden";
	}
	
	this.EnablePanning = function(boolEnable)
	{
	    if(boolEnable)
	    {   
	        AGGlobalsArray[this.m_strParentDivID].m_bEnablePan = true;
	        AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.DragLayer.style.cursor = "pointer";
	    }
	    else
	    {   
	        AGGlobalsArray[this.m_strParentDivID].m_bEnablePan = false;
	        AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.DragLayer.style.cursor = "auto";
	    }
	}
	
	this.SetZoomBarPosition = function(x,y)
	{
        AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.ZoomBarContainer.style.left = x + "px";
        AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.ZoomBarContainer.style.top = y + "px";
	}
	
	this.ResizeMap = function()
	{   
	    // save currentBBox
	    var curBBox = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.GetVisibleMainMapBoundingBox2();
	    
	    // set MapPanelDiv like given div
	    var parDiv = document.getElementById(this.m_strParentDivID);
	    AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapPanelDiv.style.width = parDiv.offsetWidth + "px";
	    AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapPanelDiv.style.height = parDiv.offsetHeight + "px";
	    
	    // resize MapContentDiv, AdvertisementDiv
	    this.ResizeMapContent();
	    
	    // AGMapGlobals : m_iTileHeight
	    var map_width = parseInt((AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.offsetWidth), 10);
        var map_height = parseInt((AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MapContentDiv.offsetHeight), 10);
        
		map_width = map_width/(AGGlobalsArray[this.m_strParentDivID].m_iTileCol-1) * (AGGlobalsArray[this.m_strParentDivID].m_iTileCol);
		map_height =map_height/(AGGlobalsArray[this.m_strParentDivID].m_iTileRow-1) * (AGGlobalsArray[this.m_strParentDivID].m_iTileRow);
		
        AGGlobalsArray[this.m_strParentDivID].m_iTileHeight =  Math.round(map_height/AGGlobalsArray[this.m_strParentDivID].m_iTileRow);
        AGGlobalsArray[this.m_strParentDivID].m_iTileWidth =  Math.round(map_width/AGGlobalsArray[this.m_strParentDivID].m_iTileCol);
	    
	    // mapInfoObject : size
	    AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.width = Math.round(AGGlobalsArray[this.m_strParentDivID].m_iTileWidth*AGGlobalsArray[this.m_strParentDivID].m_iTileCol);
	    AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.height = Math.round(AGGlobalsArray[this.m_strParentDivID].m_iTileHeight*AGGlobalsArray[this.m_strParentDivID].m_iTileRow);
	    
	    // Crosshair : position
	    this.SetCrossHairAtMidPosition(AGGlobalsArray[this.m_strParentDivID].m_iTileRow, AGGlobalsArray[this.m_strParentDivID].m_iTileCol, AGGlobalsArray[this.m_strParentDivID].m_iTileWidth, AGGlobalsArray[this.m_strParentDivID].m_iTileHeight);
	    // LoadingImage: position
	    this.SetLoadingImageAtMidPosition(AGGlobalsArray[this.m_strParentDivID].m_iTileRow, AGGlobalsArray[this.m_strParentDivID].m_iTileCol, AGGlobalsArray[this.m_strParentDivID].m_iTileWidth, AGGlobalsArray[this.m_strParentDivID].m_iTileHeight);
        
        // reset copyright width
        var mapCanvasDiv = AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas;
        var totalWidth = mapCanvasDiv.MapPanelDiv.offsetWidth - parseInt(mapCanvasDiv.CopyrightDiv.style.marginRight, 10) - parseInt(mapCanvasDiv.ScaleDiv.style.marginLeft, 10);
        //alert(totalWidth);
        mapCanvasDiv.CopyrightDiv.style.width = (Math.floor( totalWidth * 7/11) - 2) + "px";
        mapCanvasDiv.ScaleDiv.style.width = (Math.floor(totalWidth * 4/11) - 2) + "px";
        
        //var w = Math.floor( totalWidth * 2 /3) - 2;
        
        //mapCanvasDiv.ScaleDiv.style.width = expression( mapCanvasDiv.ScaleDiv.offsetWidth > w ? w+"px" : mapCanvasDiv.ScaleDiv.offsetWidth);
        
        //var s = mapCanvasDiv.CopyrightDiv.innerHTML + " ";
        //mapCanvasDiv.CopyrightDiv.innerHTML = s;
        //alert(mapCanvasDiv.CopyrightDiv.innerHTML);
        //mapCanvasDiv.ScaleDiv.innerHTML = mapCanvasDiv.ScaleDiv.innerHTML;
        
	    // show map
	    AGGlobalsArray[this.m_strParentDivID].m_objMainMap.ZoomToBoundingBox(curBBox);
	}
	
	this.RegisterFunction = function(strEvent, strFunctionName, bExecuteOnce)
	{
	    // first check if strEvent is a valid event & function
        if(typeof strEvent != "string" || typeof strFunctionName != "string")
            return false;
        if(strEvent.length == 0 || strFunctionName.length == 0)
            return false;
        
        if(typeof bExecuteOnce != "boolean" || !bExecuteOnce)
            bExecuteOnce = false;
        else
            bExecuteOnce = true;
        
        strEvent = strEvent.toUpperCase();
        switch(strEvent)
        {
            case "ZOOM":
                AGGlobalsArray[this.m_strParentDivID].m_objZoomEventHandler.AddFunction(strFunctionName, bExecuteOnce);
                break;
            case "RIGHTBUTTONCLICK":
                AGGlobalsArray[this.m_strParentDivID].m_objRightButtonClickEventHandler.AddFunction(strFunctionName, bExecuteOnce);
                break;
            case "LEFTBUTTONCLICK":
                AGGlobalsArray[this.m_strParentDivID].m_objLeftButtonClickEventHandler.AddFunction(strFunctionName, bExecuteOnce);
                break;
            case "DOUBLECLICK":
                AGGlobalsArray[this.m_strParentDivID].m_objDoubleClickEventHandler.AddFunction(strFunctionName, bExecuteOnce);
                break;
            case "SHOWROUTING":
                AGGlobalsArray[this.m_strParentDivID].m_objShowRoutingEventHandler.AddFunction(strFunctionName, bExecuteOnce);
                break;
            case "CLEARROUTING":
                AGGlobalsArray[this.m_strParentDivID].m_objClearRoutingEventHandler.AddFunction(strFunctionName, bExecuteOnce);
                break;
            case "RESETBBOX":
                AGGlobalsArray[this.m_strParentDivID].m_objResetBBoxEventHandler.AddFunction(strFunctionName, bExecuteOnce);
                break;
            case "PAN":
                AGGlobalsArray[this.m_strParentDivID].m_objPanEventHandler.AddFunction(strFunctionName, bExecuteOnce);
                break;
            default:
                return false;
        }
        
        return true;
	}
	
	
	this.UnregisterFunction = function(strEvent, strFunctionName)
	{
	    // first check if strEvent is a valid event & function
        if(typeof strEvent != "string" || typeof strFunctionName != "string")
            return;
        if(strEvent.length == 0 || strFunctionName.length == 0)
            return;
        
        strEvent = strEvent.toUpperCase();
        switch(strEvent)
        {
            case "ZOOM":
                AGGlobalsArray[this.m_strParentDivID].m_objZoomEventHandler.RemoveFunction(strFunctionName);
                break;
            case "RIGHTBUTTONCLICK":
                AGGlobalsArray[this.m_strParentDivID].m_objRightButtonClickEventHandler.RemoveFunction(strFunctionName);
                break;
            case "LEFTBUTTONCLICK":
                AGGlobalsArray[this.m_strParentDivID].m_objLeftButtonClickEventHandler.RemoveFunction(strFunctionName);
                break;
            case "DOUBLECLICK":
                AGGlobalsArray[this.m_strParentDivID].m_objDoubleClickEventHandler.RemoveFunction(strFunctionName);
                break;
            case "SHOWROUTING":
                AGGlobalsArray[this.m_strParentDivID].m_objShowRoutingEventHandler.RemoveFunction(strFunctionName);
                break;
            case "CLEARROUTING":
                AGGlobalsArray[this.m_strParentDivID].m_objClearRoutingEventHandler.RemoveFunction(strFunctionName);
                break;
            case "RESETBBOX":
                AGGlobalsArray[this.m_strParentDivID].m_objResetBBoxEventHandler.RemoveFunction(strFunctionName);
                break;
            case "PAN":
                AGGlobalsArray[this.m_strParentDivID].m_objPanEventHandler.RemoveFunction(strFunctionName);
                break;
        }
	}
	
	this.ExecuteUserFunctions = function(boolExecute)
	{
	    if(typeof boolExecute == "boolean")
            AGGlobalsArray[this.m_strParentDivID].m_bExecuteUserFunctions = boolExecute;
	}
	
	this.DrawRoute = function(boolZoomToZoomExtent)
	{
	    AGGlobalsArray[this.m_strParentDivID].DrivingDirections.DrawRoute(boolZoomToZoomExtent);
	}
	
	this.GetMapCentroid = function()
	{
	    var bbox = this.GetCurrentMapArea();
	    return AGGlobalsArray[this.m_strParentDivID].GetCenterOfBBox(bbox);
	}
	
	this.EnableDrivingDirectionsMenu = function(boolEnable)
	{
	    if(boolEnable == true)
	    {
	        AGGlobalsArray[this.m_strParentDivID].m_bEnableDDMenu = true;
	    }
	    else if(boolEnable == false)
	    {
	        AGGlobalsArray[this.m_strParentDivID].m_bEnableDDMenu = false;
	        AGGlobalsArray[this.m_strParentDivID].m_objPopupMenu.HidePopupMenu();
	    }
	}
	
	this.SetZoomOnDoubleClick = function(bZoom)
	{
	    if(bZoom==true || bZoom==false)
	        AGGlobalsArray[this.m_strParentDivID].m_bZoomOnDoubleClick = bZoom;
	}
	
	this.DisplayImagery = function(bDisplay)
	{
	    if(bDisplay==true )
	    {
	        AGGlobalsArray[this.m_strParentDivID].m_bDisplayImagery = true;
	        var imageryTileDiv = document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.SATELLITE_MAPTILES_DIV_ID);
	        imageryTileDiv.style.visibility = "visible";
	        
	        var bbox = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.bBox;
	        var width = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.width;
	        var height = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.height;
	        AGGlobalsArray[this.m_strParentDivID].satTileHandler.SetTiles(bbox, width, height);
	    }
	    else if(bDisplay==false)
	    {   
	        AGGlobalsArray[this.m_strParentDivID].m_bDisplayImagery = false;
	        var imageryTileDiv = document.getElementById(AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.SATELLITE_MAPTILES_DIV_ID);
	        imageryTileDiv.style.visibility = "hidden";
	    }
	}
	
	this.SetTransparency = function(iTransparencyPercentage)
	{   
	    AGGlobalsArray[this.m_strParentDivID].m_objMainMap.RequestManager.mapInfoObject.transperency = iTransparencyPercentage;
	}
	
    this.InitializeMap();

    // GetCapabilities
    if(strCapabilitiesStatus == NOT_REQUESTED || strCapabilitiesStatus == RESPONSE_ERROR)
    {
        strCapabilitiesStatus = REQUESTED;
        var req = AGGlobalsArray[this.m_strParentDivID].m_objMainMap.GetCapabilitiesRequest();
        AGGlobalsArray[this.m_strParentDivID].GetUsingIFrame(req);
    }
    
    AGGlobalsArray[this.m_strParentDivID].m_objPopupMenu = new PopupMenu(this.m_strParentDivID, AGGlobalsArray[this.m_strParentDivID].m_objMapCanvas.MAPCONTENT_DIV_ID);
    AGGlobalsArray[this.m_strParentDivID].DrivingDirections = new DrivingDirection(this.m_strParentDivID);
    this.DrivingDirections = AGGlobalsArray[this.m_strParentDivID].DrivingDirections;
    AGGlobalsArray[this.m_strParentDivID].GetMarbilUserInfoUsingIFrame(this.m_strUid);
}

function AGMapGlobals(strHostUrl, mapCanvasDiv, parentDivID)
{
    this.m_strParentDivId = parentDivID;
    this.m_LocalDomain = location.href;
    this.m_ptImgBasePointShift = new Point(0,0);
    
    this.localDomain = location.href;

    this.m_ptImgBasePointShift = new Point(0,0);
    this.m_arrZoomScale = new Array(50000000,20000000,7500000,5000000,2500000,1500000,1000000,500000,250000,100000,50000,24000,12000);
    this.m_arrTileIndexInUse = new Array();
    this.m_bDocumentLoaded = false;
    this.m_iRequestCount = 0;
    this.m_bEnablePan = true;
    this.m_bEnableDDMenu = true;
    this.m_bPan = 0; // Make is bool
    this.m_bFlag = true;  
    this.m_iUpZIndex = 5;
    this.m_iDownZIndex = 4;
    this.m_bZoom = false;    
//    this.m_bResetOVBBox = false; // Check if it is still needed. We don't deal with OverView Map now  
    this.m_iCurZoomLevel = 0;
    this.m_iPreviousScale = this.m_arrZoomScale[0];  // Check if it is needed. It seems unnecessary.
    this.m_bMouseOverMap = false;  
    this.m_iTileToLoad = 0;
    //this.m_strCopyrightHTML="&copy; 2006 - AfriGIS (Pty) Ltd. <a href='http://maps.afrigis.co.za/'>visit maps.afrigis.co.za</a>";
    //this.m_strCopyrightHTML="&copy; 2006 - AfriGIS (Pty) Ltd";
	this.m_strCopyrightHTML = "Map data &copy; 2008 <a href=\"http://www.afrigis.co.za\" style=\"color:black\" target=\"_blank\">AfriGIS (Pty) Ltd</a>";

    
    this.m_hostURL = strHostUrl;
    
    this.m_iTileRow     = 0;
    this.m_iTileCol     = 0;
    this.m_iMaxNoOfTile = 0;
    this.m_iTileWidth   = 0;
    this.m_iTileHeight  = 0;
    
    this.m_iMaxNoOfSatTile = MAX_SAT_TILE;
    
    // executing function
    this.m_arrExecutingFunctions = new Array();
    
    // Event Handler
    this.m_objZoomEventHandler = new EventHandler();
    this.m_objRightButtonClickEventHandler = new EventHandler();
    this.m_objLeftButtonClickEventHandler = new EventHandler();
    this.m_objDoubleClickEventHandler = new EventHandler();
    this.m_objShowRoutingEventHandler = new EventHandler();
    this.m_objClearRoutingEventHandler = new EventHandler();
    this.m_objResetBBoxEventHandler = new EventHandler();
    this.m_objPanEventHandler = new EventHandler();
    
    this.m_bZoomEventOccured = false;
    this.m_bShowRoutingEventOccured = false;
    this.m_bClearRoutingEventOccured = false;
    this.m_bPanEventOccured = false;
    this.m_bDoubleClickEventOccured = false;
    this.m_bResetBBoxOccured = false;
    
    this.m_bExecuteUserFunctions = true;
    
    // user click - GetMapCoordinate
    this.m_UserCallBackFunction = null;
    this.m_UserClickedPoints = new Array();
    this.m_UserClickedLatLongs = new Array();
    this.m_UserClickOption = null; // 1: single point    0: Multiple point
    
    this.SINGLE_POINT = 1;
    this.MULTIPLE_POINTS = 0;
    
    // right click for popup menu
    this.m_RightClikedCoordinate = new Object();
    this.m_RightClikedCoordinate.Longitude = 0;
    this.m_RightClikedCoordinate.Latitude = 0;
    
    // zoom on double click
    this.m_bZoomOnDoubleClick = true;
    
    // extara param for request
    this.m_iniMapZoomLevel = "";
    this.m_ptIniMap = new Point(0,0);
    this.m_strImgName = "";
    
    // for zoombar    
    this.m_iSegments = 13; //Specifies the number of intervals on the zoom bar
    this.m_iSegmentHeight;
    this.m_iSliderIndex = 0; //Keeps th index of the current slider position
    this.m_iCurrentSliderIndex = 0; //Keep an index to determine not to zoom to the same scale
    this.m_objSliderBar = null;
    this.m_objSlideControl = null;
    
    this.m_iSlideControllerStatus = 0;  // 0:no dragging  1:dragging on
    this.m_ptDragStartPoint = new Point(0,0);
    this.m_ptDragEndPoint = new Point(0,0);
    this.m_ptDragStartTop = 0;
    
    this.m_bShowAdvertising = null;
    
    this.m_objMainMap = null;
    this.m_objMovingContainer = null;
    this.m_objMapCanvas = null;
    
    this.m_JSFunc = "xxxx";
    this.m_LocalDomain = "";
    
    // marbil add
    this.m_strMarbilUserName = "jsapidefault";
    this.m_strMarbilPassword = "msapi";
    this.m_iAdvertWidth = 200;
    this.m_iAdvertHeight = 20;
    
    // layers
    this.m_arrLayers = new Array();
    
    // satellite image handler
    this.satTileHandler= new ImageryTileHandler(this.m_strParentDivId);
    this.m_bDisplayImagery = false;

    
    // routing layer consistency check
    this.m_bRoutingLayerConsistent = true;
    
    
    this.SetPos = function(tileIndex)
    {
        
        var imgId = this.m_objMapCanvas.TILE_IMAGE_ID+tileIndex;
        var elem = document.getElementById(imgId);
        
        if(typeof elem.posLeft != "undefined")
        {
            elem.style.width = this.m_iTileWidth + "px";
            elem.style.height = this.m_iTileHeight + "px";
        
            if(elem.zoom == "1" )   // come from GetTileImageForZoom
            {
                elem.style.left = elem.posLeft + "px";
                elem.style.top = elem.posTop + "px";        
                elem.zoom = "0";
                
                this.m_iTileToLoad --;

                this.m_iTileToLoad = this.m_iTileToLoad < 0 ? 0 : this.m_iTileToLoad;
                
                if (this.m_iTileToLoad == 0)
                {
                    this.ClearRestTile(this.m_arrTileIndexInUse);
                }
            }
            else if(elem.zoom == "0" )
            {
                elem.style.left = elem.posLeft + "px";
                elem.style.top = elem.posTop + "px";
            }
            
            if(BrowserDetect.browser=="Explorer" && BrowserDetect.version < 7 && BrowserDetect.version >= 5.5)
            {
                var ieDiv = document.getElementById( AGGlobalsArray[this.m_strParentDivId].m_objMapCanvas.TILE_IMAGE_DIV_ID+tileIndex);
                ieDiv.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+elem.src+"',sizingMethod='scale');";
                ieDiv.style.width = elem.style.width;
                ieDiv.style.height = elem.style.height;
                ieDiv.style.left = elem.style.left;
                ieDiv.style.top = elem.style.top;
                ieDiv.style.zIndex = elem.style.zIndex;
            }
        }
        else
        {
            //alert("undefined...");
        }
    } 
    
    
    this.ClearRestTile = function(arrTileInUse)
    {
        this.m_objMainMap.freeTileList.RemoveAll();
        this.m_objMainMap.usedTileList.RemoveAll();
        
        var bIEDivExist = BrowserDetect.browser=="Explorer" && BrowserDetect.version < 7 && BrowserDetect.version >= 5.5;
        
        var i;
        for(i=0;i<this.m_iMaxNoOfTile;i++)
        {
            var found = false;
            for (var j = 0; j < arrTileInUse.length; j++)
            {
                if (arrTileInUse[j] == i)
                {
                    found = true;
                    break;
                }
            }
            
            if(found)
            {
                this.m_objMainMap.usedTileList.Add(i);
            }
            else
            {
                this.m_objMainMap.freeTileList.Add(i);
                document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i).style.width = this.m_iTileWidth+"px";
                document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i).style.height = this.m_iTileHeight+"px";
                document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i).style.zIndex = this.m_iUpZIndex;
                document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i).posLeft = "-100000";
                document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i).posTop = "-100000";
                document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i).style.left = -100000+"px";
                document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i).style.top = -100000+"px";
                
                if(bIEDivExist)
                {
                    var ieDiv = document.getElementById(this.m_objMapCanvas.TILE_IMAGE_DIV_ID+i);
                    var img = document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i);
                    
                    ieDiv.style.width = img.style.width;
                    ieDiv.style.height = img.style.height;
                    ieDiv.style.zIndex = img.style.zIndex;
                    ieDiv.style.left = img.style.left;
                    ieDiv.style.top = img.style.top;
                }
            }
        }
        
        var maxTileIndex = -1;
        for(var k = 0; k < arrTileInUse.length; k++)
        {
            if( arrTileInUse[k] > maxTileIndex )
                maxTileIndex = arrTileInUse[k];
        }
        this.m_objMainMap.m_iLoadedImgIndex = maxTileIndex+1;

        arrTileInUse = new Array();
        this.m_iTileToLoad = 0;

        this.MakeFreeForRequest();
    }
   
   this.AddUserPointWithText = function( lat, lng, header, text, parentId, pointId)
    {
        var oMapInfoPointCallout = document.createElement("div");
        oMapInfoPointCallout.id = parentId + "_callout1";
        oMapInfoPointCallout.PointID = pointId;
        
        oMapInfoPointCallout.style.position = "absolute";
        oMapInfoPointCallout.style.width = "200px";
        oMapInfoPointCallout.style.height = "170px";
        oMapInfoPointCallout.style.zIndex = "0";
        var oInfoPointContent = document.createElement("div");
	    var oHeader = document.createElement("h5");
	    
	    var oInfoText = document.createElement("p");
	    var oBtnClose = document.createElement("img");
	    oBtnClose.id = parentId + "_Close";
	    var oCallOut=null;
	    var oCallOutShadow=null;
	    
	    oHeader.style.margin = "0";
	    
	    oInfoText.style.margin = "0";
	    oInfoText.style.height = "65px";
	    oInfoText.style.overflow = "auto";
	    oInfoText.style.paddingTop = "3px";
	    oInfoText.style.fontSize = "8pt";
	    oInfoText.style.fontWeight = "lighter";
	    
	    oInfoPointContent.style.color = "black";
	    oInfoPointContent.style.paddingTop = "15px";
	    oInfoPointContent.style.paddingLeft = "20px";
	    oInfoPointContent.style.paddingRight = "5px";
	    oInfoPointContent.style.textAlign = "left";
	    oInfoPointContent.style.height = "100%";
	    oInfoPointContent.style.width = "170px";
	    oInfoPointContent.style.zIndex = "10";
	    oInfoPointContent.style.fontFamily = "Verdana, Geneva, Arial, Helvetica, sans-serif";
	    oInfoPointContent.style.fontSize = "10pt";
	    oInfoPointContent.style.wordWrap = "break-word";
	    
	    oHeader.innerHTML = header;
	    oInfoText.innerHTML = text;
	    
	    oBtnClose.src=this.m_hostURL+"Images/btn_close.png";
	    oBtnClose.style.position = "absolute";
	    oBtnClose.style.top = "15px";
	    oBtnClose.style.left = "170px";
	    oBtnClose.style.zIndex = "200000";
	    oBtnClose.style.cursor = "pointer";
	    
	    oBtnClose.onclick= function(ev)
	    {
		    var lastIndex = this.id.lastIndexOf("_");
            if(lastIndex<0)
                return;
            var parentId = this.id.substring(0,lastIndex);
            
            AGGlobalsArray[parentId].m_objMovingContainer.RemoveObjectFromMap(oMapInfoPointCallout);
		    return false;
        }
        
        if(BrowserDetect.browser=="Explorer")
	    {
		    oCallOut = document.createElement("div");
		    oCallOutShadow = document.createElement("div");
	    }
	    else
	    {
		    oCallOut = document.createElement("img");
		    oCallOut.src=this.m_hostURL+"Images/Callout_v1.png";
		    oCallOutShadow = document.createElement("img");
		    oCallOutShadow.src=this.m_hostURL+"Images/CallOutSkewedShadow_v1.png";		
	    }
	    
	    oCallOut.style.top = "0px";
	    oCallOut.style.left = "0px";
	    oCallOut.style.position = "absolute";
	    oCallOut.style.width = "200px";
	    oCallOut.style.height = "170px";
	    oCallOut.style.zIndex = "-100";
	    oCallOut.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.m_hostURL+"Images/Callout_v1.png',sizingMethod='scale')";
	    
	    oCallOutShadow.style.top = "63px";
	    oCallOutShadow.style.left = "-5px";
	    oCallOutShadow.style.position = "absolute";
	    oCallOutShadow.style.width = "388px";
	    oCallOutShadow.style.height = "113px";
	    oCallOutShadow.style.zIndex = "-200";
	    oCallOutShadow.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.m_hostURL+"Images/CallOutSkewedShadow_v1.png',sizingMethod='image')";
    	
	    //Assemble the oInfoPointContent
	    oInfoPointContent.appendChild(oHeader);
	    oInfoPointContent.appendChild(oInfoText);
	  
	    //Assemble the oInfoPoint object
	    oMapInfoPointCallout.appendChild(oCallOut);
	    oMapInfoPointCallout.appendChild(oCallOutShadow);
	    oMapInfoPointCallout.appendChild(oInfoPointContent);
	    oMapInfoPointCallout.appendChild(oBtnClose);

        this.m_objMovingContainer.SetCalloutItem(oMapInfoPointCallout,lat,lng,0,-170);  // 170 is the height of oCallOut
        return false;
   }
    
    this.GetNearestZoomScale = function(zoomScale)
    {
        zoomScale = Math.round(zoomScale);
        
        // get the next scale from scaleArray
        for(var i = this.m_arrZoomScale.length ; i>=0; i--)
            if( parseFloat(this.m_arrZoomScale[i]) >= zoomScale )
                return parseFloat(this.m_arrZoomScale[i]);
        
        return parseFloat(this.m_arrZoomScale[0]);
    }
    
    
    this.GetCenterOfBBox = function(bbox)
    {
        var bboxlatlong = bbox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        return {longitude:(long1 + long2)/2, latitude: (lat1 + lat2)/2};        
    }
    
    
    this.GetCenterPointPixel = function()
    {
        var x = ( this.m_iTileWidth * (this.m_iTileCol-1) )/2 - this.m_ptImgBasePointShift.x - 1;
        var y = ( this.m_iTileHeight * (this.m_iTileRow-1) ) /2 - this.m_ptImgBasePointShift.y ;        
        x = Math.round(x);
        y = Math.round(y);
        
        var pt = new Point(x,y);
        return pt;
    }
    
    this.GetOuterMostIndex = function()
    {    
        var totalDiff=-1;
        var index=-1;
        
        
        var halfHeight = Math.round(parseInt(this.m_objMapCanvas.MapContentDiv.style.height,10)/2);     
        var halfWidth  = Math.round(parseInt(this.m_objMapCanvas.MapContentDiv.style.width,10)/2) ;
                
        var centerPoint = new Point(halfWidth,halfHeight);
        
        for(var i=0; i < this.m_iMaxNoOfTile; i++)
        {
            var imgElem = document.getElementById(this.m_objMapCanvas.TILE_IMAGE_ID+i);
            var left = parseInt(imgElem.posLeft,10) + parseInt(this.m_objMapCanvas.tileMapDiv.style.left,10);
            var top = parseInt(imgElem.posTop,10) + parseInt(this.m_objMapCanvas.tileMapDiv.style.top,10);
            if(!this.m_objMainMap.IsTileInViewRegion(i))
            {
                if(centerPoint.x-left > this.m_iTileWidth/2)                    
                    left = left+parseInt(this.m_iTileWidth,10);
                    
                if(centerPoint.y-top > this.m_iTileHeight/2)
                    top = top+parseInt(this.m_iTileHeight,10);
                    
                var x = Math.abs(left-centerPoint.x);
                var y = Math.abs(top-centerPoint.y);
                
                var difference = Math.pow((Math.pow(x,2) + Math.pow(y,2)),0.5);
                
                if(difference>totalDiff)
                {
                    index = i;
                    totalDiff = difference;
                }   
            }
        }
        return index;
    }
    
    this.GetOuterMostSatTileIndex = function(iLevel, iMinX, iMaxX, iMinY, iMaxY)
    {
        var index = -1;
        var maxDistance = -1;
        for(var i=0;i<AGGlobalsArray[this.m_strParentDivId].m_iMaxNoOfSatTile;i++)
        {
            var img = document.getElementById(AGGlobalsArray[this.m_strParentDivId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID + i);
            var l = parseInt(img.level);
            var x = parseInt(img.xVal);
            var y = parseInt(img.yVal);
            
            if(l != iLevel)     // not same level, may be zoomed in or zoomed out
                continue;
            if( x>=iMinX && x<=iMaxX && y>=iMinY && y <=iMaxY)      // inside view region
                continue;
            
            var midX = (iMinX + iMaxX)/2;
            var midY = (iMinY + iMaxY)/2;
            
            var dis = (x - midX) * (x - midX) + (y - midY) * (y - midY);
            if(dis > maxDistance)
            {
                maxDistance = dis;
                index = i;
            }
        }
        
        if(index < 0)
        {
            for(var i=0;i<AGGlobalsArray[this.m_strParentDivId].m_iMaxNoOfSatTile;i++)
            {
                var img = document.getElementById(AGGlobalsArray[this.m_strParentDivId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID + i);
                var l = parseInt(img.level);
                
                if(l != iLevel)     // not same level, may be zoomed in or zoomed out
                {
                    index = i;
                    break;
                }
            }
        }
        
        return index;
    }
    
    this.SlideObject = function(Latitude,Longitude,objWidth,objHeight)
    {
    
        var pixel = this.GetPixelFromLatLong(Latitude,Longitude);
            
        var MapSize = this.m_objMainMap.GetVisibleMainMapSize();
        var height=parseInt(MapSize.GetHeight(),10);
        var width=parseInt(MapSize.GetWidth(),10);
        
        if(pixel.y < objHeight && (pixel.x+objWidth) > width)
        {
            this.MakeBusyForRequest();
            this.SetPosition((-((pixel.x+objWidth+15) - width)),(objHeight + 10 - pixel.y),(-((pixel.x+objWidth+15) - width)),(objHeight+10-pixel.y));
        }
        else if((pixel.x+objWidth) > width)
        {
            this.MakeBusyForRequest();
            this.SetPosition((-((pixel.x+objWidth+15) - width)),0,(-((pixel.x+objWidth+15) - width)),0);
        }
        else if(pixel.y <objHeight)
        {
            this.MakeBusyForRequest();
            this.SetPosition(0,(objHeight + 10-pixel.y),0,(objHeight + 10-pixel.y));
        }
    }
    
    this.SetPosition = function(x,y,panX,panY)
    {        
        var amount=6;
        if(x>=(-amount))
        {
            this.m_objMapCanvas.tileMapDiv.style.left = ( parseInt(this.m_objMapCanvas.tileMapDiv.offsetLeft,10) +x) + "px";
            this.m_objMapCanvas.MovingContainer.style.left = ( parseInt(this.m_objMapCanvas.MovingContainer.offsetLeft,10) +x) + "px";
            x=0;
        }
        if(y<=amount)
        {
            this.m_objMapCanvas.tileMapDiv.style.top = ( parseInt(this.m_objMapCanvas.tileMapDiv.offsetTop,10) + y) + "px";
            this.m_objMapCanvas.MovingContainer.style.top = ( parseInt(this.m_objMapCanvas.MovingContainer.offsetTop,10) + y) + "px";
            y=0;
        }
        if(x==0 && y==0)
        {  
           this.m_objMainMap.Pan(panX,panY); 
            this.MakeFreeForRequest();               
            return;
        }
        if(x<(-amount) && y>amount)
        {
            this.m_objMapCanvas.tileMapDiv.style.left = ( parseInt(this.m_objMapCanvas.tileMapDiv.offsetLeft,10) -amount) + "px";
            this.m_objMapCanvas.tileMapDiv.style.top = ( parseInt(this.m_objMapCanvas.tileMapDiv.offsetTop,10) + amount) + "px";
            this.m_objMapCanvas.MovingContainer.style.left = ( parseInt(this.m_objMapCanvas.MovingContainer.offsetLeft,10) -amount) + "px";
            this.m_objMapCanvas.MovingContainer.style.top = ( parseInt(this.m_objMapCanvas.MovingContainer.offsetTop,10) + amount) + "px";
            x+=amount;
            y-=amount;
        
        }
        else if(x<(-amount))
        {
            this.m_objMapCanvas.tileMapDiv.style.left = ( parseInt(this.m_objMapCanvas.tileMapDiv.offsetLeft,10) -amount) + "px";
            this.m_objMapCanvas.MovingContainer.style.left = ( parseInt(this.m_objMapCanvas.MovingContainer.offsetLeft,10) -amount) + "px";
            x+=amount;
        }
        else if(y>amount)
        {
            this.m_objMapCanvas.tileMapDiv.style.top = ( parseInt(this.m_objMapCanvas.tileMapDiv.offsetTop,10) + amount) + "px";
            this.m_objMapCanvas.MovingContainer.style.top = ( parseInt(this.m_objMapCanvas.MovingContainer.offsetTop,10) + amount) + "px";
            y-=amount;
        }
        setTimeout("AGGlobalsArray['"+this.m_strParentDivId+"'].SetPosition("+x+","+y+","+panX+","+panY+")",1) 
    }
    
    this.GetLatLongFromPixel = function(p)
    {
        var pt = new Point(-1,-1);

        var curBBox = this.m_objMainMap.RequestManager.GetMapBoundingBox();
        
	    var bboxlatlong = curBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        var latDiff = parseFloat(lat2 - lat1);
        var longDiff =parseFloat(long2 - long1);
        
        var MapSize = this.m_objMainMap.GetExtendedMainMapSize();
        var height=parseInt(MapSize.GetHeight(),10);
        var width=parseInt(MapSize.GetWidth(),10);
       
        long1 += (longDiff * p.x / width);
        lat2 -= (latDiff * p.y / height);
        
        pt.x = long1;
        pt.y= lat2;

        return pt;
    }
    
    this.GetVisibleLatLongFromPixel = function(p)
    {
        var pt = new Point(-1,-1);

        var curBBox = this.m_objMainMap.GetVisibleMainMapBoundingBox2();
	    var bboxlatlong = curBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        var latDiff = parseFloat(lat2 - lat1);
        var longDiff =parseFloat(long2 - long1);
        
        var MapSize = this.m_objMainMap.GetVisibleMainMapSize();
        var height=parseInt(MapSize.GetHeight(),10);
        var width=parseInt(MapSize.GetWidth(),10);
       
        long1 += (longDiff * p.x / width);
        lat2 -= (latDiff * p.y / height);
        
        pt.x = long1;
        pt.y= lat2;

        return pt;
    }
    
    this.GetPixelFromLatLong = function(lattitude, longitude)
    {
        var pt = new Point(-1,-1);
        var curBBox = this.m_objMainMap.GetVisibleMainMapBoundingBox2();
        
	    var bboxlatlong = curBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        var latDiff = parseFloat(lat2 - lat1);
        var longDiff =parseFloat(long2 - long1);
        
        
        var MapSize = this.m_objMainMap.GetVisibleMainMapSize();
        var height=parseInt(MapSize.GetHeight(),10);
        var width=parseInt(MapSize.GetWidth(),10);
       
        var x = parseInt((width * Math.abs((long1-longitude)) / longDiff));
        var y = parseInt((height * Math.abs((lat2-lattitude)) /latDiff ));
        
        pt.x = x;
        pt.y= y;
        return pt;
    }

    this.MakeBusyForRequest = function()
    {   
        this.m_iRequestCount++;
        this.DeactivateMouseEvents();
        document.getElementById(this.m_objMapCanvas.ANI_IMAGE_DIV_ID).style.visibility="visible";
    }
    
    this.MakeFreeForRequest = function()
    {
        this.m_iRequestCount --;
        if(this.m_iRequestCount <= 0)
        {
            this.m_iRequestCount = 0;
            this.ActivateMouseEvents();
            document.getElementById(this.m_objMapCanvas.ANI_IMAGE_DIV_ID).style.visibility="hidden";
            
        }
    }
    
    this.ActivateMouseEvents = function()
    {
        this.m_bPan = 0;
        this.m_objMapCanvas.DragLayer.ondblclick = MouseDoubleClick;  
        this.m_objMapCanvas.DragLayer.onmousedown = MouseDown;
        this.m_objMapCanvas.DragLayer.onmousemove = MouseMove;  
        this.m_objMapCanvas.DragLayer.onmouseup = MouseUp;  
        this.m_objMapCanvas.DragLayer.onmouseout = MouseOut;
        this.m_objMapCanvas.DragLayer.onclick = MouseClick;
    }
 
    this.DeactivateMouseEvents = function()
    {
        this.m_bPan = 0;
        var dragLayerElement = this.m_objMapCanvas.DragLayer;
        dragLayerElement.onmousemove = "";
        dragLayerElement.ondblclick = "";
        dragLayerElement.onmousedown = "";
        dragLayerElement.onmouseup = "";
        dragLayerElement.onmouseout = "";
        dragLayerElement.onclick = "";
    }
    
    this.CallBackGetCapabilities = function(strCapabilities)
    {   
        var layers = strCapabilities.split("*"); // '*' is the Layer-Separator
        for(var l=0; l<layers.length; l++)
        {
            var layer = layers[l];
            var layerProperties = layer.split("|"); 
            if(layerProperties.length >= 3)
            {
                var layerName = layerProperties[0];
                var layerStyles = layerProperties[1].split(",");
                var routable = false;
                var routeParam = new Array();
                if(layerProperties[2] == "t")
                    routable = true;
                if(routable && layerProperties.length >= 4)
                    routeParam = layerProperties[3].split(",");
            }
        }
    }
    
    this.CallBackGetBBox = function(retXml) 
    {   
        var bbox = retXml;
        this.m_objMainMap.SetBoundingBox(bbox);
        if(this.m_bExecuteUserFunctions)
            this.m_bResetBBoxOccured = true;
        
        if(this.m_bDisplayImagery)
            this.satTileHandler.SetTiles(bbox, this.m_objMainMap.RequestManager.mapInfoObject.width, this.m_objMainMap.RequestManager.mapInfoObject.height);
            
        this.GetUsingIFrame(this.m_objMainMap.GetTiledMapInfoRequest());
    }
    
    this.CallBackGetToken = function(retXml)
    {   
        var token = retXml;    
        this.m_objMainMap.SetToken(token);
        
        this.m_objMainMap.GetTileImage();
        this.m_objMovingContainer.ResetObjects(); 

        this.MakeFreeForRequest();
		this.m_bFlag = true;
		this.SetScaleContent();
		
		// call user-specified functions after each zoom/pan
        try
        {		
		    for(var i=0; i<this.m_arrExecutingFunctions.length; i++)
		    {
		        eval(this.m_arrExecutingFunctions[i] + "();");
		    }
		}
		catch(err)
		{
		    // error in user specified function calling
		}
		
		this.ExecuteRegisteredFunctions();
		
    }
    
    this.SetScaleContent = function()
    {
        this.m_objMapCanvas.ScaleDiv.innerHTML = "Scale = " + this.m_iCurZoomLevel+ ":" + this.m_arrZoomScale[this.m_iCurZoomLevel];
    }
    
    this.ExecuteRegisteredFunctions = function()
    {
        
        if(this.m_bZoomEventOccured)
	        this.m_objZoomEventHandler.ExecuteFunctions();
		    
	    if(this.m_bShowRoutingEventOccured)
	        this.m_objShowRoutingEventHandler.ExecuteFunctions();
		    
	    if(this.m_bClearRoutingEventOccured)
	        this.m_objClearRoutingEventHandler.ExecuteFunctions();
		    
	    if(this.m_bPanEventOccured)
	        this.m_objPanEventHandler.ExecuteFunctions();
		    
	    if(this.m_bDoubleClickEventOccured)
	        this.m_objDoubleClickEventHandler.ExecuteFunctions();
		
		if(this.m_bResetBBoxOccured)
		    this.m_objResetBBoxEventHandler.ExecuteFunctions();
		
		this.m_bZoomEventOccured = false;
        this.m_bShowRoutingEventOccured = false;
        this.m_bClearRoutingEventOccured = false;
        this.m_bPanEventOccured = false;
        this.m_bDoubleClickEventOccured = false;
        this.m_bResetBBoxOccured = false;
    }
    
    this.GetAdvertise = function()
    {
        var duration = ADVERTISE_DURATION * 1000; // 30 sec
        var location = "bb{" + AGGlobalsArray[this.m_strParentDivId].m_objMainMap.GetVisibleMainMapBoundingBox2() + "}";
        this.GetMarbilAdUsingIFrame( this.m_strMarbilUserName, this.m_strMarbilPassword, this.m_iAdvertWidth, this.m_iAdvertHeight, location);
        setTimeout("AGGlobalsArray['"+this.m_strParentDivId+"'].GetAdvertise()",duration);
    }
    
    this.CallBackGetAdvertise = function(strGetAdvertResponse)
    {
        // '&amp;' is not replaced by '&' e.g. www.afrigis.co.za?option=op1&country=SA  is  www.afrigis.co.za?option=op1&amp;country=SA
        strGetAdvertResponse = strGetAdvertResponse.replace( /\&amp;/ig, '\&');
        var ads = strGetAdvertResponse.split("*");
        if(ads.length > 0)
        {
            var adParts = ads[0].split('|');
            if(adParts.length == 2)
                this.SetAdvertise(adParts[0], adParts[1]);
        }
    }

    this.SetAdvertise = function(strImgSrc, strRedirectUrl)
    {
        if(this.m_bShowAdvertising == true && this.m_objMapCanvas.AdvertisingDiv && this.m_objMapCanvas.AdvertiseImage)
        {   
            iImgWidth = this.m_iAdvertWidth;
            iImgHeight = this.m_iAdvertHeight;
            
            // set image
            this.m_objMapCanvas.AdvertiseImage.src = strImgSrc;
            this.m_objMapCanvas.AdvertiseImage.style.visibility = "visible";
            this.m_objMapCanvas.AdvertiseImage.style.width = this.m_iAdvertWidth + "px";
            this.m_objMapCanvas.AdvertiseImage.style.height = this.m_iAdvertHeight + "px";
            this.m_objMapCanvas.AdvertisingDiv.link = strRedirectUrl;
            
            // show AdBox
            this.m_objMapCanvas.AdvertisingDiv.style.visibility = "visible";
            
            // set position of image
            var iAdBoxW = this.m_objMapCanvas.AdvertisingDiv.offsetWidth;
            var iAdBoxH = this.m_objMapCanvas.AdvertisingDiv.offsetHeight;
            
            if( iImgWidth < iAdBoxW)
            {
                var w = parseInt( (iAdBoxW - iImgWidth)/2, 10);
                this.m_objMapCanvas.AdvertiseImage.style.left = w + "px";
            }
            else
                this.m_objMapCanvas.AdvertiseImage.style.left = "0px";
            
            if( iImgHeight < iAdBoxH)
            {   
                var l = parseInt( (iAdBoxH - iImgHeight)/2, 10);
                this.m_objMapCanvas.AdvertiseImage.style.top = l + "px";
            }
            else
                this.m_objMapCanvas.AdvertiseImage.style.top = "0px";
            
            // set copyright div position
            //this.m_objMapCanvas.CopyrightDiv.style.top =  (parseInt(this.m_objMapCanvas.MapContentDiv.offsetHeight) - 16 - this.m_objMapCanvas.AdvertisingDiv.offsetHeight)+"px";
            this.m_objMapCanvas.CopyrightDiv.style.bottom = this.m_objMapCanvas.AdvertisingDiv.offsetHeight + "px";
            this.m_objMapCanvas.ScaleDiv.style.bottom = this.m_objMapCanvas.AdvertisingDiv.offsetHeight + "px"; 
        }
    }

    this.GetUsingIFrame = function(url)
    {
        if(url.indexOf("GetCapabilitiesAG") >= 0)
        {
            document.getElementById(this.m_objMapCanvas.COMMUNICATION_IFRAME_ID_CAPABILITIES).setAttribute( "src",url);
        }
        else
        {   
            this.MakeBusyForRequest();
            document.getElementById(this.m_objMapCanvas.COMMUNICATION_IFRAME_ID).setAttribute( "src",url);
        }
        return;
    }
    
    this.GetMarbilAdUsingIFrame = function(strUserName, strPass, iWidth, iHeight, strLocation)
    {   
        var url = MARBIL_GATEWAY + "?";
        url += "LocalDomain="+ UrlEncoderDecoder.encode(location.href);
        url += "&JSFunc=" + this.m_JSFunc;
        url += "&Parent=" + this.m_strParentDivId;
        url += "&Request=GetAdvertNow";
        url += "&UserName=" + strUserName;
        url += "&Password=" + strPass;
        url += "&Width=" + iWidth;
        url += "&Height=" + iHeight;
        url += "&Location=" + strLocation;
        document.getElementById(this.m_objMapCanvas.COMMUNICATION_IFRAME_MARBIL_ID).setAttribute( "src",url);
    }
    
    this.GetMarbilUserInfoUsingIFrame = function(strApiKey)
    {
        var url = MARBIL_GATEWAY + "?";
        url += "LocalDomain="+ UrlEncoderDecoder.encode(location.href);
        url += "&JSFunc=" + this.m_JSFunc;
        url += "&Parent=" + this.m_strParentDivId;
        url += "&Request=GetMarbilUser";
        url += "&Key=" + strApiKey;
        document.getElementById(this.m_objMapCanvas.COMMUNICATION_IFRAME_MARBIL_ID).setAttribute( "src",url);
    }
    
    this.CallBackGetMarbilUser = function(strUserInfo)
    {
        strUserInfo = strUserInfo.replace( /\&amp;/ig, '\&');
        if(strUserInfo.toLowerCase() == "invalid key")
        {
            document.getElementById(this.m_strParentDivId).innerHTML = "";
            return;
        }
        
        var infoParts = strUserInfo.split("|");
        if(infoParts.length == 3)
        {
            this.m_strMarbilUserName = infoParts[0];
            this.m_strMarbilPassword = infoParts[1];
            if(infoParts[2].toLowerCase() == "false")
            {
                this.m_bShowAdvertising = false;
            }
            else
            {   
                this.m_bShowAdvertising = true;
                AGGlobalsArray[this.m_strParentDivId].GetAdvertise();
            }
        }
    }
    
    this.SetRoutingLayerConsistency = function(strNormalLayers, strRoutingLayer)
    {
        var arrNormalLayers = strNormalLayers.split(",");
        var consistent = false;
        for(var i=0; i<arrNormalLayers.length; i++)
        {
            if(arrNormalLayers[i] == strRoutingLayer)
            {
                consistent = true;
                break;
            }
        }
        
        this.m_bRoutingLayerConsistent = consistent;
        if(!consistent)
            AGGlobalsArray[this.m_strParentDivId].m_objMainMap.RequestManager.ClearRoutingParam();
    }
    
    this.GetUsingAjax = function(url, callback)
    {
      var XMLHttpRequestObject = false;
         
      if (window.XMLHttpRequest) {
        XMLHttpRequestObject = new XMLHttpRequest();
      } 
      else if (window.ActiveXObject) {
        try
        {
            XMLHttpRequestObject = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e)
        {
            XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
        }
      }
      if (XMLHttpRequestObject == null)
      {
        alert ("This browser does not support AJAX!");
        return;
      }  
     
      if(XMLHttpRequestObject) {
        XMLHttpRequestObject.open("GET", url, true); 
            
        XMLHttpRequestObject.onreadystatechange = function() 
        { 
          if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) 
          {  
              
              callback(XMLHttpRequestObject.responseXML);   
              delete XMLHttpRequestObject;
              XMLHttpRequestObject = null;
          }

        } 

        XMLHttpRequestObject.send(null); 
      }
    }


}


function Layer(strLayerName, arrLayerStyles, bRoutable, arrRouteParameters)
{
    this.m_strLayerName = strLayerName;
    this.m_arrLayerStyles = arrLayerStyles;
    this.m_bRoutable = bRoutable;
    this.m_arrRouteParameters = arrRouteParameters;
    
    this.GetLayerName = function()
    {
        return this.m_strLayerName;
    }
    
    this.GetStyleNames = function()
    {
        return this.m_arrLayerStyles;
    }
    
    this.IsRoutable = function()
    {
        return this.m_bRoutable;
    }
    
    this.GetRouteParameters = function()
    {
        if(this.m_bRoutable)
            return this.m_arrRouteParameters;
        return new Array();
    }
    
    this.ContainsStyle = function(strStyleName)
    {
        var len = this.m_arrLayerStyles.length;
        for(var i=0; i<len; i++)
        {
            if(this.m_arrLayerStyles[i] == strStyleName)
                return true;
        }
        return false;
    }
    
//    this.ContainsRouteParameter = function(strRouteParameter)
//    {
//        if(this.m_bRoutable)
//        {
//            var len = this.m_arrRouteParameters.length;
//            for(var i=0; i<len; i++)
//            {
//                if(this.m_arrRouteParameters[i] == strRouteParameter)
//                    return true;
//            }
//        }
//        return false;
//    }
    
    this.ContainsRouteParameter = function(strRouteParameter)
    {
        strRouteParameter = strRouteParameter.toLowerCase();
        if(this.m_bRoutable)
        {
            var len = this.m_arrRouteParameters.length;
            for(var i=0; i<len; i++)
            {
                if(this.m_arrRouteParameters[i].toLowerCase() == strRouteParameter)
                    return true;
            }
        }
        return false;
    }
}


// all global function and others classes File
/***********************************MouseEventHandler.js***************************************************/    
    
    function MouseCoords(ev)
    {
        ev = ev || window.event;
        if(ev.pageX || ev.pageY)
        {   
	        return {x:ev.pageX, y:ev.pageY};
	    }
	    else if (ev.clientX || ev.clientY) 	{
		    posx = ev.clientX + document.body.scrollLeft
			    + document.documentElement.scrollLeft;
		    posy = ev.clientY + document.body.scrollTop
			    + document.documentElement.scrollTop;
			    
			return { x:posx , y:posy };    
	    }
    }
    
    // for panning
    var panStartPoint;
    var panEndPoint; 

    var mousePosition1 = null;
    var mousePosition2 = null;
    
    var rightButtonClickPoint = new Point(0,0)
    
    function MouseDown(ev)
    {       
        ev = ev || window.event;
        var lastIndex = this.id.lastIndexOf("_");
        if(lastIndex<0)
            return;
            
        var parentId = this.id.substring(0,lastIndex);
        if(IsRightButton(ev))
        {
            AGGlobalsArray[parentId].m_bPan = 0;
            
            var rightButtonClickPoint = GetMouseOffset_bd(document.getElementById(parentId),ev);
            if(AGGlobalsArray[parentId].m_bEnableDDMenu)
                AGGlobalsArray[parentId].m_objPopupMenu.ShowPopupMenuAtPosition(parseInt(rightButtonClickPoint.x,10), parseInt(rightButtonClickPoint.y,10));
            
            var coord = AGGlobalsArray[parentId].GetVisibleLatLongFromPixel(rightButtonClickPoint);
            AGGlobalsArray[parentId].m_RightClikedCoordinate.Longitude = coord.x;
            AGGlobalsArray[parentId].m_RightClikedCoordinate.Latitude = coord.y;
            
            // RightButton EventHandler
            if(AGGlobalsArray[parentId].m_bExecuteUserFunctions)
                AGGlobalsArray[parentId].m_objRightButtonClickEventHandler.ExecuteFunctions();
            return false;
        }
        
        AGGlobalsArray[parentId].m_objPopupMenu.HidePopupMenu();
        if(AGGlobalsArray[parentId].m_bEnablePan && AGGlobalsArray[parentId].m_bPan == 0)
        {   
            var mousePos = MouseCoords(ev);
            panStartPoint = new Point(mousePos.x,mousePos.y);
            mousePosition1 = mousePos;
            AGGlobalsArray[parentId].m_bPan = 1 ;
        }
        return false;
    }
    
    function MouseMove(ev)
    {
        var lastIndex = this.id.lastIndexOf("_");
        if(lastIndex<0)
            return;
            
        var parentId = this.id.substring(0,lastIndex);
        
        if(typeof AGGlobalsArray[parentId].m_bDocumentLoaded == "undefined" || (typeof AGGlobalsArray[parentId].m_bDocumentLoaded == "boolean" && AGGlobalsArray[parentId].m_bDocumentLoaded==false))
            return {x:0, y:0};
            
        if(AGGlobalsArray[parentId].m_bPan==1|| AGGlobalsArray[parentId].m_bPan==2)
        {
            AGGlobalsArray[parentId].m_bPan = 2;                    
            
            mousePosition2 = MouseCoords(ev);
            
            var shiftX = parseInt(mousePosition2.x,10) - parseInt(mousePosition1.x,10);
            var shiftY = parseInt(mousePosition2.y,10) - parseInt(mousePosition1.y,10);
            
            var i = 0;
            var j = 0;
            
            AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.left = ( parseInt(AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.offsetLeft,10) + shiftX) + "px";
            AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.top = ( parseInt(AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.offsetTop,10) + shiftY) + "px";
            
            AGGlobalsArray[parentId].m_objMapCanvas.MovingContainer.style.left = ( parseInt(AGGlobalsArray[parentId].m_objMapCanvas.MovingContainer.offsetLeft,10) + shiftX) + "px";
            AGGlobalsArray[parentId].m_objMapCanvas.MovingContainer.style.top = ( parseInt(AGGlobalsArray[parentId].m_objMapCanvas.MovingContainer.offsetTop,10) + shiftY) + "px";
            
            mainMapWidth = AGGlobalsArray[parentId].m_objMainMap.GetVisibleMainMapSize().GetWidth();
            mainMapHeight = AGGlobalsArray[parentId].m_objMainMap.GetVisibleMainMapSize().GetHeight();
            
            mousePosition1 = mousePosition2;
        }
        return false;
    }
    
    function MouseUp(ev)
    {   
        ev = ev || window.event;
        
        var lastIndex = this.id.lastIndexOf("_");
        if(lastIndex<0)
            return;
            
        var parentId = this.id.substring(0,lastIndex);
        
        AGGlobalsArray[parentId].m_iSlideControllerStatus = 0;
        if(AGGlobalsArray[parentId].m_bPan == 2)
        {
            AGGlobalsArray[parentId].m_bPan = 0;
            var mousePos = MouseCoords(ev);
            panEndPoint = new Point(mousePos.x,mousePos.y);       
            AGGlobalsArray[parentId].m_objMainMap.Pan(panEndPoint.x - panStartPoint.x, panEndPoint.y - panStartPoint.y);
        }
        AGGlobalsArray[parentId].m_bPan = 0;
        return false;
    }
    
    function MouseOut(ev)
    {   
        this.onmousemove(ev);
        this.onmouseup(ev);
            
        var lastIndex = this.id.lastIndexOf("_");
        if(lastIndex<0)
            return;

        var parentId = this.id.substring(0,lastIndex);
        AGGlobalsArray[parentId].m_bPan = 0;
        
        if(this.id == AGGlobalsArray[parentId].m_objMapCanvas.DRAG_LAYER_DIV_ID)
            AGGlobalsArray[parentId].m_bMouseOverMap = false;
    }
    
    function MouseClick(ev)
    {   
        var lastIndex = this.id.lastIndexOf("_");
        if(lastIndex<0)
            return;

        var parentId = this.id.substring(0,lastIndex);
        
        if(AGGlobalsArray[parentId].m_bExecuteUserFunctions)
            AGGlobalsArray[parentId].m_objLeftButtonClickEventHandler.ExecuteFunctions(); 
    }
            
    var dragObject = null;
    var startDragPoint = null;
    var endDragPoint = null;
    var firstDragPoint = null;
    
    function IsRightButton(e) 
    {
        var rightclick = false;
       
        e = e || window.event;
            
        if (e.which) 
            rightclick = (e.which == 3);
        else if (e.button) 
            rightclick = (e.button == 2);
        
        return rightclick;
    }
    
    function GetMouseOffset_bd(target, ev)
    {
	    ev = ev || window.event;

	    var docPos    = GetPosition(target);
	    var mousePos  = MouseCoords(ev);
	    return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
    }

    function GetPosition(e){
	    var left = 0;
	    var top  = 0;

	    while (e.offsetParent){
		    left += e.offsetLeft;
		    top  += e.offsetTop;
		    e     = e.offsetParent;
	    }

	    left += e.offsetLeft;
	    top  += e.offsetTop;


	    return {x:left, y:top};
    }

    function MouseDoubleClick(ev)
    {
        var lastIndex = this.id.lastIndexOf("_");
        if(lastIndex<0)
            return;

        var parentId = this.id.substring(0,lastIndex); 
        
        if(AGGlobalsArray[parentId].m_bZoomOnDoubleClick)
        {
            var tempBasepointX = AGGlobalsArray[parentId].m_ptImgBasePointShift.x;
            var tempBasepointY = AGGlobalsArray[parentId].m_ptImgBasePointShift.y;
            
            var mousePos = MouseCoords(ev);
            var myOffset = GetMouseOffset_bd(AGGlobalsArray[parentId].m_objMapCanvas.MapContentDiv,ev);
            
            var p = new Point(Math.round(myOffset.x + Math.abs(tempBasepointX)) , Math.round(myOffset.y+Math.abs(tempBasepointY)));
            var ptLatLong = AGGlobalsArray[parentId].GetLatLongFromPixel(p);
            
            if (AGGlobalsArray[parentId].m_iCurZoomLevel == AGGlobalsArray[parentId].m_arrZoomScale.length-1)
            {
                alert("Maximum zoom level reached !!!");
                AGGlobalsArray[parentId].m_iCurZoomLevel = AGGlobalsArray[parentId].m_arrZoomScale.length - 1;
            }
            else
                AGGlobalsArray[parentId].m_objMainMap.ZoomToLocation(ptLatLong.x, ptLatLong.y, AGGlobalsArray[parentId].m_arrZoomScale[AGGlobalsArray[parentId].m_iCurZoomLevel+1]);
        }
        
        // execute double click functions    
        if(AGGlobalsArray[parentId].m_bExecuteUserFunctions)
            AGGlobalsArray[parentId].m_bDoubleClickEventOccured = true;
    }


/***********************************Zoombar.js***************************************************/    

var sliderPosition = 0;

function ClickSlider(ev, parentId)
{
    
    if(AGGlobalsArray[parentId].m_iRequestCount>0)
        return;
        
     ev = ev || window.event;
     if(!ev){return;}
     var mousePos = MouseCoords(ev);
     
     var obj = GetPosition(document.getElementById(AGGlobalsArray[parentId].m_objMapCanvas.SLIDERBAR_ID));
     dif = parseInt((mousePos.y - obj.y) / (AGGlobalsArray[parentId].m_iSegmentHeight));
     if(AGGlobalsArray[parentId].zoombarNumber=="4")
        dif = 11 - dif;
     
     if(dif<AGGlobalsArray[parentId].m_arrZoomScale.length)
        ZoomMapToScale(dif+1,parentId,AGGlobalsArray[parentId].zoombarNumber);     
     else
        ZoomMapToScale(AGGlobalsArray[parentId].m_arrZoomScale.length-1,parentId);     
}

//Handels the Zoom In button on the zoom bar
function ZoomInButtonClick(parentId,zoombarIndex)
{   
    if(AGGlobalsArray[parentId].m_iRequestCount>0)
        return;
        
    var index;
    index = AGGlobalsArray[parentId].m_iCurZoomLevel;
    if(index < AGGlobalsArray[parentId].m_arrZoomScale.length)
        ZoomMapToScale(index+1,parentId,zoombarIndex);
    else
        alert("Maximum zoom level reached !");
}

function ZoomOutButtonClick(parentId,zoombarIndex)
{
    if(AGGlobalsArray[parentId].m_iRequestCount>0)
        return;
        
    var index;
    index = AGGlobalsArray[parentId].m_iCurZoomLevel;
    if(index > 0)
        ZoomMapToScale(index-1,parentId,zoombarIndex);
    else
        alert("Minimum zoom level reached !");
} 

function ZoomMapToScale(sliderIndex, parentId,zoombarIndex)
{
    sliderIndex = parseInt(sliderIndex, 10);

    if (sliderIndex > AGGlobalsArray[parentId].m_iSegments-1)
    {
        sliderIndex = AGGlobalsArray[parentId].m_iSegments-1;
        alert("Maximum zoom level reached !");
        return;
    } 
    
    if(AGGlobalsArray[parentId].m_iCurZoomLevel == sliderIndex) // no need to redraw
        return;
     
    AGGlobalsArray[parentId].m_iCurZoomLevel = sliderIndex;
    
    var p=GetCenterPointLatLong(parentId);
    //AGGlobalsArray[parentId].m_bResetOVBBox = true;
    AGGlobalsArray[parentId].m_objMainMap.ZoomToLocation(p.x,p.y,AGGlobalsArray[parentId].m_arrZoomScale[sliderIndex]);
    AGGlobalsArray[parentId].m_iCurrentSliderIndex = sliderIndex; 
}

function GetCenterPointLatLong(parentId)
{
    var x = ( AGGlobalsArray[parentId].m_iTileWidth * (AGGlobalsArray[parentId].m_iTileCol-1) )/2 - AGGlobalsArray[parentId].m_ptImgBasePointShift.x - 1;
    var y = ( AGGlobalsArray[parentId].m_iTileHeight * (AGGlobalsArray[parentId].m_iTileRow-1) ) /2 - AGGlobalsArray[parentId].m_ptImgBasePointShift.y ;

    x = Math.round(x);
    y = Math.round(y);
    
    return AGGlobalsArray[parentId].GetLatLongFromPixel(new Point(x,y));
}

function MoveZoomSlideDown(index, parentDivId)
{
    var colorIndex =0;
    if(index<AGGlobalsArray[parentDivId].m_arrZoomScale.length)
    {
        colorIndex = 13 - index;
        var zoombarNo = AGGlobalsArray[parentDivId].zoombarNumber;
        if(zoombarNo=="2" || zoombarNo=="3" || zoombarNo=="4")
            AGGlobalsArray[parentDivId].m_objMapCanvas.ZoomSlideBar.setAttribute( 'src', AGGlobalsArray[parentDivId].m_hostURL+"zoombar/zb" + zoombarNo + "/scale_"+colorIndex+".png");
        else
            AGGlobalsArray[parentDivId].m_objMapCanvas.ZoomSlideController.style.top = Math.ceil(AGGlobalsArray[parentDivId].m_iSegmentHeight*index + AGGlobalsArray[parentDivId].m_objMapCanvas.ZoomSlideBar.offsetTop - AGGlobalsArray[parentDivId].m_objMapCanvas.ZoomSlideController.offsetHeight/2) + 'px';
            
    }
}


///////////////////////////////////////////////////////////////
////////////////////  DetectBrowser Class  ////////////////////////////
///////////////////////////////////////////////////////////////

var BrowserDetect = {
	init: function () 
	{
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	
	searchString: function (data) 
	{
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) 
	{
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();

/***********************************DetectBrowser class [END] ***************************************************/
   
///////////////////////////////////////////////////////////////
////////////////////  Point Class  ////////////////////////////
///////////////////////////////////////////////////////////////

function Point(_x,_y)
{
    this.x = _x;
    this.y = _y;
    
    this.GetX = function()
    {
        return this.x;
    }
    
    this.SetX = function(_x)
    {
        this.x = _x;
    }
    
    this.GetY = function()
    {
        return this.y;
    }
    
    this.SetY = function(_y)
    {
        this.y = _y;
    }
}

////////////////// end of Point Class /////////////////////////


///////////////////////////////////////////////////////////////
/////////////////////  Size Class  ////////////////////////////
///////////////////////////////////////////////////////////////

function Size(_width, _height)
{
    this.width = _width;
    this.height = _height;
    
    this.GetWidth = function ()
    {
        return this.width;
    }
    
    this.SetWidth = function(_width)
    {
        this.width = _width;
    }
    
    this.GetHeight = function ()
    {
        return this.height;
    }
    
    this.SetWidth = function(_height)
    {
        this.height = _height;
    }
    
}

////////////////// end of Size Class /////////////////////////


///////////////////////////////////////////////////////////////
/////////////////////  TileList Class  ////////////////////////////
///////////////////////////////////////////////////////////////

function TileList()
{
    this.items = new Array();
    this.length = 0;
    
    this.Add = function(item)
    {
        this.items[this.length] = item;
        this.length++;
    }
    
    this.RemoveAll = function()
    {
        this.length = 0;
    }
    
    this.PopFirstItem = function()
    {
        if(this.length <= 0)
            return null;
        
        var toRet = this.items[0];
        this.items[0] = this.items[this.length-1];
        this.length--;
        return toRet;
    }
    
}

////////////////// end of TileList Class /////////////////////////


///////////////////////////////////////////////////////////////
////////////////////  MapInfo Class  //////////////////////////
///////////////////////////////////////////////////////////////

function MapInfo(_bBox,_width, _height, _format, _layers, _styles, _exceptions, _routableLayer, _routableParameter, _transperency)
{
    this.bBox = _bBox;
    this.width = parseInt( _width,10);
    this.height = parseInt( _height,10);
    this.format = _format;
    this.layers = _layers;
    this.styles = _styles;
    this.exceptions = _exceptions;
    this.routableLayer = _routableLayer;
    this.routableParameter = _routableParameter;
    
    this.transperency = 0;
    if(typeof _transperency == "number" && _transperency>=0 && _transperency<=100)
        this.transperency = parseInt(_transperency+"", 10);
        
    this.token = "";
    
    
    this.SetToken = function (_token)
    {
        this.token = _token;
    }
    
    this.GetToken = function()
    {
        return this.token;
    }
    
    this.SetBoundingBox = function(_bBox)
    {
        this.bBox = _bBox;
    }
    
    this.GetBoundingBox = function()
    {
        return this.bBox;
    }
    
    this.GetSize = function()
    {
        return new Size(this.width,this.height);
    }
    
    this.SetSize = function(_size)
    {
        this.width = parseInt( _size.width,10);
        this.height = parseInt( _size.height,10);
    }
     this.SetWidth = function(w)
    {
        this.width = parseInt(w,10);
    }    
    
    this.setHeight = function(h)
    {
        this.height = parseInt(h);
        
    }        
    
}

//////////////////// End of MapInfo Class  ////////////////////

///////////////////////////////////////////////////////////////
////////////////////  MovingContainer Class  ////////////////////////
///////////////////////////////////////////////////////////////


function MovingContainer(movingContainerDiv)
{
    var lastIndex = movingContainerDiv.lastIndexOf("_");
    if(lastIndex<0)
        return;

    this.strParentId = movingContainerDiv.substring(0,lastIndex); 
            
    this.m_movingContainerDiv = movingContainerDiv;
	this.TopItemInContainer = -1; //Index of the most top item's z-index in the contianer
	this.CalloutItem=null; //The map is only allowed to display ONE callout item at a time
        
    this.AddObjectToMap = function (obj, dLat, dLong, offsetX, offsetY)
    {
        var pt = this.GetXYFromCoord(dLat, dLong);
        pt.x += offsetX;
        pt.y += offsetY;   
        pt.x -= AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.offsetLeft;
        pt.y -= AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.offsetTop;
        obj.Lat = dLat;
        obj.Long = dLong;
        obj.offsetX = offsetX;
        obj.offsetY = offsetY;        
        
        obj.style.position = "absolute";
        obj.style.top = pt.y + "px";
        obj.style.left =  pt.x + "px";

		//Set the item's zIndex in the container
		this.TopItemInContainer++;
	    obj.style.zIndex = this.TopItemInContainer;
        AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.appendChild(obj);
    }    
	
	this.SetCalloutItem = function (obj, dLat, dLong, offsetX, offsetY)
	{
		//If another call out item is visible, remove it
		if(this.CalloutItem)
			this.RemoveObjectFromMap(this.CalloutItem)
		//add the item	to the map
		if(AGGlobalsArray[this.strParentId].m_bFlag)
		{
		    this.CalloutItem=obj;
		    this.AddObjectToMap(obj, dLat, dLong, offsetX, offsetY);			
		    AGGlobalsArray[this.strParentId].SlideObject(dLat,dLong,190+offsetX,-offsetY);
		}
	}
    
    this.RemoveObjectFromMap = function (obj)
    {
		if(obj)
	        document.getElementById(this.m_movingContainerDiv).removeChild(obj)
	    if(this.CalloutItem)
    	    if(this.CalloutItem.id==obj.id)
    	    {
			    this.CalloutItem=null;	
		    }
    }
    
    this.RemoveAllObjectsFromMap = function ()
    {
        document.getElementById(this.m_movingContainerDiv).innerHTML='';
        this.TopItemInContainer=-1;
		this.CalloutItem=null;
		
    }
    
    this.GetXYFromCoord=function(latitude,longitude)
    {
        var pt = new Point(0,0);
        
        var curBBox = AGGlobalsArray[this.strParentId].m_objMainMap.RequestManager.GetMapBoundingBox();
	    var bboxlatlong = curBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        var latDiff = parseFloat( lat2 - lat1);
        var longDiff = parseFloat( long2 - long1);
        
        var newLatDiff= parseFloat(lat2 - latitude);
        var newLongDiff= parseFloat(longitude - long1);
        
        var MapSize = AGGlobalsArray[this.strParentId].m_objMainMap.RequestManager.GetMapSize();
        var height=MapSize.GetHeight();
        var width=MapSize.GetWidth();
        
        var newHeight =Math.round((height*newLatDiff)/latDiff);
        var newWidth =Math.round((width*newLongDiff)/longDiff);        
        
        pt.x = newWidth - Math.abs(AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x);
        pt.y = newHeight - Math.abs(AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y);

        return pt;
    }
    
    
    this.ResetObjects=function()
    {
        var lNoChilds = document.getElementById(this.m_movingContainerDiv).childNodes.length        
        var arrChild = document.getElementById(this.m_movingContainerDiv).childNodes;
       
        for (var i = 0; i < lNoChilds; i++)
        {
            var offX = arrChild[i].offsetX;
            var offY = arrChild[i].offsetY;
            var pt = this.GetXYFromCoord(arrChild[i].Lat, arrChild[i].Long);
            
            
            pt.x -= parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.offsetLeft,10);
            pt.y -= parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.offsetTop,10);
            
            arrChild[i].style.left = (pt.x + offX) + "px";
            arrChild[i].style.top = (pt.y + offY) + "px";
        }
    }
}

//////////////////// End of MovingContainer Class  ////////////////////

///////////////////////////////////////////////////////////////
////////////////////  CoordMapper Class  ////////////////////////
///////////////////////////////////////////////////////////////

function CoordMapper(strBBox, iMapWidth, iMapHeight)
{
    this.m_dPixelPitch = 0.1;
    this.m_dScale = -1;

    if(typeof strBBox == "string") // && widht and height are int
    {
        this.m_strBBox = strBBox;
        this.m_iMapWidth = parseInt(iMapWidth,10);
        this.m_iMapHeight = parseInt(iMapHeight,10);
    }
    
    this.CalculateScale = function()
    {
        var bboxlatlong = this.m_strBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        var dHorScale = this.m_iMapWidth / (long2 - long1);
        var dVerScale = this.m_iMapHeight / (lat2 - lat1);
        
        var minScale = (dHorScale<dVerScale) ? dHorScale : dVerScale;
        
        this.m_dScale = parseFloat( 111701000.0 / (this.m_dPixelPitch * minScale) );
        
    }
    
    this.CalculateBBoxForZoomRequest = function(midLat, midLong, scale, mapWidth, mapHeight)
    {
        var minScale = parseFloat( 111701000.0 / (this.m_dPixelPitch * scale) );
        
        var dLong = mapWidth / minScale;
        var dLat = mapHeight / minScale;
        
        var minX = midLong -  dLong/2;
        var minY = midLat -  dLat/2;
        var maxX = midLong +  dLong/2;
        var maxY = midLat +  dLat/2;

        return minX + "," + minY + "," + maxX + "," +maxY;
    }

    function getDistanceInKiloMetre(long1, lat1, long2, lat2)
	{
		var val = 180.0/Math.acos(-1.0);			// = 180.0/PI
		var r = 6378.7 ;
		var  distance = r * Math.acos(Math.sin(lat1/val) * Math.sin(lat2/val) + Math.cos(lat1/val)* Math.cos(lat2/val)* Math.cos(long2/val -long1/val));
		return distance;
	}

	function setViewRegion(midLat, midLong, dScale, width, height)
	{
		var m_dScalingFactor = 388803.72036893060/462569.0;
		dScale = dScale * m_dScalingFactor;

		
		var dHDistanceInKm = (width/96.0)*(2.54/100000.0)*dScale;
		var dVDistanceInKm = (height/96.0)*(2.54/100000.0)*dScale;

		var dLongitude = getLongitudeHavingDistance(dHDistanceInKm/2.0, midLat, midLong);
		var dLatitude = getLatitudeHavingDistance(dVDistanceInKm/2.0,midLat, midLong);

		var dHalfWidth, dHalfHeight;
		dHalfWidth = Math.abs(dLongitude - midLong);
		dHalfHeight = Math.abs(dLatitude - midLat);

		var erdXmin = midLong - dHalfWidth;
		var erdXmax = midLong + dHalfWidth;
		var erdYmin = midLat - dHalfHeight;
		var erdYmax = midLat + dHalfHeight;

		var dHDistanceInKmNew = getDistanceInKiloMetre(erdXmin,erdYmin,erdXmax,erdYmin);
		var dVDistanceInKmNew = getDistanceInKiloMetre(erdXmin,erdYmin, erdXmin, erdYmax);

		var dHDiffInCM = Math.abs((dHDistanceInKmNew - dHDistanceInKm)*1000*100);
		var dVdiffInCM = Math.abs((dVDistanceInKmNew - dVDistanceInKm)*1000*100);

		var dToleranceLevel = 1;

		if(dHDiffInCM > dToleranceLevel || dVdiffInCM > dToleranceLevel)
		{
			var ep2dX = erdXmin;
			var ep2dY = erdYmin;

			var dLongitude2 = getLongitudeHavingDistance(dHDistanceInKm,ep2dY,ep2dX);
			var dLatitude2 = getLatitudeHavingDistance(dVDistanceInKm,ep2dY,ep2dX);

			erdXmax = ep2dX + Math.abs(dLongitude2 - ep2dX);
			erdYmax = ep2dY + Math.abs(dLatitude2 - ep2dY);
		}
		
		return erdXmin + "," + erdYmin + "," + erdXmax + "," + erdYmax;
	}

	function getLongitudeHavingDistance(dDistance, lat, lon)
	{
		var dLongMin	= lon;
		var dLongMax = 180.0 ;
		var dCurrentLong ;

		var epsilon =  0.0000001; //1e-7;
		var epsilon2 = 0.0000000001; //1e-10;

		while(true)
		{
			dCurrentLong = (dLongMin + dLongMax)/2.0;

			if(Math.abs(dLongMax - dLongMin) < epsilon2)
				return dCurrentLong ;	//I don't have a choice

			var dCurrentDistance = getDistanceInKiloMetre(lon, lat, dCurrentLong, lat);

			if( Math.abs(dCurrentDistance - dDistance) < epsilon)
				return dCurrentLong;

			if(dCurrentDistance > dDistance)
				dLongMax = dCurrentLong;
			else 
				dLongMin = dCurrentLong;
		}

		return -1.0;
	}


	function getLatitudeHavingDistance( dDistance, lat, lon)
	{
		var dLatMin	= lat;
		var dLatMax = -180.0;
		var dCurrentLat ;

		var epsilon =  0.0000001; //1e-7;
		var epsilon2 = 0.0000000001; //1e-10;

		while(true)
		{
			dCurrentLat = (dLatMin + dLatMax)/2.0;

			if(Math.abs(dLatMax - dLatMin) < epsilon2)
				return dCurrentLat ;	//I don't have a choice

			var dCurrentDistance = getDistanceInKiloMetre(lon,lat,lon,dCurrentLat);
			if( Math.abs(dCurrentDistance - dDistance) < epsilon)
				return dCurrentLat;

			if(dCurrentDistance > dDistance)
				dLatMax = dCurrentLat;
			else 
				dLatMin = dCurrentLat;
		}

		return -1.0;
	}
    
    this.CalculateBBoxForPanRequest = function(currentBBox, mapWidth, mapHeight, shiftX, shiftY)
    {
        mapWidth = parseFloat(mapWidth);
        mapHeight = parseFloat(mapHeight);
        shiftX = parseFloat(shiftX);        
        shiftY = parseFloat(shiftY);               
    
        var bboxlatlong = currentBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        var shiftLong = parseFloat((shiftX*(long2 - long1)) / mapWidth);
        var shiftLat = parseFloat((shiftY*(lat2 - lat1)) / mapHeight);
        
        long1 -= shiftLong;
        lat1 += shiftLat;
        long2 -= shiftLong;
        lat2 += shiftLat;
        
        return long1 + "," + lat1 + "," + long2 + "," + lat2;
    }    
    
    this.GetScale = function()
    {   
        this.CalculateScale();
        return this.m_dScale;
    }
	
    this.GetWidthHeightByScale = function(iScale)
    {
        var bboxlatlong = this.m_strBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        var iWidth  = (111701000.0 * (long2 - long1))/(this.m_dPixelPitch * iScale);
        var iHeight = (111701000.0 * (lat2 - lat1))/(this.m_dPixelPitch * iScale);
        
        return new Point(iWidth, iHeight)
    }

}

//////////////////// End of CoordMapper Class  ////////////////////

/*****************************************************************************************************************************
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MapCanvas Class @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
*****************************************************************************************************************************/

function MapCanvas(_MapPanelDiv,ParentDivID,zoombar_no)
{
    // All the Dynamic DIV
    this.strParentId = ParentDivID;
    
    this.MOVIMG_CONTAINER_DIV_ID = ParentDivID + "_MovingContainer";
    this.MAPPANEL_DIV_ID = ParentDivID + "_MapPanel";
    this.MAPCONTENT_DIV_ID = ParentDivID + "_MapContent";
    this.TILEMAP_DIV_ID = ParentDivID + "_tileMapDiv";
    this.MAPTILES_DIV_ID = ParentDivID + "_map_tiles";
    this.SATELLITE_MAPTILES_DIV_ID = ParentDivID + "_SatelliteMaptiles";
    this.DRAG_LAYER_DIV_ID = ParentDivID + "_DragLayer";
    this.CROSS_HAIR_DIV_ID = ParentDivID + "_CrossHair";
    this.ZOOMBAR_CONTAINER_DIV_ID = ParentDivID + "_ZoomBarContainer";
    this.ANI_IMAGE_DIV_ID = ParentDivID + "_aniImage";
    this.COPYRIGHT_DIV_ID = ParentDivID + "_Copyright";
    this.SCALE_DIV_ID = ParentDivID + "_Scale";
    this.COMMUNICATION_IFRAME_ID = ParentDivID + "_commIframe";
    this.COMMUNICATION_IFRAME_ID_CAPABILITIES = ParentDivID + "_commIframeCapabilities";
    this.COMMUNICATION_IFRAME_MARBIL_ID = ParentDivID + "_commIframeMarbil";
    this.SLIDERBAR_ID = ParentDivID + "_SliderBar";
    this.SLIDECONTROL_ID = ParentDivID + "_SlideControl";
    this.ZOOMINBUTTON_ID = ParentDivID + "_ZoomInButton";
    this.ZOOMOUTBUTTON_ID = ParentDivID + "_ZoomOutButton";
    this.TILE_IMAGE_ID = ParentDivID + "_TIID";
    this.TILE_IMAGE_DIV_ID= ParentDivID + "_TIDID";
    this.SATELLITE_TILE_IMAGE_ID = ParentDivID + "_STIID";
    this.USER_LAYER_DIV_ID = ParentDivID + "_UserLayer";
    this.ADVERTISING_DIV_ID = ParentDivID + "_Advertise";
    
    // popup menu
    this.POPUP_MENU_DIV_ID = ParentDivID + "_PopupMenu";
    this.POPUP_START_HERE_DIV_ID = ParentDivID + "_StartHere";
    this.POPUP_END_HERE_DIV_ID = ParentDivID + "_EndHere";
    this.POPUP_CLEAR_DIV_ID = ParentDivID + "_ClickHere";
    
    this.MyMapDivId = document.getElementById(_MapPanelDiv.id);
    this.MapPanelDiv = null;
    this.MapContentDiv = null;
    this.tileMapDiv = null;
    this.MovingContainer = null;
    this.DragLayer = null;
    this.CrossHair = null;
    this.ZoomBarContainer = null;
    this.aniImage = null;
    this.AdvertisingDiv = null;
    this.CopyrightDiv = null;
    this.ScaleDiv = null;
    
    this.MapPanelDiv=document.createElement('div');
    this.MapPanelDiv.setAttribute('id', this.MAPPANEL_DIV_ID);
    this.MapPanelDiv.setAttribute('align', 'left');
    this.MapPanelDiv.style.position = "relative";
    this.MapPanelDiv.style.width = _MapPanelDiv.offsetWidth;
    this.MapPanelDiv.style.height = _MapPanelDiv.offsetHeight;
    this.MapPanelDiv.style.overflow = "hidden";
    this.MapPanelDiv.style.zIndex = "0";
        
    this.MapContentDiv=document.createElement('div');
    this.MapContentDiv.setAttribute('id', this.MAPCONTENT_DIV_ID);
    this.MapContentDiv.style.position = "relative";
    this.MapContentDiv.style.left = "0px";
    this.MapContentDiv.style.top = "0px";
    this.MapContentDiv.style.overflow = "hidden";
    this.MapContentDiv.style.zIndex = "0";
    
    var CommunicationIFrame=document.createElement('iframe');
    CommunicationIFrame.setAttribute('id', this.COMMUNICATION_IFRAME_ID);
    CommunicationIFrame.setAttribute('name', this.COMMUNICATION_IFRAME_ID);
    CommunicationIFrame.setAttribute('src', "");
    CommunicationIFrame.style.width = "1px";
    CommunicationIFrame.style.height = "1px";
    CommunicationIFrame.style.position = "absolute";
    CommunicationIFrame.style.left = "0px";
    CommunicationIFrame.style.top = "0px";
    CommunicationIFrame.style.visibility = "hidden";
    this.MapContentDiv.appendChild(CommunicationIFrame);
    
    var CommunicationIFrameCapabilities = document.createElement('iframe');
    CommunicationIFrameCapabilities.setAttribute('id', this.COMMUNICATION_IFRAME_ID_CAPABILITIES);
    CommunicationIFrameCapabilities.setAttribute('name', this.COMMUNICATION_IFRAME_ID_CAPABILITIES);
    CommunicationIFrameCapabilities.setAttribute('src', "");
    CommunicationIFrameCapabilities.style.width = "1px";
    CommunicationIFrameCapabilities.style.height = "1px";
    CommunicationIFrameCapabilities.style.position = "absolute";
    CommunicationIFrameCapabilities.style.left = "0px";
    CommunicationIFrameCapabilities.style.top = "0px";
    CommunicationIFrameCapabilities.style.visibility = "hidden";
    this.MapContentDiv.appendChild(CommunicationIFrameCapabilities);
    
    var CommunicationIFrameMarbil = document.createElement('iframe');
    CommunicationIFrameMarbil.setAttribute('id', this.COMMUNICATION_IFRAME_MARBIL_ID);
    CommunicationIFrameMarbil.setAttribute('name', this.COMMUNICATION_IFRAME_MARBIL_ID);
    CommunicationIFrameMarbil.setAttribute('src', "");
    CommunicationIFrameMarbil.style.width = "1px";
    CommunicationIFrameMarbil.style.height = "1px";
    CommunicationIFrameMarbil.style.position = "absolute";
    CommunicationIFrameMarbil.style.left = "0px";
    CommunicationIFrameMarbil.style.top = "0px";
    CommunicationIFrameMarbil.style.visibility = "hidden";
    this.MapContentDiv.appendChild(CommunicationIFrameMarbil);
    
    this.tileMapDiv=document.createElement('div');
    this.tileMapDiv.setAttribute('id', this.TILEMAP_DIV_ID);
    this.tileMapDiv.style.position = "relative";
    this.tileMapDiv.style.left = "0px";
    this.tileMapDiv.style.top = "0px";
    this.tileMapDiv.style.zIndex = "0";
    
    var map_tiles=document.createElement('div');
    map_tiles.setAttribute('id', this.MAPTILES_DIV_ID);
    map_tiles.style.cursor = "pointer";
    map_tiles.style.zIndex = "1";
    map_tiles.style.position = "relative";
    map_tiles.style.left = "0px";
    map_tiles.style.top = "0px";
    this.tileMapDiv.appendChild(map_tiles);
    
    this.imagery_map_tiles = document.createElement('div');
    this.imagery_map_tiles.setAttribute('id', this.SATELLITE_MAPTILES_DIV_ID);
    this.imagery_map_tiles.style.position = "absolute";
    this.imagery_map_tiles.style.left = "0px";
    this.imagery_map_tiles.style.top = "0px";
    this.imagery_map_tiles.style.zIndex = "0";
    this.tileMapDiv.appendChild(this.imagery_map_tiles);
    
    this.MapContentDiv.appendChild(this.tileMapDiv);
    
    this.MovingContainer=document.createElement('div');
    this.MovingContainer.setAttribute('id', this.MOVIMG_CONTAINER_DIV_ID);
    this.MovingContainer.style.position = "relative";
    this.MovingContainer.style.cursor = "pointer";
    this.MovingContainer.style.left = "0px";
    this.MovingContainer.style.top = "0px";
    this.MovingContainer.style.zIndex = "60";
    
    this.MapContentDiv.appendChild(this.MovingContainer);
    
    this.DragLayer=document.createElement('div');
    this.DragLayer.setAttribute('id', this.DRAG_LAYER_DIV_ID);
    this.DragLayer.style.position = "absolute";
    this.DragLayer.style.left = "0px";
    this.DragLayer.style.top = "0px";
    this.DragLayer.style.width = "100%";
    this.DragLayer.style.height = "100%";
    this.DragLayer.style.cursor = "pointer";
    this.DragLayer.style.backgroundColor = "Black";
    this.DragLayer.style.opacity = "0";
    this.DragLayer.style.filter = "alpha(opacity=0)";
    this.DragLayer.style.mozOpacity = "0";
    this.DragLayer.style.zIndex = "20";
    this.DragLayer.onmouseover="AGGlobalsArray[\'"+this.strParentId+"\'].m_bMouseOverMap=true;"
    
    this.MapContentDiv.appendChild(this.DragLayer);
    
    this.UserLayer=document.createElement('div');
    this.UserLayer.setAttribute('id', this.USER_LAYER_DIV_ID);
    this.UserLayer.style.position = "absolute";
    this.UserLayer.style.left = "0px";
    this.UserLayer.style.top = "0px";
    this.UserLayer.style.width = "100%";
    this.UserLayer.style.height = "100%";
    this.UserLayer.style.cursor = "auto";
    this.UserLayer.style.backgroundColor = "Black";
    this.UserLayer.style.opacity = "0";
    this.UserLayer.style.filter = "alpha(opacity=0)";
    this.UserLayer.style.mozOpacity = "0";
    this.UserLayer.style.zIndex = "100";
    this.UserLayer.style.visibility = "hidden";
    this.UserLayer.onmousedown = function(ev)
    {
        var lastIndex = this.id.lastIndexOf("_");
        if(lastIndex<0)
            return;

        var parentId = this.id.substring(0,lastIndex);
        
        var pt = GetMouseOffset_bd(AGGlobalsArray[parentId].m_objMapCanvas.MapContentDiv,ev);
        AGGlobalsArray[parentId].m_UserClickedPoints.push({X:pt.x, Y:pt.y});
        
        pt = AGGlobalsArray[parentId].GetVisibleLatLongFromPixel(pt)
        AGGlobalsArray[parentId].m_UserClickedLatLongs.push({Longitude:pt.x, Latitude:pt.y});
        
        if(AGGlobalsArray[parentId].m_UserClickOption == AGGlobalsArray[parentId].SINGLE_POINT)
        {
            try
            {
                AGGlobalsArray[parentId].m_objMapCanvas.UserLayer.style.visibility = "hidden";
                if(AGGlobalsArray[parentId].m_UserCallBackFunction != null)
                    eval(AGGlobalsArray[parentId].m_UserCallBackFunction + "();");
            }
            catch(err)
            {
                //alert("error");
            }
        }
    }
    
    this.MapContentDiv.appendChild(this.UserLayer);
   
    this.CrossHair = document.createElement('div');
    this.CrossHair.setAttribute('id', this.CROSS_HAIR_DIV_ID);
    this.CrossHair.style.position = "absolute";
    this.CrossHair.style.left = "600px";
    this.CrossHair.style.top = "350px";
    this.CrossHair.style.zIndex = "10";
    this.CrossHair.innerHTML = "<img id='" + this.CROSS_HAIR_DIV_ID + "' src='"+AGGlobalsArray[this.strParentId].m_hostURL+"Images/crossHair.gif' alt='' galleryimg='no' />";
    this.MapContentDiv.appendChild(this.CrossHair);
   
    var ZOOMBAR_CONTAINER_WIDTH = 30;
    var ZOOMOUTBUTTON_HEIGHT = 30;
    var ZOOMSLIDEBAR_HEIGHT = 120;
    var ZOOMINBUTTON_HEIGHT = 30;
    var ZOOMINBUTTON_WIDTH = 30;
    var ZOOMOUTBUTTON_WIDTH = 30;
    
    if(zoombar_no=="2" || zoombar_no=="3" || zoombar_no=="4" || zoombar_no=="5")
    {
        ZOOMOUTBUTTON_HEIGHT = 20;
        ZOOMINBUTTON_HEIGHT = 20;
        ZOOMSLIDEBAR_HEIGHT = 114;
        ZOOMINBUTTON_WIDTH = 20;
        ZOOMOUTBUTTON_WIDTH = 20;
    }
    if(zoombar_no=="4" || zoombar_no=="5")
    {
        ZOOMBAR_CONTAINER_WIDTH = 20;
    }
    if(zoombar_no=="5")
    {
       ZOOMSLIDEBAR_HEIGHT = 120;
    }
    this.ZoomBarContainer = document.createElement('div');
    this.ZoomBarContainer.setAttribute('id', this.ZOOMBAR_CONTAINER_DIV_ID);
    this.ZoomBarContainer.style.position = "absolute";
    this.ZoomBarContainer.style.left = "10px";  // keep a bit right from mapcontent
    this.ZoomBarContainer.style.top = "10px";   // keep a bit down from mapcontent
    this.ZoomBarContainer.style.width = ZOOMBAR_CONTAINER_WIDTH + "px";
    this.ZoomBarContainer.style.zIndex = "70";
    this.ZoomBarContainer.style.textAlign = "left";
    this.ZoomBarContainer.style.cursor = "pointer";
    this.ZoomBarContainer.ZoomBarNo = zoombar_no;
    this.ZoomBarContainer.ParentId = this.strParentId;
    this.MapContentDiv.appendChild(this.ZoomBarContainer);
    // zoom out button
    var imgSrc = AGGlobalsArray[this.strParentId].m_hostURL + "zoombar/"+"zb"+zoombar_no+"/ZoomOut.png";

    this.ZoomOutButton = document.createElement('img');
    this.ZoomOutButton.setAttribute('id', this.ZOOMOUTBUTTON_ID);
    this.ZoomOutButton.setAttribute('src', imgSrc);
    this.ZoomOutButton.style.position = "absolute";
    this.ZoomOutButton.style.left = "0px";
    if(zoombar_no =="4")
        this.ZoomOutButton.style.top = ZOOMOUTBUTTON_HEIGHT + ZOOMSLIDEBAR_HEIGHT + "px";
    else    
        this.ZoomOutButton.style.top = "0px";
    this.ZoomOutButton.style.width = "100%";
    this.ZoomOutButton.style.zIndex = "5";
    this.ZoomOutButton.style.height = ZOOMOUTBUTTON_HEIGHT + "px";
    this.ZoomOutButton.style.width = ZOOMOUTBUTTON_WIDTH + "px";
    this.ZoomOutButton.ZoomBarNo = zoombar_no;
    this.ZoomOutButton.ParentId = this.strParentId;
    this.ZoomBarContainer.appendChild(this.ZoomOutButton);
    this.ZoomOutButton.onclick = function(ev)
    {
        ZoomOutButtonClick(this.ParentId, this.ZoomBarNo)
    }
    
    // zoom slide bar button
    if(zoombar_no=="2" || zoombar_no=="3" || zoombar_no=="4" )
        imgSrc = AGGlobalsArray[this.strParentId].m_hostURL + "zoombar/"+"zb"+zoombar_no+"/scale_13.png";
    else if(zoombar_no=="5")
        imgSrc = AGGlobalsArray[this.strParentId].m_hostURL + "zoombar/zb5/sliderBack.png";    
    else
        imgSrc = AGGlobalsArray[this.strParentId].m_hostURL + "zoombar/zb1/sliderBack.png";
    this.ZoomSlideBar = document.createElement('img');
    this.ZoomSlideBar.setAttribute('id', this.SLIDERBAR_ID);
    this.ZoomSlideBar.setAttribute('src', imgSrc);
    this.ZoomSlideBar.style.position = "absolute";
    this.ZoomSlideBar.style.left = "0px";
    this.ZoomSlideBar.style.top = ZOOMOUTBUTTON_HEIGHT + "px";
    this.ZoomSlideBar.style.width = "100%";
    this.ZoomSlideBar.style.height = ZOOMSLIDEBAR_HEIGHT + "px";
    this.ZoomSlideBar.style.zIndex = "5";
    this.ZoomSlideBar.ZoomBarNo = zoombar_no;
    this.ZoomSlideBar.ParentId = this.strParentId;
    this.ZoomBarContainer.appendChild(this.ZoomSlideBar);
    this.ZoomSlideBar.onclick = function(ev)
    {   
        ClickSlider(ev, this.ParentId);
    }
    
    // zoom in button
     imgSrc = AGGlobalsArray[this.strParentId].m_hostURL + "zoombar/"+"zb"+zoombar_no+"/ZoomIn.png";
    
    this.ZoomInButton = document.createElement('img');
    this.ZoomInButton.setAttribute('id', this.ZOOMINBUTTON_ID);
    this.ZoomInButton.setAttribute('src', imgSrc);
    this.ZoomInButton.style.position = "absolute";
    this.ZoomInButton.style.left = "0px";
    if(zoombar_no=="4")
        this.ZoomInButton.style.top = "0px";
    else
        this.ZoomInButton.style.top = ZOOMOUTBUTTON_HEIGHT + ZOOMSLIDEBAR_HEIGHT + "px";
    this.ZoomInButton.style.width = "100%";
    this.ZoomInButton.style.height = ZOOMINBUTTON_HEIGHT + "px";
    this.ZoomInButton.style.width = ZOOMINBUTTON_WIDTH + "px";
    this.ZoomInButton.style.zIndex = "5";
    this.ZoomInButton.ZoomBarNo = zoombar_no;
    this.ZoomInButton.ParentId = this.strParentId;
    this.ZoomBarContainer.appendChild(this.ZoomInButton);
    this.ZoomInButton.onclick = function(ev)
    {
        ZoomInButtonClick(this.ParentId, this.ZoomBarNo)
    }
    
    // zoom Slide Controller button
    if(!(zoombar_no=="2" || zoombar_no=="3" || zoombar_no=="4"))
    {
        if(zoombar_no=="5")
            imgSrc = AGGlobalsArray[this.strParentId].m_hostURL + "zoombar/zb5/arrow_blue.png";
        else
            imgSrc = AGGlobalsArray[this.strParentId].m_hostURL + "zoombar/zb1/arrow_blue.png";
            
        this.ZoomSlideController = document.createElement('img');
        this.ZoomSlideController.setAttribute('id', this.SLIDECONTROL_ID);
        this.ZoomSlideController.setAttribute('src', imgSrc);
        this.ZoomSlideController.setAttribute('alt', "");
        this.ZoomSlideController.style.position = "absolute";
        this.ZoomSlideController.style.left = "50%";
        this.ZoomSlideController.style.top = ZOOMOUTBUTTON_HEIGHT + "px";
        this.ZoomSlideController.style.zIndex = "10";
        this.ZoomSlideController.ZoomBarNo = zoombar_no;
        this.ZoomSlideController.ParentId = this.strParentId;
        this.ZoomBarContainer.appendChild(this.ZoomSlideController);
    }
    // zoom related properties
    AGGlobalsArray[this.strParentId].m_iSegmentHeight = ZOOMSLIDEBAR_HEIGHT /(AGGlobalsArray[this.strParentId].m_iSegments-1) ;
    
    // loading image
    this.aniImage=document.createElement('div');
    this.aniImage.setAttribute('id', this.ANI_IMAGE_DIV_ID);
    this.aniImage.style.position = "absolute";
    this.aniImage.style.visibility = "hidden";    
    this.aniImage.style.zIndex = "90";
    this.aniImage.innerHTML = "<img src='"+AGGlobalsArray[this.strParentId].m_hostURL+"Images/"+ANI_IMAGE_NAME+"' alt='Please wait while loading...' />";
    this.MapContentDiv.appendChild(this.aniImage);
    this.MapPanelDiv.appendChild(this.MapContentDiv);
    
    // copyright
    this.CopyrightDiv = document.createElement('div');
    this.CopyrightDiv.setAttribute('id', this.COPYRIGHT_DIV_ID);
    this.CopyrightDiv.style.position = "absolute";
    this.CopyrightDiv.style.right="0px";
    this.CopyrightDiv.style.bottom = "0px";
    this.CopyrightDiv.style.marginBottom = "5px";
    this.CopyrightDiv.style.marginRight = "5px";
    this.CopyrightDiv.style.zIndex = "0";
    this.CopyrightDiv.style.fontFamily = "Arial";
    this.CopyrightDiv.style.fontSize = "8pt";
    this.CopyrightDiv.style.fontStyle = "normal";   // italic
    this.CopyrightDiv.style.fontWeight = "normal";  // bold
    this.CopyrightDiv.style.textAlign = "right";
    this.CopyrightDiv.innerHTML= AGGlobalsArray[this.strParentId].m_strCopyrightHTML;
    this.MapPanelDiv.appendChild(this.CopyrightDiv);
    
    // scale
    this.ScaleDiv = document.createElement('div');
    this.ScaleDiv.setAttribute('id', this.SCALE_DIV_ID);
    this.ScaleDiv.style.position = "absolute";
    this.ScaleDiv.style.left="0px";
    this.ScaleDiv.style.bottom = "0px";
    this.ScaleDiv.style.marginBottom = "5px";
    this.ScaleDiv.style.marginLeft = "5px";
    this.ScaleDiv.style.zIndex = "0";
    this.ScaleDiv.style.fontFamily = "Arial";
    this.ScaleDiv.style.fontSize = "8pt";
    this.ScaleDiv.style.fontStyle = "normal";   // italic
    this.ScaleDiv.style.fontWeight = "normal";  // bold
    this.ScaleDiv.style.textAlign = "left";
    this.ScaleDiv.innerHTML= "";
    this.MapPanelDiv.appendChild(this.ScaleDiv);
    
    this.MyMapDivId.appendChild(this.MapPanelDiv);
    
    // set max width of copyright and scale div
    //this.CopyrightDiv = document.getElementById(this.COPYRIGHT_DIV_ID);
    //this.ScaleDiv = document.getElementById(this.SCALE_DIV_ID);
    
    //alert(this.MapPanelDiv.offsetWidth);
    
    var totalWidth = this.MapPanelDiv.offsetWidth - parseInt(this.CopyrightDiv.style.marginRight, 10) - parseInt(this.ScaleDiv.style.marginLeft, 10);
    this.CopyrightDiv.style.width = (Math.floor( totalWidth * 7/11 ) - 2) + "px"; // - 2 for some space between two text
    this.ScaleDiv.style.width = (Math.floor(totalWidth * 4/11) - 2) + "px";
    
    if(AGGlobalsArray[this.strParentId].m_bShowAdvertising == null || AGGlobalsArray[this.strParentId].m_bShowAdvertising == true)
    {
        this.AdvertisingDiv = document.createElement('div');
        this.AdvertisingDiv.setAttribute('id', this.ADVERTISING_DIV_ID);
        
        this.AdvertisingDiv.style.position = "absolute";
        this.AdvertisingDiv.style.left = "0px";
        this.AdvertisingDiv.style.bottom = "0px";
        //this.AdvertisingDiv.style.top = "0px";//this.MapContentDiv.style.height;
        //this.AdvertisingDiv.style.top = "0px";
            
        //this.AdvertisingDiv.style.left = "0px";
        //this.AdvertisingDiv.style.top = "0px"; //this.MapContentDiv.style.height;
        //this.AdvertisingDiv.style.top = "0px";
        this.AdvertisingDiv.style.visibility = "hidden";
        
        this.AdvertisingDiv.style.zIndex = "100";
        this.AdvertisingDiv.style.cursor = "pointer";
        
        this.AdvertisingDiv.style.backgroundColor = "White";
        
        this.AdvertisingDiv.link = "";
        this.AdvertisingDiv.onclick = function(ev)
        {
            window.open(this.link);
        }
        
        this.AdvertiseImage = document.createElement('img');
        this.AdvertiseImage.setAttribute('src', API_HOST_URL + "Images/white.JPG");
        this.AdvertiseImage.setAttribute('alt', "");
        this.AdvertiseImage.style.visibility = "hidden";
        this.AdvertiseImage.style.position = "absolute";
        this.AdvertiseImage.style.left = "0px";
        this.AdvertiseImage.style.top = "0px";
        this.AdvertisingDiv.appendChild(this.AdvertiseImage);
        
        this.MapPanelDiv.appendChild(this.AdvertisingDiv);
    }
    
    
    
    
}
//////////////////// End of MapCanvas Class  ////////////////////

///////////////////////////////////////////////////////////////
////////////////////  RequestManager Class  ///////////////////
///////////////////////////////////////////////////////////////
function RequestManager( _mapServerUrl, _version, _crs, _mapInfoObject, _JSFunc, _localDomain, _userId, _parentDivId)
{
    this.BBOX_TAG = "&BBOX"
    this.CRS_TAG = "&CRS"
    this.EXCEPTIONS_TAG = "&EXCEPTIONS"
    this.FORMAT_TAG = "&FORMAT"
    this.HEIGHT_TAG = "&HEIGHT"
    this.LAYERS_TAG = "&LAYERS"
    this.REQUEST_TAG = "REQUEST"
    this.STYLES_TAG = "&STYLES"
    this.TILECOLUMN_TAG = "&TILECOLUMN"
    this.TILEROW_TAG = "&TILEROW"
    this.TOKEN_TAG = "&TOKEN"
    this.VERSION_TAG = "&VERSION"
    this.WIDTH_TAG = "&WIDTH"
    this.ROUTING_TAG = "&ROUTING"
    this.SERVICE_TAG = "&Service"

    this.FORMAT_TAG = "&FORMAT";
    this.VERSION_TAG = "&VERSION" ;
    this.CRS_TAG = "&CRS" ;
    this.EXCEPTION_TAG = "&EXCEPTION";
    this.TRANSPERANCY_TAG = "&TRANSPERANCY";
    
    this.JSFUNC_TAG = "&JSFunc";
    this.LOCAL_DOMAIN_TAG = "&localDomain";
    this.UID_TAG = "&UID";
    this.PARENT_DIV_ID_TAG = "&Parent";
    


    this.mapServerUrl = _mapServerUrl;
    this.version = _version;
    this.crs = _crs;
    this.mapInfoObject = _mapInfoObject;
    this.RoutableLatLong = "";
    this.m_routingPointCount = 0;
    
    this.m_strJSFunction = _JSFunc;
    this.m_strLocalDomain = UrlEncoderDecoder.encode(_localDomain);
    this.m_strUserId = _userId;
    this.m_strParentDivId = _parentDivId;
    
    
    this.m_RoutingParam = "";    
    this.m_routingPointArray = new Array();
    
    this.startingPointExists = false;
    this.endingPointExists = false;
    this.routingRequested = false;
    
    this.GetGetCapabilitiesAGRequest = function()
    {
        var req = this.mapServerUrl;
        req += "?";
        req += this.REQUEST_TAG + "=GetCapabilitiesAG";
        req += this.SERVICE_TAG += "=wms";
        
        
        req += this.JSFUNC_TAG + "=" + this.m_strJSFunction;
        req += this.LOCAL_DOMAIN_TAG + "=" + this.m_strLocalDomain;
        req += this.UID_TAG + "=" + this.m_strUserId;
        req += this.PARENT_DIV_ID_TAG + "=" + this.m_strParentDivId;

        return req;
    }
    
//    this.GetGetMapInfoAGRequest = function()
//    {
//        var req = this.mapServerUrl;
//        req += "?";
//        req += this.REQUEST_TAG + "=GetMapInfoAG";
//        req += this.VERSION_TAG + "=" + this.version;
//        req += this.CRS_TAG + "=" + this.crs;
//        req += this.BBOX_TAG + "=" + this.mapInfoObject.bBox;
//        req += this.WIDTH_TAG + "=" + this.mapInfoObject.width;
//        req += this.HEIGHT_TAG + "=" + this.mapInfoObject.height;
//        req += this.FORMAT_TAG + "=" + this.mapInfoObject.format;
//        req += this.LAYERS_TAG + "=" + this.mapInfoObject.layers;
//        req += this.STYLES_TAG + "=" + this.mapInfoObject.styles;
//        req += this.EXCEPTIONS_TAG + "=" + this.mapInfoObject.exceptions;
//        
//        req += this.JSFUNC_TAG + "=" + this.m_strJSFunction;
//        req += this.LOCAL_DOMAIN_TAG + "=" + this.m_strLocalDomain;
//        req += this.UID_TAG + "=" + this.m_strUserId;
//        req += this.PARENT_DIV_ID_TAG + "=" + this.m_strParentDivId;

//        return req;
//    }
    
    this.GetGetTiledMapInfoAGRequest = function (totalNoOfTileRows, totalNoOfTileColumns, currentTileRowNo, currentTileColumnNo)
    {
        var req = this.mapServerUrl;
        req += "?";
        req += this.REQUEST_TAG + "=GetTiledMapInfoAG";
        req += this.VERSION_TAG + "=" + this.version;
        req += this.CRS_TAG + "=" + this.crs;
        req += this.BBOX_TAG + "=TILE:TOTALEXTENT:" + this.mapInfoObject.bBox + ",";
        req += "TOTALTILES:" + totalNoOfTileRows + "," + totalNoOfTileColumns+",";
        req += "CURRENTTILE:" + currentTileRowNo + "," + currentTileColumnNo;
        req += this.WIDTH_TAG + "=" + this.mapInfoObject.width;
        req += this.HEIGHT_TAG + "=" + this.mapInfoObject.height;
        req += this.FORMAT_TAG + "=" + this.mapInfoObject.format;
        req += this.LAYERS_TAG + "=" + this.mapInfoObject.layers;
        req += this.STYLES_TAG + "=" + this.mapInfoObject.styles;
        req += this.EXCEPTIONS_TAG + "=" + this.mapInfoObject.exceptions;
        req += this.TRANSPERANCY_TAG + "=" + this.mapInfoObject.transperency;
        
        if(this.routingRequested)
            req += this.m_RoutingParam;
        
        req += this.JSFUNC_TAG + "=" + this.m_strJSFunction;
        req += this.LOCAL_DOMAIN_TAG + "=" + this.m_strLocalDomain;
        req += this.UID_TAG + "=" + this.m_strUserId;
        req += this.PARENT_DIV_ID_TAG + "=" + this.m_strParentDivId;
        
        return req;
    }
    
    this.GetGetTiledMapAGRequest = function (tileRowNo, tileColumnNo)
    {
        var req = this.mapServerUrl;
        req += "?";
        req += this.REQUEST_TAG + "=GetTiledMapAG";
        req += this.VERSION_TAG + "=" + this.version;
        req += this.TOKEN_TAG +"=" + this.mapInfoObject.token;
        req += this.TILEROW_TAG + "=" + tileRowNo;
        req += this.TILECOLUMN_TAG + "=" + tileColumnNo;
        req += this.FORMAT_TAG + "=" + this.mapInfoObject.format;
        req += this.UID_TAG + "=" + this.m_strUserId;

        return req;
    }
    
//    this.GetZoomAtLocationRequest = function (longitude, latitude, zoomScale)
//    {
//        var req = this.mapServerUrl;
//        req += "?";
//        req += this.REQUEST_TAG + "=GetMapInfoAG";
//        req += this.VERSION_TAG + "=" + this.version;
//        req += this.CRS_TAG + "=" + this.crs;
//        req += this.BBOX_TAG + "=CENTRE:";
//        req += longitude + ",";
//        req += latitude + ",";
//        req += zoomScale;
//        req += this.WIDTH_TAG + "=" + this.mapInfoObject.width;
//        req += this.HEIGHT_TAG + "=" + this.mapInfoObject.height;
//        req += this.FORMAT_TAG + "=" + this.mapInfoObject.format;
//        req += this.LAYERS_TAG + "=" + this.mapInfoObject.layers;
//        req += this.STYLES_TAG + "=" + this.mapInfoObject.styles;
//        req += this.EXCEPTIONS_TAG + "=" + this.mapInfoObject.exceptions;
//        
//        req += this.JSFUNC_TAG + "=" + this.m_strJSFunction;
//        req += this.LOCAL_DOMAIN_TAG + "=" + this.m_strLocalDomain;
//        req += this.UID_TAG + "=" + this.m_strUserId;
//        req += this.PARENT_DIV_ID_TAG + "=" + this.m_strParentDivId;
//      
//        return req;
//    }
    
    this.GetPanRequest = function (shiftX, shiftY)
    {
        var req = this.mapServerUrl;
        req += "?";
        req += this.REQUEST_TAG + "=GetMapInfoAG";
        req += this.VERSION_TAG + "=" + this.version;
        req += this.CRS_TAG + "=" + this.crs;
        req += this.BBOX_TAG + "=OPERATION:PAN,"
        req += "RASTERCONTEXT:" + this.mapInfoObject.width + "," + this.mapInfoObject.height+",";
        req += this.mapInfoObject.bBox + ",";
        req += "SHIFT:" + shiftX + "," + shiftY;
        req += this.WIDTH_TAG + "=" + this.mapInfoObject.width;
        req += this.HEIGHT_TAG + "=" + this.mapInfoObject.height;
        req += this.FORMAT_TAG + "=" + this.mapInfoObject.format;
        req += this.LAYERS_TAG + "=" + this.mapInfoObject.layers;
        req += this.STYLES_TAG + "=" + this.mapInfoObject.styles;
        req += this.EXCEPTIONS_TAG + "=" + this.mapInfoObject.exceptions;
        req += this.TRANSPERANCY_TAG + "=100";
        
        req += this.JSFUNC_TAG + "=" + this.m_strJSFunction;
        req += this.LOCAL_DOMAIN_TAG + "=" + this.m_strLocalDomain;
        req += this.UID_TAG + "=" + this.m_strUserId;
        req += this.PARENT_DIV_ID_TAG + "=" + this.m_strParentDivId;

        return req;    
    }
    
    this.CreateRoutingParam = function(arrLatLong)
    {
        if(arrLatLong.length < 2)
            return false;
            
        var strRoutingParam = this.ROUTING_TAG + "=" + this.mapInfoObject.routableLayer + "$" + this.mapInfoObject.routableParameter + "$";    
        for (var i = 0; i<arrLatLong.length; i ++)
        {
            if(typeof arrLatLong[i].Longitude == "undefined" || typeof arrLatLong[i].Latitude == "undefined")
                return false;
            strRoutingParam += "LATLONG," + arrLatLong[i].Longitude + "," + arrLatLong[i].Latitude + "^";
        }
        this.m_RoutingParam = strRoutingParam.substring(0,strRoutingParam.length-1);
        this.routingRequested = true;
        return true;
    }
    
    this.ClearRoutingParam = function()
    {
        var retVal = this.routingRequested;
        this.routingRequested = false;
        this.m_RoutingParam = "";
        return retVal;
    }
    
    this.GetMapSize = function ()
    {
        return this.mapInfoObject.GetSize();
    }
    
    this.SetMapSize =  function (_size)
    {
        this.mapInfoObject.SetSize(_size);
    }
    
    this.GetMapBoundingBox = function ()
    {
        return this.mapInfoObject.GetBoundingBox();
    }
    
    this.SetMapBoundingBox = function (_bBox)
    {
        this.mapInfoObject.SetBoundingBox(_bBox);
    }
    
    this.SetMapToken = function (_token)
    {
        this.mapInfoObject.SetToken(_token);
    }
}  
    
///////////////// end of RequestManager Class  ///////////////
/*****************************************************************************************************************************
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ MainMap Class @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
*****************************************************************************************************************************/
function MainMap(_ImageName,_req)
{
    var lastIndex = _ImageName.lastIndexOf("_");
    if(lastIndex<0)
        return;

    this.strParentId = _ImageName.substring(0,lastIndex); 
    this.RequestManager = _req;    
    this.MainMapName = _ImageName;
    this.m_iLoadedImgIndex=0;
    var i=0;
    
    // tiles
    this.freeTileList = new TileList();
    this.usedTileList = new TileList();
    for(i=0;i<AGGlobalsArray[this.strParentId].m_iMaxNoOfTile;i++)
        this.freeTileList.Add(i);
        
    // satellite tiles
    this.freeSatTileList = new TileList();
    this.usedSatTileList = new TileList();
    for(i=0;i<AGGlobalsArray[this.strParentId].m_iMaxNoOfSatTile;i++)
        this.freeSatTileList.Add(i);
    
    var imagePositionX=new Array(AGGlobalsArray[this.strParentId].m_iMaxNoOfTile);
    var imagePositionY=new Array(AGGlobalsArray[this.strParentId].m_iMaxNoOfTile);
    
    for(i=0;i<AGGlobalsArray[this.strParentId].m_iMaxNoOfTile;i++)
    {
        imagePositionX[i]=new Array(AGGlobalsArray[this.strParentId].m_iTileCol-1);
        imagePositionY[i]=new Array(AGGlobalsArray[this.strParentId].m_iTileCol-1);
    }
    
    this.GetTileMap=function(requestString)
    {  
       AGGlobalsArray[this.strParentId].GetUsingIFrame(requestString);
    }
    
    this.GetTileMapForZoomReq = function(midLong, midLat, zoomScale)
    {
        var cm = new CoordMapper();
        var bbox = cm.CalculateBBoxForZoomRequest(midLat, midLong, zoomScale, this.RequestManager.mapInfoObject.width, this.RequestManager.mapInfoObject.height);
        AGGlobalsArray[this.strParentId].CallBackGetBBox(bbox);
    }
    
    this.GetTileMapForPanReq = function(shiftX, shiftY)
    {
        var cm = new CoordMapper();
        var bbox = cm.CalculateBBoxForPanRequest(this.RequestManager.mapInfoObject.bBox, this.RequestManager.mapInfoObject.width, this.RequestManager.mapInfoObject.height, shiftX, shiftY);
        AGGlobalsArray[this.strParentId].CallBackGetBBox(bbox);
    }
    
    this.ZoomToBoundingBox = function(bboxString)
    {
        var mapWidth = parseInt(this.RequestManager.GetMapSize().GetWidth(),10);
        var mapHeight = parseInt(this.RequestManager.GetMapSize().GetHeight(),10);
        var cm = new CoordMapper(bboxString, mapWidth, mapHeight);
        var zoomScale = Math.round(cm.GetScale());
        zoomScale = AGGlobalsArray[this.strParentId].GetNearestZoomScale(zoomScale);
        var midPoint = AGGlobalsArray[this.strParentId].GetCenterOfBBox(bboxString);
        this.ZoomToLocation(midPoint.longitude, midPoint.latitude, zoomScale);
    }
    
    this.ZoomWithBBox = function(latitude,longitude,scale)
    {
        if(scale>=AGGlobalsArray[this.strParentId].m_arrZoomScale.length)
          scale=AGGlobalsArray[this.strParentId].m_arrZoomScale.length-1;
        
        if(scale<0)
          scale=0;
        
        zoomScale = AGGlobalsArray[this.strParentId].m_arrZoomScale[scale];
        AGGlobalsArray[this.strParentId].m_iCurZoomLevel = scale;
        this.ZoomToLocation(longitude, latitude, zoomScale);
    }
    
    this.ZoomToLocation = function(longitude,latitude, scale)
    {  
        var index=0;
        //AGGlobalsArray[this.strParentId].m_bResetOVBBox = true;
       
        for(i=0;i<AGGlobalsArray[this.strParentId].m_arrZoomScale.length;i++)
        {
            if(AGGlobalsArray[this.strParentId].m_arrZoomScale[i]==scale)
            {
                index=i;
                break;
            }
        }
        
        if(AGGlobalsArray[this.strParentId].m_bExecuteUserFunctions && AGGlobalsArray[this.strParentId].m_iPreviousScale != AGGlobalsArray[this.strParentId].m_arrZoomScale[index])
            AGGlobalsArray[this.strParentId].m_bZoomEventOccured = true;
     
        AGGlobalsArray[this.strParentId].m_iPreviousScale = AGGlobalsArray[this.strParentId].m_arrZoomScale[index];
        AGGlobalsArray[this.strParentId].m_iCurZoomLevel = index;

        MoveZoomSlideDown(AGGlobalsArray[this.strParentId].m_iCurZoomLevel, this.strParentId);
        SqueezeOrExpandMapNew(longitude,latitude,scale,this.strParentId);
        this.GetTileMapForZoomReq(longitude,latitude,scale);
    }    
    
    function SqueezeOrExpandMapNew(longitude,latitude,scale, parentId)
    {   
        var i,j;
        
        AGGlobalsArray[parentId].m_bZoom=true;
        var bIEDivExist = BrowserDetect.browser=="Explorer" && BrowserDetect.version < 7 && BrowserDetect.version >= 5.5;
        
        var g_doubleClickPoint = GetDoubleClickPoint(longitude,latitude, parentId);
        var strBBox = AGGlobalsArray[parentId].m_objMainMap.RequestManager.GetMapBoundingBox();
        var mapSize = AGGlobalsArray[parentId].m_objMainMap.RequestManager.GetMapSize();        
        
        var cm = new CoordMapper(strBBox, mapSize.width, mapSize.height);
        var pt = cm.GetWidthHeightByScale(scale);
        
        //SatPt.x = width of expanded image when normal width=1px
        var satPt = new Point(pt.x, pt.y);
        satPt.x = satPt.x / mapSize.width;
        satPt.y = satPt.y / mapSize.height;
        
        var newTileWidth  = Math.round(pt.x / AGGlobalsArray[parentId].m_iTileCol);
        var newTileHeight = Math.round(pt.y / AGGlobalsArray[parentId].m_iTileRow);
        
        var tx = g_doubleClickPoint.x - Math.abs(AGGlobalsArray[parentId].m_ptImgBasePointShift.x) - parseInt(AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.left,10);
        var ty = g_doubleClickPoint.y - Math.abs(AGGlobalsArray[parentId].m_ptImgBasePointShift.y) - parseInt(AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.top,10);
        
        AGGlobalsArray[parentId].m_ptImgBasePointShift.x = Math.round(-AGGlobalsArray[parentId].m_iTileWidth/2);
        AGGlobalsArray[parentId].m_ptImgBasePointShift.y = Math.round(-AGGlobalsArray[parentId].m_iTileHeight/2);
        
        AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.left = AGGlobalsArray[parentId].m_ptImgBasePointShift.x + "px";
        AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.top = AGGlobalsArray[parentId].m_ptImgBasePointShift.y + "px";
        
        var centerPoint = AGGlobalsArray[parentId].GetCenterPointPixel();
        
        // expand or squeeze mapserver image
        for(i=0; i<AGGlobalsArray[parentId].m_objMainMap.usedTileList.length; i++)
        {
            var ind = AGGlobalsArray[parentId].m_objMainMap.usedTileList.items[i];
            var imgElem = document.getElementById(AGGlobalsArray[parentId].m_objMapCanvas.TILE_IMAGE_ID+ind);
            var l1 = tx - parseInt(imgElem.style.left,10);
            var t1 = ty - parseInt(imgElem.style.top,10);
            
            var l2 = Math.round(newTileWidth * l1 / AGGlobalsArray[parentId].m_iTileWidth);
            var t2 = Math.round(newTileHeight * t1 / AGGlobalsArray[parentId].m_iTileHeight);
            
            var newLeft = centerPoint.x - l2;
            var newTop = centerPoint.y - t2;
            
            imgElem.posLeft = newLeft;
            imgElem.posTop = newTop;
            
            imgElem.style.left = newLeft + "px";
            imgElem.style.top = newTop + "px";
            imgElem.style.width = newTileWidth+"px";
            imgElem.style.height = newTileHeight+"px";
            imgElem.style.zIndex = AGGlobalsArray[parentId].m_iDownZIndex;
            
            if(bIEDivExist)
            {
                // for IE, to show transparent png image
                var divElem = document.getElementById(AGGlobalsArray[parentId].m_objMapCanvas.TILE_IMAGE_DIV_ID + ind);
                divElem.style.left = imgElem.style.left;
                divElem.style.top = imgElem.style.top;
                divElem.style.width = imgElem.style.width;
                divElem.style.height = imgElem.style.height;
                divElem.style.zIndex = imgElem.style.zIndex;
            }
        }
        
        // expand or squeeze imagery
        for(i=0; i<AGGlobalsArray[parentId].m_objMainMap.usedSatTileList.length; i++)
        {
            var ind = AGGlobalsArray[parentId].m_objMainMap.usedSatTileList.items[i];
            var imgElem = document.getElementById(AGGlobalsArray[parentId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID+ind);
            
            var oldTileWidth = parseInt(imgElem.style.width,10);
            var oldTileHeight = parseInt(imgElem.style.height,10);
            
            var newTileWidth  = Math.round(satPt.x * oldTileWidth );
            var newTileHeight = Math.round(satPt.y * oldTileHeight );
            
            var l1 = tx - parseInt(imgElem.style.left,10);
            var t1 = ty - parseInt(imgElem.style.top,10);
            
            var l2 = Math.round(newTileWidth * l1 / oldTileWidth);
            var t2 = Math.round(newTileHeight * t1 / oldTileHeight);
            
            var newLeft = centerPoint.x - l2;
            var newTop = centerPoint.y - t2;
            
            imgElem.posLeft = newLeft;
            imgElem.posTop = newTop;
            imgElem.style.left = newLeft + "px";
            imgElem.style.top = newTop + "px";
            imgElem.style.width = newTileWidth+"px";
            imgElem.style.height = newTileHeight+"px";
            imgElem.style.zIndex = AGGlobalsArray[parentId].satTileHandler.m_iDownZIndex;
        }
    }
    
    function SqueezeOrExpandMap(longitude,latitude,scale, parentId)
    {   
        var i,j;
        
        AGGlobalsArray[parentId].m_bZoom=true;


        var g_doubleClickPoint = GetDoubleClickPoint(longitude,latitude, parentId);
        
        var strBBox = AGGlobalsArray[parentId].m_objMainMap.RequestManager.GetMapBoundingBox();
        var mapSize = AGGlobalsArray[parentId].m_objMainMap.RequestManager.GetMapSize();        
        
        var cm = new CoordMapper(strBBox, mapSize.width, mapSize.height);
        var pt = cm.GetWidthHeightByScale(scale);
        
        var newTileWidth  = Math.round(pt.x / AGGlobalsArray[parentId].m_iTileCol);
        var newTileHeight = Math.round(pt.y / AGGlobalsArray[parentId].m_iTileRow);
        
        var tx = g_doubleClickPoint.x - Math.abs(AGGlobalsArray[parentId].m_ptImgBasePointShift.x) - parseInt(AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.left,10);
        var ty = g_doubleClickPoint.y - Math.abs(AGGlobalsArray[parentId].m_ptImgBasePointShift.y) - parseInt(AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.top,10);
        
        AGGlobalsArray[parentId].m_ptImgBasePointShift.x = Math.round(-AGGlobalsArray[parentId].m_iTileWidth/2);
        AGGlobalsArray[parentId].m_ptImgBasePointShift.y = Math.round(-AGGlobalsArray[parentId].m_iTileHeight/2);
        
        AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.left = AGGlobalsArray[parentId].m_ptImgBasePointShift.x + "px";
        AGGlobalsArray[parentId].m_objMapCanvas.tileMapDiv.style.top = AGGlobalsArray[parentId].m_ptImgBasePointShift.y + "px";
        
        var centerPoint = AGGlobalsArray[parentId].GetCenterPointPixel();
        for(i=0; i<AGGlobalsArray[parentId].m_objMainMap.usedTileList.length; i++)
        {
            var ind = AGGlobalsArray[parentId].m_objMainMap.usedTileList.items[i];
            var imgElem = document.getElementById(AGGlobalsArray[parentId].m_objMapCanvas.TILE_IMAGE_ID+ind);
            var l1 = tx - parseInt(imgElem.style.left,10);
            var t1 = ty - parseInt(imgElem.style.top,10);
            
            var l2 = Math.round(newTileWidth * l1 / AGGlobalsArray[parentId].m_iTileWidth);
            var t2 = Math.round(newTileHeight * t1 / AGGlobalsArray[parentId].m_iTileHeight);
            
            var newLeft = centerPoint.x - l2;
            var newTop = centerPoint.y - t2;
            
            imgElem.posLeft = newLeft;
            imgElem.posTop = newTop;
            
            imgElem.style.left = newLeft + "px";
            imgElem.style.top = newTop + "px";
            imgElem.style.width = newTileWidth+"px";
            imgElem.style.height = newTileHeight+"px";
            imgElem.style.zIndex = AGGlobalsArray[parentId].m_iDownZIndex;
        }
        
    }
    
    function GetDoubleClickPoint(longitude,latitude, parentId)
    {
        var curBBox = AGGlobalsArray[parentId].m_objMainMap.RequestManager.GetMapBoundingBox();
	    var bboxlatlong = curBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);
        
        var latDiff = parseFloat(lat2 - lat1);
        var longDiff =parseFloat(long2 - long1);
        
        var px = Math.round(AGGlobalsArray[parentId].m_iTileWidth * AGGlobalsArray[parentId].m_iTileCol * (longitude-long1) / longDiff);
        var py = Math.round(AGGlobalsArray[parentId].m_iTileHeight * AGGlobalsArray[parentId].m_iTileRow * (lat2-latitude) / latDiff);
        
        return new Point(px,py);
    }
    
    this.RedrawCurrentArea = function()
    {
        // find current midpoint
        var strVisibleBBox = this.GetVisibleMainMapBoundingBox2();
        var midPoint = AGGlobalsArray[this.strParentId].GetCenterOfBBox(strVisibleBBox);
        
        // find current zoomscale
        var iCurZoomIndex = AGGlobalsArray[this.strParentId].m_iCurZoomLevel;
        if(typeof iCurZoomIndex != "number")
            iCurZoomIndex = 0;
        else if (iCurZoomIndex<0)
            iCurZoomIndex = 0;
        else if(iCurZoomIndex >= AGGlobalsArray[this.strParentId].m_arrZoomScale.length)
            iCurZoomIndex = AGGlobalsArray[this.strParentId].m_arrZoomScale.length - 1;
        
        var currentZoomScale = AGGlobalsArray[this.strParentId].m_arrZoomScale[iCurZoomIndex];
        this.ZoomToLocation(midPoint.longitude, midPoint.latitude, currentZoomScale);
    }
    
    this.Pan = function(shiftX,shiftY)
    {   
        var newShift;
        newShift=this.GetVisualToActualShift(shiftX,shiftY);
        //if(newShift.x != 0 || newShift.y!=0 || AGGlobalsArray[this.strParentId].m_bResetOVBBox==true)
        if(newShift.x != 0 || newShift.y!=0)
        {
            AGGlobalsArray[this.strParentId].m_bFlag = false;
            var requestString = this.RequestManager.GetPanRequest(newShift.x,newShift.y);
            
            if(AGGlobalsArray[this.strParentId].m_bExecuteUserFunctions)
                AGGlobalsArray[this.strParentId].m_bPanEventOccured = true;
                
            this.GetTileMapForPanReq(newShift.x,newShift.y);
        }
    }        
    
    this.Pan2 = function(shiftX,shiftY)
    {   
        AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.left = ( parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.offsetLeft,10) + shiftX) + "px";
        AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.top = ( parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.offsetTop,10) + shiftY) + "px";
        AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.style.left = ( parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.offsetLeft,10) + shiftX) + "px";
        AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.style.top = ( parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.MovingContainer.offsetTop,10) + shiftY) + "px";
        this.Pan(shiftX,shiftY);
    }     
    
    
//    this.GetMapInfo = function()
//    {                       
//        var requestString = this.RequestManager.GetGetMapInfoAGRequest();
//        return requestString;
//    }    
    
    this.GetTiledMapInfoRequest = function ()
    {        
        var requestString = this.RequestManager.GetGetTiledMapInfoAGRequest(AGGlobalsArray[this.strParentId].m_iTileRow,AGGlobalsArray[this.strParentId].m_iTileCol,0,0);
        return requestString;
    }
    
    this.GetCapabilitiesRequest = function ()
    {        
        var requestString = this.RequestManager.GetGetCapabilitiesAGRequest();
        return requestString;
    }
    
    this.GetTileImage = function()
    {  
        if(AGGlobalsArray[this.strParentId].m_bZoom)
        {
            this.GetTileImageForZoom();
            return;
        }
        
    	for (var i= 0; i <AGGlobalsArray[this.strParentId].m_iTileRow; i++)
		{
			for (var j = 0; j <AGGlobalsArray[this.strParentId].m_iTileCol; j++)
			{
				var pt = new Point(j*AGGlobalsArray[this.strParentId].m_iTileWidth, i*AGGlobalsArray[this.strParentId].m_iTileHeight)
				
				if (!this.IsPointInTile(pt))
				{
                    var newTileIndex = this.GetTileIndexForNewTile();
                    requestString = this.RequestManager.GetGetTiledMapAGRequest(i,j);
                    
                    var tileMapDivLeft = parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.left,10);
                    var tileMapDivTop = parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.top,10);
                    
                    var posLeft = Math.floor(j*AGGlobalsArray[this.strParentId].m_iTileWidth - tileMapDivLeft + AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x);
                    var posTop = Math.floor(i*AGGlobalsArray[this.strParentId].m_iTileHeight - tileMapDivTop + AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y);
                    
                    document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).posLeft = posLeft;
                    document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).posTop = posTop;                    
                    document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).zoom = "0";
                    document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).style.width = AGGlobalsArray[this.strParentId].m_iTileWidth + "px";
                    document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).style.height = AGGlobalsArray[this.strParentId].m_iTileHeight + "px";
                    document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).style.zIndex = AGGlobalsArray[this.strParentId].m_iUpZIndex;
                    document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).src = requestString;
				}
			}
		}    
		
    }
    
    this.GetTileImageForZoom = function()
    {
        AGGlobalsArray[this.strParentId].MakeBusyForRequest();
        AGGlobalsArray[this.strParentId].m_bZoom=false;
	    AGGlobalsArray[this.strParentId].m_arrTileIndexInUse = new Array();
	    AGGlobalsArray[this.strParentId].m_iTileToLoad = 0;
        
        var tileInUse = new Array();
        for (var i= 0; i <AGGlobalsArray[this.strParentId].m_iTileRow; i++)
		{
			for (var j = 0; j <AGGlobalsArray[this.strParentId].m_iTileCol; j++)
			{
				var pt = new Point(j*AGGlobalsArray[this.strParentId].m_iTileWidth, i*AGGlobalsArray[this.strParentId].m_iTileHeight)
				
                var newTileIndex = this.GetTileIndexForNewTile();
                
                AGGlobalsArray[this.strParentId].m_arrTileIndexInUse.push(newTileIndex);
			    AGGlobalsArray[this.strParentId].m_iTileToLoad ++;
                
                requestString = this.RequestManager.GetGetTiledMapAGRequest(i,j);
                var tileMapDivLeft = parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.left,10);
                var tileMapDivTop = parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.top,10);
                var posLeft = Math.floor(j*AGGlobalsArray[this.strParentId].m_iTileWidth - tileMapDivLeft + AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x);
                var posTop = Math.floor(i*AGGlobalsArray[this.strParentId].m_iTileHeight - tileMapDivTop + AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y);
                
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).zoom = "1";
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).posLeft = posLeft;
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).posTop = posTop;
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).style.left = "-100000px";
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).style.top = "-100000px";
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).style.width = AGGlobalsArray[this.strParentId].m_iTileWidth + "px";
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).style.height = AGGlobalsArray[this.strParentId].m_iTileHeight + "px";
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).style.zIndex = AGGlobalsArray[this.strParentId].m_iUpZIndex;
                document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+newTileIndex).src = requestString;
			}
		} 
    }
    
    this.SetToken = function(token)
    {
        this.RequestManager.SetMapToken(token);
    }            
    
    this.SetBoundingBox = function(bbox)
    {        
        this.RequestManager.SetMapBoundingBox(bbox);
    }    

    this.GetVisualToActualShift = function(iShiftX, iShiftY)
	{
		var pt = new Point(0,0);

		if (iShiftX >= 0)
		{
			iShiftX += AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x;
			if (iShiftX > 0)
			    pt.x = iShiftX/Math.abs(iShiftX)*(Math.floor(Math.abs(iShiftX)/(AGGlobalsArray[this.strParentId].m_iTileWidth + 1)) + 1)* AGGlobalsArray[this.strParentId].m_iTileWidth;
			AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x = -(pt.x - iShiftX);
		}
		else
		{
			iShiftX += (AGGlobalsArray[this.strParentId].m_iTileWidth + AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x);
			if (iShiftX < 0)
			    pt.x = iShiftX/Math.abs(iShiftX)*(Math.floor(Math.abs(iShiftX)/(AGGlobalsArray[this.strParentId].m_iTileWidth + 1)) + 1)* AGGlobalsArray[this.strParentId].m_iTileWidth;
			AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x = -(AGGlobalsArray[this.strParentId].m_iTileWidth + (pt.x - iShiftX));
		}
		
		if (iShiftY >= 0)
		{
			iShiftY += AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y;
			if (iShiftY > 0)
			    pt.y = iShiftY/Math.abs(iShiftY)*(Math.floor(Math.abs(iShiftY)/(AGGlobalsArray[this.strParentId].m_iTileHeight + 1)) + 1)* AGGlobalsArray[this.strParentId].m_iTileHeight;
			AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y = -(pt.y - iShiftY);
		}
		else
		{
			iShiftY += (AGGlobalsArray[this.strParentId].m_iTileHeight + AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y);
			if (iShiftY < 0)
			    pt.y = iShiftY/Math.abs(iShiftY)*(Math.floor(Math.abs(iShiftY)/(AGGlobalsArray[this.strParentId].m_iTileHeight + 1)) + 1)* AGGlobalsArray[this.strParentId].m_iTileHeight;
			AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y = -(AGGlobalsArray[this.strParentId].m_iTileHeight + (pt.y - iShiftY));
		}
		
		return pt;
	}    
    
	this.IsPointInTile = function(pt)
	{
		for(i=0; i<AGGlobalsArray[this.strParentId].m_objMainMap.usedTileList.length; i++)
		{
		    var ind = AGGlobalsArray[this.strParentId].m_objMainMap.usedTileList.items[i];
            var left = parseInt ( parseInt(document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+ind).posLeft,10) + parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.left,10) );
            var width = AGGlobalsArray[this.strParentId].m_iTileWidth;
            var top = parseInt ( parseInt(document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+ind).posTop,10) + parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.top,10) );
            var height = AGGlobalsArray[this.strParentId].m_iTileHeight;
            
	        if ( (pt.x > left && pt.x < left + width) && (pt.y > top && pt.y < top + height))            
			    return true;
		}
		
		return false;
	}

    this.GetTileIndexForNewTile = function()
	{
	    var newTileIndex = this.freeTileList.PopFirstItem();
	    if(newTileIndex!=null)
	    {
	        // free tile found
	        this.usedTileList.Add(newTileIndex);
	        return newTileIndex;
	    }
	    else
	    {
	        // all tiles are in use
	        newTileIndex = AGGlobalsArray[this.strParentId].GetOuterMostIndex();
	        if(newTileIndex < 0)
	        {
	            for (var i = 0; i < AGGlobalsArray[this.strParentId].m_iMaxNoOfTile; i++)
	            {
	                var w = parseInt(document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+i).style.width,10);
	                var h = parseInt(document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+i).style.height,10);
	                
	                if(w!=AGGlobalsArray[this.strParentId].m_iTileWidth || h!=AGGlobalsArray[this.strParentId].m_iTileHeight)
	                    return i;
	            }
	        }
            return newTileIndex;
	    }
	}
	
	this.GetTileIndexForNewSatTile = function(iLevel, iMinX, iMaxX, iMinY, iMaxY)
	{
	    var newTileIndex = this.freeSatTileList.PopFirstItem();
	    if(newTileIndex!=null)
	    {
	        // free tile found
	        this.usedSatTileList.Add(newTileIndex);
	        return newTileIndex;
	    }
	    else
	    {
	        // all tiles are in use
	        newTileIndex = AGGlobalsArray[this.strParentId].GetOuterMostSatTileIndex(iLevel, iMinX, iMaxX, iMinY, iMaxY);
            return newTileIndex;
	    }
	}
	
//	this.ClearSatImages = function()
//	{
//	    this.freeSatTileList = new TileList();
//        this.usedSatTileList = new TileList();
//        
//	    for(var i=0; i<AGGlobalsArray[this.strParentId].m_iMaxNoOfSatTile; i++)
//	    {
//	        this.freeSatTileList.Add(i);
//	        var img = document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID + i);
//	        img.setAttribute('src', API_HOST_URL+"Images/transparentpixel.gif");
//	        img.style.visibility = "hidden";
//	        img.style.left = "-1000000px";
//	        img.style.top = "-1000000px";
//	        img.level = "-1";
//	        img.xVal = "-1";
//	        img.yVal = "-1";
//	    }
//	}
	
	this.IsTileInViewRegion=function(iTileIndex)
	{
	    var vTop    = 0;
	    var vLeft   = 0;	    
	    var vBottom = parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.MapContentDiv.style.height,10) + vTop;	    
        var vRight  = parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.MapContentDiv.style.width,10) + vLeft;	            
        
        var tLeft = parseInt ( parseInt(document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+iTileIndex).posLeft,10) + parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.left,10) );
        var tTop = parseInt ( parseInt(document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+iTileIndex).posTop,10) + parseInt(AGGlobalsArray[this.strParentId].m_objMapCanvas.tileMapDiv.style.top,10) );
        
        var width = parseInt(document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+iTileIndex).style.width,10);
        var height = parseInt(document.getElementById(AGGlobalsArray[this.strParentId].m_objMapCanvas.TILE_IMAGE_ID+iTileIndex).style.height,10);
        
        var bRet = true;
	    if (((tLeft + width) < vLeft) || (tLeft > vRight) || ((tTop + height) < vTop) || (tTop > vBottom))
	        bRet = false;
		
		return bRet;
	}	
	
	this.GetVisibleMainMapSize = function()
	{
	    return new Size(Math.round(AGGlobalsArray[this.strParentId].m_iTileWidth*(AGGlobalsArray[this.strParentId].m_iTileCol-1)), Math.round(AGGlobalsArray[this.strParentId].m_iTileHeight*(AGGlobalsArray[this.strParentId].m_iTileRow-1)))
	}
	
	this.GetExtendedMainMapSize = function()
	{
	    return this.RequestManager.GetMapSize();
	}

	this.GetVisibleMainMapBoundingBox2 = function()
	{
	    var extendedMainMapSize = this.GetExtendedMainMapSize();
	    var pt = new Point (0,0);
	    pt.x = Math.abs(AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x);
	    pt.y = Math.abs(extendedMainMapSize.GetHeight()-(AGGlobalsArray[this.strParentId].m_iTileHeight + AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y));
	    
	    var latLon1 = AGGlobalsArray[this.strParentId].GetLatLongFromPixel(pt);
	    
	    pt.x = Math.abs(extendedMainMapSize.GetWidth() - (AGGlobalsArray[this.strParentId].m_iTileWidth + AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.x));
	    pt.y = Math.abs(AGGlobalsArray[this.strParentId].m_ptImgBasePointShift.y);
	    
	    var latLon2 = AGGlobalsArray[this.strParentId].GetLatLongFromPixel(pt);

        return ("" + latLon1.x +","+latLon1.y+","+latLon2.x+","+latLon2.y) ;
	}	
}
///////////////// end of MainMap Class  ///////////////

/*****************************************************************************************************************************
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ PopupMenu Class @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
*****************************************************************************************************************************/

function PopupMenu( strParentId, strMapContentId)
{
    this.strParentId = strParentId;
    document.getElementById(strParentId).oncontextmenu = function (ev)
    {
        return false;
    }
    
    this.objOrigin = null;
    this.objDestination = null;
    
    this.POPUP_MENU_DIV_ID = this.strParentId + "_PopupMenu";
    this.POPUP_START_HERE_DIV_ID = this.strParentId + "_StartHere";
    this.POPUP_END_HERE_DIV_ID = this.strParentId + "_EndHere";
    this.POPUP_CLEAR_DIV_ID = this.strParentId + "_Clear";
    
    this.NORMAL_BGCOLOR = "#D2D2B4";
    this.SELECTION_BGCOLOR = "#FFFFFF";
    
    this.StartPointCoordinate = null;
    this.EndPointCoordinate = null;
    
    // add popup menu
    this.PopupMenuDiv = document.createElement('div');
    this.PopupMenuDiv.setAttribute('id', this.POPUP_MENU_DIV_ID);
    this.PopupMenuDiv.style.position = "absolute";
    this.PopupMenuDiv.style.width = "120px";
    // in IE, border is inside boundary. in FF/Opeara/Safari border is outside boundary.
    if(BrowserDetect.browser=="Explorer")
        this.PopupMenuDiv.style.height = "63px";    // extra 3: topBorderWidth=1 + bottomBorderWidth=2
    else
        this.PopupMenuDiv.style.height = "60px";
        
    this.PopupMenuDiv.style.zIndex = "75";
    this.PopupMenuDiv.style.textAlign = "center";
    this.PopupMenuDiv.style.cursor = "default";
    this.PopupMenuDiv.style.backgroundColor = "#000000";
    this.PopupMenuDiv.ParentId = this.strParentId;
    
    this.PopupMenuDiv.style.borderLeft = '1px solid #000000';
    this.PopupMenuDiv.style.borderTop = '1px solid #000000';
    this.PopupMenuDiv.style.borderRight = '2px solid #000000';
    this.PopupMenuDiv.style.borderBottom = '2px solid #000000';
    this.PopupMenuDiv.onmouseout = function(ev)
    {
        AGGlobalsArray[this.ParentId].m_objPopupMenu.ClearPopupMenuSelection();
    }
    
    // insert start here in popup menu
    this.PopupStartHereDiv = document.createElement('div');
    this.PopupStartHereDiv.setAttribute('id', this.POPUP_START_HERE_DIV_ID);
    this.PopupStartHereDiv.style.position = "absolute";
    this.PopupStartHereDiv.style.left = "0px";
    this.PopupStartHereDiv.style.top = "0px";
    this.PopupStartHereDiv.style.width = "100%";
    this.PopupStartHereDiv.style.height = "20px";
    //this.PopupStartHereDiv.style.zIndex = "40";
    this.PopupStartHereDiv.style.backgroundColor =this.NORMAL_BGCOLOR;
    this.PopupStartHereDiv.innerHTML = "Start Here";
    this.PopupStartHereDiv.ParentId = this.strParentId;
    this.PopupStartHereDiv.onmouseover = function(ev)
    {
        AGGlobalsArray[this.ParentId].m_objPopupMenu.SelectStartHereMenu();
    }
    this.PopupStartHereDiv.onclick = function(ev)
    {
        AGGlobalsArray[this.ParentId].m_objPopupMenu.StartMenuClicked();
    }
    this.PopupMenuDiv.appendChild(this.PopupStartHereDiv);
    
    // insert End Here in popup menu
    this.PopupEndHereDiv = document.createElement('div');
    this.PopupEndHereDiv.setAttribute('id', this.POPUP_END_HERE_DIV_ID);
    this.PopupEndHereDiv.style.position = "absolute";
    this.PopupEndHereDiv.style.left = "0px";
    this.PopupEndHereDiv.style.top = "20px";
    this.PopupEndHereDiv.style.width = "100%";
    this.PopupEndHereDiv.style.height = "20px";
    this.PopupEndHereDiv.style.backgroundColor =this.NORMAL_BGCOLOR;
    this.PopupEndHereDiv.innerHTML = "End Here";
    this.PopupEndHereDiv.ParentId = this.strParentId;
    this.PopupEndHereDiv.onmouseover = function(ev)
    {
        AGGlobalsArray[this.ParentId].m_objPopupMenu.SelectEndHereMenu();
    }
    this.PopupEndHereDiv.onclick = function(ev)
    {
        AGGlobalsArray[this.ParentId].m_objPopupMenu.EndMenuClicked();
    }
    this.PopupMenuDiv.appendChild(this.PopupEndHereDiv);
    
    // insert clear in popup menu
    this.PopupClearDiv = document.createElement('div');
    this.PopupClearDiv.setAttribute('id', this.POPUP_CLEAR_DIV_ID);
    this.PopupClearDiv.style.position = "absolute";
    this.PopupClearDiv.style.left = "0px";
    this.PopupClearDiv.style.top = "40px";
    this.PopupClearDiv.style.width = "100%";
    this.PopupClearDiv.style.height = "20px";
    this.PopupClearDiv.style.backgroundColor =this.NORMAL_BGCOLOR;
    this.PopupClearDiv.innerHTML = "Clear";
    this.PopupClearDiv.ParentId = this.strParentId;
    this.PopupClearDiv.onmouseover = function(ev)
    {
        AGGlobalsArray[this.ParentId].m_objPopupMenu.SelectClearMenu();
    }
    
    this.PopupClearDiv.onclick = function(ev)
    {
        AGGlobalsArray[this.ParentId].m_objPopupMenu.ClearMenuClicked();
    }
    this.PopupMenuDiv.appendChild(this.PopupClearDiv);
    
    // insert whole popup inside mapcontent
    this.MapContentDiv = document.getElementById(strMapContentId);
    this.MapContentDiv.appendChild(this.PopupMenuDiv);
    
    this.MapContentWidth = parseInt(this.MapContentDiv.offsetWidth,10);
    this.MapContentHeight = parseInt(this.MapContentDiv.offsetHeight,10);
    this.PopupMenuWidth = parseInt(this.PopupMenuDiv.offsetWidth,10);
    this.PopupMenuHeight = parseInt(this.PopupMenuDiv.offsetHeight,10);
    
    this.ClearPopupMenuSelection = function()
    {
        this.PopupMenuDiv.style.backgroundColor =this.NORMAL_BGCOLOR;
        this.PopupStartHereDiv.style.backgroundColor =this.NORMAL_BGCOLOR;
        this.PopupEndHereDiv.style.backgroundColor =this.NORMAL_BGCOLOR;
        this.PopupClearDiv.style.backgroundColor =this.NORMAL_BGCOLOR;
    }

    this.HidePopupMenu = function()
    {
        this.PopupMenuDiv.style.visibility = "hidden";
    }
    
    this.ShowPopupMenuAtPosition = function(pointX, pointY)
    {
        this.ClearPopupMenuSelection();
        
        if(pointX + this.PopupMenuWidth > this.MapContentWidth)
            pointX -= this.PopupMenuWidth;
            
        if(pointY + this.PopupMenuHeight > this.MapContentHeight)
            pointY -= this.PopupMenuHeight;
        
        this.PopupMenuDiv.style.left = pointX + "px";
        this.PopupMenuDiv.style.top =  pointY + "px";
        this.PopupMenuDiv.style.visibility = "visible";
    }
    
    this.SelectStartHereMenu = function()
    {   
        this.ClearPopupMenuSelection();
        this.PopupStartHereDiv.style.backgroundColor =this.SELECTION_BGCOLOR;
    }
    
    this.SelectEndHereMenu = function()
    {
        this.ClearPopupMenuSelection();
        this.PopupEndHereDiv.style.backgroundColor =this.SELECTION_BGCOLOR;
    }
    
    this.SelectClearMenu = function()
    {
        this.ClearPopupMenuSelection();
        this.PopupClearDiv.style.backgroundColor =this.SELECTION_BGCOLOR;
    }
    
    this.StartMenuClicked = function()
    {
        this.HidePopupMenu();
        
        // set origin
        this.objOrigin = new Object();
        this.objOrigin.Latitude = AGGlobalsArray[this.strParentId].m_RightClikedCoordinate.Latitude;
        this.objOrigin.Longitude = AGGlobalsArray[this.strParentId].m_RightClikedCoordinate.Longitude;
        
        //set image
        this.ClearStartImage();
        this.OriginImage = document.createElement("img");
	    this.OriginImage.src = AGGlobalsArray[this.strParentId].m_hostURL + "Images/start.png";
        this.SetRoutingImage(this.OriginImage, this.objOrigin);        
        
        this.PerformRoutingTask();
    }
    
    this.EndMenuClicked = function()
    {
        this.HidePopupMenu();
        
        // set destination
        this.objDestination = new Object();
        this.objDestination.Latitude = AGGlobalsArray[this.strParentId].m_RightClikedCoordinate.Latitude;
        this.objDestination.Longitude = AGGlobalsArray[this.strParentId].m_RightClikedCoordinate.Longitude;
        
        // set image
        this.ClearEndImage();
        this.DestinationImage = document.createElement("img");
	    this.DestinationImage.src = AGGlobalsArray[this.strParentId].m_hostURL + "Images/end.png";
        this.SetRoutingImage(this.DestinationImage, this.objDestination);
        
        this.PerformRoutingTask();
    }
    
    this.ClearMenuClicked = function()
    {
        this.HidePopupMenu();
        
        // clear origin and destination
        this.objOrigin = null;
        this.objDestination = null;
        
        // clear images
        this.ClearStartImage();
        this.ClearEndImage();
        
        AGGlobalsArray[this.strParentId].DrivingDirections.Clear();
    }
    
    this.SetRoutingImage = function(imageElement, coord)
    {
        var offX = - 14;
        var offY = - 32;
        
        AGGlobalsArray[this.strParentId].m_objMovingContainer.AddObjectToMap(imageElement, coord.Latitude, coord.Longitude, offX, offY);
        imageElement.style.visibility = "visible";
    }
    
    this.ClearStartImage = function()
    {
        if(this.OriginImage != null)
        {
            try
            {
                AGGlobalsArray[this.strParentId].m_objMovingContainer.RemoveObjectFromMap(this.OriginImage);
            }
            catch(err)
            {
            }
            this.OriginImage = null;
        }
    }
    
    this.ClearEndImage = function()
    {
        if(this.DestinationImage != null)
        {
            try
            {
                AGGlobalsArray[this.strParentId].m_objMovingContainer.RemoveObjectFromMap(this.DestinationImage);
            }
            catch(err)
            {
            }
            this.DestinationImage = null;
        }
    }
    
    this.PerformRoutingTask = function()
    {
        if(this.objOrigin==null || this.objDestination==null)
            return;
        
        // clear images
        this.ClearStartImage();
        this.ClearEndImage();
        
        // set both origin and destination
        AGGlobalsArray[this.strParentId].DrivingDirections.SetOrigin(this.objOrigin.Latitude, this.objOrigin.Longitude);
        AGGlobalsArray[this.strParentId].DrivingDirections.SetDestination(this.objDestination.Latitude, this.objDestination.Longitude);
        
        // make origin & dest null, so that they have no effect on next origin selection
        this.objOrigin = null;
        this.objDestination = null;
        
        // Draw route
        AGGlobalsArray[this.strParentId].DrivingDirections.DrawRoute();
     }

    
    this.HidePopupMenu();
}

///////////////// end of PopupMenu Class  ///////////////

//////////////////////////////////////////////////////////////////// 
///////////////// DrivingDirection Class  //////////////////////////
////////////////////////////////////////////////////////////////////

function DrivingDirection(_strParentId)
{
    this.strParentId = _strParentId;
    this.objOrigin = null;
    this.objDestination = null;
    this.RoutingPoints = new Array();

    this.OriginImage = null;
    this.DestinationImage = null;
    
    this.strPostRoutingFunc = null;
    
    this.objDDDiv = null;    
    this.strCSSUrl = null;
    this.objDDIFrame = null;
    
    this.SetOrigin = function(Latitude, Longitude)
    {
        this.objOrigin = new Object();
        this.objOrigin.Latitude = Latitude;
        this.objOrigin.Longitude = Longitude;

    }
    
    this.SetDestination = function(Latitude, Longitude)
    {
        this.objDestination = new Object();
        this.objDestination.Latitude = Latitude;
        this.objDestination.Longitude = Longitude;

    }
    
//    this.ClearOriginImage = function()
//    {
//        if(this.OriginImage != null)
//        {
//            try
//            {
//                AGGlobalsArray[this.strParentId].m_objMovingContainer.RemoveObjectFromMap(this.OriginImage);
//            }
//            catch(err)
//            {
//            }
//            this.OriginImage = null;
//        }
//    }
    
//    this.ClearDestinationImage = function()
//    {
//        if(this.DestinationImage != null)
//        {
//            try
//            {
//                AGGlobalsArray[this.strParentId].m_objMovingContainer.RemoveObjectFromMap(this.DestinationImage);
//            }
//            catch(err)
//            {
//            }
//            this.DestinationImage = null;
//        }
//    }
    
    this.Clear = function()
    {
        this.objOrigin = null;
        this.objDestination = null;
        this.RoutingPoints = new Array();   // clear

        var hadRouting = AGGlobalsArray[this.strParentId].m_objMainMap.RequestManager.ClearRoutingParam();
        if(hadRouting)
        {
            AGGlobalsArray[this.strParentId].m_objMainMap.RedrawCurrentArea();
            // call post routing func
            if(AGGlobalsArray[this.strParentId].m_bExecuteUserFunctions)
                AGGlobalsArray[this.strParentId].m_bClearRoutingEventOccured = true;
        }
    }

    this.DrawRoute = function(bZoomToDDExtent)
    {
        // check is routing layer consistent
        if(AGGlobalsArray[this.strParentId].m_bRoutingLayerConsistent == false)
            return false;
        if(this.objOrigin==null || this.objDestination==null)
            return false;
        
        this.RoutingPoints = new Array();
        this.RoutingPoints.push(this.objOrigin);
        this.RoutingPoints.push(this.objDestination);
        
        
        AGGlobalsArray[this.strParentId].m_objMainMap.RequestManager.CreateRoutingParam(this.RoutingPoints);
        if(bZoomToDDExtent == true)
            AGGlobalsArray[this.strParentId].m_objMainMap.ZoomToBoundingBox(this.GetDDBBox());
        else
            AGGlobalsArray[this.strParentId].m_objMainMap.RedrawCurrentArea();
        
        // call post routing func
        if(AGGlobalsArray[this.strParentId].m_bExecuteUserFunctions)
            AGGlobalsArray[this.strParentId].m_bShowRoutingEventOccured = true;
        
        return true;
    }
    
    this.GetPoints = function()
    {
        return this.RoutingPoints;
    }
    
//    this.SetRoutingImage = function(imageElement, coord)
//    {
//        var offX = - 14;
//        var offY = - 32;
//        
//        AGGlobalsArray[this.strParentId].m_objMovingContainer.AddObjectToMap(imageElement, coord.Latitude, coord.Longitude, offX, offY);
//        imageElement.style.visibility = "visible";
//    }
    
    
    this.GetDDBBox = function()
    {   
        // calculate new BBox &  Return
        var EXTRA_BBOX_PERCENTAGE = 0.25;
        
        // calculate max-min of latLong
        var maxLat = -500;
        var minLat = 500;
        var maxLong = -500;
        var minLong = 500;
        
        for(var i=0; i<this.RoutingPoints.length; i++)
        {
            var tempLong = parseFloat(this.RoutingPoints[i].Longitude);
            var tempLat = parseFloat(this.RoutingPoints[i].Latitude);
            
            if(maxLong < tempLong)
                maxLong = tempLong;
            if(minLong > tempLong)
                minLong = tempLong;
                
            if(maxLat < tempLat)
                maxLat = tempLat;
            if(minLat > tempLat)
                minLat = tempLat;
        }
        
        //construct new BBox
        var diffLong = parseFloat(maxLong - minLong);
        var diffLat = parseFloat(maxLat - minLat);
        
        maxLong += (EXTRA_BBOX_PERCENTAGE * diffLong);
        maxLat += (EXTRA_BBOX_PERCENTAGE * diffLat);
        minLong -= (EXTRA_BBOX_PERCENTAGE * diffLong);
        minLat -= (EXTRA_BBOX_PERCENTAGE * diffLat);
        
        return minLong + "," + minLat + "," + maxLong + "," + maxLat ;
        
    }
    
    this.SetPanel = function(oDiv)
    {
        try
        {
            this.objDDDiv = oDiv;
            this.objDDDiv.innerHTML = "";
            
            var iframeIndex = 0;
            var strDDIFrameIdPrefrix = this.strParentId + "_DDIFrame";
            while(document.getElementById(strDDIFrameIdPrefrix + iframeIndex) != null)
                iframeIndex++;
            var strIframeId = strDDIFrameIdPrefrix + iframeIndex;
            
            this.objDDIFrame = document.createElement('iframe');
            this.objDDIFrame.setAttribute('id', strIframeId);
            this.objDDIFrame.setAttribute('name', strIframeId);
            this.objDDIFrame.setAttribute('src', "");
            this.objDDIFrame.style.width = "100%";
            this.objDDIFrame.style.height = "100%";
            this.objDDIFrame.style.border = '0px solid #000000';
            this.objDDIFrame.style.overflow = "auto";
            this.objDDIFrame.style.visibility = "hidden";
            this.objDDDiv.appendChild(this.objDDIFrame);
            return true;
        }
        catch(err)
        {
            this.objDDDiv = null;
            return false;
        }
    }
    
    this.SetCSSUrl = function(strCssUrl)
    {
        this.strCSSUrl = strCssUrl;
    }
    
    this.Load = function()
    {
        // check is routing layer consistent
        if(AGGlobalsArray[this.strParentId].m_bRoutingLayerConsistent == false)
            return false;
        if(this.objDDIFrame == null)
        {
            //alert("Driving Directions could not be retrieved.\nPlease set driving direction panel.")
            return false;
        }
        if(this.objOrigin == null ||  this.objDestination == null)
        {
            alert("Driving Directions could not be retrieved.\nPlease select an orgin and a destination.")
            return false;
        }
        
        var url = DD_GATEWAY;
        url += "?";
        url += "Waypoints=" + this.objOrigin.Latitude + "|" + this.objOrigin.Longitude + "$" + this.objDestination.Latitude + "|" + this.objDestination.Longitude;
        url += "&RouteParameter=" + AGGlobalsArray[this.strParentId].m_objMainMap.RequestManager.mapInfoObject.routableParameter;
        url += "&RouteLayer=" + AGGlobalsArray[this.strParentId].m_objMainMap.RequestManager.mapInfoObject.routableLayer;
        var cssUrl = this.strCSSUrl;
        if(cssUrl == null)
            cssUrl = API_HOST_URL + DEFAULT_DD_CSS_FILE_NAME;
            
        url += "&CSS=" + cssUrl;
        this.objDDIFrame.setAttribute('src',url);
        this.objDDIFrame.style.visibility = "visible";
        return true;
    }
    
}
///////////////// end of DrivingDirection Class  ///////////////////

////////////////////////////////////////////////////////////////////
/////////////////////  EventHandler  ///////////////////////////////
////////////////////////////////////////////////////////////////////

function EventHandler()
{
    this.m_arrFuncNames = new Array();
    this.m_arrExecOnce = new Array();
    
    this.AddFunction = function(strFuncName, bExecuteOnce)
    {
        var bFunctionExist = false;
        for(var i=0; i<this.m_arrFuncNames.length; i++)
        {
            if(this.m_arrFuncNames[i] == strFuncName)
            {
                bFunctionExist = true;
                break;
            }
        }
        
        if(!bFunctionExist)
        {
            this.m_arrFuncNames.push(strFuncName);
            this.m_arrExecOnce.push(bExecuteOnce);
        }
    }
    
    this.RemoveFunction = function(strFuncName)
    {
        for(var i=0; i<this.m_arrFuncNames.length; i++)
        {
            if(this.m_arrFuncNames[i] == strFuncName)
            {
                // forward the next functions by one position
                for(var j=i+1; j<this.m_arrFuncNames.length; j++)
                {
                    this.m_arrFuncNames[j-1] = this.m_arrFuncNames[j];
                    this.m_arrExecOnce[j-1] = this.m_arrExecOnce[j];
                }
                
                this.m_arrFuncNames.pop();
                this.m_arrExecOnce.pop();
                return;
            }
        }
    }
    
    this.Clear = function()
    {
        this.m_arrFuncNames = new Array();
        this.m_arrExecOnce = new Array();
    }
    
    this.ExecuteFunctions = function()
    {
        for(var i=0; i<this.m_arrFuncNames.length; i++)
        {
            var strFunctionName = this.m_arrFuncNames[i];
            if(this.m_arrExecOnce[i])
            {
                this.RemoveFunction(strFunctionName);
                i--;    // next function stays at same index
            }
            
            try
            {
                eval(strFunctionName+"();");
            }
            catch(err)
            {
                // error in executing user-defined function   
            }
        }
    }
}

////////////////////////////////////////////////////////////////////
/////////////////////  ImageryTileHandler  /////////////////////////
////////////////////////////////////////////////////////////////////

function ImageryTileHandler (strParentId)
{
    this.m_strParentId = strParentId;
    this.iCurrentLevel = -5;    // not -1, as initial images have cur level -1
    this.m_iSatTileToLoad = 0;
    this.m_iUpZIndex = 2;
    this.m_iDownZIndex = 1;
    
    // initiate base urls
    this.m_arrBaseUrls = new Array();
    this.m_iMaxZoomLevel = 12;
    for(var i=0; i<=this.m_iMaxZoomLevel; i++)
        this.m_arrBaseUrls[i] = "";
        
    var urlParts = IMAGERY_BASE_URLS.split(";");
    for(var i=0; i<urlParts.length; i++)
    {
        var strPart = urlParts[i];
        var temp = strPart.split("|");
        if(temp.length != 2)
            continue;
        
        var strUrl = temp[1];
        
        var indexes = temp[0].split("-");
        if(indexes.length != 2)
            continue;
        
        var startIndex = parseInt(indexes[0], 10);
        var endIndex = parseInt(indexes[1], 10);
        for(var j=startIndex; j<=endIndex; j++)
            this.m_arrBaseUrls[j] = strUrl;
    }
    
    
    this.ToTileServiceBoundingBox = function(tsd, view) 
    {
	    var view_scale = {
		    x: (view.bb.x1 - view.bb.x0) / view.size.x,
		    y: (view.bb.y1 - view.bb.y0) / view.size.y
	    };
	    var ts_scale = {
		    x: tsd.scale.x / tsd.size.x,
		    y: tsd.scale.y / tsd.size.y
	    };
	    var level = Math.floor((Math.log(Math.abs(view_scale.x / ts_scale.x)) / Math.log(0.5) + Math.log(Math.abs(view_scale.x / ts_scale.x)) / Math.log(0.5)) * 0.5 + 0.4);
	    if (level < 0) level = 0;
	    var scale = { 
		    x: tsd.scale.x * Math.pow(0.5, level),
		    y: tsd.scale.y * Math.pow(0.5, level)
	    };
    	
	    return {
		    level: level,
		    x0: Math.floor((view.bb.x0 - tsd.origin.x) / scale.x),
		    y0: Math.floor((view.bb.y0 - tsd.origin.y) / scale.y),
		    x1: Math.ceil((view.bb.x1 - tsd.origin.x) / scale.x) - 1,
		    y1: Math.ceil((view.bb.y1 - tsd.origin.y) / scale.y) - 1
	    };
    }

    this.ToTileServiceTile = function(tsd, view, tst) 
    {
	    var view_scale = 
	    {
		    x: (view.bb.x1 - view.bb.x0) / view.size.x,
		    y: (view.bb.y1 - view.bb.y0) / view.size.y
	    };
	    var scale = 
	    { 
		    x: tsd.scale.x * Math.pow(0.5, tst.level),
		    y: tsd.scale.y * Math.pow(0.5, tst.level)
	    };
	    var bb = 
	    {
		    x0: Math.round((tst.x * scale.x + tsd.origin.x - view.bb.x0) / view_scale.x),
		    y0: Math.round((tst.y * scale.y + tsd.origin.y - view.bb.y0) / view_scale.y),
		    x1: Math.round(((tst.x + 1) * scale.x + tsd.origin.x - view.bb.x0) / view_scale.x),
		    y1: Math.round(((tst.y + 1) * scale.y + tsd.origin.y - view.bb.y0) / view_scale.y)
	    };
	    
	    //var strDS = this.GetDatasetName(tst.level, tst.x, tst.y);
	    var strBaseUrl = this.GetBaseUrl();
	    
	    return {
		    level: tst.level,
		    x: tst.x,
		    y: tst.y,
		    url: strBaseUrl+"&level="+ tst.level +"&x="+ tst.x +"&y="+ tst.y,
		    offset: {
			    x: bb.x0,
			    y: bb.y0
		    },
		    size: {
			    x: bb.x1 - bb.x0,
			    y: bb.y1 - bb.y0
		    }
	    };
    }
    
    this.GetDatasetName = function(iLevel, iX, iY)
    {
        if(iLevel <= 7)
            return "bmng.topo.bathy.200401";
        else
            return "spot5";
    }
    
    this.GetBaseUrl = function()
    {
        var curZoomLevel = AGGlobalsArray[this.m_strParentId].m_iCurZoomLevel;
        return this.m_arrBaseUrls[curZoomLevel];
    }
    
    this.getExistingTileIndex = function(iLevel, iX, iY)
    {
        for(var i=0; i<AGGlobalsArray[this.m_strParentId].m_objMainMap.usedSatTileList.length; i++)
        {
            var index = AGGlobalsArray[this.m_strParentId].m_objMainMap.usedSatTileList.items[i];
            var img = document.getElementById(AGGlobalsArray[this.m_strParentId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID + index);
            if(img.level == (iLevel+"") && img.xVal == (iX+"") && img.yVal == (iY+""))
                return index;
        }
        return -1;
    }
    
    this.SetTiles = function(strBBox, iMapWidth, iMapHeight)
    {
        var tsd = { // TileService description
			url: "http://s0.tileservice.worldwindcentral.com/getTile?interface=map&version=1",  //&dataset=bmng.topo.bathy.200401&
			size: { x: 512, y: 512 },
			origin: { x: -180.0, y: 90.0 },
			scale: { x: 360.0, y: -360.0 } 
		};
		
		var bboxlatlong = strBBox.split(",",4);
        var long1 = parseFloat(bboxlatlong[0]);
        var lat1 = parseFloat(bboxlatlong[1]);
        var long2 = parseFloat(bboxlatlong[2]);
        var lat2 = parseFloat(bboxlatlong[3]);

		var view = { // Example map view
			size: { x: iMapWidth, y: iMapHeight},
			bb: { x0: long1, y0: lat2, x1: long2, y1: lat1 }
		};

		var tsbb = this.ToTileServiceBoundingBox(tsd, view);

        var mapContentLeft = AGGlobalsArray[this.m_strParentId].m_objMapCanvas.tileMapDiv.offsetLeft - AGGlobalsArray[this.m_strParentId].m_ptImgBasePointShift.x;
        var mapContentTop = AGGlobalsArray[this.m_strParentId].m_objMapCanvas.tileMapDiv.offsetTop - AGGlobalsArray[this.m_strParentId].m_ptImgBasePointShift.y;
		
		
		var curLevel = tsbb.level;
		var minX = tsbb.x0;
		var maxX = tsbb.x1;
		var minY = tsbb.y0;
		var maxY = tsbb.y1;
		
		this.m_iSatTileToLoad = 0;
		// pixwlization
		var bZoom = false;
		if(this.iCurrentLevel != curLevel)
		{
		    bZoom = true;
		    this.m_iSatTileToLoad = 0;
		}
		this.iCurrentLevel = curLevel;
		
		// iterate over every tile within the bounding box
		for (var y = tsbb.y0; y <= tsbb.y1; ++y) 
		{
			for (var x = tsbb.x0; x <= tsbb.x1; ++x) 
			{
				var tst = this.ToTileServiceTile(tsd, view, { level: tsbb.level, x: x, y: y });
				
				var existingTileIndex = this.getExistingTileIndex(tsbb.level, x, y);
				
                if(existingTileIndex < 0)
                {
				    var index = AGGlobalsArray[this.m_strParentId].m_objMainMap.GetTileIndexForNewSatTile(curLevel, minX, maxX, minY, maxY);
				    if(index >= 0)
				    {
				        var img = document.getElementById(AGGlobalsArray[this.m_strParentId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID + index);
				        
				        img.setAttribute('width',tst.size.x);
				        img.setAttribute('height',tst.size.y);
				        img.style.left = "-1000000px";
				        img.style.top = "-1000000px";
				        
				        img.posLeft = (tst.offset.x  - mapContentLeft);
				        img.posTop = (tst.offset.y - mapContentTop);
				        
				        img.style.width = tst.size.x + "px";
				        img.style.height = tst.size.y + "px";
                        //img.style.visibility = "visible";
                        img.style.zIndex = this.m_iUpZIndex;
                        img.level = tsbb.level + "";
                        img.xVal = x + "";
                        img.yVal = y + "";
                        
                        if(bZoom)
                        {
				            this.m_iSatTileToLoad ++;
				            img.zoom = "1";
				        }
				        else
				            img.zoom = "0";
				            
				        img.setAttribute('src',tst.url);
                    }
                }
                else
                {
                        var img = document.getElementById(AGGlobalsArray[this.m_strParentId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID + existingTileIndex);
				        
				        img.setAttribute('width',tst.size.x);
				        img.setAttribute('height',tst.size.y);
				        
				        img.posLeft = (tst.offset.x  - mapContentLeft);
				        img.posTop = (tst.offset.y - mapContentTop);
				        img.style.left = (tst.offset.x  - mapContentLeft) + "px";
				        img.style.top = (tst.offset.y - mapContentTop) + "px";
				        
				        
				        img.style.width = tst.size.x + "px";
				        img.style.height = tst.size.y + "px";
                }
			}
		}
    }
    
    this.SetPos = function(tileIndex)
    {
        var imgId = AGGlobalsArray[this.m_strParentId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID+tileIndex;
        var elem = document.getElementById(imgId);
        
        if(typeof elem.posLeft != "undefined")
        {
            if(elem.zoom == "1" )   // come from GetTileImageForZoom
            {
                elem.style.left = elem.posLeft + "px";
                elem.style.top = elem.posTop + "px";        
                elem.zoom = "0";
                
                if(elem.level+"" == this.iCurrentLevel+"")
                {
                    this.m_iSatTileToLoad --;
                    this.m_iSatTileToLoad = this.m_iSatTileToLoad < 0 ? 0 : this.m_iSatTileToLoad;
                    
                    if (this.m_iSatTileToLoad == 0)
                    {
                        this.ClearRestTile(this.iCurrentLevel);
                    }
                }
            }
            else if(elem.zoom == "0" )
            {
                elem.style.left = elem.posLeft + "px";
                elem.style.top = elem.posTop + "px";
            }
        }
        else
        {
            //alert("undefined...");
        }
    } 
    
    this.ClearRestTile = function(iCurLevel)
    {   
        AGGlobalsArray[this.m_strParentId].m_objMainMap.freeSatTileList = new TileList();
        AGGlobalsArray[this.m_strParentId].m_objMainMap.usedSatTileList = new TileList();
        
        for(var i=0; i<AGGlobalsArray[this.m_strParentId].m_iMaxNoOfSatTile; i++)
        {
            var imgElem = document.getElementById(AGGlobalsArray[this.m_strParentId].m_objMapCanvas.SATELLITE_TILE_IMAGE_ID+i);
            if(imgElem.level+"" != iCurLevel+"")
            {
                AGGlobalsArray[this.m_strParentId].m_objMainMap.freeSatTileList.Add(i);
                //imgElem.style.visibility = "hidden";
                imgElem.posLeft = "-1000000";
	            imgElem.posTop = "-1000000";
	            imgElem.style.left = "-1000000px";
	            imgElem.style.top = "-1000000px";
	            imgElem.level = "-1";
	            imgElem.xVal = "-1";
	            imgElem.yVal = "-1";
	            imgElem.zoom = "0";
            }
            else
            {
                AGGlobalsArray[this.m_strParentId].m_objMainMap.usedSatTileList.Add(i);
            }
        }
    }
}