using System;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace CustomFormsPDA
{
	public enum EventType 
    { 
        Information, 
        Warning, 
        Error 
    };

	public delegate void ShowEventDelegate(string Text, EventType EventType);

	public partial class NotifyForm : Form
	{
		readonly ImageList ImageList;
		int MainThreadId;

		public NotifyForm(ImageList aImageList)
		{
			InitializeComponent();
			//
			Left = 40;
			Top = 100;
			ImageList = aImageList;
			MainThreadId = Thread.CurrentThread.ManagedThreadId;
			//
		}


		private void ShowProc(string txt, EventType EventType)
		{
#if _ENGLISH_
			CancelBtn.Caption = "Close";
#else
			CancelBtn.Caption = "Çàêðûòü";
#endif

			Sound SS;
			switch (EventType)
			{
				case EventType.Information:
#if _ENGLISH_
					TitleLbl.Text = "INFORMATION";
#else
					TitleLbl.Text = "ÈÍÔÎÐÌÀÖÈß";
#endif
					SS = new Sound(SoundImages.NotifySound);
					SS.Play();
					break;
				case EventType.Warning:
#if _ENGLISH_
					TitleLbl.Text = "WARNING";
#else
					TitleLbl.Text = "ÏÐÅÄÓÏÐÅÆÄÅÍÈÅ";
#endif
					SS = new Sound(SoundImages.WarningSound);
					SS.Play();
					break;
				case EventType.Error:
#if _ENGLISH_
					TitleLbl.Text = "ERROR";
#else
					TitleLbl.Text = "ÎØÈÁÊÀ";
#endif
					SS = new Sound(SoundImages.ErrorSound);
					SS.Play();
					break;
			}

			PromptLbl.Text = txt;
			PictureBox.Image = ImageList.Images[(int)EventType];

			Show();		
		}
		private delegate void ShowDelegate(string Text, EventType EventType);

		public void Show(string txt, EventType EventType)
		{
			//System.Diagnostics.Process.GetCurrentProcess()
			if (InvokeRequired)
			{
				BeginInvoke(new ShowDelegate(ShowProc) , txt, EventType);
			}
			else
				ShowProc(txt, EventType);
		}

		public void Show(string txt)
		{
			Show(txt, EventType.Error);
		}

		private void CancelBtn_Click(object sender, EventArgs e)
		{
			Hide();
		}
	}
	public class Sound
	{
		private readonly byte[] m_soundBytes;
		private readonly string m_fileName;

		[Flags]
		private enum Flags
		{
// ReSharper disable UnusedMember.Local
			SND_SYNC = 0x0000,  /* play synchronously (default) */
			SND_ASYNC = 0x0001,  /* play asynchronously */
			SND_NODEFAULT = 0x0002,  /* silence (!default) if sound not found */
			SND_MEMORY = 0x0004,  /* pszSound points to a memory file */
			SND_LOOP = 0x0008,  /* loop the sound until next sndPlaySound */
			SND_NOSTOP = 0x0010,  /* don't stop any currently playing sound */
			SND_NOWAIT = 0x00002000, /* don't wait if the driver is busy */
			SND_ALIAS = 0x00010000, /* name is a registry alias */
			SND_ALIAS_ID = 0x00110000, /* alias is a predefined ID */
			SND_FILENAME = 0x00020000, /* name is file name */
			SND_RESOURCE = 0x00040004  /* name is resource name or atom */
// ReSharper restore UnusedMember.Local
		}

		[DllImport("coredll.dll", EntryPoint = "PlaySound", SetLastError = true)]
		private extern static int PlaySound(string szSound, IntPtr hMod, int flags);

		[DllImport("coredll.dll", EntryPoint = "PlaySound", SetLastError = true)]
		private extern static int PlaySoundBytes(byte[] szSound, IntPtr hMod, int flags);

		/// <summary>
		/// Construct the Sound object to play sound data from the specified file.
		/// </summary>
		public Sound(string fileName)
		{
			m_fileName = fileName;
		}

		/// <summary>
		/// Construct the Sound object to play sound data from the specified stream.
		/// </summary>
		public Sound(Stream stream)
		{
			try
			{
				// read the data from the stream
				m_soundBytes = new byte[stream.Length];
				stream.Read(m_soundBytes, 0, (int)stream.Length);
			}
			catch { }
		}

		/// <summary>
		/// Construct the Sound object to play sound data from the specified byte array.
		/// </summary>
		public Sound(byte[] bytes)
		{
			try
			{
				m_soundBytes = bytes;
			}
			catch { }
		}
		/// <summary>
		/// Play the sound
		/// </summary>
		public void Play()
		{
			// if a file name has been registered, call WCE_PlaySound,
			//  otherwise call WCE_PlaySoundBytes
			if (m_fileName != null)
				PlaySound(m_fileName, IntPtr.Zero, (int)(Flags.SND_ASYNC | Flags.SND_FILENAME));
			else
				PlaySoundBytes(m_soundBytes, IntPtr.Zero, (int)(Flags.SND_ASYNC | Flags.SND_MEMORY));
		}
	}

	public static class SoundImages
	{
		public static byte[] ErrorSound;
		public static byte[] WarningSound;
		public static byte[] NotifySound;

		static SoundImages()
		{
			ErrorSound = GetHexBytes(ErrorStr);
			WarningSound = GetHexBytes(WarningStr);
			NotifySound = GetHexBytes(NotifyStr);
		}
		private static byte[] GetHexBytes(string s)
		{
			byte[] res = new byte[0];
			if (!string.IsNullOrEmpty(s))
				try
				{
					res = new byte[s.Length / 2];
					StringBuilder SB;
					for (int i = 0; i < res.Length; i++)
					{
						SB = new StringBuilder(2);
						SB.Append(s[i * 2]).Append(s[i * 2 + 1]);
						res[i] = byte.Parse(SB.ToString(), NumberStyles.HexNumber);
					}
				}
				catch
				{
					res = new byte[0];
				}
			return res;
		}
		#region Sound Strings
		private const string WarningStr = "[encoded data, 16200 characters]";

		private const string ErrorStr = "[encoded data, 75344 characters]";

		private const string NotifyStr = "[encoded data, 18936 characters]";
		#endregion
	}

}