private void menuItemAddSys_Click(object sender, EventArgs e = null)
        {
            string system; DataGridViewRow clickedRow; if (!menuItem_GetActionInfo(sender, out system, out clickedRow))

            {
                return;
            }

            try
            {
                string systems = clickedRow.Cells[colValidFor.Name].Value == null ? string.Empty : clickedRow.Cells[colValidFor.Name].Value.ToString();
                if (!dgvRates.SetCellValue(clickedRow, colValidFor.Name, ExchangeRate.AddToValidFor(systems, system)))
                {
                    ShowGridLastError();
                }
            }
            catch (Exception exception) { UserInfoHandler.ShowException(exception); }
        }
        internal bool HasDifferences() // find out whether there are differences, if not the dialog does not need to be shown
        {                              // at the same time prepare dialog (for the case that there are differences)
            // remove all 'questionable systems' (systems for which exchange-rate differs) from ratesGlobal
            // and put them into the data-grid (for further treatment by the user)
            // also add exchange-rates from ratesCountry which do not (yet) exist in ratesGlobal to the data-grid
            foreach (ExchangeRate rateCountry in ratesCountry)
            {
                foreach (string system in rateCountry.ValidForToList())
                {
                    ExchangeRate matchingGlobal = null;
                    foreach (ExchangeRate rateGlobal in ratesGlobal)
                    {
                        if (rateCountry.Country.ToLower() != rateGlobal.Country.ToLower())
                        {
                            continue;
                        }
                        if (!rateGlobal.ValidForToList().Contains(system))
                        {
                            continue;
                        }
                        matchingGlobal = rateGlobal; break;
                    }
                    if (matchingGlobal != null && matchingGlobal.DefaultRate() == rateCountry.DefaultRate())
                    {
                        continue;               // exchange-rate exists and is equal
                    }
                    if (matchingGlobal == null) // exchange-rate does not (yet) exist in global table
                    {
                        if (rateCountry.DefaultRate() == 1)
                        {
                            continue;                                 // euro-country
                        }
                        int iRow = dgvDiff.Rows.Add(rateCountry.Country, system, rateCountry.DefaultRate(), "n/a",
                                                    true, false, ExchangeRate.JUNE30, "Rate does not (yet) exist in global table.");
                        DataGridViewCheckBoxCell check = dgvDiff.Rows[iRow].Cells[colTakeGlobal.Index] as DataGridViewCheckBoxCell;
                        check.ReadOnly = true; check.Style.BackColor = Color.LightGray;
                    }
                    else // exchange-rate exists, but is different
                    {
                        string hint = string.Empty;
                        if (matchingGlobal.June30 == rateCountry.DefaultRate())
                        {
                            hint = ExchangeRate.JUNE30;
                        }
                        else if (matchingGlobal.YearAverage == rateCountry.DefaultRate())
                        {
                            hint = ExchangeRate.YEARAVERAGE;
                        }
                        else if (matchingGlobal.FirstSemester == rateCountry.DefaultRate())
                        {
                            hint = ExchangeRate.FIRSTSEMESTER;
                        }
                        else if (matchingGlobal.SecondSemester == rateCountry.DefaultRate())
                        {
                            hint = ExchangeRate.SECONDSEMESTER;
                        }
                        if (hint != string.Empty)
                        {
                            hint = string.Format("Country exchange rate matches with global table '{0}': consider changing 'Rate Type'.", hint);
                        }

                        int iRow = dgvDiff.Rows.Add(matchingGlobal.Country, system, rateCountry.DefaultRate(), matchingGlobal.DefaultRate(),
                                                    false, true, matchingGlobal.Default, hint);
                        dgvDiff.Rows[iRow].Tag = matchingGlobal;
                        matchingGlobal.RemoveFromValidFor(system); // remove the system (to add on OK in the way user choses)
                    }
                }
            }
            return(dgvDiff.Rows.Count > 0);
        }
        private void btnOK_Click(object sender, EventArgs e)
        {
            try
            {
                // first overtake all current rows of the global table and check if they need adaptation due to grid-view-entries ...
                List <int> done = new List <int>();
                Dictionary <string, List <Tuple <string, string> > > changesCountryFiles = new Dictionary <string, List <Tuple <string, string> > >();
                foreach (ExchangeRate rateGlobal in ratesGlobal)
                {
                    string country = rateGlobal.Country.ToLower();
                    foreach (DataGridViewRow rowSync in dgvDiff.Rows)
                    {
                        if (done.Contains(rowSync.Index) ||
                            country != rowSync.Cells[colCountry.Index].Value.ToString().ToLower() ||
                            rateGlobal.Default != rowSync.Cells[colDefault.Index].Value.ToString())
                        {
                            continue;
                        }

                        bool takeCountry;
                        if (rowSync.Cells[colTakeCountry.Index].Value.ToString() == true.ToString())
                        {
                            takeCountry = true;
                        }
                        else if (rowSync.Cells[colTakeGlobal.Index].Value.ToString() == true.ToString())
                        {
                            takeCountry = false;
                        }
                        else
                        {
                            continue;
                        }

                        string rate = rowSync.Cells[takeCountry ? colRateCountry.Index : colRateGlobal.Index].Value.ToString();
                        if (rateGlobal.DefaultRate().ToString() != rate)
                        {
                            continue;
                        }

                        string system = rowSync.Cells[colSystem.Index].Value.ToString();
                        rateGlobal.AddToValidFor(system);
                        done.Add(rowSync.Index);

                        // memorise which systems need to be changed in the country files (to do so below)
                        if (!takeCountry &&
                            rate.ToString() != rowSync.Cells[colRateCountry.Index].Value.ToString()) // it is still possible that the country file does not need to be changed if the period (June 30, ...) was changed
                        {
                            if (!changesCountryFiles.ContainsKey(country))
                            {
                                changesCountryFiles.Add(country, new List <Tuple <string, string> >());
                            }
                            changesCountryFiles[country].Add(new Tuple <string, string>(system, rate));
                        }
                    }
                    ratesSync.Add(rateGlobal);
                }

                // ... then add new rows to global table, for those grid-view-entries which do not fit into existing global table rows ...
                foreach (DataGridViewRow rowSync in dgvDiff.Rows)
                {
                    if (done.Contains(rowSync.Index))
                    {
                        continue;
                    }

                    bool takeCountry;
                    if (rowSync.Cells[colTakeCountry.Index].Value.ToString() == true.ToString())
                    {
                        takeCountry = true;
                    }
                    else if (rowSync.Cells[colTakeGlobal.Index].Value.ToString() == true.ToString())
                    {
                        takeCountry = false;
                    }
                    else
                    {
                        continue;
                    }

                    double june30 = -1, yearAverage = -1, firstSemester = -1, secondSemester = -1;
                    if (rowSync.Tag != null)
                    {
                        ExchangeRate gr = rowSync.Tag as ExchangeRate;
                        june30 = gr.June30; yearAverage = gr.YearAverage; firstSemester = gr.FirstSemester; secondSemester = gr.SecondSemester;
                    }
                    string def  = rowSync.Cells[colDefault.Index].Value.ToString();
                    double rate = double.Parse(rowSync.Cells[takeCountry ? colRateCountry.Index : colRateGlobal.Index].Value.ToString());
                    ratesSync.Add(new ExchangeRate()
                    {
                        Country        = rowSync.Cells[colCountry.Index].Value.ToString().ToUpper(),
                        Default        = def,
                        ValidFor       = rowSync.Cells[colSystem.Index].Value.ToString().ToLower(),
                        June30         = def == ExchangeRate.JUNE30 ? rate : june30,
                        YearAverage    = def == ExchangeRate.YEARAVERAGE ? rate : yearAverage,
                        FirstSemester  = def == ExchangeRate.FIRSTSEMESTER ? rate : firstSemester,
                        SecondSemester = def == ExchangeRate.SECONDSEMESTER ? rate : secondSemester
                    });
                }

                // ... finally remove global tabel rows which got useless (i.e. are not valid for any system anymore)
                for (int del = ratesSync.Count - 1; del >= 0; --del)
                {
                    if (ratesSync[del].ValidFor.Trim() == string.Empty)
                    {
                        ratesSync.RemoveAt(del);
                    }
                }

                // finally, finally change country files where necessary (take global chosen)
                UpdateCountryFiles(changesCountryFiles, this);

                DialogResult = DialogResult.OK;
                Close();
            }
            catch (Exception exception) { UserInfoHandler.ShowException(exception); }
        }
        private void dgvRates_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                Cursor = Cursors.WaitCursor;
                if (e.ColumnIndex < 0 || e.RowIndex < 0 || dgvRates.Columns[e.ColumnIndex].Name != colValidFor.Name)
                {
                    return;                                                                                                  // one needs to request the Name, the index of colValidFor does not work (seems to be 0)
                }
                DataGridViewRow clickedRow = dgvRates.Rows[e.RowIndex]; string country = clickedRow.Cells[colCountry.Index].Value.ToString().ToLower();
                // gether the systems for which rates exist
                List <string> sysDel = new List <string>(), sysMove = new List <string>();
                foreach (DataGridViewRow row in dgvRates.Rows)
                {
                    if (row.Cells[colCountry.Name].Value.ToString().ToLower() != country ||
                        row.Cells[colValidFor.Name].Value == null || row.Cells[colValidFor.Name].Value.ToString() == string.Empty)
                    {
                        continue;
                    }
                    List <string> sys = ExchangeRate.ValidForToList(row.Cells[colValidFor.Name].Value.ToString());
                    if (row.Index == e.RowIndex)
                    {
                        sysDel = sys.ToList();
                    }
                    else
                    {
                        sysMove.AddRange(sys);
                    }
                }
                // gether the systems for which no rates exist
                List <string>       sysAdd = new List <string>();
                CountryConfigFacade ccf    = CountryAdministrator.GetCountryConfigFacade(country);
                foreach (CountryConfig.SystemRow sys in ccf.GetSystemRows())
                {
                    if (!sysDel.Contains(sys.Name.ToLower()) && !sysMove.Contains(sys.Name.ToLower()))
                    {
                        sysAdd.Add(sys.Name.ToLower());
                    }
                }

                // construct menu with systems to delete (from the clicked row), systems to move (from other rows of the country), systems to add (not yet existent in any row)
                ContextMenuStrip menu = new ContextMenuStrip(); menu.ShowImageMargin = false; menu.ShowCheckMargin = false;
                if (sysAdd.Count > 0)
                {
                    ToolStripMenuItem menuItemAdd = new ToolStripMenuItem("Add ...");
                    foreach (string sys in sysAdd)
                    {
                        menuItemAdd.DropDownItems.Add(sys, null, menuItemAddSys_Click).Tag = clickedRow;
                    }
                    menu.Items.Add(menuItemAdd);
                }
                if (sysDel.Count > 0)
                {
                    ToolStripMenuItem menuItem = new ToolStripMenuItem("Delete ...");
                    foreach (string sys in sysDel)
                    {
                        menuItem.DropDownItems.Add(sys, null, menuItemDelSys_Click).Tag = clickedRow;
                    }
                    menu.Items.Add(menuItem);
                }
                if (sysMove.Count > 0)
                {
                    ToolStripMenuItem menuItem = new ToolStripMenuItem("Move ...");
                    foreach (string sys in sysMove)
                    {
                        menuItem.DropDownItems.Add(sys, null, menuItemMoveSys_Click).Tag = clickedRow;
                    }
                    menu.Items.Add(menuItem);
                }
                menu.Show(MousePosition);
            }
            catch (Exception exception) { UserInfoHandler.ShowException(exception); }
            finally { Cursor = Cursors.Default; }
        }
 internal ExchangeRate(ExchangeRate rate)
 {
     Country = rate.Country; Default = rate.Default; ValidFor = rate.ValidFor;
     June30  = rate.June30; YearAverage = rate.YearAverage; FirstSemester = rate.FirstSemester; SecondSemester = rate.SecondSemester;
 }