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 XNA_Aquarium
{
    //Eine Klasse für Tintenkleckse
    public class TintenKlecks
    {
        //Position des Kleckses
        public Vector2 posKlecks;
        //Achse zum drehen
        public Vector2 posOrigin;
        //Rotions-Winkel
        public float fRotation;
        //Transparenz
        public int iTransparenz;
        //Dauer der Anzeige
        public TimeSpan StartTime;
    }
    public class Krake : Microsoft.Xna.Framework.DrawableGameComponent
    {
        //Lokales spriteBatch Objekt
        SpriteBatch spriteBatch;
        //Lokales Game Objekt
        Game game;
        //Textur des Kraken
        Texture2D texKrake;
        //Textur der Tinte
        Texture2D texTinte;
        //X Achse des Sensors merken
        double letztesX = 0;
        //Wird "geschüttelt"
        bool boSchuetteln = false;
        //Position des Kraken
        Vector2 posKrake;
        //Bewegung der Krake
        float fXMovement = 0.5F;
        float fYMovement = 0.5F;
        //Panik: Schnellere Bewegung
        float fPanik = 0;
        //Accelerometer
        Microsoft.Devices.Sensors.Accelerometer accelerometer = new Microsoft.Devices.Sensors.Accelerometer();
        //Liste für TintenKleckse
        List<TintenKlecks> tintenkleckse = new List<TintenKlecks>();
        SoundEffect sndTinte;
        public Krake(Game game)
            : base(game)
        {
            //Game speichern
            this.game = game;
        }

        public override void Initialize()
        {
            //Acceleromter registrieren und starten
            accelerometer.ReadingChanged += new EventHandler<Microsoft.Devices.Sensors.AccelerometerReadingEventArgs>(accelerometer_ReadingChanged);
            accelerometer.Start();
            //Kraken initial positionieren
            posKrake = new Vector2(700, 200);
            base.Initialize();
        }

        void accelerometer_ReadingChanged(object sender, Microsoft.Devices.Sensors.AccelerometerReadingEventArgs e)
        {
            //Wenn die X Achse um >0.7 gegenüber des letzten lesens bewegt wird gilt es als "Schütteln"
            double deltaX = Math.Abs((double)(letztesX - e.X));
            if (Math.Abs((double)(letztesX - e.X)) > 0.7)
            {
                boSchuetteln = true;
            }
            else
            {
                if (boSchuetteln)
                    boSchuetteln = false;
            }
            //Für die nächste Abfrage speichern
            letztesX = e.X;
        }

        protected override void LoadContent()
        {
            //Das spriteBatch Objekt der Game Klasse abfragen
            spriteBatch = (SpriteBatch)game.Services.GetService(typeof(SpriteBatch));
            //Kraken-Textur laden
            texKrake = game.Content.Load<Texture2D>("Krake");
            //Tintenkleks-Textur laden
            texTinte = game.Content.Load<Texture2D>("Tintenklecks");
            //SoundEffect laden
            sndTinte = game.Content.Load<SoundEffect>("TintenklecksSound");
            base.LoadContent();
        }

        public override void Update(GameTime gameTime)
        {
            //Wenn "geschüttelt" wird einen neuen Tintenkleks erzeugen
            if (boSchuetteln)
            {
                TintenKlecks tk = new TintenKlecks();
                //Keine Rotation
                tk.fRotation = 0;
                //Vollständig sichtbar
                tk.iTransparenz = 255;
                //Positionieren
                tk.posKlecks = new Vector2(posKrake.X+(texTinte.Width/2),posKrake.Y+(texTinte.Height/2));
                tk.posOrigin = new Vector2(texTinte.Width / 2, texTinte.Height / 2);
                //Startzeit festhalten
                tk.StartTime = gameTime.TotalGameTime;
                //Der Liste hinzufügen
                tintenkleckse.Add(tk);
                //Panik erhöhen
                fPanik += 2;
                //Maximale Panik prüfen & festlegen
                if (fPanik > 10)
                    fPanik = 10;
                //Vibrieren
                Microsoft.Devices.VibrateController vibrate;
                vibrate = Microsoft.Devices.VibrateController.Default;
                vibrate.Start(TimeSpan.FromSeconds(0.2));
                //Sound abspielen
                sndTinte.Play();
            }
            //Alle Tintenflecke durchlaufen
            foreach (TintenKlecks tk in tintenkleckse)
            {
                //Rotation erhöhen
                tk.fRotation += 0.1F;
                if (tk.fRotation > 360)
                    tk.fRotation = 0;
                //Transparenz erhöhen (innerhlab von 10 Sekunden komplett verblassen)
                tk.iTransparenz = (int)Math.Abs(255.0F - ((255.0F / 10000.0F) * (float)(gameTime.TotalGameTime.TotalMilliseconds - tk.StartTime.TotalMilliseconds)));
            }
            //Flecke die nicht mehr sichtbar sind aus der Liste entfernen
            for (int i = 0; i < tintenkleckse.Count; i++)
            {
                if (tintenkleckse[i].iTransparenz <= 0)
                {
                    tintenkleckse.RemoveAt(i);
                    if (tintenkleckse.Count < 5)
                        fPanik -= 2;
                }
            }
            //Kraken bewegen
            if (fPanik == 0)
            {
                posKrake.X += fXMovement;
                posKrake.Y += fYMovement;
            }
            else
            {
                if (fXMovement <= 0.5 && fXMovement >= -0.5)
                {
                    if (fXMovement > 0)
                        fXMovement += fPanik;
                    else
                        fXMovement -= fPanik;
                }
                if (fYMovement <= 0.5 && fYMovement >= -0.5)
                {
                    if (fYMovement > 0)
                        fYMovement += fPanik;
                    else
                        fYMovement -= fPanik;
                }
                posKrake.X += fXMovement;
                posKrake.Y += fYMovement;
            }
            //Kollision prüfen und Richtung ändern
            if (posKrake.X > 800 - texKrake.Width)
                fXMovement = -0.5F;
            if (posKrake.X < 0)
                fXMovement = 0.5F;
            if (posKrake.Y < 80)
                fYMovement = 0.5F;
            if (posKrake.Y > 300 - texKrake.Height)
                fYMovement = -0.5F;
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            //Kraken zeichen
            spriteBatch.Draw(texKrake, posKrake, Color.White);
            //Alle Tintenflecke zeichnen
            foreach(TintenKlecks tk in tintenkleckse)
                spriteBatch.Draw(texTinte, tk.posKlecks, null, new Color(0, 0, 255, tk.iTransparenz), tk.fRotation, tk.posOrigin, 1.0f, SpriteEffects.None, 0);
            base.Draw(gameTime);
        }
    }
}
