Ejemplo n.º 1
0
 private GameState()
 {
     currencyState = new CurrencyState();
     merchState = new MerchState();
     concertState = new ConcertState();
     equipmentState = new EquipmentState();
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Computes the overall currency
        /// </summary>
        public void RefreshCurrency()
        {
            // Compute currency according to 61.57(c)(6) ( => (c)(3)) (i) and (ii) including each one's expiration.

            if (m_fCacheValid)
            {
                return;
            }

            // 61.57(c)(6)(i) => (c)(3)(i) -  no passengers.  IPC covers this.
            FlightCurrency fc6157c6i = fcGliderIFRTime.AND(fcGliderInstrumentManeuvers).OR(fcGliderIPC);

            // 61.57(c)(6)(ii) => (c)(3)(ii) -  passengers.  Above + two more.  Again, IPC covers this too.
            FlightCurrency fc6157c6ii = fc6157c6i.AND(fcGliderIFRTimePassengers).AND(fcGliderInstrumentPassengers).OR(fcGliderIPC);

            m_fCurrentSolo       = fc6157c6i.IsCurrent();
            m_fCurrentPassengers = fc6157c6ii.IsCurrent();

            if (m_fCurrentSolo || m_fCurrentPassengers)
            {
                if (m_fCurrentPassengers)
                {
                    m_csCurrent     = fc6157c6ii.CurrentState;
                    m_dtExpiration  = fc6157c6ii.ExpirationDate;
                    m_szDiscrepancy = fc6157c6ii.DiscrepancyString;
                }
                else // must be current solo)
                {
                    m_csCurrent     = fc6157c6i.CurrentState;
                    m_dtExpiration  = fc6157c6i.ExpirationDate;
                    m_szDiscrepancy = fc6157c6i.DiscrepancyString;
                }

                // check to see if there is an embedded gap that needs an IPC
                CurrencyPeriod[] rgcpMissingIPC = fc6157c6i.FindCurrencyGap(fcGliderIPC.MostRecentEventDate, 6);
                if (rgcpMissingIPC != null && m_szDiscrepancy.Length == 0)
                {
                    m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.IPCMayBeRequired, rgcpMissingIPC[0].EndDate.ToShortDateString(), rgcpMissingIPC[1].StartDate.ToShortDateString());
                }
            }
            else
            {
                // And expiration date is the later of the passenger/no-passenger date
                m_dtExpiration = fc6157c6i.ExpirationDate.LaterDate(fc6157c6ii.ExpirationDate);

                // see if we need an IPC
                // if more than 6 calendar months have passed since expiration, an IPC is required.
                // otherwise, just name the one that is short
                if (DateTime.Compare(m_dtExpiration.AddCalendarMonths(6).Date, DateTime.Now.Date) > 0)
                {
                    m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateGliderIFRPassengers, fcGliderIFRTime.Discrepancy, fcGliderInstrumentManeuvers.Discrepancy);
                }
                else
                {
                    m_szDiscrepancy = Resources.Currency.IPCRequired;
                }
            }

            m_fCacheValid = true;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Return the currency status for all of the user's current deadlines.
        /// </summary>
        /// <param name="szUser">The user</param>
        /// <param name="daysForWarning">How many days to use for "getting close"</param>
        /// <returns></returns>
        public static IEnumerable <CurrencyStatusItem> CurrencyForUser(string szUser, int daysForWarning = 30)
        {
            List <CurrencyStatusItem>      lst       = new List <CurrencyStatusItem>();
            IEnumerable <DeadlineCurrency> deadlines = DeadlinesForUser(szUser);

            foreach (DeadlineCurrency dc in deadlines)
            {
                string szLabel = dc.AircraftID > 0 ? String.Format(CultureInfo.CurrentCulture, "{0} - {1}", dc.TailNumber, dc.Name) : dc.Name;

                if (dc.UsesHours)
                {
                    lst.Add(new CurrencyStatusItem(szLabel, dc.AircraftHours.ToString("#,##0.0#", CultureInfo.CurrentCulture), CurrencyState.NoDate, string.Empty)
                    {
                        AssociatedResourceID = dc.AircraftID, CurrencyGroup = CurrencyStatusItem.CurrencyGroups.Deadline
                    });
                }
                else if (dc.Expiration.HasValue())
                {
                    TimeSpan      ts   = dc.Expiration.Subtract(DateTime.Now);
                    int           days = (int)Math.Ceiling(ts.TotalDays);
                    CurrencyState cs   = (ts.Days < 0) ? CurrencyState.NotCurrent : ((days < daysForWarning) ? CurrencyState.GettingClose : CurrencyState.OK);
                    lst.Add(new CurrencyStatusItem(szLabel, dc.Expiration.ToShortDateString(), cs, cs == CurrencyState.GettingClose ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.ProfileCurrencyStatusClose, days) :
                                                   (cs == CurrencyState.NotCurrent) ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.ProfileCurrencyStatusNotCurrent, -days) : string.Empty)
                    {
                        AssociatedResourceID = dc.AircraftID, CurrencyGroup = CurrencyStatusItem.CurrencyGroups.Deadline
                    });
                }
            }
            return(lst);
        }
