private void exportButton_Click(object sender, System.EventArgs e)
        {
            exportButton.Enabled = false;
            browseButton.Enabled = false;
            loadButton.Enabled   = false;
            closeButton.Text     = "Cancel";
            progressBar1.Visible = true;
            Cursor.Current       = Cursors.WaitCursor;

            if (Project.exportDestFolder.Length == 0)
            {
                setExportDestFolder();
            }

            if (Project.exportDestFolder.Length > 0 && Directory.Exists(Project.exportDestFolder))
            {
                int countExported = 0;
                int countTotal    = 0;

                m_working   = true;
                m_canceling = false;

                exportByList(m_listOfTiles, out countExported, out countTotal);

                if (m_canceling)
                {
                    this.estimateLabel.Text = "aborted copying tiles to folder: " + Project.exportDestFolder;
                }
                else
                {
                    bool didFrame = false;

                    if (CameraManager.This.Elev < 87000.0d)
                    {
                        Hashtable listOfTiles = new Hashtable();
                        int       scaleIndex  = 14;                  // TileSetTerra.This.ScaleIndex
                        TileSetTerraLayout.listTilesAtLevelsWithType(listOfTiles,
                                                                     CameraManager.This.CoverageTopLeft, CameraManager.This.CoverageBottomRight,
                                                                     scaleIndex, true, m_doAerial, m_doColor, m_doTopo);

                        // remove the tiles that were already downloaded/exported before:
                        foreach (string key in m_listOfTiles.Keys)
                        {
                            if (listOfTiles.ContainsKey(key))
                            {
                                listOfTiles.Remove(key);
                            }
                        }

                        string message = "OK: Exported " + countTotal + " tiles along the route.\r\n\r\n"
                                         + "Do you want to also export " + listOfTiles.Count + " tiles covering the map as you see it? (16m to 64m per pixel tiles)";

                        if (Project.YesNoBox(this, message))
                        {
                            int countExported1 = 0;
                            int countTotal1    = 0;

                            exportByList(listOfTiles, out countExported1, out countTotal1);

                            countExported += countExported1;
                            countTotal    += countTotal1;
                            didFrame       = true;
                        }
                    }

                    if (didFrame)
                    {
                        this.estimateLabel.Text = "OK: " + countExported + " tiles exported to folder:\r\n        " + Project.exportDestFolder;
                    }
                    else
                    {
                        this.estimateLabel.Text = "OK: " + countExported + " tiles out of "
                                                  + countTotal + "\n  exported to folder: " + Project.exportDestFolder;
                    }
                }
            }
            else
            {
                this.estimateLabel.Text = "Error: folder '" + Project.exportDestFolder + "' not valid.";
                setExportDestFolder();
            }
            exportButton.Enabled = true;
            browseButton.Enabled = true;
            loadButton.Enabled   = true;
            Cursor.Current       = Cursors.Default;
            closeButton.Text     = "Close";
            progressBar1.Visible = false;
            m_working            = false;
        }
        private void estimateOrAct(bool doAct, bool doDraw)
        {
            if (!m_loaded || m_working)
            {
                return;
            }

            estimateLabel.Text = "estimating download... please wait ...";
            estimateLabel.Refresh();
            Application.DoEvents();

            Graphics graphics = PictureManager.This.Graphics;

            Cursor.Current = Cursors.WaitCursor;

            double spreadMeters  = m_spread * Distance.METERS_PER_MILE;
            double spreadDegrees = spreadMeters / Distance.METERS_PER_DEGREE;

            int scaleIndex = 10 + m_preloadScale;

            if (!doAct)
            {
                m_listOfTiles.Clear();
            }

            for (int i = 0; i < m_trk.Trackpoints.Count - 1; i++)
            {
                Waypoint trkpt1 = (Waypoint)m_trk.Trackpoints.GetByIndex(i);
                Waypoint trkpt2 = (Waypoint)m_trk.Trackpoints.GetByIndex(i + 1);

                Distance d       = trkpt2.Location.distanceFrom(trkpt1.Location);
                int      steps   = (int)Math.Ceiling(d.Meters / spreadMeters * 2);
                double   stepLng = (trkpt2.Location.Lng - trkpt1.Location.Lng) / steps;
                double   stepLat = (trkpt2.Location.Lat - trkpt1.Location.Lat) / steps;

                GeoCoord center = new GeoCoord(trkpt1.Location.Lng, trkpt1.Location.Lat);

                for (int j = 0; j < steps; j++)
                {
                    GeoCoord topLeft     = new GeoCoord(center.Lng - spreadDegrees, center.Lat + spreadDegrees);
                    GeoCoord bottomRight = new GeoCoord(center.Lng + spreadDegrees, center.Lat - spreadDegrees);

                    if (doAct)
                    {
                        TileSetTerraLayout.downloadThemesAtLevel(topLeft, bottomRight, scaleIndex, scaleUpCheckBox.Checked, m_doAerial, m_doColor, m_doTopo);
                    }
                    else
                    {
                        TileSetTerraLayout.listTilesAtLevelsWithType(m_listOfTiles, topLeft, bottomRight,
                                                                     scaleIndex, scaleUpCheckBox.Checked, m_doAerial, m_doColor, m_doTopo);
                    }

                    if (doDraw)
                    {
                        CameraManager.This.PaintGeoRect(topLeft, bottomRight, graphics, Pens.Red, null);

                        // Brush brush = new SolidBrush(Color.FromArgb(10, 255, 0, 0));
                        // CameraManager.This.HighlightGeoRect(topLeft, bottomRight, graphics, brush);
                    }

                    center.Lng += stepLng;
                    center.Lat += stepLat;

                    Application.DoEvents();
                }
            }

            if (doAct)
            {
                estimateLabel.Text = "You can close this dialog now and do other things,\r\nincluding preload along another route.\r\nDownload will continue, watch the green button at the bottom of the screen.";
            }
            else
            {
                // try to come up with some numbers here:
                int    factor   = 0;
                double mbFactor = 0;
                if (m_doAerial)
                {
                    factor++; mbFactor += 10.0d;
                }
                if (m_doColor)
                {
                    factor++; mbFactor += 15.0d;
                }
                if (m_doTopo)
                {
                    factor++; mbFactor += 10.0d;
                }
                mbFactor /= factor;
                int toCover  = m_listOfTiles.Count;
                int toLoad   = toCover;                 // no way to know which are loaded
                int toLoadMb = (int)Math.Round(m_listOfTiles.Count * mbFactor / 1000.0d);
                estimateLabel.Text = "tiles cache: " + Project.GetTerraserverMapsBasePath()
                                     + "\r\ntiles along the route: " + toCover
                                     + (toLoadMb > 0 ? "  - approximately " + toLoadMb + " Mb" : "");

                // Estimate exported size:
                int    toLoadMbExport = toLoadMb;
                double tileSize       = 41.5d;
                double aerialTileSize = Project.pdaExportUseWebsafeGrayscalePalette ? 40.1d : 19.6d;
                double aerialShare    = m_doAerial ? (1.0d / factor) : 0.0d;
                double nonAerialShare = 1.0d - aerialShare;

                switch (Project.pdaExportImageFormat)
                {
                case 0:                                 // bmp websafe
                case 1:                                 // bmp optimized
                    toLoadMbExport = (int)Math.Round(m_listOfTiles.Count * (tileSize * nonAerialShare + aerialTileSize * aerialShare) / 1000.0d);
                    break;

                case 2:                                 // jpeg
                    break;
                }
                estimateLabel.Text += "\r\nPDA export size: " + toLoadMbExport + " Mb - to folder: " + Project.exportDestFolder;
            }

            // wrap-up and return:
            Cursor.Current = Cursors.Default;
            if (doAct)
            {
                closeButton.Text = "Close";
            }

            LibSys.StatusBar.Trace("Preload along route: working...");
        }