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

namespace WinGreed
{
    public partial class frmPersonRound : Form
    {
        int y = 79;
        int x = 0;
        int row = 0;
        int tempMax = 0;
        int tempChsn = 0;
        bool maxHeatPoints = false;
        private List<Button> _dice = new List<Button>();
        private HandleThrow _ht;
        public string Player { get; set; }
        public int TotPoints { get; set; }
        public int AddedPoints { get; set; }
        
        List<int> Points = new List<int>();
        public frmPersonRound(string player)
        {
            InitializeComponent();
            Player = player;
            this.Text = $"Din tur - {Player}";
            _ht = new HandleThrow();
            _ht.Who = Player;
            ///ht.Throw();
            btnThrow.Enabled = true;
            btnCollect.Enabled = true;
        }

        private void btnThrow_Click(object sender, EventArgs e)
        {

            x = 0;
            y = y + btnDiceTmpl1.Height + 5;
            var no = 0;
            var result = _ht.Throw();


            Button btn = null;
            if (MarkGrayAndDisable(row))
            {
                result = _ht.Throw();
            }


            row++;


            foreach (var item in result)
            {
                no++;
                switch (item.Number)
                {
                    case 1:
                        {
                            btn = btnDiceTmpl1.Clone<Button>();
                            btn.Name = $"btnDice{row}1";
                            break;
                        }
                    case 2:
                        {
                            btn = btnDiceTmpl2.Clone<Button>();
                            btn.Name = $"btnDice{row}2";
                            break;
                        }
                    case 3:
                        {
                            btn = btnDiceTmpl3.Clone<Button>();
                            btn.Name = $"btnDice{row}3";
                            break;
                        }
                    case 4:
                        {
                            btn = btnDiceTmpl4.Clone<Button>();
                            btn.Name = $"btnDice{row}4";
                            break;
                        }
                    case 5:
                        {
                            btn = btnDiceTmpl5.Clone<Button>();
                            btn.Name = $"btnDice{row}5";
                            break;
                        }
                    case 6:
                        {
                            btn = btnDiceTmpl6.Clone<Button>();
                            btn.Name = $"btnDice{row}6";
                            break;
                        }
                    default:
                        break;
                }

                _dice.Add(btn);
                btn.Location = new Point(x + (btn.Width + 5) * no, y);
                btn.Visible = true;
                btn.Tag = item;
                btn.Click += new System.EventHandler(btnDiceTmpl_Click);
                this.Controls.Add(_dice.Last());
                this.Refresh();
            }

            CalculateResult(result);

        }

        private void CalculateResult(List<Dice> result)
        {
            List<int> Numbers = new List<int>();
            foreach (var item in result)
            {
                Numbers.Add(item.Number);
            }

            AnalyseNumbers(Numbers);
        }

        private bool MarkGrayAndDisable(int row)
        {
            var ok = false;
            List<int> Numbers = new List<int>();

            if (row > 0)
            {
                foreach (var item in _dice)
                {
                    if (item.Name.Contains($"btnDice{row}"))
                    {
                        item.Enabled = false;
                        if (item.BackColor == Color.Red)
                        {
                            item.BackColor = Color.Gray;
                            Numbers.Add(((Dice)item.Tag).Number);
                        }
                    }
                }
                ok = AnalyseNumbers(Numbers, false);
            }
            return ok;
        }

        private bool AnalyseNumbers(List<int> numbers, bool before = true)
        {
            var result = false;
            if (before)
            {
                TextBox txt = null;
                TextBox txtRes = null;

                txt = txtMaxValue.Clone<TextBox>();
                txt.Name = $"txtMaxValue{row}";
                txt.Location = new Point(x + 400, y);
                txt.Visible = true;
                this.Controls.Add(txt);
                this.Refresh();

                txtRes = txtChosenValue.Clone<TextBox>();
                txtRes.Name = $"txtChosenValue{row}";
                txtRes.Location = new Point(x + 400 + (txtRes.Width + 5), y);
                txtRes.Visible = true;
                this.Controls.Add(txtRes);
                this.Refresh();

                var outPut = CheckForDifferentOutCome(numbers);
                var actTxtBox = ((TextBox)this.Controls.Find($"txtMaxValue{row}", true).FirstOrDefault());
                actTxtBox.Text = outPut.StrSum;
                actTxtBox.Refresh();
                tempMax += outPut.NumSum;
                txtMaxPoints.Text = tempMax.ToString();
                if (numbers.Count > 0 && int.Parse(outPut.StrSum.Trim()) == 0)
                {
                    btnThrow.Enabled = false;
                    btnCollect.Enabled = false;
                    MarkGrayAndDisable(row);
                    txtMaxPoints.Text = "0";
                    txtChosenPoints.Text = "0";
                }
            }
            else
            {
                var outPut = CheckForDifferentOutCome(numbers);
                var actTxtBox = ((TextBox)this.Controls.Find($"txtChosenValue{row}", true).FirstOrDefault());
                actTxtBox.Text = outPut.StrSum;
                actTxtBox.Refresh();
                tempChsn += outPut.NumSum;
                txtChosenPoints.Text = tempChsn.ToString();
                
                if (((TextBox)this.Controls.Find($"txtMaxValue{row}", true).FirstOrDefault()).Text == actTxtBox.Text
                    && int.Parse(actTxtBox.Text.Trim()) > 0
                    && _ht.Dices.Count(x => x.Chosen == true) == _ht.Dices.Count)
                {
                    _ht.Dices.ForEach(x => x.Chosen = false);
                    result = true;
                }
            }

            //numbers.ForEach(x => Debug.Write($"{x}, "));
            //Debug.WriteLine(" -");
            return result;

        }

