//--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 19JUN2009  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * Get a map tile image.
  * @param mtype the map type of the map tile.
  * @param X the X index of the map tile.
  * @param Y the Y index of the map tile.
  * @param zoomLevel the zoom level of the map tile.
  * @return the image at give location.
  */
 internal IImage GetImage(int mtype, int x, int y, int zoomLevel)
 {
     string key = mtype + "|" +
             x + "|" +
             y + "|" +
             zoomLevel;
     IImage image;
     _lastestZoomLevel = zoomLevel;
     byte[] imageArray;
     lock (_imageCache)
     {
         imageArray = (byte[])_imageCache[key];
     }
     if (imageArray == null)
     {
         ImageTileIndex needToDownloadImageTileIndex
                 = new ImageTileIndex();
         needToDownloadImageTileIndex.MapType = mtype;
         needToDownloadImageTileIndex.XIndex = x;
         needToDownloadImageTileIndex.YIndex = y;
         needToDownloadImageTileIndex.MapZoomLevel = zoomLevel;
         AddToImageDownloadList(needToDownloadImageTileIndex);
         image = TileDownloading;
     }
     else
     {
         image = MapLayer.GetAbstractGraphicsFactory().CreateImage(imageArray, 0, imageArray.Length);
     }
     return image;
 }
            //--------------------------------- REVISIONS --------------------------
            // Date       Name                 Tracking #         Description
            // ---------  -------------------  -------------      ------------------
            // 19JUN2009  James Shen                 	          Initial Creation
            ////////////////////////////////////////////////////////////////////////
            /**
             * get one map tile.
             * @param imageTileIndex the index of given map tile.
             */
            internal virtual void GetImage(ImageTileIndex imageTileIndex)
            {
                try
                {
                    string key = imageTileIndex.MapType + "|" +
                            imageTileIndex.XIndex + "|" +
                            imageTileIndex.YIndex + "|" +
                            imageTileIndex.MapZoomLevel;
                    byte[] imageArray;
                    IImage image = TileNotAvaiable;
                    //this is a block methods,it returns when the download is done.

                    _mapTileReader.GetImage(imageTileIndex.MapType,
                            imageTileIndex.XIndex, imageTileIndex.YIndex,
                            imageTileIndex.MapZoomLevel);
                    //if the downloading is successful
                    if (_mapTileReader.ImageArraySize > 0
                            && _mapTileReader.IsImagevalid)
                    {
                        imageArray = _mapTileReader.ImageArray;
                        if (imageArray != null)
                        {
                            try
                            {
                                image = MapLayer.GetAbstractGraphicsFactory()
                                        .CreateImage(imageArray, 0, imageArray.Length);
                            }
                            catch (Exception)
                            {

                                _mapTileReader.IsImagevalid = false;
                                image = TileNotAvaiable;

                            }
                            if (_mapTileReader.IsImagevalid)
                            {
                                _mapTileDownloadManager.AddToImageCache(key, imageArray);
                            }
                        }

                    }
                    _mapTileDownloadManager.OneDownloadImageTileDone(key);
                    _mapTileDownloadManager._mapTileReadyListener.Done(imageTileIndex, image);
                }
                catch (Exception)
                {

                }
            }
            //--------------------------------- REVISIONS --------------------------
            // Date       Name                 Tracking #         Description
            // ---------  -------------------  -------------      ------------------
            // 19JUN2009  James Shen                 	          Initial Creation
            ////////////////////////////////////////////////////////////////////////
            /**
             * the actually thread run.
             */
            public virtual void Run()
            {
                while (!_stopDownloadWorker)
                {
                    try
                    {
                        //get one map tile index from dowload manager's download list.
                        ImageTileIndex imageTileIndex = _mapTileDownloadManager
                                .GetAImageTileIndex();
                        if (imageTileIndex != null)
                        {
                            _pauseDownloadWorker = false;
                            _mapTileDownloadManager.
                                    AddToAssignedImageDownloadList(imageTileIndex);
                            if (imageTileIndex.MapType == MapType.ROUTING_DIRECTION)
                            {
                                //if it's to render the map direction, just assign
                                //it to  mapDirectionRenderer.
                                lock (_mapTileDownloadManager._assignedMapDirectionRenderListMutex)
                                {
                                    string key = imageTileIndex.MapType + "|" +
                                            imageTileIndex.XIndex + "|" +
                                            imageTileIndex.YIndex + "|" +
                                            imageTileIndex.MapZoomLevel;
                                    if (!_mapTileDownloadManager._assignedMapDirectionRenderList.ContainsKey(key))
                                    {
                                        ImageTileIndex newImagetileIndex = new ImageTileIndex();
                                        newImagetileIndex.MapType = imageTileIndex.MapType;
                                        newImagetileIndex.XIndex = imageTileIndex.XIndex;
                                        newImagetileIndex.YIndex = imageTileIndex.YIndex;
                                        newImagetileIndex.MapZoomLevel = imageTileIndex.MapZoomLevel;
                                        _mapTileDownloadManager._assignedMapDirectionRenderList.Add(key, newImagetileIndex);
                                        Monitor.Pulse(_mapTileDownloadManager._assignedMapDirectionRenderListMutex);
                                    }

                                }
                            }
                            else
                            {
                                GetImage(imageTileIndex);
                            }
                        }
                        else
                        {
                            lock (_syncObjectWorker)
                            {
                                try
                                {
                                    _pauseDownloadWorker = true;
                                    Monitor.Wait(_syncObjectWorker, _maxWaitingTime * 1000);

                                }
                                catch (Exception)
                                {
                                    Thread.CurrentThread.Interrupt();

                                }
                            }

                        }
                    }
                    catch (Exception)
                    {
                        //catch whatever exception to make sure the thread is not dead.

                    }
                }
            }
            //--------------------------------- REVISIONS --------------------------
            // Date       Name                 Tracking #         Description
            // ---------  -------------------  -------------      ------------------
            // 19JUN2009  James Shen                 	          Initial Creation
            ////////////////////////////////////////////////////////////////////////
            /**
             * get one map tile.
             * @param imageTileIndex the index of given map tile.
             */
            internal override void GetImage(ImageTileIndex imageTileIndex)
            {
                try
                {
                    string key = imageTileIndex.MapType + "|" +
                            imageTileIndex.XIndex + "|" +
                            imageTileIndex.YIndex + "|" +
                            imageTileIndex.MapZoomLevel;
                    IImage image = TileNotAvaiable;
                    if (_mapTileReader is MapDirectionRenderer)
                    {
                        MapDirectionRenderer mapDirectionRenderer = (MapDirectionRenderer)_mapTileReader;
                        //this is a block methods,it returns when the download is done.
                        if (imageTileIndex.MapZoomLevel == _mapTileDownloadManager._lastestZoomLevel)
                        {
                            image = mapDirectionRenderer.GetImage(
                                    imageTileIndex.XIndex, imageTileIndex.YIndex,
                                    imageTileIndex.MapZoomLevel);
                        }
                        if (image == null)
                        {
                            image = TileNotAvaiable;
                        }
                        _mapTileDownloadManager.OneDownloadImageTileDone(key);
                        _mapTileDownloadManager._mapTileReadyListener.Done(imageTileIndex, image);
                    }

                }
                catch (Exception)
                {

                }
            }
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 19JUN2009  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * Add one map tile index to the download list.
         * @param imageTileIndex
         */
        private void AddToImageDownloadList(ImageTileIndex imageTileIndex)
        {
            lock (_assignedImageTileDownloadListMutex)
            {
                string key = imageTileIndex.MapType + "|" +
                        imageTileIndex.XIndex + "|" +
                        imageTileIndex.YIndex + "|" +
                        imageTileIndex.MapZoomLevel;
                object object3 = _imageCache[key];
                object object1 = _imageTileDownloadList[key];
                object object2 = _assignedImageTileDownloadList[key];

                if (object3 == null && object1 == null && object2 == null)
                {

                    ImageTileIndex newImagetileIndex = new ImageTileIndex();
                    newImagetileIndex.MapType = imageTileIndex.MapType;
                    newImagetileIndex.XIndex = imageTileIndex.XIndex;
                    newImagetileIndex.YIndex = imageTileIndex.YIndex;
                    newImagetileIndex.MapZoomLevel = imageTileIndex.MapZoomLevel;

                    _imageTileDownloadList.Add(key, newImagetileIndex);
                    lock (_syncObjectManager)
                    {
                        Monitor.Pulse(_syncObjectManager);

                    }
                }
            }
        }
 //--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 19JUN2009  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * Add one map tile index to the assigned download list.
  * @param imageTileIndex
  */
 private void AddToAssignedImageDownloadList(ImageTileIndex imageTileIndex)
 {
     lock (_assignedImageTileDownloadListMutex)
     {
         string key = imageTileIndex.MapType + "|" +
                 imageTileIndex.XIndex + "|" +
                 imageTileIndex.YIndex + "|" +
                 imageTileIndex.MapZoomLevel;
         _assignedImageTileDownloadList[key]= imageTileIndex;
     }
 }