Ejemplo n.º 4
0
    protected override void LoadData(MemoryStream ms)
    {
        IFormatter formatter = new BinaryFormatter();
        GameState gd = (GameState)formatter.Deserialize(ms);

        this.tourState = gd.tourState == null ? new TourState() : gd.tourState;
        this.currencyState = gd.currencyState == null ? new CurrencyState() : gd.currencyState;
    }
Ejemplo n.º 5
0
    protected override void LoadData(MemoryStream ms)
    {
        IFormatter formatter = new BinaryFormatter();
        GameState  gd        = (GameState)formatter.Deserialize(ms);

        this.tourState     = gd.tourState == null ? new TourState() : gd.tourState;
        this.currencyState = gd.currencyState == null ? new CurrencyState() : gd.currencyState;
    }
Ejemplo n.º 6
0
    void Awake()
    {
        songController = (SongController)FindObjectOfType (typeof(SongController));
        concertController = (ConcertController)FindObjectOfType (typeof(ConcertController));
        tourController = (TourController)FindObjectOfType(typeof(TourController));
        merchController = (MerchController)FindObjectOfType(typeof(MerchController));
        equipmentController = (EquipmentController)FindObjectOfType(typeof(EquipmentController));
        hudUI = (HudUI)FindObjectOfType(typeof(HudUI));

        currencyState = GameState.instance.Currency;
    }
Ejemplo n.º 7
0
        private void RefreshCurrency()
        {
            if (m_fCacheValid)
            {
                return;
            }

            // Compute both loose (ignores takeoffs) and strict (requires takeoffs) night currencies.
            // Discrepancy can't be counted on after AND/OR so we set that to the one we wish to expose
            FlightCurrency fc6157b    = this; // just for clarity that the "this" object does the basic 61.57(b) implementation.
            FlightCurrency fc6157e4i  = m_fc6157eTotalTime.AND(m_fc6157Passenger).AND(m_fc6157TimeInType).AND(m_fc6157ei);
            FlightCurrency fc6157e4ii = m_fc6157eTotalTime.AND(m_fc6157Passenger).AND(m_fc6157TimeInType).AND(m_fc6157eii);
            FlightCurrency fcLoose    = fc6157b.OR(fc6157e4i.OR(fc6157e4ii));

            fcLoose.Discrepancy = fc6157b.Discrepancy;

            FlightCurrency fc6157bStrict    = fc6157b.AND(NightTakeoffCurrency);
            FlightCurrency fc6157e4iStrict  = fc6157e4i.AND(m_fc6157eiTakeoffs);
            FlightCurrency fc6157e4iiStrict = fc6157e4ii.AND(m_fc6157eiiTakeoffs);
            FlightCurrency fcStrict         = fc6157bStrict.OR(fc6157e4iStrict).OR(fc6157e4iiStrict);

            // Loose rules for purposes of determining state
            m_csCurrent     = fcLoose.CurrentState;
            m_dtExpiration  = fcLoose.ExpirationDate;
            m_szDiscrepancy = fcLoose.DiscrepancyString;

            // determine the correct discrepancy string to show
            // if we've met the strict definition, we're fine - no discrepancy
            if (fcStrict.CurrentState.IsCurrent())
            {
                m_szDiscrepancy = string.Empty;
                m_dtExpiration  = fcStrict.ExpirationDate;
            }
            // else if we met the loose definition but not strict - meaning takeoffs were not found; Give a reminder about required takeoffs
            else if (m_csCurrent.IsCurrent())
            {
                if (NightTakeoffCurrency.Discrepancy >= NightTakeoffCurrency.RequiredEvents)
                {
                    m_szDiscrepancy = Resources.Currency.NightTakeoffReminder;
                }
                else
                {
                    m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateNight, NightTakeoffCurrency.Discrepancy, (NightTakeoffCurrency.Discrepancy > 1) ? Resources.Currency.Takeoffs : Resources.Currency.Takeoff);
                }
            }
            // else we aren't current at all - use the full discrepancy template using 61.57(b).  DON'T CALL DISCREPANCY STRING because that causes an infinite recursion.
            else
            {
                m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplate, this.Discrepancy, (this.Discrepancy > 1) ? Resources.Totals.Landings : Resources.Totals.Landing);
            }

            m_fCacheValid = true;
        }
        protected string CSSForItem(CurrencyState cs)
        {
            switch (cs)
            {
            case CurrencyState.GettingClose:
                return("currencynearlydue");

            case CurrencyState.NotCurrent:
                return("currencyexpired");

            case CurrencyState.OK:
                return("currencyok");
            }
            return(string.Empty);
        }
