using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Speech.Synthesis;
using System.Speech.AudioFormat;
using System.Diagnostics;

namespace WindowsApplication1
{

    /// <summary>
    /// Converte Texto em um arquivo de áudio .mp2 -> Autor: Rafael Rend -> rafaelrend@gmail.com
    /// </summary>
    public partial class Form1 : Form
    {

        private void carregaComboVozes(ComboBox cmb)
        {
            SpeechSynthesizer synth = new SpeechSynthesizer();


            foreach (InstalledVoice voice in synth.GetInstalledVoices())
            {
                VoiceInfo info = voice.VoiceInfo;
                string AudioFormats = "";
                foreach (SpeechAudioFormatInfo fmt in info.SupportedAudioFormats)
                {
                    AudioFormats += String.Format("{0}\n",
                    fmt.EncodingFormat.ToString());
                }
                string detalhesVoz =
                    "Nome : " + info.Name + " - Idioma: " + info.Culture + " - Idade: " +
                    info.Age + " Gênero: " + info.Gender + " - Descrição: " + info.Description;

                SimplesCodigoNome obj = new SimplesCodigoNome(info.Name, detalhesVoz);

                cmb.DisplayMember = "Nome";
                cmb.ValueMember = "Codigo";
                cmb.Items.Add(obj);

             

            }



        }

        public Form1()
        {
            InitializeComponent();

            carregaComboVozes(cmbVoz);
           
            string caminhoFFmpeg = Application.StartupPath;

            caminhoFFmpeg = caminhoFFmpeg.Replace("\\bin\\Debug", "");
            caminhoFFmpeg = caminhoFFmpeg.Replace("\\bin\\Release", "");



            txtArquivoSaida.Text = caminhoFFmpeg + "\\teste.mp3";
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (txtArquivoSaida.Text.Trim() != String.Empty)
            {
                try
                {
                    System.IO.FileInfo info = new System.IO.FileInfo(txtArquivoSaida.Text.Trim());

                    saveFileDialog1.InitialDirectory = info.Directory.FullName;

                }
                catch { }

            }

            saveFileDialog1.Filter = "Arquivo de áudio MP3|*.mp3";
            saveFileDialog1.ShowDialog();

            txtArquivoSaida.Text = saveFileDialog1.FileName;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (cmbVoz.SelectedItem == null)
            {
                MessageBox.Show("Selecione uma voz!");
                return;

            }


            if (txtArquivoSaida.Text.Trim() == String.Empty)
            {
                MessageBox.Show("Informe um arquivo!");
                return;

            }

            converteArquivo(button1);


        }

        private void button2_Click(object sender, EventArgs e)
        {

            if (cmbVoz.SelectedItem == null)
            {
                MessageBox.Show("Selecione uma voz!");
                return;

            }

            if (txtArquivoSaida.Text.Trim() == String.Empty)
            {
                MessageBox.Show("Informe um arquivo!");
                return;

            }

            converteArquivo(button2);
        }

        private void converteArquivo(Button bt)
        {
            SimplesCodigoNome sitem = (SimplesCodigoNome)cmbVoz.SelectedItem;
            string arquivoWav = txtArquivoSaida.Text.Trim().Replace(".mp3", ".wav").Replace(".Mp3", ".wav").Replace(".MP3", ".wav"); // oFile.FullName.Replace(oFile.Extension, ".wav");

            using (SpeechSynthesizer synth = new SpeechSynthesizer())
            {


             
                // Configure the audio output. 
                synth.SetOutputToWaveFile(arquivoWav,
                  new SpeechAudioFormatInfo(32000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));

                //synth.SelectVoice(cmbVoz.SelectedItem.ToString());
                // Create a SoundPlayer instance to play output audio file.

                System.Media.SoundPlayer m_SoundPlayer =
                  new System.Media.SoundPlayer(arquivoWav);


                // Build a prompt.
                PromptBuilder builder = new PromptBuilder();


                PromptStyle pstyle = new PromptStyle(PromptRate.Slow);

                
                builder.StartVoice(sitem.Codigo);

                //new PromptStyle() ( Emphasis = PromptEmphasis.Strong, Rate = PromptRate.ExtraSlow });

                //System.Speech.Synthesis.VoiceGender.Male, System.Speech.Synthesis.VoiceAge.Adult);
                builder.StartStyle(pstyle);
                builder.AppendText(richTextBox1.Text);
                builder.EndStyle();
               
                builder.EndVoice();
                // Speak the prompt.
                synth.Speak(builder);

                if (bt.Equals(button1))
                {
                    

                    //Caso queira ouvir o arquivo .wav, descomente abaixo:
                    m_SoundPlayer.Play();

                }
                if (bt.Equals(button2))
                {

                    System.IO.FileInfo oFile = new System.IO.FileInfo(txtArquivoSaida.Text.Trim());

                    string saidaarquivo = oFile.FullName.Replace(oFile.Extension, ".mp3");

                    converteArquivosFFmpeg(arquivoWav, "mp3", ref saidaarquivo );
                    MessageBox.Show("arquivo " + oFile.FullName + " gerado com sucesso!");

                }


            }
            if (bt.Equals(button2))
            {
                try
                {

                    System.IO.File.Delete(arquivoWav);
                }
                catch { }

            }
        }


        /// <summary>
        /// Executa a linha de comando para o ffmpeg
        /// </summary>
        /// <param name="origem"></param>
        /// <param name="formatosaida"></param>
        /// <param name="nomesaida"></param>
        /// <returns></returns>
        private string converteArquivosFFmpeg(string origem, string formatosaida, ref string nomesaida)
        {

            System.IO.FileInfo fil = new System.IO.FileInfo(origem);

            string saida = fil.FullName.Replace(fil.Extension, "." + formatosaida);
            nomesaida = saida;
            string caminhoFFmpeg = Application.StartupPath;

            caminhoFFmpeg = caminhoFFmpeg.Replace("\\bin\\Debug", "");
            caminhoFFmpeg = caminhoFFmpeg.Replace("\\bin\\Release", "");

            ProcessStartInfo processStartInfo =
                                new ProcessStartInfo(caminhoFFmpeg + "\\ffmpeg\\ffmpeg.exe", "-i \"" +
                                origem + "\" -f  " + formatosaida + " \"" + saida + "\"");
            processStartInfo.ErrorDialog = false;

            processStartInfo.RedirectStandardOutput = true;
            processStartInfo.RedirectStandardError = true;
            processStartInfo.UseShellExecute = false;


            string displayText = "";
            Process process = new Process();
            process.StartInfo = processStartInfo;
            try
            {
                bool processStarted = process.Start();
                if (processStarted)
                {
                    //Get the output stream
                    System.IO.StreamReader outputReader = process.StandardOutput;
                    System.IO.StreamReader errorReader = process.StandardError;
                    //       process.WaitForExit();

                    //Display the result
                    displayText = "Comando:   -i \"" + origem + "\" -f  " + formatosaida + " \"" + saida + "\"" + Environment.NewLine + " " + Environment.NewLine;
                    displayText += outputReader.ReadToEnd();
                    displayText += Environment.NewLine + Environment.NewLine + "==============" +
                                   Environment.NewLine;
                    displayText += errorReader.ReadToEnd();
                    // txtResult.Text = displayText;
                }
            }
            catch (Exception expp)
            {
                MessageBox.Show("ERRO:" + expp.Message);
            }

            return displayText;

        }

  
    }
}