using System;
using System.Runtime.InteropServices;

namespace Nativ {

    

    [StructLayout(LayoutKind.Sequential)]
    public struct PCMWAVEFORMAT {
        public short wFormatTag;
        public short nChannels;
        public int nSamplesPerSec;
        public int nAvgBytesPerSec;
        public short nBlockAlign;
        public short wBitsPerSample;
        public short cbSize;
    }

    [StructLayout(LayoutKind.Sequential,Pack = 1)]
    public struct BITMAPFILEHEADER {
        public Int16 bfType; //"magic cookie" - must be "BM"
        public Int32 bfSize;
        public Int16 bfReserved1;
        public Int16 bfReserved2;
        public Int32 bfOffBits;
    }


    [StructLayout(LayoutKind.Sequential,Pack = 1)]
    public struct AVIFILEINFO {
        public Int32 dwMaxBytesPerSecond;
        public Int32 dwFlags;
        public Int32 dwCaps;
        public Int32 dwStreams;
        public Int32 dwSuggestedBufferSize;
        public Int32 dwWidth;
        public Int32 dwHeight;
        public Int32 dwScale;
        public Int32 dwRate;
        public Int32 dwLength;
        public Int32 dwEditCount;
        [MarshalAs(UnmanagedType.ByValArray,SizeConst = 64)]
        public char[] szFileType;
    }