Ejemplo n.º 9
0
 private static CurrencyStatusItem StatusForDate(DateTime dt, string szLabel, CurrencyStatusItem.CurrencyGroups rt)
 {
     if (dt.CompareTo(DateTime.MinValue) != 0)
     {
         TimeSpan      ts   = dt.Subtract(DateTime.Now);
         int           days = (int)Math.Ceiling(ts.TotalDays);
         CurrencyState cs   = (days < 0) ? CurrencyState.NotCurrent : ((ts.Days < 30) ? CurrencyState.GettingClose : CurrencyState.OK);
         return(new CurrencyStatusItem(szLabel, CurrencyExaminer.StatusDisplayForDate(dt), cs, (cs == CurrencyState.GettingClose) ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.ProfileCurrencyStatusClose, days) :
                                       (cs == CurrencyState.NotCurrent) ? String.Format(CultureInfo.CurrentCulture, Resources.Profile.ProfileCurrencyStatusNotCurrent, -days) : string.Empty)
         {
             CurrencyGroup = rt
         });
     }
     else
     {
         return(null);
     }
 }
Ejemplo n.º 10
0
    protected string CSSForItem(CurrencyState cs)
    {
        switch (cs)
        {
        case CurrencyState.GettingClose:
            return(CssCurrencyNearlyDue);

        case CurrencyState.NotCurrent:
            return(CssNotCurrent);

        case CurrencyState.OK:
            return(CssOK);

        case CurrencyState.NoDate:
            return(CssCurrencyNoDate);
        }
        return(string.Empty);
    }
Ejemplo n.º 11
0
        private void RefreshCurrency()
        {
            if (m_fCacheValid)
            {
                return;
            }

            // 401.05(3)(a)-(c) say you have an IPC OR 6approaches+6hours OR 6approaches+6hours instructing.
            FlightCurrency fcIFRCanada = fc401_05_3_a.OR(fc401_05_3_bTime.AND(fc401_05_3_bApproaches)).OR(fc401_05_3_cTime.AND(fc401_05_3_cApproaches));

            m_csCurrent    = fcIFRCanada.CurrentState;
            m_dtExpiration = fcIFRCanada.ExpirationDate;
            if (m_csCurrent == CurrencyState.NotCurrent)
            {
                m_szDiscrepancy = Resources.Currency.IPCRequired;
            }

            m_fCacheValid = true;
        }
