using AlienAttack.MonoGame.Audio;
using AlienAttack.MonoGame.GameLoops;
using AlienAttack.MonoGame.Textures;
using AlienAttack.MonoGame.View;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System;
using System.Runtime.InteropServices;

namespace AlienAttack.MonoGame;

public class AlienAttackGame : Game
{
    private readonly GraphicsDeviceManager _graphics;
    private readonly ViewTransform _viewTransform;

    private SpriteBatch _spriteBatch;
    private GameLoop _gameLoop;

    public SpriteBatch SpriteBatch => _spriteBatch;
    public ViewTransform ViewTransform => _viewTransform;
    public AudioManager Audio { get; private set; } = new();
    public TextureCache Textures { get; } = new();

    private const string SDL = "SDL2.dll";

    [DllImport(SDL, CallingConvention = CallingConvention.Cdecl)]
    public static extern void SDL_MaximizeWindow(IntPtr window);

    public AlienAttackGame()
    {
        _graphics = new GraphicsDeviceManager(this);
        _viewTransform = new(this, _graphics);
        Content.RootDirectory = "Content";
        IsMouseVisible = true;
    }

    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        ConfigureWindow();
        SetResolution();

        IsFixedTimeStep = true;  //Force the game to update at fixed time intervals
        TargetElapsedTime = TimeSpan.FromSeconds(1 / 120.0f);  //Se

        base.Initialize();

        MaximizeWindow();

        //Audio.PlayMusic(Content, @"Music\Untitled");
    }

    private void ConfigureWindow()
    {
        Window.AllowUserResizing = true;
    }

    private void SetResolution()
    {
        _graphics.PreferredBackBufferWidth = 1280;
        _graphics.PreferredBackBufferHeight = 720;
        _graphics.ApplyChanges();
    }

    private void MaximizeWindow()
    {
        SDL_MaximizeWindow(Window.Handle);
    }

    protected override void LoadContent()
    {
        _spriteBatch = new SpriteBatch(GraphicsDevice);
        _gameLoop = new GameLoop(this);

        // TODO: use this.Content to load your game content here
        Audio.LoadContent(Content);
        Textures.Initialize(Content);
    }

    protected override void Update(GameTime gameTime)
    {
        if (IsActive == false)
            return;

        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        // TODO: Add your update logic here
        _gameLoop.Update(gameTime);

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);

        // TODO: Add your drawing code here
        _gameLoop.Draw(gameTime);

        base.Draw(gameTime);
    }
}