    /// <summary>
    /// This class represents WAVEFORMATEX structure.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct WAVEFORMATEX {
        public ushort wFormatTag;
        public ushort nChannels;
        public uint nSamplesPerSec;
        public uint nAvgBytesPerSec;
        public ushort nBlockAlign;
        public ushort wBitsPerSample;
        public ushort cbSize;
    }

    /// <summary>AviSaveV needs a pointer to a pointer to an AVICOMPRESSOPTIONS structure</summary>
    [StructLayout(LayoutKind.Sequential,Pack = 1)]
    public class AVICOMPRESSOPTIONS_CLASS {
        public UInt32 fccType;
        public UInt32 fccHandler;
        public UInt32 dwKeyFrameEvery;  // only used with AVICOMRPESSF_KEYFRAMES
        public UInt32 dwQuality;
        public UInt32 dwBytesPerSecond; // only used with AVICOMPRESSF_DATARATE
        public UInt32 dwFlags;
        public IntPtr lpFormat;
        public UInt32 cbFormat;
        public IntPtr lpParms;
        public UInt32 cbParms;
        public UInt32 dwInterleaveEvery;

        //public AVICOMPRESSOPTIONS ToStruct() {
        //    AVICOMPRESSOPTIONS returnVar = new AVICOMPRESSOPTIONS();
        //    returnVar.fccType = this.fccType;
        //    returnVar.fccHandler = this.fccHandler;
        //    returnVar.dwKeyFrameEvery = this.dwKeyFrameEvery;
        //    returnVar.dwQuality = this.dwQuality;
        //    returnVar.dwBytesPerSecond = this.dwBytesPerSecond;
        //    returnVar.dwFlags = this.dwFlags;
        //    returnVar.lpFormat = this.lpFormat;
        //    returnVar.cbFormat = this.cbFormat;
        //    returnVar.lpParms = this.lpParms;
        //    returnVar.cbParms = this.cbParms;
        //    returnVar.dwInterleaveEvery = this.dwInterleaveEvery;
        //    return returnVar;
        //}
    }


    // Define the coordinates of the upper-left and
    // lower-right corners of a rectangle
    [StructLayout(LayoutKind.Sequential,Pack = 1)]
    public struct RECT {
        [MarshalAs(UnmanagedType.I4)]
        public int left;
        [MarshalAs(UnmanagedType.I4)]
        public int top;
        [MarshalAs(UnmanagedType.I4)]
        public int right;
        [MarshalAs(UnmanagedType.I4)]
        public int bottom;
    }

    // Contains information for a single stream
    [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode,Pack = 1)]
    public struct AVISTREAMINFO {
        [MarshalAs(UnmanagedType.I4)]
        public int type;
        [MarshalAs(UnmanagedType.I4)]
        public int handler;
        [MarshalAs(UnmanagedType.I4)]
        public int dwFlags;
        [MarshalAs(UnmanagedType.I4)]
        public int dwCaps;
        [MarshalAs(UnmanagedType.I2)]
        public short wPriority;
        [MarshalAs(UnmanagedType.I2)]
        public short wLanguage;
        [MarshalAs(UnmanagedType.I4)]
        public int scale;
        [MarshalAs(UnmanagedType.I4)]
        public int rate;		// dwRate / dwScale == samples/second
        [MarshalAs(UnmanagedType.I4)]
        public int dwStart;
        [MarshalAs(UnmanagedType.I4)]
        public int length;
        [MarshalAs(UnmanagedType.I4)]
        public int initialFrames;
        [MarshalAs(UnmanagedType.I4)]
        public int suggestedBufferSize;
        [MarshalAs(UnmanagedType.I4)]
        public int quality;
        [MarshalAs(UnmanagedType.I4)]
        public int sampleSize;
        [MarshalAs(UnmanagedType.Struct,SizeConst = 16)]
        public RECT rectFrame;
        [MarshalAs(UnmanagedType.I4)]
        public int dwEditCount;
        [MarshalAs(UnmanagedType.I4)]
        public int dwFormatChangeCount;
        [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 64)]
        public string name;
    }

    // Contains information about the dimensions and color format of a DIB
    [StructLayout(LayoutKind.Sequential,Pack = 1)]
    public struct BITMAPINFOHEADER {
       
        [MarshalAs(UnmanagedType.I4)]
        public int size;
        [MarshalAs(UnmanagedType.I4)]
        public int width;
        [MarshalAs(UnmanagedType.I4)]
        public int height;
        [MarshalAs(UnmanagedType.I2)]
        public short planes;
        [MarshalAs(UnmanagedType.I2)]
        public short bitCount;
        [MarshalAs(UnmanagedType.I4)]
        public int compression;
        [MarshalAs(UnmanagedType.I4)]
        public int sizeImage;
        [MarshalAs(UnmanagedType.I4)]
        public int biXPelsPerMeter;
        [MarshalAs(UnmanagedType.I4)]
        public int biYPelsPerMeter;
        [MarshalAs(UnmanagedType.I4)]
        public int biClrUsed;
        [MarshalAs(UnmanagedType.I4)]
        public int biClrImportant;
    }

    // Contains information about a stream and how it is compressed and saved
    [StructLayout(LayoutKind.Sequential,Pack = 1)]
    public struct AVICOMPRESSOPTIONS {
        [MarshalAs(UnmanagedType.I4)]
        public int fccType;
        [MarshalAs(UnmanagedType.I4)]
        public int handler;
        [MarshalAs(UnmanagedType.I4)]
        public int dwKeyFrameEvery;
        [MarshalAs(UnmanagedType.I4)]
        public int quality;
        [MarshalAs(UnmanagedType.I4)]
        public int dwBytesPerSecond;
        [MarshalAs(UnmanagedType.I4)]
        public int dwFlags;
        [MarshalAs(UnmanagedType.I4)]
        public int lpFormat;
        [MarshalAs(UnmanagedType.I4)]
        public int cbFormat;
        [MarshalAs(UnmanagedType.I4)]
        public int lpParms;
        [MarshalAs(UnmanagedType.I4)]
        public int cbParms;
        [MarshalAs(UnmanagedType.I4)]
        public int dwInterleaveEvery;
    }

    // --- enumerations

    // File access modes
    [Flags]
    public enum OpenFileMode {
        Read = 0x00000000,
        Write = 0x00000001,
        ReadWrite = 0x00000002,
        ShareCompat = 0x00000000,
        ShareExclusive = 0x00000010,
        ShareDenyWrite = 0x00000020,
        ShareDenyRead = 0x00000030,
        ShareDenyNone = 0x00000040,
        Parse = 0x00000100,
        Delete = 0x00000200,
        Verify = 0x00000400,
        Cancel = 0x00000800,
        Create = 0x00001000,
        Prompt = 0x00002000,
        Exist = 0x00004000,
        Reopen = 0x00008000
    }
    [Flags]
    public enum StreamType:uint {
        /// <summary>
        /// Indicates an audio stream.
        /// </summary>
        AUDIO = 1935963489,
        /// <summary>
        /// Indicates a MIDI stream.
        /// </summary>
        MIDI = 1935960429,
        /// <summary>
        /// Indicates a text stream.
        /// </summary>
        TEXT = 1937012852,
        /// <summary>
        /// Indicates a video stream.
        /// </summary>
        VIDEO = 1935960438
    }
    [Flags]
    public enum AviError:uint {
        /// <summary>
        /// Compression is not supported for this type of data.
        /// This error might be returned if you try to compress
        /// data that is not audio or video.
        /// </summary>
        AVIERR_UNSUPPORTED = 0x80044065,
        /// <summary>
        /// The file couldn't be read, indicating a corrupt file or an unrecognized format
        /// </summary>
        AVIERR_BADFORMAT = 0x80044066,
        /// <summary>
        /// There is not enough memory to complete the operation.
        /// </summary>
        AVIERR_MEMORY = 0x80044067,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_INTERNAL = 0x80044068,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_BADFLAGS = 0x80044069,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_BADPARAM = 0x8004406A,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_BADSIZE = 0x8004406B,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_BADHANDLE = 0x8004406C,
        /// <summary>
        /// A disk error occurred while reading the file
        /// </summary>
        AVIERR_FILEREAD = 0x8004406D,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_FILEWRITE = 0x8004406E,
        /// <summary>
        /// A disk error occurred while opening the file
        /// </summary>
        AVIERR_FILEOPEN = 0x8004406F,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_COMPRESSOR = 0x80044070,
        /// <summary>
        /// A suitable compressor cannot be found.
        /// </summary>
        AVIERR_NOCOMPRESSOR = 0x80044071,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_READONLY = 0x80044072,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_NODATA = 0x80044073,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_BUFFERTOOSMALL = 0x80044074,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_CANTCOMPRESS = 0x80044075,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_USERABORT = 0x800440C6,
        /// <summary>
        ///
        /// </summary>
        // TODO : Put documentation
        AVIERR_ERROR = 0x800440C7,
        /// <summary>
        /// Operation successful
        /// </summary>
        AVIERR_OK = 0x0
    }

}