Ejemplo n.º 12
0
        public IEnumerable <CurrencyStatusItem> CurrencyForUser()
        {
            List <CurrencyStatusItem> rgCS = new List <CurrencyStatusItem>();

            IEnumerable <CurrencyStatusItem> lstMedicals = MedicalStatus();
            CurrencyStatusItem csBasicMed = new BasicMed(CurrentUser.UserName).Status;

            /* Scenarios for combining regular medical and basicmed.
             *
             *   +--------------------+--------------------+--------------------+--------------------+
             *   |\_____    Medical   |                    |                    |                    |
             *   |      \______       |   Never Current    |     Expired        |      Valid         |
             *   | BasicMed    \_____ |                    |                    |                    |
             *   +--------------------+--------------------+--------------------+--------------------+
             *   |  Never Current     |    Show Nothing    |   Show Expired     |    Show Valid      |
             *   |                    |                    |     Medical        |     Medical        |
             *   +--------------------+--------------------+--------------------+--------------------+
             *   |      Expired       |        N/A         |   Show Expired     | Show Valid Medical |
             *   |                    |                    | Medical, BasicMed  | Suppress BasicMed  |
             *   +--------------------+--------------------+--------------------+--------------------+
             *   |                    |                    |    Show Valid      |    Show Valid      |
             *   |       Valid        |        N/A         |   BasicMed, note   |   Medical, show    |
             *   |                    |                    |    BasicMed only   |   BasicMed too     |
             *   +--------------------+--------------------+--------------------+--------------------+
             *
             *
             * a) Medical has never been valid -> by definition, neither has basic med: NO STATUS
             * b) Medical expired
             *      1) BasicMed never valid -> show only expired medical
             *      2) BasicMed expired -> show expired medical, expired basicmed (so you can tell which is easier to renew)
             *      3) BasicMed is valid -> Show valid BasicMed, that you are ONLY basicmed
             * c) Medical valid:
             *      1) BasicMed never valid -> Show only valid medical
             *      2) BasicMed expired -> show valid medical don't bother showing the expired basicmed since it's kinda pointless
             *      3) BasicMed is still valid -> show both (hey, seeing green is good)
             */

            if (lstMedicals.Any())      // (a) above - i.e., left column of chart; nothing to add if never had valid medical
            {
                if (csBasicMed == null) // b.1 and c.1 above, i.e., top row of chart - Just show medical status
                {
                    rgCS.AddRange(lstMedicals);
                }
                else
                {
                    CurrencyState state = CurrencyState.NotCurrent;

                    foreach (CurrencyStatusItem cs in lstMedicals)
                    {
                        state = (CurrencyState)Math.Max((int)state, (int)cs.Status);
                    }
                    switch (state)
                    {
                    case CurrencyState.OK:
                    case CurrencyState.GettingClose:
                        // Medical valid - c.2 and c.3 above - show medical, show basic med if valid
                        rgCS.AddRange(lstMedicals);
                        if (csBasicMed.Status != CurrencyState.NotCurrent)
                        {
                            rgCS.Add(csBasicMed);
                        }
                        break;

                    case CurrencyState.NotCurrent:
                        // Medical is not current but basicmed has been - always show basicmed, show medical only if basicmed is also expired
                        rgCS.Add(csBasicMed);
                        if (csBasicMed.Status == CurrencyState.NotCurrent)
                        {
                            rgCS.AddRange(lstMedicals);
                        }
                        break;
                    }
                }
            }

            BFREvents = null; // clear the cache - but this will let the next three calls (LastBFR/LastBFRR22/LastBFRR44) hit the DB only once.
            DateTime dtBfrLast = LastBFR();

            if (dtBfrLast.HasValue())
            {
                rgCS.Add(StatusForDate(NextBFR(dtBfrLast), Resources.Currency.NextFlightReview, CurrencyStatusItem.CurrencyGroups.FlightReview));
            }

            BFREvents = null; // clear the cache again (memory).

            if (CurrentUser.CertificateExpiration.HasValue())
            {
                rgCS.Add(StatusForDate(CurrentUser.CertificateExpiration, Resources.Currency.CertificateExpiration, CurrencyStatusItem.CurrencyGroups.Certificates));
            }

            if (CurrentUser.EnglishProficiencyExpiration.HasValue())
            {
                rgCS.Add(StatusForDate(CurrentUser.EnglishProficiencyExpiration, Resources.Currency.NextLanguageProficiency, CurrencyStatusItem.CurrencyGroups.Certificates));
            }

            return(rgCS);
        }
Ejemplo n.º 13
0
    protected override void LoadData(MemoryStream ms)
    {
        IFormatter formatter = new BinaryFormatter();
        GameState gd = (GameState)formatter.Deserialize(ms);

        this.currencyState = gd.currencyState == null ? new CurrencyState() : gd.currencyState;
        this.merchState = gd.merchState == null ? new MerchState() : gd.merchState;
        this.concertState = gd.concertState == null ? new ConcertState() : gd.concertState;
        this.equipmentState = gd.equipmentState == null ? new EquipmentState() : gd.equipmentState;

        this.currencyState.SynchronizeRealCurrencyAndScreenCurrency();
    }
