void ConfigurationDialog::Update()
{
    if(m_bBlockUpdate)
        return;

    bool refresh = false;
    RouteMapConfiguration configuration;
    std::list<RouteMapOverlay*> currentroutemaps = m_WeatherRouting.CurrentRouteMaps();
    for(std::list<RouteMapOverlay*>::iterator it = currentroutemaps.begin();
        it != currentroutemaps.end(); it++) {

        configuration = (*it)->GetConfiguration();

        GET_CHOICE(Start);
        GET_CHOICE(End);

        if(NO_EDITED_CONTROLS || std::find(m_edited_controls.begin(), m_edited_controls.end(), (wxObject*)m_dpStartDate) != m_edited_controls.end()) {
            if(!m_dpStartDate->GetDateCtrlValue().IsValid())
                continue;
            // We must preserve the time in case only date but not time, is being changed by the user...
            // configuration.StartTime is UTC, m_dpStartDate Local or UTC so adjust  
            wxDateTime time = configuration.StartTime;
            if(m_WeatherRouting.m_SettingsDialog.m_cbUseLocalTime->GetValue())
                time = time.FromUTC();
            
            wxDateTime date = m_dpStartDate->GetDateCtrlValue();
            // ... and add it afterwards
            date.SetHour(time.GetHour());
            date.SetMinute(time.GetMinute());
            date.SetSecond(time.GetSecond());
            
            if(m_WeatherRouting.m_SettingsDialog.m_cbUseLocalTime->GetValue())
                date = date.ToUTC();
            
            configuration.StartTime = date;
            m_dpStartDate->SetForegroundColour(wxColour(0, 0, 0));
        }

        if(NO_EDITED_CONTROLS || std::find(m_edited_controls.begin(), m_edited_controls.end(), (wxObject*)m_tpTime) != m_edited_controls.end()) {
            // must use correct data on UTC conversion to preserve Daylight Savings Time changes across dates
            wxDateTime time = configuration.StartTime;
            if(m_WeatherRouting.m_SettingsDialog.m_cbUseLocalTime->GetValue())
                time = time.FromUTC();

            time.SetHour(m_tpTime->GetTimeCtrlValue().GetHour());
            time.SetMinute(m_tpTime->GetTimeCtrlValue().GetMinute());
            time.SetSecond(m_tpTime->GetTimeCtrlValue().GetSecond());

            if(m_WeatherRouting.m_SettingsDialog.m_cbUseLocalTime->GetValue())
                time = time.ToUTC();

            configuration.StartTime = time;
            m_tpTime->SetForegroundColour(wxColour(0, 0, 0));
        }

        if(!m_tBoat->GetValue().empty()) {
            configuration.boatFileName = m_tBoat->GetValue();
            m_tBoat->SetForegroundColour(wxColour(0, 0, 0));
        }

        if(NO_EDITED_CONTROLS || std::find(m_edited_controls.begin(), m_edited_controls.end(), (wxObject*)m_sTimeStepHours) != m_edited_controls.end() || std::find(m_edited_controls.begin(), m_edited_controls.end(), (wxObject*)m_sTimeStepMinutes) != m_edited_controls.end() || std::find(m_edited_controls.begin(), m_edited_controls.end(), (wxObject*)m_sTimeStepSeconds) != m_edited_controls.end()) {
            configuration.DeltaTime = 60*(60*m_sTimeStepHours->GetValue()
                                   + m_sTimeStepMinutes->GetValue())
                + m_sTimeStepSeconds->GetValue();
            m_sTimeStepHours->SetForegroundColour(wxColour(0, 0, 0));
            m_sTimeStepMinutes->SetForegroundColour(wxColour(0, 0, 0));
            m_sTimeStepSeconds->SetForegroundColour(wxColour(0, 0, 0));
        }

        if(m_cIntegrator->GetValue() == _T("Newton"))
            configuration.Integrator = RouteMapConfiguration::NEWTON;
        else if(m_cIntegrator->GetValue() == _T("Runge Kutta"))
            configuration.Integrator = RouteMapConfiguration::RUNGE_KUTTA;

        GET_SPIN(MaxDivertedCourse);
        GET_SPIN(MaxCourseAngle);
        GET_SPIN(MaxSearchAngle);
        GET_SPIN(MaxTrueWindKnots);
        GET_SPIN(MaxApparentWindKnots);

        GET_SPIN(MaxSwellMeters);
        GET_SPIN(MaxLatitude);
        GET_SPIN(TackingTime);
        GET_SPIN(WindVSCurrent);

        GET_CHECKBOX(AvoidCycloneTracks);
        GET_SPIN(CycloneMonths);
        GET_SPIN(CycloneDays);
        GET_SPIN(SafetyMarginLand);

        GET_CHECKBOX(DetectLand);
        GET_CHECKBOX(DetectBoundary);
        GET_CHECKBOX(Currents);
        GET_CHECKBOX(OptimizeTacking);
        
        GET_CHECKBOX(InvertedRegions);
        GET_CHECKBOX(Anchoring);

        GET_CHECKBOX(UseGrib);
        if(m_cClimatologyType->GetSelection() != -1)
            configuration.ClimatologyType = (RouteMapConfiguration::ClimatologyDataType)
                m_cClimatologyType->GetSelection();
        GET_CHECKBOX(AllowDataDeficient);
        if(m_sWindStrength->IsEnabled())                     \
            configuration.WindStrength = m_sWindStrength->GetValue() / 100.0;

        GET_SPIN(FromDegree);
        GET_SPIN(ToDegree);
        if(!m_tByDegrees->GetValue().empty())
            m_tByDegrees->GetValue().ToDouble(&configuration.ByDegrees);

        (*it)->SetConfiguration(configuration);

        /* if the start position changed, we must reset the route */
        RouteMapConfiguration newc = (*it)->GetConfiguration();
        if(newc.StartLat != configuration.StartLat || newc.StartLon != configuration.StartLon) {
            (*it)->Reset();
            refresh = true;
        } else if(newc.EndLat != configuration.EndLat || newc.EndLon != configuration.EndLon)
            refresh = true; // update drawing
    }

    double by;
    m_tByDegrees->GetValue().ToDouble(&by);
    if(m_sToDegree->GetValue() - m_sFromDegree->GetValue() < 2*by) {
        wxMessageDialog mdlg(this, _("Warning: less than 4 different degree steps specified\n"),
                             wxString(_("Weather Routing"), wxOK | wxICON_WARNING));
        mdlg.ShowModal();
    }

    m_WeatherRouting.UpdateCurrentConfigurations();

    if(refresh)
        m_WeatherRouting.GetParent()->Refresh();
}
void ConfigurationDialog::Update()
{
    if(m_bBlockUpdate)
        return;

    bool refresh = false;
    RouteMapConfiguration configuration;
    std::list<RouteMapOverlay*> currentroutemaps = m_WeatherRouting.CurrentRouteMaps();
    for(std::list<RouteMapOverlay*>::iterator it = currentroutemaps.begin();
        it != currentroutemaps.end(); it++) {

        configuration = (*it)->GetConfiguration();

        GET_CHOICE(Start);
        GET_CHOICE(End);

        if(m_dpStartDate->GetValue().IsValid())
            configuration.StartTime = m_dpStartDate->GetValue();

        if(!m_tStartHour->GetValue().empty()) {
            double hour;
            m_tStartHour->GetValue().ToDouble(&hour);
            configuration.StartTime.SetHour((int)hour);
            configuration.StartTime.SetMinute((int)(60*hour)%60);
        }

        if(m_WeatherRouting.m_SettingsDialog.m_cbUseLocalTime->GetValue())
            configuration.StartTime = configuration.StartTime.ToUTC();

        if(!m_tBoat->GetValue().empty())
            configuration.boatFileName = m_tBoat->GetValue();

        if(m_sTimeStepHours->IsEnabled()) {
            configuration.dt = 60*(60*m_sTimeStepHours->GetValue()
                                   + m_sTimeStepMinutes->GetValue())
                + m_sTimeStepSeconds->GetValue();
        }

        if(m_cIntegrator->GetValue() == _T("Newton"))
            configuration.Integrator = RouteMapConfiguration::NEWTON;
        else if(m_cIntegrator->GetValue() == _T("Runge Kutta"))
            configuration.Integrator = RouteMapConfiguration::RUNGE_KUTTA;

        GET_SPIN(MaxDivertedCourse);
        GET_SPIN(MaxCourseAngle);
        GET_SPIN(MaxSearchAngle);
        GET_SPIN(MaxTrueWindKnots);
        GET_SPIN(MaxApparentWindKnots);

        GET_SPIN(MaxSwellMeters);
        GET_SPIN(MaxLatitude);
        GET_SPIN(TackingTime);
        GET_SPIN(WindVSCurrent);

        GET_CHECKBOX(AvoidCycloneTracks);
        GET_SPIN(CycloneMonths);
        GET_SPIN(CycloneDays);

        GET_CHECKBOX(DetectLand);
        GET_CHECKBOX(Currents);
        GET_CHECKBOX(InvertedRegions);
        GET_CHECKBOX(Anchoring);

        GET_CHECKBOX(UseGrib);
        if(m_cClimatologyType->GetSelection() != -1)
            configuration.ClimatologyType = (RouteMapConfiguration::ClimatologyDataType)
                m_cClimatologyType->GetSelection();
        GET_CHECKBOX(AllowDataDeficient);
        if(m_sWindStrength->IsEnabled())                     \
            configuration.WindStrength = m_sWindStrength->GetValue() / 100.0;

        GET_SPIN(FromDegree);
        GET_SPIN(ToDegree);
        if(!m_tByDegrees->GetValue().empty())
            m_tByDegrees->GetValue().ToDouble(&configuration.ByDegrees);

        (*it)->SetConfiguration(configuration);

        /* if the start position changed, we must reset the route */
        RouteMapConfiguration newc = (*it)->GetConfiguration();
        if(newc.StartLat != configuration.StartLat || newc.StartLon != configuration.StartLon) {
            (*it)->Reset();
            refresh = true;
        } else if(newc.EndLat != configuration.EndLat || newc.EndLon != configuration.EndLon)
            refresh = true; // update drawing
    }

    double by;
    m_tByDegrees->GetValue().ToDouble(&by);
    if(m_sToDegree->GetValue() - m_sFromDegree->GetValue() < 2*by) {
        wxMessageDialog mdlg(this, _("Warning: less than 4 different degree steps specified\n"),
                             wxString(_("Weather Routing"), wxOK | wxICON_WARNING));
        mdlg.ShowModal();
    }

    m_WeatherRouting.UpdateCurrentConfigurations();

    if(refresh)
        m_WeatherRouting.GetParent()->Refresh();
}