public virtual void addGimnasticar(GimnasticarUcesnik g, RezultatskoTakmicenje rezTak,
                                           RezultatskoTakmicenje rezTak1, RezultatskoTakmicenje rezTak2)
        {
            RezultatUkupnoFinaleKupa rezultat = new RezultatUkupnoFinaleKupa();

            rezultat.Gimnasticar = g;

            foreach (RezultatUkupno r in rezTak1.Takmicenje1.PoredakUkupno.Rezultati)
            {
                if (r.Gimnasticar.Equals(g))
                {
                    rezultat.initPrvoKolo(r);
                    break;
                }
            }
            foreach (RezultatUkupno r in rezTak2.Takmicenje1.PoredakUkupno.Rezultati)
            {
                if (r.Gimnasticar.Equals(g))
                {
                    rezultat.initDrugoKolo(r);
                    break;
                }
            }
            rezultat.calculateTotal(rezTak.Propozicije.NacinRacunanjaOceneFinaleKupaTak2);
            Rezultati.Add(rezultat);
            rankRezultati(rezTak.Propozicije);
        }
        public virtual void deleteGimnasticar(GimnasticarUcesnik g, RezultatskoTakmicenje rezTak)
        {
            RezultatUkupnoFinaleKupa r = getRezultat(g);

            if (r != null)
            {
                Rezultati.Remove(r);
                rankRezultati(rezTak.Propozicije);
            }
        }
        public virtual void loadFromDump(StringReader reader, IdMap map)
        {
            DeoTakmicenjaKod = (DeoTakmicenjaKod)Enum.Parse(typeof(DeoTakmicenjaKod), reader.ReadLine());

            int brojRezultata = int.Parse(reader.ReadLine());

            for (int i = 0; i < brojRezultata; ++i)
            {
                reader.ReadLine();  // id
                RezultatUkupnoFinaleKupa r = new RezultatUkupnoFinaleKupa();
                r.loadFromDump(reader, map);
                Rezultati.Add(r);
            }
        }
        public virtual void create(RezultatskoTakmicenje rezTak, RezultatskoTakmicenje rezTak1,
                                   RezultatskoTakmicenje rezTak2)
        {
            // NOTE: Da bi GimnasticarUcesnik mogao da se koristi kao key u Dictionary, mora da implementira
            // interfejs IEquatable<GimnasticarUcesnik>.
            IDictionary <GimnasticarUcesnik, RezultatUkupnoFinaleKupa> rezultatiMap =
                new Dictionary <GimnasticarUcesnik, RezultatUkupnoFinaleKupa>();

            foreach (GimnasticarUcesnik g in rezTak.Takmicenje1.Gimnasticari)
            {
                RezultatUkupnoFinaleKupa rezultat = new RezultatUkupnoFinaleKupa();
                rezultat.Gimnasticar = g;
                rezultatiMap.Add(g, rezultat);
            }

            foreach (RezultatUkupno r in rezTak1.Takmicenje1.PoredakUkupno.Rezultati)
            {
                if (rezultatiMap.ContainsKey(r.Gimnasticar))
                {
                    rezultatiMap[r.Gimnasticar].initPrvoKolo(r);
                }
            }
            foreach (RezultatUkupno r in rezTak2.Takmicenje1.PoredakUkupno.Rezultati)
            {
                if (rezultatiMap.ContainsKey(r.Gimnasticar))
                {
                    rezultatiMap[r.Gimnasticar].initDrugoKolo(r);
                }
            }

            Rezultati.Clear();
            foreach (RezultatUkupnoFinaleKupa r in rezultatiMap.Values)
            {
                // Total moze da bude krajnja finalna ocena ili ulazna finalna ocena. U oba slucaja se Total izracunava
                // na isti nacin.
                r.calculateTotal(rezTak.Propozicije.NacinRacunanjaOceneFinaleKupaTak2);
                Rezultati.Add(r);
            }
            rankRezultati(rezTak.Propozicije);
        }
        public virtual void create(RezultatskoTakmicenje rezTak, PoredakUkupno poredakPrvoKolo,
            PoredakUkupno poredakDrugoKolo)
        {
            IList<GimnasticarUcesnik> gimnasticari = new List<GimnasticarUcesnik>(rezTak.Takmicenje1.Gimnasticari);

            // NOTE: Da bi GimnasticarUcesnik mogao da se koristi kao key u Dictionary, mora da implementira
            // interfejs IEquatable<GimnasticarUcesnik>.
            IDictionary<GimnasticarUcesnik, RezultatUkupnoFinaleKupa> rezultatiMap =
                new Dictionary<GimnasticarUcesnik, RezultatUkupnoFinaleKupa>();
            foreach (GimnasticarUcesnik g in gimnasticari)
            {
                RezultatUkupnoFinaleKupa rezultat = new RezultatUkupnoFinaleKupa();
                rezultat.Gimnasticar = g;
                rezultatiMap.Add(g, rezultat);
            }

            if (poredakPrvoKolo != null)
            {
                foreach (RezultatUkupno r in poredakPrvoKolo.Rezultati)
                {
                    if (rezultatiMap.ContainsKey(r.Gimnasticar))
                    {
                        rezultatiMap[r.Gimnasticar].ParterPrvoKolo = r.Parter;
                        rezultatiMap[r.Gimnasticar].KonjPrvoKolo = r.Konj;
                        rezultatiMap[r.Gimnasticar].KarikePrvoKolo = r.Karike;
                        rezultatiMap[r.Gimnasticar].PreskokPrvoKolo = r.Preskok;
                        rezultatiMap[r.Gimnasticar].RazbojPrvoKolo = r.Razboj;
                        rezultatiMap[r.Gimnasticar].VratiloPrvoKolo = r.Vratilo;
                        rezultatiMap[r.Gimnasticar].DvovisinskiRazbojPrvoKolo = r.DvovisinskiRazboj;
                        rezultatiMap[r.Gimnasticar].GredaPrvoKolo = r.Greda;
                        rezultatiMap[r.Gimnasticar].TotalPrvoKolo = r.Total;
                    }
                }
            }

            if (poredakDrugoKolo != null)
            {
                foreach (RezultatUkupno r in poredakDrugoKolo.Rezultati)
                {
                    if (rezultatiMap.ContainsKey(r.Gimnasticar))
                    {
                        rezultatiMap[r.Gimnasticar].ParterDrugoKolo = r.Parter;
                        rezultatiMap[r.Gimnasticar].KonjDrugoKolo = r.Konj;
                        rezultatiMap[r.Gimnasticar].KarikeDrugoKolo = r.Karike;
                        rezultatiMap[r.Gimnasticar].PreskokDrugoKolo = r.Preskok;
                        rezultatiMap[r.Gimnasticar].RazbojDrugoKolo = r.Razboj;
                        rezultatiMap[r.Gimnasticar].VratiloDrugoKolo = r.Vratilo;
                        rezultatiMap[r.Gimnasticar].DvovisinskiRazbojDrugoKolo = r.DvovisinskiRazboj;
                        rezultatiMap[r.Gimnasticar].GredaDrugoKolo = r.Greda;
                        rezultatiMap[r.Gimnasticar].TotalDrugoKolo = r.Total;
                    }
                }
            }

            List<RezultatUkupnoFinaleKupa> rezultati = new List<RezultatUkupnoFinaleKupa>(rezultatiMap.Values);
            Rezultati.Clear();
            foreach (RezultatUkupnoFinaleKupa rez in rezultati)
                Rezultati.Add(rez);

            // Total moze da bude krajnja finalna ocena ili ulazna finalna ocena. U oba slucaja se Total izracunava
            // na isti nacin.
            foreach (RezultatUkupnoFinaleKupa rez in Rezultati)
            {
                if (rez.TotalPrvoKolo == null && rez.TotalDrugoKolo == null)
                {
                    rez.setTotal(null);
                    continue;
                }
                float total1 = rez.TotalPrvoKolo == null ? 0 : rez.TotalPrvoKolo.Value;
                float total2 = rez.TotalDrugoKolo == null ? 0 : rez.TotalDrugoKolo.Value;
                float total;

                if (rezTak.Propozicije.Tak2FinalnaOcenaJeZbirObaKola)
                    total = total1 + total2;
                else if (rezTak.Propozicije.Tak2FinalnaOcenaJeMaxObaKola)
                    total = total1 > total2 ? total1 : total2;
                else
                {
                    // TODO3: Proveri da li ovde treba podesavati broj decimala.
                    total = (total1 + total2) / 2;
                    if (rezTak.Propozicije.Tak2NeRacunajProsekAkoNemaOceneIzObaKola
                        && (rez.TotalPrvoKolo == null || rez.TotalDrugoKolo == null))
                    {
                        total = total1 + total2;
                    }
                }
                rez.setTotal(total);
            }

            rankRezultati();
            if (rezTak.Propozicije.OdvojenoTak2)
                updateKvalStatus(rezTak.Propozicije.BrojFinalistaTak2,
                                 rezTak.Propozicije.NeogranicenBrojTakmicaraIzKlubaTak2,
                                 rezTak.Propozicije.MaxBrojTakmicaraIzKlubaTak2,
                                 rezTak.Propozicije.BrojRezerviTak2);
        }
        private void updateKvalStatus(Propozicije propozicije)
        {
            if (!propozicije.odvojenoTak2())
            {
                foreach (RezultatUkupnoFinaleKupa r in Rezultati)
                {
                    r.KvalStatus = KvalifikacioniStatus.None;
                }
                return;
            }

            List <RezultatUkupnoFinaleKupa> rezultati = new List <RezultatUkupnoFinaleKupa>(Rezultati);
            PropertyDescriptor propDesc =
                TypeDescriptor.GetProperties(typeof(RezultatUkupnoFinaleKupa))["RedBroj"];

            rezultati.Sort(new SortComparer <RezultatUkupnoFinaleKupa>(propDesc,
                                                                       ListSortDirection.Ascending));

            // moram da koristim dve mape zato sto je moguca situacija da klub i
            // drzava imaju isti id
            IDictionary <int, int> brojTakmicaraKlubMap   = new Dictionary <int, int>();
            IDictionary <int, int> brojTakmicaraDrzavaMap = new Dictionary <int, int>();

            int finCount = 0;
            int rezCount = 0;

            for (int i = 0; i < rezultati.Count; i++)
            {
                RezultatUkupnoFinaleKupa rezultat = rezultati[i];
                if (rezultat.Total == null)
                {
                    rezultat.KvalStatus = KvalifikacioniStatus.None;
                    continue;
                }

                int id;
                IDictionary <int, int> brojTakmicaraMap;

                if (rezultat.Gimnasticar.KlubUcesnik != null)
                {
                    id = rezultat.Gimnasticar.KlubUcesnik.Id;
                    brojTakmicaraMap = brojTakmicaraKlubMap;
                }
                else
                {
                    id = rezultat.Gimnasticar.DrzavaUcesnik.Id;
                    brojTakmicaraMap = brojTakmicaraDrzavaMap;
                }

                if (!brojTakmicaraMap.ContainsKey(id))
                {
                    brojTakmicaraMap.Add(id, 0);
                }

                if (finCount < propozicije.BrojFinalistaTak2)
                {
                    if (propozicije.NeogranicenBrojTakmicaraIzKlubaTak2)
                    {
                        finCount++;
                        rezultat.KvalStatus = KvalifikacioniStatus.Q;
                    }
                    else
                    {
                        if (brojTakmicaraMap[id] < propozicije.MaxBrojTakmicaraIzKlubaTak2)
                        {
                            finCount++;
                            brojTakmicaraMap[id]++;
                            rezultat.KvalStatus = KvalifikacioniStatus.Q;
                        }
                        else
                        {
                            if (Opcije.Instance.UzimajPrvuSlobodnuRezervu &&
                                rezCount < propozicije.BrojRezerviTak2)
                            {
                                rezCount++;
                                rezultat.KvalStatus = KvalifikacioniStatus.R;
                            }
                            else
                            {
                                rezultat.KvalStatus = KvalifikacioniStatus.None;
                            }
                        }
                    }
                }
                else if (rezCount < propozicije.BrojRezerviTak2)
                {
                    if (propozicije.NeogranicenBrojTakmicaraIzKlubaTak2)
                    {
                        rezCount++;
                        rezultat.KvalStatus = KvalifikacioniStatus.R;
                    }
                    else
                    {
                        if (brojTakmicaraMap[id] < propozicije.MaxBrojTakmicaraIzKlubaTak2)
                        {
                            rezCount++;
                            brojTakmicaraMap[id]++;
                            rezultat.KvalStatus = KvalifikacioniStatus.R;
                        }
                        else
                        {
                            if (Opcije.Instance.UzimajPrvuSlobodnuRezervu &&
                                rezCount < propozicije.BrojRezerviTak2)
                            {
                                rezCount++;
                                rezultat.KvalStatus = KvalifikacioniStatus.R;
                            }
                            else
                            {
                                rezultat.KvalStatus = KvalifikacioniStatus.None;
                            }
                        }
                    }
                }
                else
                {
                    rezultat.KvalStatus = KvalifikacioniStatus.None;
                }
            }
        }