Ejemplo n.º 14
0
 /// <summary>
 /// Determines if the currency state is any of the current states.
 /// </summary>
 /// <param name="cs"></param>
 /// <returns></returns>
 public static bool IsCurrent(this CurrencyState cs)
 {
     return(cs != CurrencyState.NotCurrent);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Computes the overall currency - DEPRECATED
        /// </summary>
        public void RefreshCurrencyOLD()
        {
            // Compute currency according to 61.57(c)(6) (i) and (ii)  => (c)(3) including each one's expiration.

            if (m_fCacheValid)
            {
                return;
            }

            m_szDiscrepancy = string.Empty;
            m_csCurrent     = CurrencyState.NotCurrent;
            m_dtExpiration  = DateTime.MinValue;

            DateTime dtExpirationSolo;
            DateTime dtExpirationPassengers;

            // 61.57(c)(6)(i)  => (c)(3)(i) - basic instrument currency
            if (fcGliderIFRTime.HasBeenCurrent && fcGliderInstrumentManeuvers.HasBeenCurrent)
            {
                // find the earliest expiration
                DateTime dtExpIFRTime = fcGliderIFRTime.ExpirationDate;
                DateTime dtExpInstMan = fcGliderInstrumentManeuvers.ExpirationDate;

                dtExpirationSolo = dtExpIFRTime;
                dtExpirationSolo = dtExpInstMan.EarlierDate(dtExpirationSolo);
                m_dtExpiration   = dtExpirationSolo;

                m_csCurrent = FlightCurrency.IsAlmostCurrent(m_dtExpiration) ? CurrencyState.GettingClose :
                              (FlightCurrency.IsCurrent(m_dtExpiration) ? CurrencyState.OK : CurrencyState.NotCurrent);

                m_fCurrentSolo = (m_csCurrent != CurrencyState.NotCurrent);

                // at this point we've determined if you're current for solo (61.57(c)(6)(i))  => (c)(3)(i); now see if we can carry passengers
                if (m_fCurrentSolo && fcGliderIFRTimePassengers.HasBeenCurrent && fcGliderInstrumentPassengers.HasBeenCurrent)
                {
                    DateTime dtExpIFRTimePassengers = fcGliderIFRTimePassengers.ExpirationDate;
                    DateTime dtExpIFRPassengers     = fcGliderInstrumentPassengers.ExpirationDate;

                    dtExpirationPassengers = dtExpIFRTimePassengers.EarlierDate(dtExpIFRPassengers);

                    CurrencyState csPassengers = FlightCurrency.IsAlmostCurrent(dtExpirationPassengers) ? CurrencyState.GettingClose :
                                                 (FlightCurrency.IsCurrent(dtExpirationPassengers) ? CurrencyState.OK : CurrencyState.NotCurrent);

                    // if current for passengers, then we are the more restrictive of overall close to losing currency or fully current.
                    if (m_fCurrentPassengers = (csPassengers != CurrencyState.NotCurrent))
                    {
                        m_csCurrent    = (m_csCurrent == CurrencyState.OK && csPassengers == CurrencyState.OK) ? CurrencyState.OK : CurrencyState.GettingClose;
                        m_dtExpiration = dtExpirationPassengers.EarlierDate(dtExpirationSolo);
                    }
                }
            }

            // IPC can also set currency.
            if (fcGliderIPC.HasBeenCurrent)
            {
                // set currency to the most permissive of either current state or IPC state
                m_csCurrent = (fcGliderIPC.CurrentState > m_csCurrent) ? fcGliderIPC.CurrentState : m_csCurrent;

                // Expiration date is the LATER of the current expiration date OR the IPC expiration date, with one exception below.
                m_dtExpiration = fcGliderIPC.ExpirationDate.LaterDate(m_dtExpiration);

                // if you have a valid IPC, you are currently valid for both passengers and solo.
                // however, IPC could expire before the solo requirements expire, so if it is the
                // IPC that is driving passengers, use the IPC date as the expiration date.  Otherwise, use the later one.
                // That way, when the IPC expires, your passenger privs expire too, so you'll see a new "no passengers" priv remaining
                // with a new date.
                if (fcGliderIPC.IsCurrent())
                {
                    if (m_fCurrentSolo && !m_fCurrentPassengers)
                    {
                        m_dtExpiration = fcGliderIPC.ExpirationDate;
                    }
                    m_fCurrentPassengers = m_fCurrentSolo = true;
                }
            }

            m_fCacheValid = true;
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Computes the overall currency
        /// </summary>
        protected void RefreshCurrency()
        {
            // Compute currency according to 61.57(c)(1)-(5) and 61.57(e)
            // including each one's expiration.  The one that expires latest is the expiration date if you are current, the one that
            // expired most recently is the expiration date since when you were not current.

            if (m_fCacheValid)
            {
                return;
            }

            // This is ((61.57(c)(1) OR (2) OR (3) OR (4) OR (5) OR 61.57(e)), each of which is the AND of several currencies.

            // 61.57(c)(1) (66-HIT in airplane)
            FlightCurrency fc6157c1 = fcIFRApproach.AND(fcIFRHold);

            // 61.57(c)(2) (66-HIT in an FTD or flight simulator)
            FlightCurrency fc6157c2 = fcFTDApproach.AND(fcFTDHold);

            // 61.57(c)(3) - ATD
            FlightCurrency fc6157c3 = fcATDHold.AND(fcATDApproach).AND(fcUnusualAttitudesAsc).AND(fcUnusualAttitudesDesc).AND(fcInstrumentHours);

            // 61.57(c)(4) - Combo STRICT - 6 approaches/hold in an ATD PLUS an approach/hold in an airplane PLUS an approach/hold in an FTD
            FlightCurrency fc6157c4 = fcATDAppch6Month.AND(fcATDHold6Month).AND(fcIFRHold).AND(fcAirplaneApproach6Month).AND(fcFTDApproach6Month).AND(fcFTDHold);

            // 61.57(c)(4) - Combo LOOSE - any combination that yields 66-HIT, but require at least one aircraft approach and hold.
            // FlightCurrency fc6157c4Loose = fcComboApproach6Month.AND(fcAirplaneApproach6Month).AND(fcIFRHold.OR(fcATDHold6Month).OR(fcFTDHold));

            // 61.57(c)(5) - combo meal, but seems redundant with (c)(2)/(3).  I.e., if you've met this, you've met (2) or (3).

            // 61.57 (e) - IPC; no need to AND anything together for this one.

            FlightCurrency fcIFR = fc6157c1.OR(fc6157c2).OR(fc6157c3).OR(fc6157c4).OR(fcIPCOrCheckride);

            /*
             * if (m_fUseLoose6157c4)
             *  fcIFR = fcIFR.OR(fc6157c4Loose);
             */

            m_csCurrent    = fcIFR.CurrentState;
            m_dtExpiration = fcIFR.ExpirationDate;

            if (fcIPCOrCheckride.IsCurrent() && fcIPCOrCheckride.ExpirationDate.CompareTo(m_dtExpiration) >= 0)
            {
                Query.HasHolds = Query.HasApproaches = false;
                Query.PropertiesConjunction = GroupConjunction.Any;
                Query.PropertyTypes.Clear();
                foreach (CustomPropertyType cpt in CustomPropertyType.GetCustomPropertyTypes())
                {
                    if (cpt.IsIPC)
                    {
                        Query.PropertyTypes.Add(cpt);
                    }
                }
            }

            if (m_csCurrent == CurrencyState.NotCurrent)
            {
                // if more than 6 calendar months have passed since expiration, an IPC is required.
                // otherwise, just assume 66-HIT.
                if (DateTime.Compare(m_dtExpiration.AddCalendarMonths(6).Date, DateTime.Now.Date) > 0)
                {
                    m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.DiscrepancyTemplateIFR,
                                                    fcIFRHold.Discrepancy,
                                                    (fcIFRHold.Discrepancy == 1) ? Resources.Currency.Hold : Resources.Currency.Holds,
                                                    fcIFRApproach.Discrepancy,
                                                    (fcIFRApproach.Discrepancy == 1) ? Resources.Totals.Approach : Resources.Totals.Approaches);
                }
                else
                {
                    m_szDiscrepancy = Resources.Currency.IPCRequired;
                }
            }
            else
            {
                // Check to see if IPC is required by looking for > 6 month gap in IFR currency.
                // For now, we won't make you un-current, but we'll warn.
                // (IPC above, though, is un-current).
                CurrencyPeriod[] rgcpMissingIPC = fcIFR.FindCurrencyGap(fcIPCOrCheckride.MostRecentEventDate, 6);

                if (rgcpMissingIPC != null)
                {
                    m_szDiscrepancy = String.Format(CultureInfo.CurrentCulture, Resources.Currency.IPCMayBeRequired, rgcpMissingIPC[0].EndDate.ToShortDateString(), rgcpMissingIPC[1].StartDate.ToShortDateString());
                }
                else
                {
                    m_szDiscrepancy = string.Empty;
                }
            }

            m_fCacheValid = true;
        }