using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Interop;

namespace TwoMbit {

    public class DLLCore {

        //snes
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setHwnd")]
        static extern void snesSetHwnd(IntPtr wih);
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clearVideo")]
        static extern void snesClearVideo();
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clearAudio")]
        static extern void snesClearAudio();
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "pauseAudio")]
        static extern void snesPauseAudio();
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "playAudio")]
        static extern void snesPlayAudio();
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "test")]
        static extern void snesCoreTest();
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "power")]
        static extern void snesPower();
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "reset")]
        static extern void snesReset();
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "enter")]
        static extern void snesEnter();
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setCartMemory")]
        public static extern void snesSetCartMemory(byte[] rom, uint romSize, byte[] sram, uint sramSize, byte[] rtc, uint rtcSize, byte[] slotArom, uint slotAromSize, byte[] slotAsram, uint slotAsramSize, byte[] slotBrom, uint slotBromSize, byte[] slotBsram, uint slotBsramSize);
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "map")]
        static extern void snesMap(Header.Type type, Header.Region region, uint unit);
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "initVideo")]
        [return: MarshalAs(UnmanagedType.I1)]
        static extern bool snesInitVideo(IntPtr wih, int width, int height, bool vsync, bool fullscreen);
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "initSound")]
        [return: MarshalAs(UnmanagedType.I1)]
        static extern bool snesInitSound(bool audio_active, uint speed, uint frequency, uint volume);
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "updateColor")]
        static extern void snesUpdateColor(int contrast, int gamma, int brightness, int filter_type, int ntsc_filter_cable, bool ntsc_filter_merge);
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setHWFilter")]
        static extern void snesSetHwFilter(int filter);
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setCounter")]
        static extern void snesSetCounter(bool state);
        [DllImport(@"SnesCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setScanlines")]
        static extern void snesSetScanlines(bool state, uint intensity);

        //genesis
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setHwnd")]
        static extern void genSetHwnd(IntPtr wih);
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clearVideo")]
        static extern void genClearVideo();
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clearAudio")]
        static extern void genClearAudio();
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "pauseAudio")]
        static extern void genPauseAudio();
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "playAudio")]
        static extern void genPlayAudio();
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "test")]
        static extern void genCoreTest();
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "power")]
        static extern void genPower();
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "reset")]
        static extern void genReset();
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "enter")]
        static extern void genEnter();
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setCartMemory")]
        public static extern void genSetCartMemory(byte[] rom, uint romSize, byte[] sram, uint sramSize);
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "map")]
        static extern void genMap(Header.Type type, Header.Region region, uint unit);
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "initVideo")]
        [return: MarshalAs(UnmanagedType.I1)]
        static extern bool genInitVideo(IntPtr wih, int width, int height, bool vsync, bool fullscreen);
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "initSound")]
        [return: MarshalAs(UnmanagedType.I1)]
        static extern bool genInitSound(bool audio_active, uint speed, uint frequency, uint volume);
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "updateColor")]
        static extern void genUpdateColor(int contrast, int gamma, int brightness, int filter_type, int ntsc_filter_cable, bool ntsc_filter_merge);
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setHWFilter")]
        static extern void genSetHwFilter(int filter);
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setCounter")]
        static extern void genSetCounter(bool state);
        [DllImport(@"GenesisCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setScanlines")]
        static extern void genSetScanlines(bool state, uint intensity);

        //sms
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setHwnd")]
        static extern void smsSetHwnd(IntPtr wih);
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clearVideo")]
        static extern void smsClearVideo();
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "clearAudio")]
        static extern void smsClearAudio();
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "pauseAudio")]
        static extern void smsPauseAudio();
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "playAudio")]
        static extern void smsPlayAudio();
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "test")]
        static extern void smsCoreTest();
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "power")]
        static extern void smsPower();
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "reset")]
        static extern void smsReset();
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "enter")]
        static extern void smsEnter();
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setCartMemory")]
        public static extern void smsSetCartMemory(byte[] rom, uint romSize, byte[] sram, uint sramSize, byte[] slotArom, uint slotAromSize);
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "map")]
        static extern void smsMap(Header.Type type, Header.Region region, uint unit);
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "initVideo")]
        [return: MarshalAs(UnmanagedType.I1)]
        static extern bool smsInitVideo(IntPtr wih, int width, int height, bool vsync, bool fullscreen);
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "initSound")]
        [return: MarshalAs(UnmanagedType.I1)]
        static extern bool smsInitSound(bool audio_active, uint speed, uint frequency, uint volume);
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "updateColor")]
        static extern void smsUpdateColor(int contrast, int gamma, int brightness, int filter_type, int ntsc_filter_cable, bool ntsc_filter_merge);
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setHWFilter")]
        static extern void smsSetHwFilter(int filter);
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setCounter")]
        static extern void smsSetCounter(bool state);
        [DllImport(@"SmsCore.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setScanlines")]
        static extern void smsSetScanlines(bool state, uint intensity);

        public delegate void SetHwnd(IntPtr wih);
        public delegate void ClearVideo();
        public delegate void ClearAudio();
        public delegate void PauseAudio();
        public delegate void PlayAudio();
        public delegate void CoreTest();
        public delegate void Power();
        public delegate void Reset();
        public delegate void Enter();
        public delegate void Map(Header.Type type, Header.Region region, uint unit);
        public delegate bool InitVideo(IntPtr wih, int width, int height, bool vsync, bool fullscreen);
        public delegate bool InitSound(bool audio_active, uint speed, uint frequency, uint volume);
        public delegate void UpdateColor(int contrast, int gamma, int brightness, int filter_type, int ntsc_filter_cable, bool ntsc_filter_merge);
        public delegate void SetHwFilter(int filter);
        public delegate void SetCounter(bool state);
        public delegate void SetScanlines(bool state, uint intensity);

        public static SetHwnd setHwnd;
        public static ClearVideo clearVideo;
        public static ClearAudio clearAudio;
        public static PauseAudio pauseAudio;
        public static PlayAudio playAudio;
        public static CoreTest coreTest;
        public static Power power;
        public static Reset reset;
        public static Enter enter;
        public static Map map;
        public static InitVideo initVideo;
        public static InitSound initSound;
        public static UpdateColor updateColor;
        public static SetHwFilter setHwFilter;
        public static SetCounter setCounter;
        public static SetScanlines setScanlines;

        public static void assignCore(Cart._System system) {
            switch (system) {
                case Cart._System.SMS:
                    setHwnd = new SetHwnd(smsSetHwnd);
                    clearVideo = new ClearVideo(smsClearVideo);
                    clearAudio = new ClearAudio(smsClearAudio);
                    pauseAudio = new PauseAudio(smsPauseAudio);
                    playAudio = new PlayAudio(smsPlayAudio);
                    coreTest = new CoreTest(smsCoreTest);
                    power = new Power(smsPower);
                    reset = new Reset(smsReset);
                    enter = new Enter(smsEnter);
                    map = new Map(smsMap);
                    initVideo = new InitVideo(smsInitVideo);
                    initSound = new InitSound(smsInitSound);
                    updateColor = new UpdateColor(smsUpdateColor);
                    setHwFilter = new SetHwFilter(smsSetHwFilter);
                    setCounter = new SetCounter(smsSetCounter);
                    setScanlines = new SetScanlines(smsSetScanlines);
                    break;
                case Cart._System.SNES:
                    setHwnd = new SetHwnd(snesSetHwnd);
                    clearVideo = new ClearVideo(snesClearVideo);
                    clearAudio = new ClearAudio(snesClearAudio);
                    pauseAudio = new PauseAudio(snesPauseAudio);
                    playAudio = new PlayAudio(snesPlayAudio);
                    coreTest = new CoreTest(snesCoreTest);
                    power = new Power(snesPower);
                    reset = new Reset(snesReset);
                    enter = new Enter(snesEnter);
                    map = new Map(snesMap);
                    initVideo = new InitVideo(snesInitVideo);
                    initSound = new InitSound(snesInitSound);
                    updateColor = new UpdateColor(snesUpdateColor);
                    setHwFilter = new SetHwFilter(snesSetHwFilter);
                    setCounter = new SetCounter(snesSetCounter);
                    setScanlines = new SetScanlines(snesSetScanlines);
                    break;
                case Cart._System.GENESIS:
                    setHwnd = new SetHwnd(genSetHwnd);
                    clearVideo = new ClearVideo(genClearVideo);
                    clearAudio = new ClearAudio(genClearAudio);
                    pauseAudio = new PauseAudio(genPauseAudio);
                    playAudio = new PlayAudio(genPlayAudio);
                    coreTest = new CoreTest(genCoreTest);
                    power = new Power(genPower);
                    reset = new Reset(genReset);
                    enter = new Enter(genEnter);
                    map = new Map(genMap);
                    initVideo = new InitVideo(genInitVideo);
                    initSound = new InitSound(genInitSound);
                    updateColor = new UpdateColor(genUpdateColor);
                    setHwFilter = new SetHwFilter(genSetHwFilter);
                    setCounter = new SetCounter(genSetCounter);
                    setScanlines = new SetScanlines(genSetScanlines);
                    break;
            }
        }
    }
}
