using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightGame
{
    public class AnimationData
    {
        public string[] frames = null;
        public double fps = 0;
        public int width = 0;
        public int height = 0;

        public AnimationData(string[] frames, double fps, int width, int height)
        {
            this.frames = frames;
            this.fps = fps;
            this.width = width;
            this.height = height;
        }
    }
    
    public class AnimatedGameObject : BaseObject
    {
        protected Rectangle rect = null;
        protected ImageBrush imageBrush = null;
        protected double timeSinceLastFrame = 0;
        protected int currentFrame = 0;
        protected AnimationData animationData = null;

        public Point Position
        {
            set
            {
                rect.SetValue(Canvas.LeftProperty, value.X);
                rect.SetValue(Canvas.TopProperty, value.Y); 
            }
            get
            {
                return new Point((double)rect.GetValue(Canvas.LeftProperty), (double)rect.GetValue(Canvas.TopProperty));
            }
        }

        public AnimatedGameObject startupAnimatedGameObject(AnimationData animationData)
        {
            base.startupBaseObject();

            // initialise variables
            this.animationData = animationData;
            currentFrame = 0;
            timeSinceLastFrame = 0;
            imageBrush = null;

            rect = new Rectangle()
            {
                Height = animationData.height,
                Width = animationData.width
            };
            rect.SetValue(Canvas.LeftProperty, 0.0d);
            rect.SetValue(Canvas.TopProperty, 0.0d);  
            (SilverlightGame.App.Current.RootVisual as Page).LayoutRoot.Children.Add(rect);

            // display the first frame
            prepareNextFrame();

            return this;
        }

        public override void shutdown()
        {
            (SilverlightGame.App.Current.RootVisual as Page).LayoutRoot.Children.Remove(rect);
            rect = null;
            base.shutdown();
        }

        public override void enterFrame(double dt)
        {
            base.enterFrame(dt);

            timeSinceLastFrame += dt;

            if (timeSinceLastFrame >= 1 / animationData.fps)
            {
                // we don't get a render event if the page is not displayed. Using this while
                // loop means that if we come back to the game after browsing another page
                // the animations don't go crazy
                while (timeSinceLastFrame >= 1 / animationData.fps)
                {
                    timeSinceLastFrame -= 1 / animationData.fps;
                    ++currentFrame;
                    currentFrame %= animationData.frames.Length;
                }

                prepareNextFrame();
            }
        }

        protected void prepareNextFrame()
        {
            // get the embedded image and display it on the rectangle
            imageBrush = new ImageBrush
            {
                Stretch = Stretch.None,
                AlignmentX = AlignmentX.Left,
                AlignmentY = AlignmentY.Top
            };
            imageBrush.ImageSource = ResourceHelper.GetBitmap(animationData.frames[currentFrame]);
            rect.Fill = imageBrush;
        }
    }


}