using System;
using System.IO;
using System.Text;
using System.Resources;
using System.Reflection;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Puzzle
{
    class MIDI : IDisposable
    {

        private string data = "";                                                                    // enthält den aktuellen DateiPfad
        ResourceManager res = new ResourceManager("Puzzle.Songs", Assembly.GetExecutingAssembly());  // ein Link zur Ressourcendatei
        public readonly string[] songs;                                                              // enthält ein Array aller Songs
        private Random change;                                                                       // Zufallsgenerator
        private Timer t = new Timer();                                                               // Für den Zufall

      
        public MIDI(Random change)
        {
            this.change = change;
            string songlist = "";

            songlist += ",Dream_On,Dreams,Fred_Come_To_Bed";
            songlist += ",Gangstas_Paradise,Lambada_Mix,Liberian_Girl";
            songlist += ",Love_Hurts,My_Heart_My_Soul,Strange_Love";
            songlist += ",Si_Maman_Si,Una_Notte_Speciale,A_Matter_Of_Trust";


            this.songs = songlist.Split(',');
        }
        
        public bool Playing()
        {

            StringBuilder ret = new StringBuilder();                                               //  Rückgabe-Objekt 
            long lRet;
            lRet = mission("status midi mode", ret, 16, IntPtr.Zero);                             // Status vom MCI abfragen
            if (ret.ToString() == "playing") return true;
            return false;
        }
       
        public void Play(string song)
        {
            bool existing = false;                                                              // prüft, ob der track vorhanden ist
            for (int i = 0; i < this.songs.Length; i++)
            {
                if (this.songs[i] == song)
                {
                    existing = true;
                    break;
                }
            }

            if (existing)
            {
                long lRet;                                                                      // Rückgabewert der MCI-Steuerung
                string ald = this.data;                                                         // alte datei (zum löschen)
                this.data = Path.GetTempFileName();                                             // neue temporäre Datei erstellen
                File.WriteAllBytes(this.data, (Byte[])this.res.GetObject(song));                // Song extrahieren

                if (File.Exists(this.data))
                {
                    lRet = mission("stop midi", null, 0, IntPtr.Zero);                              // Abspielen
                    lRet = mission("close midi", null, 0, IntPtr.Zero);
                    lRet = mission("open \"" + this.data + "\" type mpegvideo alias midi", null, 0, IntPtr.Zero);
                    lRet = mission("play midi", null, 0, IntPtr.Zero);

                    if (File.Exists(ald)) File.Delete(ald);                                           // alte Datei löschen
                }
                else
                {
                    this.data = ald;                                                              // nur neue Datei löschen, denn die alte läuft ja noch
                    if (File.Exists(ald)) File.Delete(ald);
                }
            }
        }

        
        public void Check(object sender, EventArgs e)
        {
            if (!this.Playing()) this.Change(false);
        }

        
        public void Change(bool Continue)
        {
            int number;
            do
            {
                number = this.change.Next(0, this.songs.Length * 10) / 10;
            } while (number < 0 && number >= this.songs.Length);
            this.Play(this.songs[number]);
            if (Continue)
            {
                this.t.Interval = 500;
                if (!this.t.Enabled) this.t.Tick += new EventHandler(this.Check);
                this.t.Enabled = true;
            }
        }
       
        public void Stop()
        {
            long lRet;
            lRet = mission("stop midi", null, 0, IntPtr.Zero);
            lRet = mission("close midi", null, 0, IntPtr.Zero);
            this.t.Enabled = false;
            if (File.Exists(this.data)) File.Delete(this.data);
        }
        
        public void Dispose()
        {
            long lRet;
            lRet = mission("stop midi", null, 0, IntPtr.Zero);
            lRet = mission("close midi", null, 0, IntPtr.Zero);
            if (File.Exists(this.data)) File.Delete(this.data);
        }
        



        //                            *************************    Destruktor    *************************
        ~MIDI()
        {
            this.Dispose();
        }



        //                            ****************    Der API-Call zum MCI-Interface    ****************

        [DllImport("winmm.dll", EntryPoint = "mciSendStringA")]
        private static extern long mission(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);
    }
}
