/// <summary>
        /// PostTask. Repeats sending resources and training troops. Needs to fill up training above X hours.
        /// </summary>
        /// <param name="htmlDoc">html of the page</param>
        /// <param name="acc">Account</param>
        public void RepeatTrainingCycle(HtmlDocument htmlDoc, Account acc)
        {
            var trainingEnds = TroopsHelper.GetTrainingTimeForBuilding(building, vill);

            // If sendRes is activated and there are some resources left to send
            if (vill.Settings.SendRes && MarketHelper.GetResToMainVillage(this.vill).Sum() > 0)
            {
                // Check If all troops are filled in this vill before sending resources back to main village
                if (TroopsHelper.EverythingFilled(acc, vill))
                {
                    TaskExecutor.AddTask(acc, new SendResToMain()
                    {
                        vill = this.vill, ExecuteAt = DateTime.MinValue.AddHours(1)
                    });
                }
            }
            if (vill.Settings.GetRes)
            {
                var nextCycle = trainingEnds.AddHours(-acc.Settings.FillInAdvance);
                if (nextCycle < DateTime.Now)
                {
                    // Send resources asap.
                    nextCycle = DateTime.MinValue.AddHours(3);
                }
                else
                {
                    TaskExecutor.AddTask(acc, new UpdateDorf1()
                    {
                        ExecuteAt = nextCycle,
                        vill      = this.vill
                    });
                }

                TaskExecutor.AddTask(acc, new SendResFillTroops()
                {
                    ExecuteAt  = nextCycle.AddMilliseconds(1),
                    vill       = AccountHelper.GetMainVillage(acc),
                    TargetVill = this.vill,
                    TrainTask  = this
                });
                this.NextExecute = nextCycle.AddMinutes(30); //will get overwritten in sendResFillTroops
                TaskExecutor.ReorderTaskList(acc);
            }
            else
            {
                var later = DateTime.Now.AddMinutes(1);
                // Don't training again sooner than after 10min
                if (later > trainingEnds)
                {
                    trainingEnds = later;
                }

                this.NextExecute = trainingEnds;
            }
        }
        private void UpdateGS(Account acc, Village vill, CellCollection cells, int column)
        {
            bool enabled = cells[column].Checked;
            if (vill.Settings.GreatStableTrain == enabled) return; //no difference

            vill.Settings.GreatStableTrain = enabled;
            if (enabled)
            {
                if (!TroopsHelper.EverythingFilled(acc, vill)) TroopsHelper.ReStartTroopTraining(acc, vill);
            }
        }
        //Save button
        private void button1_Click(object sender, EventArgs e)
        {
            var acc = GetSelectedAcc();
            //change vill names list
            var changeVillNames = new List <(int, string)>();

            for (int i = 0; i < tableModelMain.Rows.Count; i++)
            {
                var cells  = tableModelMain.Rows[i].Cells;
                int column = 0;
                //Village id
                var id   = Int32.Parse(cells[column].Text);
                var vill = acc.Villages.First(x => x.Id == id);

                //check if name is different. if it is, change the name
                var name = cells[++column].Text;
                if (name != vill.Name)
                {
                    changeVillNames.Add((id, name));
                }
                column++;
                UpdateBarracks(acc, vill, cells, column);
                column++;
                UpdateGB(acc, vill, cells, column);
                column++;
                UpdateStable(acc, vill, cells, column);
                column++;
                UpdateGS(acc, vill, cells, column);
                column++;
                UpdateWorkshop(acc, vill, cells, column);
                column++;
                vill.Settings.AutoImprove = cells[column].Checked;

                // Reset training
                if (!TroopsHelper.EverythingFilled(acc, vill) && acc.Tasks != null)
                {
                    TroopsHelper.ReStartTroopTraining(acc, vill);
                }
            }
            //Change name of village/s
            if (0 < changeVillNames.Count && acc.Tasks != null)
            {
                TaskExecutor.AddTaskIfNotExists(acc,
                                                new ChangeVillageName()
                {
                    ExecuteAt  = DateTime.Now,
                    ChangeList = changeVillNames
                });
            }
        }
        private async void NewTick()
        {
            // Dirty hack. TODO fix the code, so building/troops filling tasks won't fail by themselves
            restartTasksCounter++;
            if (restartTasksCounter > 7200)
            {
                restartTasksCounter = 0;
                foreach (var vill in acc.Villages)
                {
                    if (!TroopsHelper.EverythingFilled(acc, vill))
                    {
                        TroopsHelper.ReStartTroopTraining(acc, vill);
                    }
                    BuildingHelper.ReStartBuilding(acc, vill);
                }
            }

            if (acc.Tasks.Count == 0)
            {
                return;                       //No tasks
            }
            // Another task is already in progress. wait
            var taskInProgress = acc.Tasks.FirstOrDefault(x => x.Stage != TaskStage.Start);

            if (taskInProgress != null)
            {
                if (taskInProgress.DurationCounter++ > 30) //after 20sec try to re-execute the task
                {
                    Console.WriteLine($"Task {taskInProgress} timed out. Restarting it..");
                    taskInProgress.DurationCounter = 15;
                    taskInProgress.Stage           = TaskStage.Start; //re-navigate & execute
                                                                      //We have tried re-executing the task 3 times already, something is clearly wrong. Just delete the task.
                    if (++taskInProgress.RetryCounter > 3)
                    {
                        acc.Tasks.Remove(taskInProgress);
                    }
                }
                return;
            }

            var tasks = acc.Tasks.Where(x => x.ExecuteAt <= DateTime.Now).ToList();

            if (tasks.Count == 0)
            {
                return;                   // No tasks yet
            }
            BotTask firstTask = tasks.FirstOrDefault(x => x.Priority == TaskPriority.High);

            if (firstTask == null)
            {
                firstTask = tasks.FirstOrDefault(x => x.Priority == TaskPriority.Medium);
            }
            if (firstTask == null)
            {
                firstTask = tasks.FirstOrDefault();
            }

            //Console.WriteLine($"---Tasks: {acc.Tasks.Count}, first one {firstTask.GetType()}");


            if (firstTask.Stage != TaskStage.Start)
            {
                return;
            }
            //If correct village is selected, otherwise change village
            if (firstTask.vill != null)
            {
                var active = acc.Villages.FirstOrDefault(x => x.Active);
                if (active != null) //error handling
                {
                    if (firstTask.vill != active && firstTask.GetType() != typeof(SwitchVillage))
                    {
                        //wrong village selected, reselect village
                        TaskExecutor.AddTask(acc, new SwitchVillage()
                        {
                            vill = firstTask.vill, Priority = TaskPriority.High
                        });
                        return;
                    }
                }
            }

            firstTask.Stage = TaskStage.Executing;
            _ = TaskExecutor.Execute(acc, firstTask);
        }