/* -LICENSE-START-
** Copyright (c) 2017 Blackmagic Design
**
** Permission is hereby granted, free of charge, to any person or organization
** obtaining a copy of the software and accompanying documentation covered by
** this license (the "Software") to use, reproduce, display, distribute,
** execute, and transmit the Software, and to prepare derivative works of the
** Software, and to permit third-parties to whom the Software is furnished to
** do so, all subject to the following:
** 
** The copyright notices in the Software and this entire statement, including
** the above license grant, this restriction and the following disclaimer,
** must be included in all copies of the Software, in whole or in part, and
** all derivative works of the Software, unless such copies or derivative
** works are solely in the form of machine-executable object code generated by
** a source language processor.
** 
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
** DEALINGS IN THE SOFTWARE.
** -LICENSE-END-
*/
using System;
using System.Drawing;
using System.Windows.Forms;
using DeckLinkAPI;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace SignalGenCSharp
{
    public partial class PreviewWindow : Control, IDeckLinkScreenPreviewCallback
    {
        private IDeckLinkDX9ScreenPreviewHelper m_previewHelper;

        private Direct3D.Device                 m_d3DDevice;

        public PreviewWindow()
        {
            m_previewHelper = new CDeckLinkDX9ScreenPreviewHelper();
            InitializeComponent();
        }

        public void InitD3D()
        {
            var d3dpp = new Direct3D.PresentParameters();
            d3dpp.BackBufferFormat = Direct3D.Format.Unknown;
            d3dpp.BackBufferCount = 2;
            d3dpp.Windowed = true;
            d3dpp.SwapEffect = Direct3D.SwapEffect.Discard;
            d3dpp.DeviceWindow = this;
            d3dpp.PresentationInterval = Direct3D.PresentInterval.Default;

            m_d3DDevice = new Direct3D.Device(0, Direct3D.DeviceType.Hardware, this, Direct3D.CreateFlags.HardwareVertexProcessing | Direct3D.CreateFlags.MultiThreaded, d3dpp);

            unsafe
            {
                m_previewHelper.Initialize(new IntPtr(m_d3DDevice.UnmanagedComPointer));
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
        }

        void Render()
        {
            m_d3DDevice.BeginScene();

            tagRECT rect;
            rect.top = m_d3DDevice.Viewport.Y;
            rect.left = m_d3DDevice.Viewport.X;
            rect.bottom = m_d3DDevice.Viewport.Y + m_d3DDevice.Viewport.Height;
            rect.right = m_d3DDevice.Viewport.X + m_d3DDevice.Viewport.Width;

            m_previewHelper.Render(rect);

            m_d3DDevice.EndScene();
            m_d3DDevice.Present();
        }

        void IDeckLinkScreenPreviewCallback.DrawFrame(IDeckLinkVideoFrame theFrame)
        {
            if (theFrame != null)
            {
                // First, pass the frame to the DeckLink screen preview helper
                m_previewHelper.SetFrame(theFrame);

                // Then draw the frame to the scene
                Render();

                System.Runtime.InteropServices.Marshal.ReleaseComObject(theFrame);
            }
        }
    }
}
