using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Threading;
using System.Threading;
using EvoBoat.EvoAlg;
using EvoBoat.EvoAlg.ZOProg;

namespace KnapsackTest
{
    using VecSol = VecSolution<BoolVector, bool>;
    using EA = EAlg<KnapsackProblem, VecSolution<BoolVector, bool>, BoolVector, bool>;
    using ATD = AlgTestData<KnapsackProblem, VecSolution<BoolVector, bool>, BoolVector, bool>;

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        KnapsackProblem problem;
        BoolVectorSolutionFactory<KnapsackProblem, VecSolution<BoolVector, bool>> factory;
        EA[] algs;
        EA[] cAlgs;
        List<ATD> testData;

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += Window_Loaded;
            rbMaxIters.Checked += rbMaxIters_Checked;
            rbMaxIters.Unchecked += rbMaxIters_Unchecked;
            chkPorg.Checked += chkPorg_Checked;
            chkPorg.Unchecked += chkPorg_Unchecked;
            btnRun.Click += btnRun_Click;
            btnClear.Click += btnClear_Click;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //MessageBox.Show(BoolVector.SumSel((BoolVector)(new int[] { 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1 }), TestProblems.P07.Profits).ToString());
            foreach (KnapsackProblem p in TestProblems.Problems)
                cmbProblems.Items.Add(p);
            cmbProblems.SelectionChanged += CmbProblems_SelectionChanged;
            cmbProblems.SelectedIndex = 0;
            algs = new EA[] { new ZO_GA<KnapsackProblem, VecSol>(), new ZO_BBOAlg<KnapsackProblem, VecSol>(), new ZO_WWOAlg<KnapsackProblem, VecSol>(), new ZO_NWWOAlg<KnapsackProblem, VecSol>() };
            for (int i = 0; i < algs.Length; i++)
            {
                lbAlgs.Items.Add(algs[i]);
            }
            //lbAlgs.SelectedItem = lbAlgs.Items[lbAlgs.Items.Count - 1];
            lbAlgs.SelectAll();
            lbAlgs.Focus();
        }

        private void CmbProblems_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            problem = (KnapsackProblem)cmbProblems.SelectedItem;
        }

        private void btnAlgSel_Click(object sender, RoutedEventArgs e)
        {

        }
        private void rbMaxIters_Checked(object sender, RoutedEventArgs e)
        {
            tbMaxIters.IsEnabled = true;
            tbMaxNfes.IsEnabled = false;
        }

        void rbMaxIters_Unchecked(object sender, RoutedEventArgs e)
        {
            tbMaxIters.IsEnabled = false;
            tbMaxNfes.IsEnabled = true;
        }

        private void chkPorg_Checked(object sender, RoutedEventArgs e)
        {
            tbIntvs.IsEnabled = true;
        }

        void chkPorg_Unchecked(object sender, RoutedEventArgs e)
        {
            tbIntvs.IsEnabled = false;
        }

        void btnRun_Click(object sender, RoutedEventArgs e)
        {
            if (lbAlgs.SelectedIndex == -1)
            {
                MessageBox.Show("请选择至少一个算法");
                return;
            }
            int runs = int.Parse(tbRuns.Text);
            int upper = (rbMaxIters.IsChecked == true) ? int.Parse(tbMaxIters.Text) : int.Parse(tbMaxNfes.Text);
            int interval = (chkPorg.IsChecked == true) ? int.Parse(tbIntvs.Text) : 0;
            if (interval > 0 && upper / interval > 670)
            {
                if (MessageBox.Show("详细数据列数超过670,是否继续?", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
                    return;
            }
            factory = new BoolVectorSolutionFactory<KnapsackProblem, VecSolution<BoolVector, bool>>(problem);
            cAlgs = new EA[lbAlgs.SelectedItems.Count];
            testData = new List<ATD>(cAlgs.Length);
            for (int i = 0; i < cAlgs.Length; i++)
                cAlgs[i] = (EA)lbAlgs.SelectedItems[i];
            for (int i = 0; i < cAlgs.Length; i++)
            {
                EA alg = cAlgs[i];
                new Thread(() =>
                {
                    DispatcherOperation ar = this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        testData.Add(ATD.Get(alg, problem, factory, runs, upper, interval, rbMaxNfes.IsChecked == true));
                    }));
                    ar.Completed += ar_Completed;
                }).Start();
            }
        }

        void ar_Completed(object sender, EventArgs e)
        {
            tbResult.AppendText(testData[testData.Count - 1].ToString());
        }

        void btnClear_Click(object sender, RoutedEventArgs e)
        {
            tbResult.Clear();
            testData = null;
        }

        private void btnExport_Click(object sender, RoutedEventArgs e)
        {
        }
    }
}
