using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WindowsGame1
{

    public class Game1 : Microsoft.Xna.Framework.Game
    {

        public class snakebody
        {
            public int x;
            public int y;
        }
        public class fruits
        {
            public int x;
            public int y;
        }
        int count = 0;
        Texture2D food;
        Texture2D role;
        Texture2D body;
        Texture2D bg;
        int c = 0;
            int u = 0 ;
        Vector2 screenpos, texturesize;
        int screenheight;
        int screenwidth;
        int score = 0;
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
  
        MyAudio audio; // 音效類別
        SpriteFont Font1; // 字型物件
        int countsnake = 3;
        int fail = 0;
        int tempX = 0;
        int tempY = 0;
        snakebody[] _snakebody = new snakebody[1000];//身體最常100單位

        int direction = 0;  //控制方向
      
        fruits Fruit = new fruits();
        Random rnd = new Random();
        
        public Game1()
        {
            
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            audio = new MyAudio(); // 建立audio 聲音
            //this.IsMouseVisible = true;  // 呈現滑鼠游標
            this.Window.AllowUserResizing = true; // 允許視窗縮放wa
           graphics.PreferredBackBufferWidth = 1024;  //視窗的預設寬
           graphics.PreferredBackBufferHeight = 960; //視窗的預設高
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            for (int i = 0; i < 100; i++)
            {
                _snakebody[i] = new snakebody();
            }
            while (true) 
            {
                Fruit.x = rnd.Next(0, graphics.GraphicsDevice.Viewport.Width);
                Fruit.x = rnd.Next(0, graphics.GraphicsDevice.Viewport.Height);
                
                if (Fruit.x % 64 == 0 && Fruit.y % 64 == 0)
                    break;  
            }

            _snakebody[0].x = 320;
            _snakebody[1].x = 320 - 64;
            _snakebody[2].x = 320 - 64 -64;
            _snakebody[0].y = _snakebody[1].y = _snakebody[2].y = 320;

            screenheight = GraphicsDevice.Viewport.Height;
            screenwidth = GraphicsDevice.Viewport.Width;
            screenpos = new Vector2(0, 0);


            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here

            bg = Content.Load<Texture2D>("new");
            texturesize = new Vector2(0, bg.Height);
            food = Content.Load<Texture2D>("fod");
            body = Content.Load<Texture2D>("body");
            role = Content.Load<Texture2D>("thehead");
            Font1 = Content.Load<SpriteFont>("SpriteFont1");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            UpdateKey();

            if (_snakebody[0].x == Fruit.x  &&  _snakebody[0].y == Fruit.y)   //吃到水果後產生新水果
            {
                count++;
                score += 10;
                countsnake++;
                _snakebody[countsnake - 1].x = _snakebody[countsnake - 2].x;
                _snakebody[countsnake - 1].y = _snakebody[countsnake - 2].y;
                while (true)
                {
                    Boolean exist=false;
                    Fruit.x = rnd.Next(0, graphics.GraphicsDevice.Viewport.Width);
                    Fruit.y = rnd.Next(0, graphics.GraphicsDevice.Viewport.Height);
                    for (int i = 0; i < countsnake; i++) {
                        if (Fruit.x == _snakebody[i].x && Fruit.y == _snakebody[i].y)
                            exist = true;
                    }
                        if (Fruit.x %64 == 0 && Fruit.y % 64 == 0&& !exist)
                            break;
                }
                audio.PlaySound("chimes");//圖片在碰撞時產生音效
            }

           if ((_snakebody[0].x == 0&&count==5) || (_snakebody[0].y == 0&&count==5) || (_snakebody[0].x ==960&&count==5)||(_snakebody[0].y== 960&&count==5))
         
            {
                if (c == 0)
                {
                    Form1 form1 = new Form1();
                    form1.Show();

                    c++;
                }
            }


            if (score ==120)
            {

                if(u==0){

                Form2 form2 = new Form2();
                form2.Show();
                u++;
                }


            }

                if (gameTime.TotalGameTime.Milliseconds % 100== 0)
                {
                    fail = 0;
                    tempX = 0;
                    tempY = 0;
                    int W = graphics.GraphicsDevice.Viewport.Width;
                    int H = graphics.GraphicsDevice.Viewport.Height;

                    switch (direction)
                    {
                        case 0:
                            tempX +=64;
                            break;
                        case 1:
                            tempX -=64;
                            break;
                        case 2:
                            tempY += 64;
                            break;
                        case 3:
                            tempY -=64;
                            break;
                    }
                    for (int i = 1; i < countsnake; i++)
                    {
                        if (_snakebody[0].x + tempX == _snakebody[i].x &&_snakebody[0].y + tempY == _snakebody[i].y)
                            fail++;
                    }
                    if (_snakebody[0].x + tempX < 0 || _snakebody[0].x + tempX == W ||
                        _snakebody[0].y + tempY < 0 || _snakebody[0].y + tempY == H)
                        fail++;

                    

                    if (fail > 0)
                    {
                        _snakebody[0].x = _snakebody[0].x;
                        _snakebody[0].y = _snakebody[0].y;
                        //audio.PlaySound("soap60");
                    }
                    else
                    {

                        for (int i = countsnake - 1; i > 0; i--)
                        {
                            _snakebody[i].x = _snakebody[i - 1].x;
                            _snakebody[i].y = _snakebody[i - 1].y;
                        }
                        switch (direction)
                        {
                            case 0:
                                _snakebody[0].x += 64;
                                break;
                            case 1:
                                _snakebody[0].x -=64;
                                break;
                            case 2:
                                _snakebody[0].y +=64;
                                break;
                            case 3:
                                _snakebody[0].y -=64;
                                break;

                        }
                    }
                }
           
                // TODO: Add your update logic here
                
                base.Update(gameTime);
        }
        public void UpdateKey()
        {
            KeyboardState key = Keyboard.GetState();
            if (key.IsKeyDown(Keys.Up)) 
            {
                direction = 3;
            }
            else if (key.IsKeyDown(Keys.Down)) 
            { 
                direction=2;
            }
            else if (key.IsKeyDown(Keys.Left)) 
            { 
                direction=1;
            }
            else if (key.IsKeyDown(Keys.Right)) 
            { 
                direction=0;
            }
            

        }
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();

            spriteBatch.Draw(bg, new Vector2(0, 0), Color.White);
            // spriteBatch.Draw(bg, screenpos - texturesize, Color.White);




            for (int i = 0; i < countsnake; i++)
            {
                if (i == 0)
                {
                    spriteBatch.Draw(role, new Vector2(_snakebody[i].x, _snakebody[i].y), Color.White);
                }
                else
                    spriteBatch.Draw(body, new Vector2(_snakebody[i].x, _snakebody[i].y), Color.White);
                spriteBatch.Draw(food, new Vector2(Fruit.x, Fruit.y), Color.White);
            }

            Vector2 FontPos = new Vector2(128,64);
            string message ="score : "+score.ToString();
            Vector2 FontOrigin = Font1.MeasureString(message) / 2; // 字串中心

            spriteBatch.DrawString(Font1,   // 字型
                                   message,  // 字串
                                   FontPos, // 位置
                                   Color.White, // 字的顏色
                                   0,         // 旋轉角度
                                   FontOrigin,// 字串中心點
                                   2.0f,      // 縮放倍數
                                   SpriteEffects.None,// 旋轉校果
                                   0); // 圖層深度 0.0 ~ 1.0 (後)



            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
