bool InternetRetrievalDialog::OpenXML(wxString filename)
{
    ClearInternetRetrieval();
    m_lServers->Clear();

    TiXmlDocument doc;
    wxString error;
    wxProgressDialog *progressdialog = NULL;
//    wxDateTime start = wxDateTime::Now();

    if(!doc.LoadFile(filename.mb_str()))
        FAIL(_("Failed to load file: ") + filename);
    else {
        TiXmlElement *root = doc.RootElement();
        if(strcmp(root->Value(), "OCPNWeatherFaxInternetRetrieval"))
            FAIL(_("Invalid xml file"));

        int count = 0;
        for(TiXmlElement* e = root->FirstChildElement(); e; e = e->NextSiblingElement())
            count++;

        int i=0;
        for(TiXmlElement* e = root->FirstChildElement(); e; e = e->NextSiblingElement(), i++) {
            if(progressdialog) {
                if(!progressdialog->Update(i))
                    return true;
            } else {
//                wxDateTime now = wxDateTime::Now();
                if(1/*(now-start).GetMilliseconds() > 1000 && i < count/2*/) {
                    progressdialog = new wxProgressDialog(
                        _("WeatherFax InternetRetrieval"), _("Loading"), count, this,
                        wxPD_CAN_ABORT | wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME);
                }
            }

            if(!strcmp(e->Value(), "Server")) {
                wxString server = wxString::FromUTF8(e->Attribute("Name"));
                m_lServers->Append(server);
                std::list<FaxUrl> urls;
                std::list<FaxArea> Areas;

                for(TiXmlElement* f = e->FirstChildElement(); f; f = f->NextSiblingElement()) {
                    if(!strcmp(f->Value(), "Map")) {
                        FaxUrl url;
                                    
                        url.Selected = false;
                        url.Server = server;
                         
                        url.Url = wxString::FromUTF8(f->Attribute("Url"));
                        url.Contents = wxString::FromUTF8(f->Attribute("Contents"));

                        urls.push_back(url);
                    } else if(!strcmp(f->Value(), "Area")) {
                        FaxArea Area;
                        Area.name = wxString::FromUTF8(f->Attribute("Name"));
                        Area.description = wxString::FromUTF8(f->Attribute("Description"));
                        
                        Area.lat1 = ParseLatLon(wxString::FromUTF8(f->Attribute("lat1")));
                        Area.lat2 = ParseLatLon(wxString::FromUTF8(f->Attribute("lat2")));
                        Area.lon1 = ParseLatLon(wxString::FromUTF8(f->Attribute("lon1")));
                        Area.lon2 = ParseLatLon(wxString::FromUTF8(f->Attribute("lon2")));

                        Areas.push_back(Area);
                    } else
                        FAIL(_("Unrecognized xml node"));
                }

                for(std::list<FaxUrl>::iterator it = urls.begin();
                    it != urls.end(); it++) {
                    if((*it).area_name.size()) {
                        for(std::list<FaxArea>::iterator it2 = Areas.begin();
                            it2 != Areas.end(); it2++)
                            if((*it).area_name == (*it2).name) {
                                (*it).Area = *it2;
                                goto resolved;
                            }
                        FAIL(_("Failed to match Area: ") + (*it).area_name);
                    }
                resolved:
                    FaxUrl *s = new FaxUrl(*it);
                    m_InternetRetrieval.push_back(s);
                }
            } else
                FAIL(_("Unrecognized xml node"));
        }
    }

    delete progressdialog;
    return true;

failed:
    delete progressdialog;

    wxMessageDialog mdlg(this, error, _("Weather Fax"), wxOK | wxICON_ERROR);
    mdlg.ShowModal();

    return false;
}
bool InternetRetrievalDialog::OpenXML(wxString filename)
{
    ClearInternetRetrieval();
    m_lServers->Clear();

    TiXmlDocument doc;
    wxString error;
    wxProgressDialog *progressdialog = NULL;
    wxDateTime start = wxDateTime::UNow();

    if(!doc.LoadFile(filename.mb_str()))
        FAIL(_("Failed to load file: ") + filename);
    else {
        TiXmlElement *root = doc.RootElement();
        if(strcmp(root->Value(), "OCPNWeatherFaxInternetRetrieval"))
            FAIL(_("Invalid xml file"));

        int count = 0;
        for(TiXmlElement* e = root->FirstChildElement(); e; e = e->NextSiblingElement())
            count++;

        int i=0;
        for(TiXmlElement* e = root->FirstChildElement(); e; e = e->NextSiblingElement(), i++) {
            if(progressdialog) {
                if(!progressdialog->Update(i))
                    return true;
            } else {
                wxDateTime now = wxDateTime::UNow();
                if((now-start).GetMilliseconds() > 500 && i < count/3) {
                    progressdialog = new wxProgressDialog(
                        _("WeatherFax Internet Retrieval"), _("Loading"), count, this,
                        wxPD_CAN_ABORT | wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME);
                }
            }

            if(!strcmp(e->Value(), "Server")) {
                FaxServer server;
                server.Name = wxString::FromUTF8(e->Attribute("Name"));

                m_Servers.push_back(server);

                wxString server_url = wxString::FromUTF8(e->Attribute("Url"));
                m_lServers->Append(server.Name);

                for(TiXmlElement* f = e->FirstChildElement(); f; f = f->NextSiblingElement()) {
                    if(!strcmp(f->Value(), "Region")) {
                        FaxRegion region;
                        region.Name = wxString::FromUTF8(f->Attribute("Name"));
                        region.Server = server.Name;

                        for(std::list<FaxRegion>::iterator it = m_Regions.begin();
                            it != m_Regions.end(); it++)
                            if(it->Name == region.Name && it->Server == region.Server)
                                goto duplicate_region;

                        m_Regions.push_back(region);
                    duplicate_region:

                        wxString region_url = server_url + wxString::FromUTF8(f->Attribute("Url"));

                        std::list<FaxUrl> urls;
                        std::list<FaxArea> Areas;

                        for(TiXmlElement* g = f->FirstChildElement(); g; g = g->NextSiblingElement()) {
                            if(!strcmp(g->Value(), "Iterator")) {
                                wxString s_start = wxString::FromUTF8(g->Attribute("From"));
                                wxString s_to = wxString::FromUTF8(g->Attribute("To"));
                                wxString s_by = wxString::FromUTF8(g->Attribute("By"));

                                if(s_start.size() == 0 || s_to.size() == 0 || s_by.size() == 0)
                                    FAIL(_("Invalid iterator: ") + wxString::FromUTF8(g->Value()));
                                
                                long start, to, by;
                                s_start.ToLong(&start);
                                s_to.ToLong(&to);
                                s_by.ToLong(&by);

                                for(TiXmlElement* h = g->FirstChildElement(); h; h = h->NextSiblingElement()) {
                                    if(!strcmp(h->Value(), "Map")) {
                                        FaxUrl url;
                                    
                                        url.Scheduled = false;
                                        url.Server = server.Name;
                                        url.Region = region.Name;
                         
                                        for(int index = start; index <= to; index += by) {
                                            wxString iurl = wxString::FromUTF8(h->Attribute("Url"));
                                            url.Url = region_url + wxString::Format
                                                (iurl, index);
                                            url.Contents = wxString::Format
                                                (wxString::FromUTF8(h->Attribute("Contents")), index);
                                            url.area_name = wxString::FromUTF8(h->Attribute("Area"));
                                        
                                            urls.push_back(url);
                                        }
                                    } else
                                        FAIL(_("Unrecognized xml node: ") + wxString::FromUTF8(g->Value()));
                                }
                            } else if(!strcmp(g->Value(), "Map")) {
                                FaxUrl url;
                                    
                                url.Scheduled = false;
                                url.Server = server.Name;
                                url.Region = region.Name;
                         
                                url.Url = region_url + wxString::FromUTF8(g->Attribute("Url"));
                                url.Contents = wxString::FromUTF8(g->Attribute("Contents"));
                                url.area_name = wxString::FromUTF8(g->Attribute("Area"));

                                urls.push_back(url);
                            } else if(!strcmp(g->Value(), "Area")) {
                                FaxArea Area;
                                Area.name = wxString::FromUTF8(g->Attribute("Name"));
                                Area.description = wxString::FromUTF8(g->Attribute("Description"));
                        
                                Area.lat1 = ParseLatLon(wxString::FromUTF8(g->Attribute("lat1")));
                                Area.lat2 = ParseLatLon(wxString::FromUTF8(g->Attribute("lat2")));
                                Area.lon1 = ParseLatLon(wxString::FromUTF8(g->Attribute("lon1")));
                                Area.lon2 = ParseLatLon(wxString::FromUTF8(g->Attribute("lon2")));

                                Areas.push_back(Area);
                            } else
                                FAIL(_("Unrecognized xml node: ") + wxString::FromUTF8(g->Value()));
                        }

                        for(std::list<FaxUrl>::iterator it = urls.begin();
                            it != urls.end(); it++) {
                            if((*it).area_name.size()) {
                                for(std::list<FaxArea>::iterator it2 = Areas.begin();
                                    it2 != Areas.end(); it2++)
                                    if((*it).area_name == (*it2).name) {
                                        (*it).Area = *it2;
                                        goto resolved;
                                    }
                                FAIL(_("Failed to match Area: ") + (*it).area_name);
                            }
                        resolved:
                            FaxUrl *s = new FaxUrl(*it);
                            m_InternetRetrieval.push_back(s);
                        }
                    } else
                        FAIL(_("Unrecognized xml node: ") + wxString::FromUTF8(f->Value()));
                }
            } else
                FAIL(_("Unrecognized xml node: ") + wxString::FromUTF8(e->Value()));
        }
    }

    delete progressdialog;
    return true;

failed:
    delete progressdialog;

    wxMessageDialog mdlg(this, error, _("Weather Fax"), wxOK | wxICON_ERROR);
    mdlg.ShowModal();

    return false;
}