using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Collections;

namespace SoundDirectory
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            #if DEBUG
                MinimizeBox = false;
            #else
                MinimizeBox = true;
            #endif
        }

        /// <summary>
        /// This is the offset size in bytes of each string returned by the sound directories array 
        /// returned from the native method SndGetSoundDirectoriesList 
        /// MAXPATH = 260 , Bytes = 2
        /// OffSet = MAXPATH * Bytes
        /// </summary>
        private const int OffSet = 520;



        [DllImport("coredll.dll", SetLastError = true)]
        public static extern IntPtr LocalFree(IntPtr hMem);


        [DllImport("aygshell.dll")]
        internal static extern uint SndGetSoundDirectoriesList(
            uint soundEvent,
            uint location,
            ref IntPtr soundDirectories,
            ref IntPtr directoriesCount);

        /// <summary>
        /// Bitmask for the locations of the sounds
        /// </summary>
        [FlagsAttribute]
        public enum SndLocation
        {
            /// <summary>
            /// Sound files from the Storage Card
            /// </summary>
            StorageCard = 0x1,

            /// <summary>
            /// Sound files from the user data (ie, \My Documents)
            /// </summary>
            UserData = 0x2,

            /// <summary>
            /// Sound files from the ROM
            /// </summary>
            Rom = 0x4
        }

        /// <summary>
        /// This enum indicates which sound event type that we want to set or query
        /// </summary>
        public enum SndEvent
        {
            /// <summary>
            /// All Events
            /// </summary>
            All = 0x0,

            /// <summary>
            /// The ringtone for line 1
            /// </summary>
            RingToneLine1 = 0x1,

            /// <summary>
            /// The ringtone for line 2
            /// </summary>
            RingToneLine2 = 0x2,

            /// <summary>
            /// The ringtone to play for  a caller on the contact list
            /// </summary>
            KnowCallerRingTone = 0x3,

            /// <summary>
            /// The ringtone to play while roaming
            /// </summary>
            RoamingRingTone = 0x4,

            /// <summary>
            /// The ringtone for VoIP line on the phone
            /// </summary>
            VoipRingTone = 5
        }

        /// <summary>
        /// It calls SndGetSoundDirectoriesList to get the list of directories in user data for ringtone line 1. 
        /// </summary>
        /// <returns>An Array that contains the list of ringtone directories</returns>
        private string[] GetRingToneDirectories()
        {
            IntPtr directoryList = new IntPtr();
            IntPtr directoryCount = new IntPtr();
            SndGetSoundDirectoriesList(
                (uint)SndEvent.RingToneLine1,
                (uint)SndLocation.UserData,
                ref directoryList,
                ref directoryCount);

            ArrayList result = new ArrayList();
            int numberOfDirectories = directoryCount.ToInt32();
            for (int i = 0; i < numberOfDirectories; i++)
            {
                // We are offsetting the pointer by the slot on the array that we want to read
                IntPtr nextDirectory = new IntPtr(directoryList.ToInt32() + i * OffSet);
                result.Add(Marshal.PtrToStringUni(nextDirectory));
            }

            // We need to free the memory that was created by SndGetSoundDirectoriesList. We use Local Free
            // to free the memory.
            if (LocalFree(directoryList) != IntPtr.Zero)
            {
                textBox1.Text = "Cannot free memory";
            }

            return (string[])result.ToArray(typeof(string));
        }


        private void button1_Click(object sender, EventArgs e)
        {
            label1.Text = GetRingToneDirectories().Length.ToString();

            for (int i = 0; i < GetRingToneDirectories().Length; i++)
               listBox1.Items.Add(GetRingToneDirectories()[i]);
        }


    }
}