#if DEBUG
#warning Pamiętaj o skompilowaniu ostatecznej wersji z optymalizacją
#endif

#if DEBUG
#warning Kompilacja "debug"
#else
#warning Kompilacja "release"
#endif

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CS
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int i = 1;
            long l = 1L;
            string s = "Helion";
            float f = 1.0f;
            double d = 1.0;

            //polecenia zapobiegające ostrzeżeniom podczas kompilacji
            i--;
            l--;
            s += s;
            f--;
            d--;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var i = 5;
            var l = 5L;
            var s = "Helion";
            var f = 1.0f;
            var d = 1.0;

            MessageBox.Show(i.GetType().FullName);
            MessageBox.Show(l.GetType().FullName);
            MessageBox.Show(s.GetType().FullName);
            MessageBox.Show(f.GetType().FullName);
            MessageBox.Show(d.GetType().FullName);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Object o = new Button();
            if (o is Button) MessageBox.Show("Obiekt jest przyciskiem");
            else MessageBox.Show("Obiekt nie jest przyciskiem");
            MessageBox.Show(o.GetType().FullName);

            Button b = o as Button;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            string s = "Wydawnictwo Helion";
            int dlugosc = s.Length;

            string helion = "Wydawnictwo \" \u0048 \u0065 \u006c \u0069 \u006f \u006e \"";
            MessageBox.Show(helion);

            //string nazwapliku = "\\Windows\\BubbleBreaker.exe";
            string nazwapliku = @"\Windows\BubbleBreaker.exe";
            MessageBox.Show(nazwapliku);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            //string
            string s = "abc---";
            s += "xyz";
            s = s.Replace("---", " ijk ");
            MessageBox.Show(s);

            //StringBuilder
            StringBuilder sb = new StringBuilder("abc---");
            sb.Append("xyz");
            sb.Replace("---", " ijk ");
            MessageBox.Show(sb.ToString());
        }

        public enum DniTygodnia : byte { niedziela = 1, poniedzialek, wtorek, sroda, czwartek, piatek, sobota };

        private void button6_Click(object sender, EventArgs e)
        {
            byte nrDniaTygodnia = (byte)DniTygodnia.poniedzialek;
            MessageBox.Show(nrDniaTygodnia.ToString());
        }

        delegate int Uchwyt(byte arg);

        private int Kwadrat(byte arg)
        {
            return arg * arg;
        }

        event Uchwyt ZdarzenieKwadrat;

        private void button7_Click(object sender, EventArgs e)
        {
            Uchwyt UchwytMetodyKwadrat = new Uchwyt(Kwadrat);

            int i = Kwadrat(2);
            int j = UchwytMetodyKwadrat(2);            

            ZdarzenieKwadrat+=new Uchwyt(Kwadrat);
            int k=ZdarzenieKwadrat(2);

            MessageBox.Show("i=" + i + ", j=" + j + ", k=" + k);
        }

        delegate int DInc(int n);
        delegate bool DIsEqual(double x, double y);
        delegate void DShow(int n);

        private void button8_Click(object sender, EventArgs e)
        {
            DInc Inc = (int n) => n + 1;
            MessageBox.Show("Inc(1)=" + Inc(1));

            DIsEqual IsEqual = (x, y) => x == y;
            int a = 10;
            int b = 20;
            MessageBox.Show("Czy równe a=" + a + " i b=" + b + "? " + (IsEqual(a, b) ? "Tak" : "Nie"));
            MessageBox.Show("Czy równe a=" + a + " i a=" + a + "? " + (IsEqual(a, a) ? "Tak" : "Nie"));

            DShow Show = n => { MessageBox.Show(n.ToString()); };
            Show(10);

            string[] slowa = { "czereśnia", "jabłko", "borówka", "wiśnia", "jagoda" };
            int dlugoscNajkrotszego = slowa.Min(slowo => slowo.Length);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            Button b = new Button();
            b.Text = "Przycisk b";
            int i = 1;

            Button a = b;
            a.Text = "Przycisk a";
            int j = i;
            j = 2;

            MessageBox.Show("b.Text=" + b.Text + ", a.Text=" + a.Text);
            MessageBox.Show("i=" + i.ToString() + ", j=" + j.ToString());
        }

        private void button10_Click(object sender, EventArgs e)
        {
            Nullable<int> ni = 1;
            int i1;
            if (ni.HasValue)
            {
                i1 = ni.Value;
            }
            else
            {
                i1 = default(int);
            }
            int i2 = ni.GetValueOrDefault();
            MessageBox.Show("i1=" + i1 + ", i2=" + i2);
        }

        private void button11_Click(object sender, EventArgs e)
        {
            int i = 1;
            object o = i;
            MessageBox.Show(o.GetType().ToString()); //zwraca System.Int32
            int j = (int)o;
            MessageBox.Show(j.ToString());
        }

        private void button12_Click(object sender, EventArgs e)
        {
            Random r = new Random();
            int n = r.Next(8);
            MessageBox.Show("" + n);

            //Składnia podstawowa if
            if (n < 6) MessageBox.Show("Wylosowana liczba jest mniejsza od 6.");

            //Składnia rozszerzona if..else
            if (n <= 4) MessageBox.Show("Wylosowana liczba jest mniejsza lub równa 4.");
            else MessageBox.Show("Wylosowana liczba jest większa od 4.");
        }

        private void button13_Click(object sender, EventArgs e)
        {
            Random r = new Random();
            int n = r.Next(8);
            string opis;
            switch (n)
            {
                case 1: opis = "niedziela"; break;
                case 2: opis = "poniedziałek"; break;
                case 3: opis = "wtorek"; break;
                case 4: opis = "środa"; break;
                case 5: opis = "czwartek"; break;
                case 6: opis = "piątek"; break;
                case 7: opis = "sobota"; break;
                default: opis = "błąd!"; break;
            }
            MessageBox.Show("Dzień tygodnia: " + n + ", " + opis);
        }

        long silnia(byte arg)
        {
            if (arg == 0) return 0;
            long wartosc = 1;
            for (byte i = 1; i <= arg; i++)
                wartosc *= i;
            return wartosc;
        }

        private void button14_Click(object sender, EventArgs e)
        {
            byte n = 4;
            MessageBox.Show(n.ToString() + "!=" + silnia(n).ToString());
        }

        long najwiekszyDzielnik(long arg)
        {
            long dzielnik = arg - 1;
            while (arg % dzielnik != 0)
                dzielnik--;
            return dzielnik;
        }

        private void button15_Click(object sender, EventArgs e)
        {
            int n = 111;
            MessageBox.Show("ND(" + n.ToString() + ")=" + najwiekszyDzielnik(n).ToString());
        }

        private void button16_Click(object sender, EventArgs e)
        {
            Random r = new Random();
            int n = r.Next(8);
            //Zadanie komputera to odgadnąć 
            //liczbę z zakresu od 0 do 7
            int z; int licznik = 0;
            do
            {
                licznik++;
                z = r.Next(8);
            }
            while (n != z);
            MessageBox.Show("Komputer zgadł liczbę " + z + " po " + licznik + " próbach!");
        }

        private void button17_Click(object sender, EventArgs e)
        {
            for (int i = -1; i <= 1; i++)
                for (int j = -1; j <= 1; j++)
                {
                    if (i == 0 && j == 0) continue; //pomijamy przypadki, gdy obie zmienne równe są 0
                    MessageBox.Show("i=" + i + ", j=" + j);
                }
        }

        private void zakresDouble(ref double min, ref double max)
        {
            min = double.MinValue;
            max = double.MaxValue;
            MessageBox.Show("Liczby double mogą należeć do przedziału (" + min + "," + max + ")");
        }

        private void button18_Click(object sender, EventArgs e)
        {
            double min = 0, max = 0;
            zakresDouble(ref min, ref max);
            MessageBox.Show("Liczby double mogą należeć do przedziału (" + min + "," + max + ")");
        }

        private void button19_Click(object sender, EventArgs e)
        {
            try
            {
                int x = 0;
                int y = 1 / x;
                MessageBox.Show("To polecenie nie zostanie wykonane!");
            }
            catch (DivideByZeroException exc)
            {
                MessageBox.Show("Dzielenie przez zero ("+exc.Message+")");
            }
            catch (Exception exc)
            {
                MessageBox.Show("Inne wyjątki\n" + exc.Message);
            }

        }

        private void button20_Click(object sender, EventArgs e)
        {
            throw new Exception("To jest wyjątek, który nie jest otoczony instrukcjami try..catch");
        }

        private void button21_Click(object sender, EventArgs e)
        {
            try
            {
                int x = 0;
                int y = 1 / x;
            }
            catch (DivideByZeroException exc)
            {
                MessageBox.Show("Dzielenie przez zero (" + exc.Message + ")");
                return;
            }
            catch (Exception exc)
            {
                MessageBox.Show("Inne wyjątki\n" + exc.Message);
                return;
            }
            finally
            {
                MessageBox.Show("Kod wykonywany w każdym przypadku");
            }
        }

        private void button22_Click(object sender, EventArgs e)
        {
            #if DEBUG
            MessageBox.Show("Kompilacja \"debug\"");
            #else
            MessageBox.Show("Kompilacja \"release\"");
            #endif
        }

        [Obsolete("Metoda przestarzała. Lepiej użyj metody NowaMetoda",false)]
        private void MetodaOznaczonaJakoPrzestarzała()
        {
            MessageBox.Show("MetodaOznaczonaJakoPrzestarzała");
        }

        private void button23_Click(object sender, EventArgs e)
        {
            MetodaOznaczonaJakoPrzestarzała();
        }

        private void button24_Click(object sender, EventArgs e)
        {
            int[] it = new int[3] { 1, 2, 4 };
            int[,] i2 = new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } };

            Button[] b = new Button[3];
            for (int i = 0; i < b.Length; i++)
            {
                b[i] = new Button();
                b[i].Text = "" + i;
                b[i].Top = i * 30;
                //b[i].Parent = this;
                b[i].Parent = tabPage3;
            }

            foreach (Button bi in b)
            {
                //bi.Text = "" + 0;
                MessageBox.Show(bi.Text);
            }

            foreach (int i in i2) MessageBox.Show("" + i);
        }

        private void button25_Click(object sender, EventArgs e)
        {
            int[] losy = new int[30];
            Random r = new Random();
            for (int indeks = 0; indeks < losy.Length; indeks++)
                losy[indeks] = r.Next(100);

            string s = "Przed sortowaniem:\n";
            foreach (int los in losy) s += los.ToString() + "\t";
            MessageBox.Show(s);

            Array.Sort(losy);

            s = "Po sortowaniu:\n";
            foreach (int los in losy) s += los.ToString() + "\t";
            MessageBox.Show(s);
        }

        private void button26_Click(object sender, EventArgs e)
        {
            if(MessageBox.Show("Uruchomienie tej metody powoduje wystąpienie wyjątku. Czy chcesz kontynuować?","Ostrzeżenie przed wyjątkiem",MessageBoxButtons.YesNo,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button2)==DialogResult.No)
                return;

            Button[] przyciski = new Button[100];
            Random r = new Random();
            for (int indeks = 0; indeks < przyciski.Length; indeks++)
            {
                przyciski[indeks] = new Button();
                przyciski[indeks].Text = "" + r.Next(100);
            }

            Array.Sort(przyciski);
        }

        private void button27_Click(object sender, EventArgs e)
        {
            int rozmiar = 30;
            Random r = new Random();
            List<int> a = new List<int>(new int[rozmiar]);
            for (int i = 0; i < rozmiar; i++) a[i] = r.Next(100);
            a.AddRange(new int[10]);
            int[] i5 = { -1, -1, -1, -1, -1 };
            a.InsertRange(rozmiar / 2, i5);
            a.Insert(0, 1);

            /*
            //tu kryją się błędy
            for (int i = 0; i < rozmiar; i++)
            {
                if (a[i] > 20)
                    a.RemoveAt(i);
            }
            */

            for (int i = 0; i < a.Count; i++)
            {
                if (a[i] > 20)
                {
                    a.RemoveAt(i);
                    i--;
                }
            }

            a.Sort();

            string s = "Elementy listy:\n";
            foreach (object ai in a) s += ai.ToString() + "\t";
            MessageBox.Show(s);

        }

        private void button28_Click(object sender, EventArgs e)
        {
            SortedList<string, string> artysci = new SortedList<string, string>();
            artysci.Add("Sting", "Gordon Matthew Sumner");
            artysci.Add("Bolesław Prus", "Aleksander Głowacki");
            artysci.Add("Pola Negri", "Barbara Apolonia Chałupiec");
            artysci.Add("John Wayne", "Marion Michael Morrison");
            artysci.Add("Chico", "Leonard Marx");
            artysci.Add("Harpo", "Arthur Marx");
            artysci.Add("Groucho", "Julius Marx");
            artysci.Add("Bono", "Paul Hewson");
            artysci.Add("Ronaldo", "Luiz Nazario de Lima");
            artysci.Add("Madonna", "Madonna Louise Veronica Ciccone");
            artysci.Add("Gabriela Zapolska", "Maria G. Śnieżko-Błocka");

            string komunikat = "Zawartość listy:\n\n";
            foreach (KeyValuePair<string, string> artysta in artysci)
                komunikat += artysta.Key + " - " + artysta.Value + "\n";
            MessageBox.Show(komunikat);
        }

        private int Suma(params int[] lista)
        {
            MessageBox.Show("Liczba argumentów: " + lista.Length);
            int suma = 0;
            foreach (int liczba in lista) suma += liczba;
            return suma;
        }

        private void button29_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Suma: " + Suma(new int[] { 1, 2, 3 }));
            MessageBox.Show("Suma: " + Suma(1, 2, 3));
        }

        int[] metoda_tradycyjna(int rozmiar)
        {
            int[] wynik = new int[rozmiar];
            Random r = new Random();
            for (int i = 0; i < rozmiar; ++i)
            {
                wynik[i] = r.Next(100);
            }
            return wynik;
        }

        IEnumerable<int> metoda(int rozmiar)
        {
            Random r = new Random();
            for (int i = 0; i < rozmiar; ++i)
            {
                yield return r.Next(100);
            }
            yield break;
        }

        IEnumerable<int> metoda_tradycyjna1(int próg)
        {
            List<int> wynik=new List<int>();
            Random r = new Random();
            int los;
            do
            {
                los = r.Next(15);
                wynik.Add(los);
            }
            while (los < próg);
            return wynik.AsEnumerable<int>();
        }

        IEnumerable<int> metoda1(int próg)
        {
            Random r = new Random();
            int los;
            do
            {
                los = r.Next(15);
                yield return los;
            }
            while (los < próg);
            yield break;
        }

        private void button30_Click(object sender, EventArgs e)
        {
            int[] ti = metoda1(10).ToArray();

            string s = "";
            foreach (int element in ti)
                s += element.ToString() + "\n";
            MessageBox.Show(s);
        }

        private void button32_Click(object sender, EventArgs e)
        {
            Button b = new Button { Text = "Przycisk", Left=200, Top=30, Parent = tabPage3 };

            var it = new[] { 5, 4, 3, 2, 1, 0 };
            var lt = new[] { 5L, 4L, 3L, 2L, 1L, 0L };
            var st = new[] { "Helion", "Onepress", "Sensus", "Septem", "Editio" };
            var ft = new[] { 1.0f, 0.75f, 0.5f, 0.25f, 0.0f };
            var dt = new[] { 1.0, 0.75, 0.5, 0.25, 0.0 };

            List<string> lista = new List<string> { "Helion", "Onepress", "Sensus", "Septem", "Editio" };
        }

        private void button33_Click(object sender, EventArgs e)
        {
            int rozmiar = 10;
            Queue<int> kolejka = new Queue<int>(rozmiar);
            Stack<int> stos = new Stack<int>(rozmiar);
            for (int i = 0; i < rozmiar; ++i)
            {
                kolejka.Enqueue(i);
                stos.Push(i);
            }

            string s = "Elementy zdjęte z kolejki (" + kolejka.Count + " elementów):\n";
            for (int i = 0; i < rozmiar; ++i) s += kolejka.Dequeue().ToString() + " ";
            s += "\n\nElementy zdjęte ze stosu (" + stos.Count + " elementów):\n";
            for (int i = 0; i < rozmiar; ++i) s += stos.Pop().ToString() + " ";
            MessageBox.Show(s);
        }

        private void button31_Click(object sender, EventArgs e)
        {
            dynamic o; //nie działa IntelliSence
            o = 5; MessageBox.Show(o.ToString() + ", " + o.GetType().FullName);
            o = 5L; MessageBox.Show(o.ToString() + ", " + o.GetType().FullName);
            o = "Helion"; MessageBox.Show(o.ToString() + ", " + o.GetType().FullName);
            o = 1.0f; MessageBox.Show(o.ToString() + ", " + o.GetType().FullName);
            o = 1.0; MessageBox.Show(o.ToString() + ", " + o.GetType().FullName);

            /*
            object o1;
            o1 = 5; MessageBox.Show(o1.ToString() + ", " + o1.GetType().FullName);
            o1 = 5L; MessageBox.Show(o1.ToString() + ", " + o1.GetType().FullName);
            o1 = "Helion"; MessageBox.Show(o1.ToString() + ", " + o1.GetType().FullName);
            o1 = 1.0f; MessageBox.Show(o1.ToString() + ", " + o1.GetType().FullName);
            o1 = 1.0; MessageBox.Show(o1.ToString() + ", " + o1.GetType().FullName);
            */
        }

        dynamic obiekt; //pole

        dynamic Obiekt //własność
        {
            get
            {
                return zwrocObiekt();
            }
            set
            {
                obiekt = value;
            }
        }

        dynamic zwrocObiekt(int ktoryObiekt = 0) //wartość zwracana przez metodę
        {
            dynamic wartosc;
            switch (ktoryObiekt)
            {
                case 0: wartosc = 5; break;
                case 1: wartosc = 5L; break;
                case 2: wartosc = "Helion"; break;
                case 3: wartosc = 1.0f; break;
                case 4: wartosc = 1.0; break;
                case 5: wartosc = button1; break;
                default: wartosc = obiekt; break;
            }
            return wartosc;
        } 

        private void button34_Click(object sender, EventArgs e)
        {
            try
            {
                dynamic o = zwrocObiekt(comboBox1.SelectedIndex);
                MessageBox.Show("Obiekt: " + o.ToString() + ", typ: " + o.GetType().FullName);
                o.Metoda(); //tu pojawi się wyjątek
            }
            catch (Exception exc)
            {
                MessageBox.Show("Błąd: " + exc.Message);
            }
        }

        private void button35_Click(object sender, EventArgs e)
        {
            Lazy<int> li = new Lazy<int>(() => 1);
            MessageBox.Show(li.IsValueCreated.ToString());
            MessageBox.Show("Odwołanie do zmiennej, li=" + li.Value);
            MessageBox.Show(li.IsValueCreated.ToString());
        }

        private void button36_Click(object sender, EventArgs e)
        {
            Lazy<Button> lb = new Lazy<Button>(() =>
            {
                Button b = new Button();
                b.Parent = tabPage1;
                b.Top = button36.Top;
                b.Left = button36.Bounds.Right + 10;
                b.Text = "Lewniwy przycisk";
                return b;
            });
            MessageBox.Show(lb.IsValueCreated.ToString());
            MessageBox.Show("Odwołanie do zmiennej, etykieta przycisku: \"" + lb.Value.Text + "\"");
            MessageBox.Show(lb.IsValueCreated.ToString());
        }
    }
}
