#region Using directives

using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System.Drawing;
using System.Windows.Forms;
using PunkMan.Shared;

#endregion

namespace PunkMan.Game
{
    /// <summary>
    /// Monster class
    /// </summary>
    public class Monster : Entity
    {
        /// <summary>
        /// Player object
        /// </summary>
        protected Player player;
        /// <summary>
        /// Current map object
        /// </summary>
        protected Map map;
        /// <summary>
        /// Is monster alive?
        /// </summary>
        protected bool killed = false;
        /// <summary>
        /// Is monster alive?
        /// </summary>
        /// <value></value>
        public bool Killed
        {
            get { return killed; }
            set { killed = value; }
        }

        /// <summary>
        /// Mighty constructor
        /// </summary>
        /// <param name="dev">D3D device</param>
        /// <param name="map">current map</param>
        /// <param name="mesh">monster mesh</param>
        /// <param name="mat">monster material list</param>
        /// <param name="tex">monster texture list</param>
        /// <param name="player">player object</param>
        public Monster(Device dev, Map map, Mesh mesh, Material[] mat, Texture[] tex,
            Player player):base(dev, mesh, mat, tex)
        {
            //speed = 7f;
            moving = false;
            this.map = map;
            this.player = player;
        }

        /// <summary>
        /// can see player
        /// </summary>
        /// <param name="dx">direction of viewing</param>
        /// <param name="dy">direction of viewing</param>
        /// <returns></returns>
        protected bool CanSeePlayer(int dx, int dy)
        {
            Point pos = Map.Convert(position);
            MapCell c = map[pos];
            int x = pos.X;
            int y = pos.Y;
            while (c != null && c.Walkable)
            {
                if (player.MapPosition.X == x && player.MapPosition.Y == y) return true;
                x += dx;
                y += dy;
                if (x < 0 || x >= map.DataWidth || y < 0 || y >= map.DataHeight)
                    break;
                c = map.Data[x, y];
            }
            return false;
        }

        /// <summary>
        /// Attack event
        /// </summary>
        public event Game.GameEventHandler OnAttack;

        /// <summary>
        /// Update monster state
        /// </summary>
        protected override void Update()
        {

            // make direction
            bool seenPlayer = false;
            //int[] moveScore = new int[4];
            int bestScore = 0;
            MoveDirection bestDir = MoveDirection.Up;
            MoveDirection invDir = (MoveDirection)(((int) moveDirection + 2) % 4);
            for (int i = 0; i < 4; i++)
            {
                Point p = Map.Convert(position);
                Entity.MoveDirection dir = (Entity.MoveDirection)i;
                int dx, dy = dx = 0;

                switch (dir)
                {
                    case MoveDirection.Up:
                        p.Y++;
                        dy++;
                        break;

                    case MoveDirection.Down:
                        p.Y--;
                        dy--;
                        break;

                    case MoveDirection.Left:
                        p.X--;
                        dx--;
                        break;

                    case MoveDirection.Right:
                        p.X++;
                        dx++;
                        break;
                }
                MapCell c = map[p];
                //Game.LogFile.WriteLine("nm p: {0}, {1}", p.X, p.Y);
                int score = 0;
                if (c != null && c.Walkable) score = 100;
                if (score > 0)
                {
                    if (CanSeePlayer(dx, dy))
                    {
                        if (player.Delirium)
                            score -= 10;
                        else score += 10;
                        seenPlayer = true;
                    }
                }
                if (dir == moveDirection) score += 2;
                if (dir == invDir) score -= 5;
                if (bestScore < score)
                {
                    bestScore = score;
                    bestDir = dir;

                }
            }
            if (!moving || seenPlayer)
            {
                MoveTo(bestDir);
                
            }
            if (player.MapPosition.Equals(mapPosition) && OnAttack != null) 
                OnAttack(this, mapPosition.X, mapPosition.Y);
            base.Update();
        }


        /// <summary>
        /// Draw monster
        /// </summary>
        public override void Render()
        {
            if (killed) return;
            base.Render();
        }


    }
}