        private ResultSum CheckForDifferentOutCome(List<int> numbers)
        {
            var result = new ResultSum();
            result.StrSum = "";
            result.NumSum = 0;
            maxHeatPoints = false;
            numbers.Sort();
            result.NumSum = CheckForDoubleTriple(numbers);
            result.NumSum += CheckForTripleDouble(numbers);
            result.NumSum += CheckForSerial(numbers);
            result.NumSum += CheckForThreeOrMore(numbers);
            result.StrSum = result.NumSum.ToString();
            return result;
        }

        private int CheckForSerial(List<int> numbers)
        {
            if (numbers.Count > 5)
            {
                for (int i = 0; i < numbers.Count; i++)
                {
                    if (numbers[i] != i + 1)
                    {
                        return 0;
                    }
                }
                maxHeatPoints = true;
                return 1500;
            }
            return 0;
        }

        private int CheckForThreeOrMore(List<int> numbers)
        {
            var result = 0;

            var ones = 0;
            var twos = 0;
            var threes = 0;
            var fours = 0;
            var fives = 0;
            var sixs = 0;

            //if(numbers.Count > 2)
            //{
            foreach (var number in numbers)
            {
                switch (number)
                {
                    case 1:
                        {
                            ones++;
                            break;
                        }
                    case 2:
                        {
                            twos++;
                            break;
                        }
                    case 3:
                        {
                            threes++;
                            break;
                        }
                    case 4:
                        {
                            fours++;
                            break;
                        }
                    case 5:
                        {
                            fives++;
                            break;
                        }
                    case 6:
                        {
                            sixs++;
                            break;
                        }
                    default:
                        break;
                }
            }

            result += NumberCounts(ones, 1);
            result += NumberCounts(twos, 2);
            result += NumberCounts(threes, 3);
            result += NumberCounts(fours, 4);
            result += NumberCounts(fives, 5);
            result += NumberCounts(sixs, 6);
            //}


            return result;
        }

        public int NumberCounts(int value, int nmbr)
        {
            if (value > 2 && !maxHeatPoints)
            {
                var back = nmbr == 1 ? 1000 : nmbr * 100;

                if (value > 3)
                {
                    back *= 2;
                }
                if (value > 4)
                {
                    back *= 2;
                }
                if (value > 5)
                {
                    back *= 2;
                }
                return back;
            }
            else
            {
                if ((value < 3 && (nmbr == 1 || nmbr == 5)) && !maxHeatPoints)
                {
                    var back = value * (nmbr == 1 ? 100 : 50);
                    return back;
                }
            }
            return 0;
        }

        private int CheckForTripleDouble(List<int> numbers)
        {
            if (numbers.Count == 6
                && numbers[0] == numbers[1]
                && numbers[2] == numbers[3]
                && numbers[4] == numbers[5]
                && numbers[1] != numbers[2]
                && numbers[3] != numbers[4]
                && numbers[0] != numbers[5])
            {
                maxHeatPoints = true;
                return 1500;
            }
            return 0;
        }

        private int CheckForDoubleTriple(List<int> numbers)
        {
            if (numbers.Count == 6
                && numbers[0] == numbers[2]
                && numbers[3] == numbers[5]
                && numbers[2] != numbers[3])
            {
                maxHeatPoints = true;
                return 1500;
            }
            return 0;
        }

        private void btnDiceTmpl_Click(object sender, EventArgs e)
        {
            if (((Dice)((Button)sender).Tag).Chosen)
            {
                ((Button)sender).BackColor = Color.Green;
                ((Dice)((Button)sender).Tag).Chosen = false;
            }
            else
            {
                ((Dice)((Button)sender).Tag).Chosen = true;
                ((Button)sender).BackColor = Color.Red;
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnCollect_Click(object sender, EventArgs e)
        {
            btnThrow.Enabled = false;
            MarkGrayAndDisable(row);
            var totalSum = 0;
            for (int i = row; i > 0; i--)
            {
                var acttxt = (TextBox)this.Controls.Find($"txtChosenValue{i}", true).FirstOrDefault();
                totalSum += int.Parse(acttxt.Text);
            }
            if (_ht.Score == 0 && totalSum < 1000)
            {
                //Startspärr
            }
            else
            {
                _ht.Score += totalSum;
            }
            TotPoints = _ht.Score;
            txtTotalPoints.Text = _ht.Score.ToString();
        }

        private void frmPersonRound_Shown(object sender, EventArgs e)
        {
            txtTotalPoints.Text = TotPoints.ToString();
            _ht.Score = TotPoints;
        }

        private void frmPersonRound_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (int.Parse( txtChosenPoints.Text.Trim() )>0)
            {
                AddedPoints = tempChsn;
            }
        }
    }
}
