using System.Collections.Generic;
using System.Runtime.InteropServices;
using Decal.Interop.Core;
using Decal.Interop.D3DService;

namespace Decal.D3DService
{
    [ComVisible(true)]
    [Guid("F0CC07A0-2C89-4FA4-9356-714665BC2F8B")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("D3DService.CService")]
    public class D3DServiceImpl : ID3DService, IDecalService, IDecalRender
    {
        private readonly List<D3DObjImpl> _objects = new List<D3DObjImpl>();

        private CD3DObj CreateObj()
        {
            var obj = new D3DObjImpl();
            _objects.Add(obj);
            return (CD3DObj)(object)obj;
        }

        // ID3DService
        public CD3DObj NewD3DObj() => CreateObj();

        public CD3DObj PointToObject(int guid, int color)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetShape(eShape.eVArrow);
            ((ID3DObj)obj).color = color;
            ((ID3DObj)obj).AnchorToObject(guid, 1.0f, 0, 0, 0);
            return obj;
        }

        public CD3DObj PointToCoords(float lat, float lng, float alt, int color)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetShape(eShape.eVArrow);
            ((ID3DObj)obj).color = color;
            ((ID3DObj)obj).AnchorToCoords(lat, lng, alt);
            return obj;
        }

        public CD3DObj MarkObjectWithIcon(int guid, int icon)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetIcon(icon);
            ((ID3DObj)obj).AnchorToObject(guid, 1.0f, 0, 0, 0);
            return obj;
        }

        public CD3DObj MarkObjectWithIconFromFile(int guid, string filename)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetIconFromFile(filename);
            ((ID3DObj)obj).AnchorToObject(guid, 1.0f, 0, 0, 0);
            return obj;
        }

        public CD3DObj MarkObjectWithShape(int guid, eShape shape, int color)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetShape(shape);
            ((ID3DObj)obj).color = color;
            ((ID3DObj)obj).AnchorToObject(guid, 1.0f, 0, 0, 0);
            return obj;
        }

        public CD3DObj MarkObjectWithShapeFromFile(int guid, string filename, int color)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetShapeFromFile(filename);
            ((ID3DObj)obj).color = color;
            ((ID3DObj)obj).AnchorToObject(guid, 1.0f, 0, 0, 0);
            return obj;
        }

        public CD3DObj MarkCoordsWithIcon(float lat, float lng, float alt, int icon)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetIcon(icon);
            ((ID3DObj)obj).AnchorToCoords(lat, lng, alt);
            return obj;
        }

        public CD3DObj MarkCoordsWithIconFromFile(float lat, float lng, float alt, string filename)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetIconFromFile(filename);
            ((ID3DObj)obj).AnchorToCoords(lat, lng, alt);
            return obj;
        }

        public CD3DObj MarkCoordsWithShape(float lat, float lng, float alt, eShape shape, int color)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetShape(shape);
            ((ID3DObj)obj).color = color;
            ((ID3DObj)obj).AnchorToCoords(lat, lng, alt);
            return obj;
        }

        public CD3DObj MarkCoordsWithShapeFromFile(float lat, float lng, float alt, string filename, int color)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).SetShapeFromFile(filename);
            ((ID3DObj)obj).color = color;
            ((ID3DObj)obj).AnchorToCoords(lat, lng, alt);
            return obj;
        }

        public void TraceOneFrame() { }

        public CD3DObj MarkObjectWith2DText(int guid, string szText, string szFont, int options)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).Set2DText(szText, szFont, options);
            ((ID3DObj)obj).AnchorToObject(guid, 1.0f, 0, 0, 0);
            return obj;
        }

        public CD3DObj MarkObjectWith3DText(int guid, string szText, string szFont, int options)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).Set3DText(szText, szFont, options);
            ((ID3DObj)obj).AnchorToObject(guid, 1.0f, 0, 0, 0);
            return obj;
        }

        public CD3DObj MarkCoordsWith2DText(float lat, float lng, float alt, string szText, string szFont, int options)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).Set2DText(szText, szFont, options);
            ((ID3DObj)obj).AnchorToCoords(lat, lng, alt);
            return obj;
        }

        public CD3DObj MarkCoordsWith3DText(float lat, float lng, float alt, string szText, string szFont, int options)
        {
            var obj = CreateObj();
            ((ID3DObj)obj).Set3DText(szText, szFont, options);
            ((ID3DObj)obj).AnchorToCoords(lat, lng, alt);
            return obj;
        }

        // IDecalService
        public void Initialize(DecalCore pDecal) { }
        public void BeforePlugins() { }
        public void AfterPlugins() { }
        public void Terminate() { _objects.Clear(); }

        // IDecalRender
        public void Render2D() { }
        public void Render3D() { }
        public void PreReset() { }
        public void PostReset() { }
        public void ChangeHWND() { }
        public void ChangeDirectX() { }
    }
}
