﻿// BeatMe
// Copyright 2015 Tim Potze
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Drawing;
using System.Windows.Forms;
using BeatMe.Game.Algorithm;
using BeatMe.Game.Logic;
using BeatMe.Game.Move;

namespace BeatMe.UI
{
    public partial class FullAIPlayerPairUserControl : UserControl
    {
        private IDrawableBoardGame _game;
        private IDrawableBoardGame _opponent;

        public FullAIPlayerPairUserControl()
        {
            InitializeComponent();
            DoubleBuffered = true;
        }

        public IBoardGameAlgorithm Algorithm { get; set; }

        public void SetGame<TBoardGame>()
            where TBoardGame : IDrawableBoardGame
        {
            _game = (IDrawableBoardGame) Activator.CreateInstance(typeof (TBoardGame));
            _opponent = (IDrawableBoardGame) Activator.CreateInstance(typeof (TBoardGame));
        }

        #region Overrides of Control

        protected override void OnDoubleClick(EventArgs e)
        {
            if (_game.IsFinished || Algorithm == null || _game == null)
            {
                return;
            }
            /* Do a move for 'max' player. */
            IBoardMove move = Algorithm.CalculateBestMove(_game);
            _game = _game.WithMoveApplied(move) as IDrawableBoardGame;

            move.Invert();
            _opponent = _opponent.WithMoveApplied(move) as IDrawableBoardGame;

            /* If game is finished, break free from loop. */
            if (_game.IsFinished)
            {
                Invalidate();
                return;
            }

            /* Do a move for 'min' player. */
            IBoardMove move2 = Algorithm.CalculateBestMove(_opponent);
            _opponent = _opponent.WithMoveApplied(move2) as IDrawableBoardGame;

            move2.Invert();
            _game = _game.WithMoveApplied(move2) as IDrawableBoardGame;


            Invalidate();
            base.OnClick(e);
        }

        /// <summary>
        ///     Raises the <see cref="E:System.Windows.Forms.Control.Paint" /> event.
        /// </summary>
        /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs" /> that contains the event data. </param>
        protected override void OnPaint(PaintEventArgs e)
        {
            if (_game != null)
                _game.Draw(e.Graphics, new Point(Margin.Left, Margin.Top));
        }

        #endregion
    }
}