//seamless texture free
// http://www.free-seamless-textures.com/

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
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D myBGTexture;
        Texture2D eat;
        Texture2D mySpriteTexture;
        Texture2D dust;
        Texture2D start;
        Texture2D stop;
        Texture2D ya;
        Texture2D no;
        Song song;
        int Offset_X = 0;  // X 軸 偏移値
        int Offset_Y = 0;  // Y 軸 偏移値
        int TDX=0, TDY = 0;
        int ex=100, ey=50;
        int dx = 500, dy = 30;
        SpriteFont Font1; // 字型物件
        int count = 0;
        int enter=0;
        Boolean col = false,col2=false,ohya=false ,ohno=false;

        Rectangle[,] srcRect = new Rectangle[4, 4];
        int pcW = 100; // 主角的寬
        int pcH = 140; // 主角的高
        int Dir = 0; // 走路的方向 0 往上 1 往下 2 往左 3 往右
        int Seq = 0; // 該方向走路的第幾個動作
        bool pcStop = true; // 主角 停止走路
        KeyboardState oldState;
        double StepDuration = 0;
        int times=60;
        System.Timers.Timer time = new System.Timers.Timer(10000);
        System.Timers.Timer timeout = new System.Timers.Timer(1000);
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            this.IsMouseVisible = true;  // 呈現滑鼠游標
            this.Window.AllowUserResizing = false; // 允許視窗縮放
            graphics.PreferredBackBufferWidth = 1000;  //視窗的預設寬
            graphics.PreferredBackBufferHeight = 600; //視窗的預設高

            this.Window.Title = "Totoro大冒險";

            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 4; j++)
                {
                    srcRect[i, j] = new Rectangle(j * pcW, i * pcH, pcW, pcH);
                }
            
            time.Elapsed += new System.Timers.ElapsedEventHandler(theout);
            time.AutoReset = true;//設置是執行一次（false）還是一直執行(true)； 

            time.Enabled = true;//是否執行System.Timers.Timer.Elapsed事件；
            timeout.Elapsed += new System.Timers.ElapsedEventHandler(timeup);
            timeout.AutoReset = true;//設置是執行一次（false）還是一直執行(true)； 

            timeout.Enabled = true;//是否執行System.Timers.Timer.Elapsed事件；
            
        }

        /// <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

            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
            myBGTexture = Content.Load<Texture2D>("grass2");
            eat = Content.Load<Texture2D>("acorn1");
            mySpriteTexture = Content.Load<Texture2D>("totoroall");
            dust = Content.Load<Texture2D>("dust");
            start = Content.Load<Texture2D>("start");
            stop = Content.Load<Texture2D>("stop");
            ya = Content.Load<Texture2D>("ya");
            no = Content.Load<Texture2D>("no");
            Font1 = Content.Load<SpriteFont>("SpriteFont1");
            MediaPlayer.IsRepeating = true;
            song = Content.Load<Song>("Ponyo");
            MediaPlayer.Play(song);
        }

        /// <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)
        {
            int W = graphics.GraphicsDevice.Viewport.Width;
            int H = graphics.GraphicsDevice.Viewport.Height;
             TDX = Offset_X;  TDY = Offset_Y;
            if ((this.Window.ClientBounds.Width / 2 - pcW / 2) + TDX + pcW >= W)
                TDX = W - (this.Window.ClientBounds.Width / 2 - pcW / 2) - pcW;
            if ((this.Window.ClientBounds.Width / 2 - pcW / 2) + TDX <= 0)
              TDX = -(this.Window.ClientBounds.Width / 2 - pcW / 2);
            if ((this.Window.ClientBounds.Height / 2 - pcH / 2) + TDY + pcH >= H)
                TDY = H - (this.Window.ClientBounds.Height / 2 - pcH / 2) - pcH;
            if ((this.Window.ClientBounds.Height / 2 - pcH / 2) + TDY <= 0)
                TDY = -(this.Window.ClientBounds.Height / 2 - pcH / 2);
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            KeyboardState newState;  // 宣告一個 KeyboardState 結構的變數
            newState = Keyboard.GetState();  //得到目前鍵盤全部按鍵的狀況
            if (newState.IsKeyDown(Keys.Escape)) this.Exit();  //判斷Esc鍵是否已經被按下
            else if (newState.IsKeyDown(Keys.Down)) // && Dir != 0)
            {
                Dir = 0;
                Seq = 0;
                pcStop = false;
            }else if (newState.IsKeyDown(Keys.Up) ) // && Dir != 1)
            {
                Dir = 1;
                Seq = 0;
                pcStop = false;
            }
            
            else if (newState.IsKeyDown(Keys.Right)) // && Dir != 2)
            {
                Dir = 2;
                Seq = 0;
                pcStop = false;
            }else if (newState.IsKeyDown(Keys.Left)) // && Dir != 3)
            {
                Dir = 3;
                Seq = 0;
                pcStop = false;
            }
            
            
            else if (newState.IsKeyDown(Keys.Space) && oldState.IsKeyUp(Keys.Space))
            {
                pcStop = !pcStop;
            }
            else if (!pcStop)
            {
                StepDuration += gameTime.ElapsedGameTime.TotalMilliseconds;
                if (StepDuration > 300)
                {
                    StepDuration = 0;
                    Seq++;  // 下一張
                    Seq = Seq % 4; // 每一方向只有四張
                }
                
            }

            oldState = newState;

            if (pcStop) { }
            else if (Dir == 0) // 向下
                Offset_Y += 2;
            else if (Dir == 1) // 向上
                Offset_Y -= 2;
            else if (Dir == 2) // 向右
                Offset_X += 2;
            else if (Dir == 3) // 向左
                Offset_X -= 2;
            Vector2 a = new Vector2((this.Window.ClientBounds.Width / 2 - pcW / 2) + TDX, (this.Window.ClientBounds.Height / 2 - pcH / 2) + TDY);
            Vector2 b = new Vector2(ex, ey);
            Vector2 c = new Vector2(dx, dy);
            if (times <= 0) { TDX = 0; TDY = 0; }
            if (collide(mySpriteTexture, a, eat, b) && col && times > 0) { count+=10; ohya = true; ohno = false;
            Random rx = new Random(); Random ry = new Random();
            ex = (rx.Next(0, W - eat.Width / 2 - 10) + 10); ey = (ry.Next(0, H - eat.Height / 2));
            dx = (ry.Next(0, W - dust.Width)); dy = (rx.Next(0, H - dust.Height));
            }
            if (collide(mySpriteTexture, a, dust, c) && col2 && times > 0) { count-=5; ohno = true; ohya = false;
            Random rx = new Random(); Random ry = new Random();
            ex = (rx.Next(0, W - eat.Width / 2 - 10) + 10); ey = (ry.Next(0, H - eat.Height / 2));
            dx = (ry.Next(0, W - dust.Width)); dy = (rx.Next(0, H - dust.Height));
            }
           if (collide(eat, b, dust, c))
            {
                Random rx = new Random(); Random ry = new Random();
                ex = (rx.Next(0, W - eat.Width / 2 - 10) + 10); ey = (ry.Next(0, H - eat.Height / 2));
                dx = (ry.Next(0, W - dust.Width)); dy = (rx.Next(0, H - dust.Height));
            }
            if (newState.IsKeyDown(Keys.Enter)  && enter == 0)
            {
                enter = 1;
                oldState = newState;
            }
             
            base.Update(gameTime);
            
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        /// 
        public void theout(object source, System.Timers.ElapsedEventArgs e) {
            int W = graphics.GraphicsDevice.Viewport.Width;
            int H = graphics.GraphicsDevice.Viewport.Height;
            Random rx = new Random(); Random ry = new Random();
            ex=(rx.Next(0, W - eat.Width )); ey=(ry.Next(0, H - eat.Height ));
            dx = (ry.Next(0, W - dust.Width));dy=(rx.Next(0,H-dust.Height));
            col = true;
            col2 = true;
        }
        public void timeup(object source, System.Timers.ElapsedEventArgs e) {
            if(enter==1)
            times--;
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            // TODO: Add your drawing code here
            int W = graphics.GraphicsDevice.Viewport.Width;
            int H = graphics.GraphicsDevice.Viewport.Height;
            /*Random rx = new Random(); Random ry = new Random();
            int ex,ey;
            ex=rx.Next(0, W - eat.Width / 2); ey=ry.Next(0, H - eat.Height / 2);*/
           /* int TDX = Offset_X; int TDY = Offset_Y;
            if ((this.Window.ClientBounds.Width / 2 - pcW / 2) + TDX + pcW >= W)
                TDX = W - (this.Window.ClientBounds.Width / 2 - pcW / 2) - pcW;
            if ((this.Window.ClientBounds.Width / 2 - pcW / 2) + TDX <= 0)
              TDX = -(this.Window.ClientBounds.Width / 2 - pcW / 2);
            if ((this.Window.ClientBounds.Height / 2 - pcH / 2) + TDY + pcH >= H)
                TDY = H - (this.Window.ClientBounds.Height / 2 - pcH / 2) - pcH;
            if ((this.Window.ClientBounds.Height / 2 - pcH / 2) + TDY <= 0)
                TDY = -(this.Window.ClientBounds.Height / 2 - pcH / 2);*/
            Vector2 s = new Vector2(0, 0);
            if (enter == 0)
                spriteBatch.Draw(start, s, Color.White);
            if (enter == 1)
            {
                
                for (int i = -1; i <= W / myBGTexture.Width + 1; i++)        // i 是 X 方向 要貼幾次
                {
                    for (int j = -1; j <= H / myBGTexture.Height + 1; j++)  // j 是 Y 方向 要貼幾次
                    {
                        Vector2 position = new Vector2(
                                           i * myBGTexture.Width,
                                           j * myBGTexture.Height); // 算出要 貼上的位置

                        spriteBatch.Draw(myBGTexture, position, Color.White);
                    }
                }

                Rectangle DesRect = new Rectangle(
                       (this.Window.ClientBounds.Width / 2 - pcW / 2) + TDX,
                       (this.Window.ClientBounds.Height / 2 - pcH / 2) + TDY,
                       pcW, pcH);
                Rectangle srcyano = new Rectangle((this.Window.ClientBounds.Width / 2 - pcW / 2) + TDX,
                     (this.Window.ClientBounds.Height / 2 - pcH / 2) + TDY-no.Height,
                       no.Width, no.Height);
                Rectangle src = new Rectangle(ex, ey, eat.Width, eat.Height);
                spriteBatch.Draw(eat, src, Color.White);
                Rectangle src2 = new Rectangle(dx, dy, dust.Width, dust.Height);
                spriteBatch.Draw(dust, src2, Color.White);
                spriteBatch.Draw(mySpriteTexture,
                                 DesRect,
                                 srcRect[Dir, Seq], Color.White);

                if (ohya) spriteBatch.Draw(ya, srcyano, Color.White);
                if (ohno) spriteBatch.Draw(no, srcyano, Color.White);
                Vector2 a = new Vector2((this.Window.ClientBounds.Width / 2 - pcW / 2) + TDX, (this.Window.ClientBounds.Height / 2 - pcH / 2) + TDY);
                Vector2 b = new Vector2(ex, ey);

                Vector2 FontPos = new Vector2(600, 32);
                string message = times.ToString();
                Vector2 FontOrigin = Font1.MeasureString(message) / 2; // 字串中心

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



                /*   Vector2 FontPos2 = new Vector2(200, 32);
                   string message2 = b.X.ToString();
                   Vector2 FontOrigin2 = Font1.MeasureString(message) / 2; // 字串中心

                   spriteBatch.DrawString(Font1, // 字型
                   message2, // 字串
                   FontPos2, // 位置
                   Color.Red, // 字的顏色
                   0, // 旋轉角度
                   FontOrigin2,// 字串中心點
                   1.5f, // 縮放倍數
                   SpriteEffects.None,// 旋轉校果
                   0); // 圖層深度 0.0 ~ 1.0 (後)
               */
                //if (collide(mySpriteTexture, a, eat, b)) {

                Vector2 FontPos3 = new Vector2(150, 32);
                string message3 = "Score:" + count.ToString();
                Vector2 FontOrigin3 = Font1.MeasureString(message3) / 2; // 字串中心

                spriteBatch.DrawString(Font1, // 字型
                message3, // 字串
                FontPos3, // 位置
                Color.Red, // 字的顏色
                0, // 旋轉角度
                FontOrigin3,// 字串中心點
                2f, // 縮放倍數
                SpriteEffects.None,// 旋轉校果
                0); // 圖層深度 0.0 ~ 1.0 (後)
                //}
                if (times <= 0)
                {
                    MediaPlayer.Stop();
                    spriteBatch.Draw(stop, s, Color.White);
                    Vector2 FontPos2 = new Vector2(400, 300);
                    string message2 = "Score:"+count.ToString();
                    Vector2 FontOrigin2 = Font1.MeasureString(message) / 2; // 字串中心

                    spriteBatch.DrawString(Font1, // 字型
                    message2, // 字串
                    FontPos2, // 位置
                    Color.Tomato, // 字的顏色
                    0, // 旋轉角度
                    FontOrigin2,// 字串中心點
                    3f, // 縮放倍數
                    SpriteEffects.None,// 旋轉校果
                    0); // 圖層深度 0.0 ~ 1.0 (後)
                    time.Stop();
                    timeout.Stop();
                }

            }
            spriteBatch.End();
            base.Draw(gameTime);
        }

        public Boolean collide(Texture2D a,Vector2 apos,Texture2D b,Vector2 bpos) {
            if (apos.X + pcW > bpos.X && apos.X < bpos.X + b.Width &&
                apos.Y + pcH > bpos.Y && apos.Y < bpos.Y + b.Height) return true;
            return false;
        }
    }
}
