using Sandbox.ModAPI.Ingame;
using System;
using System.Collections.Generic;
using VRage.Game.GUI.TextPanel;
using VRageMath;

namespace IngameScript
{
    partial class Program
    {
        // TODO: refactor this, possibly into a SpriteFactory mixin
        public static MySprite[] BuildCheckMark(Vector2 position, float scale)
        {
            MySprite[] result = new MySprite[2];

            result[0] = new MySprite(SpriteType.TEXTURE, "SquareSimple", new Vector2(-6f, 5f) * scale + position, new Vector2(12f, 3f) * scale, Color.Green, null, TextAlignment.CENTER, 1.0472f); // short
            result[1] = new MySprite(SpriteType.TEXTURE, "SquareSimple", position, new Vector2(3f, 22f) * scale, Color.Green, null, TextAlignment.CENTER, 0.4189f); // long

            return result;
        }

        public class AirMonitorDisplay
        {
            private class ZoneRow
            {
                public AirZone Zone { get; private set; }
                public MySprite Name { get; private set; }
                public MySprite Triggered { get; private set; }
                public MySprite[] Ok;
                public MySprite Level;

                public ZoneRow(RectangleF viewport, AirZone zone, float xPadding, float xIncrement, float yIndex, float yIncrement, float scale)
                {
                    float textureSize = 25f * scale;
                    Zone = zone;
                    Name = new MySprite(SpriteType.TEXT, Zone.Name, new Vector2(xPadding, yIndex) + viewport.Position, null, Color.White, "White", TextAlignment.LEFT, scale);
                    Level = new MySprite(SpriteType.TEXT, "----", new Vector2(xIncrement, yIndex) + viewport.Position, null, Color.White, "White", TextAlignment.LEFT, scale);
                    Triggered = new MySprite(SpriteType.TEXTURE, "Danger", new Vector2(xIncrement * 2, yIndex + textureSize / 2) + viewport.Position, new Vector2(textureSize, textureSize), Color.White, null, TextAlignment.LEFT, 0f);
                    Ok = Program.BuildCheckMark(new Vector2(xIncrement * 2 + textureSize / 2, yIndex + (textureSize / 2)) + viewport.Position, scale);
                }
            }

            private IMyTextSurface _surface;
            private Dictionary<string, MySprite> _staticSprites = new Dictionary<string, MySprite>();
            private List<ZoneRow> _rows = new List<ZoneRow>();

            public AirMonitorDisplay(IMyTextSurface surface, List<AirZone> zones)
            {
                // Setup draw surface
                _surface = surface;
                _surface.ScriptBackgroundColor = new Color(0, 0, 0, 255);
                _surface.ContentType = ContentType.SCRIPT;
                _surface.Script = "";

                RectangleF viewport = new RectangleF(
                    (_surface.TextureSize - _surface.SurfaceSize) / 2f,
                    _surface.SurfaceSize
                );

                // The tuning values here are derived experimentally
                float scale = viewport.Size.Y / 400;

                float yIndex = 5f;
                float yIncrement = 35f;

                float xPadding = 2f;
                float xIncrement = viewport.Size.X / 3;

                // build static sprites
                _staticSprites["title"] = new MySprite(SpriteType.TEXT, "OXYGEN REPORT", new Vector2(viewport.Size.X / 2, yIndex) + viewport.Position, null, Color.White, "Debug", TextAlignment.CENTER, 1.3f * scale);
                yIndex += yIncrement * scale * 1.2f;
                _staticSprites["zoneHeading"] = new MySprite(SpriteType.TEXT, "ZONE", new Vector2(xPadding, yIndex) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * scale);
                _staticSprites["levelHeading"] = new MySprite(SpriteType.TEXT, "O2 LEVEL", new Vector2(xIncrement, yIndex) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * scale);
                _staticSprites["statusHeading"] = new MySprite(SpriteType.TEXT, "STATUS", new Vector2(xIncrement * 2, yIndex) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * scale);
                yIndex += yIncrement * scale * 1.1f;

                // build dynamic sprites
                foreach (AirZone zone in zones)
                {
                    _rows.Add(new ZoneRow(viewport, zone, xPadding, xIncrement, yIndex, yIncrement, scale));
                    yIndex += yIncrement * scale;
                }
            }

            public void Draw()
            {
                MySpriteDrawFrame frame = _surface.DrawFrame();

                foreach (MySprite sprite in _staticSprites.Values)
                {
                    frame.Add(sprite);
                }

                // for (int i=0; i < _rows.Count; i++)
                foreach (ZoneRow row in _rows)
                {
                    frame.Add(row.Name);
                    row.Level.Data = row.Zone.OxygenLevel.ToString("P2");
                    frame.Add(row.Level);
                    if (row.Zone.Triggered) frame.Add(row.Triggered);
                    else
                    {
                        frame.Add(row.Ok[0]);
                        frame.Add(row.Ok[1]);
                    }
                }
                frame.Dispose();
            }
        }
    }
}