using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using Word = Microsoft.Office.Interop.Word;
using System.Reflection;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Data;


namespace classes
{
    /// <summary>
    /// En esta clase se tokenizan, etiquetan y guardan en xml los textos 
    /// </summary>
    public class Etiquetado
    {
        /// <summary>
        /// Etiquetar etiqueta una transcripcion.
        /// </summary>
        /// <param name="nombre">El nombre del texto.</param>
        /// <param name="lineas">La coleccion de intervenciones de una transcripcion.</param>
        /// <param name="etiquetar">if set to <c>true</c> [etiquetar] se etiquetan los elementos antes de guardarlos.</param>
        /// <returns>
        /// Retorna true si la operacion finaliza con exito
        /// </returns>
        public bool etiquetar(string nombre, SortedList<int, string> lineas, bool etiquetar,string ruta)
        {
            //Quitamos la extension (.doc) del nombre del archivo
            if(nombre.Contains(".doc")) nombre=nombre.Substring(0, nombre.Length - 4);

            //ruta donde guardaremos los xml
            string ruta_xml = ruta+"xml\\";

            //ruta donde almacenaremos el etiquetador
            string ruta_freeling = ruta;

            texto transcripcion = new texto(nombre);
            linea linea;
            List<string> interlocutores = new List<string>();
            string interlocutor, interlocutor_anterior="";
            foreach (int i in lineas.Keys)
            {
                string contenido = "";
                lineas.TryGetValue(i, out contenido);
                linea = new linea(i, contenido);
                
                if (!interlocutores.Contains(interlocutor = ProcesarLinea(linea)))
                    if (interlocutor != null) interlocutores.Add(interlocutor);
                    else linea.Interlocutor = interlocutor_anterior;
                transcripcion.Lineas.Add(linea.Numero, linea);
                interlocutor_anterior = interlocutor;
            }
            transcripcion.Interlocutores = interlocutores;
            if (etiquetar) freeling(transcripcion, ruta_freeling);
            xml(transcripcion,ruta_xml);
            return true;

        }
        /// <summary>
        /// ProcesarLinea tokeniza una intervencion(linea) y crea las estructuras en las que se almacenan los elementos tokenizados.
        /// </summary>
        /// <param name="linea">La linea(intervencion).</param>
        /// <returns>Retorna la string con la que se representa al interlocutor de dicha intervencion</returns>
        private string ProcesarLinea(linea linea)
        {
            if (linea.Contenido.Length > 0)
                {
                    #region 1: Inicializacion de variables
                    //contador-> posicion en que se encuentra el recorrido de la linea.
                    //NumElemento-> numero de elementos encontrados durante el recorrido de la linea hasta la posicion actual.
                    int contador = 0, NumElemento = 0;
                    //ant-> caracter inmediatamente anterior al actual
                    char ant = new char();
                    // texto-> conjunto de caracteres a tokenizar
                    // AuxSimbolos-> buffer auxiliar para almacenar simbolos compuestos de los que aun faltan caracteres por leer
                    // aux-> buffer auxiliar para almacenar caracteres de una palabra que aun no ha sido terminada de leer
                    string texto = "", AuxSimbolos = "", aux = "";
                    //s,p-> variables auxiliar utilizadas para crear las estructuras de los elementos tokenizados.
                    simbolo s;
                    palabra p;
                    #endregion
                    #region 2: Correspondencia de simbolos
                        //En esta fase los segundos se guardarán como ", y no como '' ni como `` o ´´
                        if (linea.Contenido.Contains("\'\'"))
                            linea.Contenido = linea.Contenido.Replace("\'\'", "\"");
                        if (linea.Contenido.Contains("´´"))
                            linea.Contenido = linea.Contenido.Replace("´´", "\"");
                        if (linea.Contenido.Contains("``"))
                            linea.Contenido = linea.Contenido.Replace("``", "\"");
                        if (linea.Contenido.Contains("\')") && (int.TryParse((linea.Contenido.ElementAt(linea.Contenido.IndexOf("\')") - 1)).ToString(), out NumElemento)))
                            linea.Contenido = linea.Contenido.Replace("\')", "\"");
                    //Devolvemos la variable NumElemento a su estado inicial
                    NumElemento = 0;
                    #endregion
                    #region 3: Division de la intervencion en 2 partes: 
                        #region 3.1:  1.interlocutor
                        if (linea.Contenido.Contains(':'))
                        {
                            linea.Interlocutor = linea.Contenido.Substring(0, (linea.Contenido.IndexOf(':')));
                            contador = (linea.Contenido.IndexOf(':')) + 1;
                        }
                        else contador = 0;
                        #endregion
                        #region 3.2: 2.contenido
                        if (contador == 0) { texto = linea.Contenido; }
                        else { for (int i = contador; i < linea.Contenido.Length; i++) { texto += linea.Contenido[i]; } }
                        #endregion
                    #endregion
                    #region 4: Para cada caracter del contenido de la intervencion
                    // c -> caracter a procesar en esta iteración
                        foreach (char c in texto)
                        {
                            #region 4.1: Evaluacion de coincidencias compuestas
                            //En este switch se evaluan las condiciones para determinar si se encuentra coincidencia de un determinado tipo de simbolo.
                            switch (AuxSimbolos)
                            {
                                #region 4.1.1: Simbolo "Silencio de x segundos"
                                case "(\")": if (aux.Length > 0)
                                        try
                                        {
                                            s = new simbolo("(" + aux + "\")", "Silencio de " + aux + "segundos", contador - 3 - aux.Length);
                                            linea.Elementos.Add(NumElemento++, s);
                                            aux = ""; AuxSimbolos = "";
                                        }
                                        catch (Exception e)
                                        {
                                            throw new Classes.Excepciones.Excepcion_crear_simbolo("Error! al intentar añadir un nuevo simbolo se detecta " + e.Message);
                                        } break;
                                #endregion
                                #region 4.1.2: Simbolos "Fragmento indescifrable" y "Transcripcion dudosa"
                                #region 4.1.2.1: Simbolo "Fragmento indescifrable"
                                case "(())": if (aux.Length == 0 || aux.Contains(' '))
                                    {
                                        s = new simbolo("(())", "Fragmento indescifrable", contador - 4);
                                        linea.Elementos.Add(NumElemento++, s);
                                        AuxSimbolos = "";
                                        aux = "";
                                    }
                                #endregion
                                #region 4.1.2.2: Simbolo "Transcripcion dudosa"
                                else
                                    {
                                        s = new simbolo("(("+aux+"))", "Transcripcion dudosa", contador - 4 - aux.Length);
                                        linea.Elementos.Add(NumElemento++, s);
                                        p = new palabra(aux, contador - aux.Length);
                                        linea.Elementos.Add(NumElemento++, p);
                                        AuxSimbolos = ""; aux = "";
                                    }
                                    break;
                                    #endregion
                                #endregion
                                #region 4.1.3: Simbolo "Interrupcion de la grabacion"
                                case "((...))": s = new simbolo("((...))", "Interrupcion de la grabacion", contador - 7); linea.Elementos.Add(NumElemento++,s); AuxSimbolos = ""; break;
                                #endregion
                                #region 4.1.4: Simbolos "Entre risas" y "Reconstruido"
                                #region 4.1.4.1: Simbolo "Entre risas"
                                case "()": if (aux.Equals("RISAS"))
                                    {
                                        s = new simbolo("(RISAS)", "Entre risas", contador - 4 - aux.Length);
                                        linea.Elementos.Add(NumElemento++, s);
                                        AuxSimbolos = ""; aux = "";
                                    }
                                #endregion
                                    #region 4.1.4.2: Simbolo "Reconstruido"
                                    else
                                    {
                                        s = new simbolo("( )", "Reconstruido", contador - 2 - aux.Length);
                                        linea.Elementos.Add(NumElemento++, s);
                                        AuxSimbolos = "";
                                    }
                                    break;
                                    #endregion
                                #endregion
                                #region 4.1.5: Simbolo "Pausa corta"
                                case "/": if (!(c.Equals('/')) && ant.Equals('/'))
                                    {
                                        s = new simbolo("/", "Pausa corta", contador - 1);
                                        linea.Elementos.Add(NumElemento++, s);
                                        AuxSimbolos = "";
                                    }
                                    break;
                                #endregion
                                #region 4.1.6: Simbolo "Pausa intermedia"
                                case "//": if (!(c.Equals('/')) && ant.Equals('/'))
                                    {
                                        s = new simbolo("//", "Pausa intermedia", contador - 2);
                                        linea.Elementos.Add(NumElemento++, s);
                                        AuxSimbolos = "";
                                    }
                                    break;
                                #endregion
                            }
                            #endregion
                            #region 4.2: Evaluacion de coincidencias simples
                            //Este switch evalua si se cumplen las condiciones para otros tipos de símbolos
                            switch (c)
                            {
                                #region 4.2.1: Simbolo "Sucesion inmediata"
                                case '§': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    s = new simbolo("§", "Sucesion inmediata", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.2: Simbolo "Mantenimiento del turno"
                                case '=': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    s = new simbolo("=", "Mantenimiento del turno", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.3: Simbolo "Inicio solapamiento"
                                case '[': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    s = new simbolo("[", "Inicio solapamiento", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.4: Simbolo "Final solapamiento"
                                case ']': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    s = new simbolo("]", "Final solapamiento", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.5: Simbolo "Reinicio"
                                case '-': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    s = new simbolo("-", "Reinicio", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.6: Simbolo "Pausa larga"
                                case '/': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    if (AuxSimbolos.Equals("//")) { s = new simbolo("///", "Pausa larga", contador - 2); linea.Elementos.Add(NumElemento++, s); AuxSimbolos = ""; }
                                    else AuxSimbolos += '/'; break;
                                #endregion
                                #region 4.2.7: Simbolo '('
                                case '(': AuxSimbolos += '(';
                                    if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    break;
                                #endregion
                                #region 4.2.8: Simbolo "Entonacion ascendente"
                                case '↑': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    s = new simbolo("↑", "Entonacion ascendente", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.9: Simbolo "Entonacion descendente"
                                case '↓': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    s = new simbolo("↓", "Entonacion descendente", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.10: Simbolo "Entonacion mantenida"
                                case '→': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    s = new simbolo("→", "Entonacion mantenida", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.11: Simbolo ')'
                                case ')': AuxSimbolos += ')'; break;
                                #endregion
                                #region 4.2.12: Simbolo '"'
                                case '"':
                                    if (AuxSimbolos.Equals("(")) AuxSimbolos += c; else { p = new palabra("\"", contador); linea.Elementos.Add(NumElemento++, p); } break;
                                #endregion
                                #region 4.2.13: Simbolo '.'
                                case '.': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    if (AuxSimbolos.Equals("((") || AuxSimbolos.Equals("((.") || AuxSimbolos.Equals("((..")) { AuxSimbolos += '.'; }
                                    else 
                                    { 
                                        p = new palabra(".", contador); linea.Elementos.Add(NumElemento++, p); 
                                    } break;
                                #endregion
                                #region 4.2.14: Simbolo ' '
                                case ' ': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    } break;
                                #endregion
                                #region 4.2.15: Simbolo "Bajo"
                                case 'º': if (!ant.Equals(')')) AuxSimbolos = "º";
                                    else if (AuxSimbolos.Equals("º()"))
                                    {
                                        s = new simbolo("º()º", "Bajo", contador - 3 - aux.Length);
                                        linea.Elementos.Add(NumElemento++, s);
                                        AuxSimbolos = "";
                                        if (aux.Length > 0)
                                        {
                                            p = new palabra(aux, contador - aux.Length - 2);
                                            linea.Elementos.Add(NumElemento++, p);
                                            aux = "";
                                        }
                                    } break;
                                #endregion
                                #region 4.2.16: Simbolo "Interrogación" '¿'
                                case '¿': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    } s = new simbolo("¿", "Interrogación", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.17: Simbolo "Exclamación" '¡'
                                case '¡': if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    } s = new simbolo("¡", "Exclamación", contador); linea.Elementos.Add(NumElemento++, s); break;
                                #endregion
                                #region 4.2.18: Signos de puntuacion
                                case '?':
                                case ',':
                                case ':':
                                case ';':
                                case '!':
                                case '&':

                                    if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                                    {
                                        p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                                    }
                                    p = new palabra(c.ToString(), contador); linea.Elementos.Add(NumElemento++, p);
                                    break;
                                #endregion
                                #region 4.2.19: Default
                                default: if (!c.Equals(' ') && !c.Equals('\a') && !c.Equals('\b') && !c.Equals('\f') && !c.Equals('\n') && !c.Equals('\r') && !c.Equals('\t') && !c.Equals('\v')) aux += c; break;
                                #endregion
                            }
                            #endregion
                            #region 4.3: Actualizacion de variables
                            contador++;
                            ant = c;
                            #endregion
                        }
                    #endregion
                    #region 5: Comprobaciones adicionales
                //Las siguientes comprobaciones son para que ningun elemento colocado al final de una intervencion quede sin representar

                if (AuxSimbolos.Length > 0)
                {
                    switch (AuxSimbolos)
                    {
                        #region 5.1: Simbolo "Silencio de x segundos"
                        case "(\")": if (aux.Length > 0)
                                {
                                    s = new simbolo("(" + aux + "\")", "Silencio de " + aux + "segundos", contador - 3 - aux.Length);
                                    linea.Elementos.Add(NumElemento++, s);
                                    aux = ""; AuxSimbolos = "";
                                }
                                break;
                        #endregion
                        #region 5.2: Simbolos "Fragmento indescifrable" y "Transcripcion dudosa"
                            #region 5.2.1: Simbolo "Fragmento indescifrable"
                            case "(())": if (aux.Length == 0 || aux.Contains(' '))
                            {
                                s = new simbolo("(())", "Fragmento indescifrable", contador - 4);
                                linea.Elementos.Add(NumElemento++, s);
                                AuxSimbolos = "";
                                aux = "";
                            }
                            #endregion
                            #region 5.2.2: Simbolo "Transcripcion dudosa"
                            else
                            {
                                s = new simbolo("(("+aux+"))", "Transcripcion dudosa", contador - 4 - aux.Length);
                                linea.Elementos.Add(NumElemento++, s);
                                p = new palabra(aux, contador - aux.Length);
                                linea.Elementos.Add(NumElemento++, p);
                                AuxSimbolos = ""; aux = "";
                            }
                            #endregion
                            break;
                        #endregion
                        #region 5.3: Simbolo "Interrupcion de la grabacion"
                        case "((...))": s = new simbolo("((...))", "Interrupcion de la grabacion", contador - 7); break;
                        #endregion
                        #region 5.4: Simbolos "Entre risas" y "Reconstruido"
                        #region 5.4.1: Simbolo "Entre risas"
                        case "()": if (aux.Equals("RISAS"))
                            {
                                s = new simbolo("(RISAS)", "Entre risas", contador - 4 - aux.Length);
                                linea.Elementos.Add(NumElemento++, s);
                                AuxSimbolos = ""; aux = "";
                            }
                        #endregion
                            #region 5.4.2: Simbolo "Reconstruido"
                            else
                            {
                                s = new simbolo("( )", "Reconstruido", contador - 2 - aux.Length);
                                linea.Elementos.Add(NumElemento++, s);
                                AuxSimbolos = "";
                            }
                        #endregion
                            break;
                        #endregion
                    }
                }
                #region 5.5: Elemento guardado en buffer de caracteres
                if (!aux.Equals("") && !aux.Equals(" ") && !aux.Equals("RISAS"))
                {
                    p = new palabra(aux, contador - aux.Length); linea.Elementos.Add(NumElemento++, p); aux = "";
                }
                #endregion
                    #endregion
                }
                else linea.Interlocutor = null;
                    #region 6: Return
                        return linea.Interlocutor;
                    #endregion
        }
        /// <summary>
        /// Freeling hace uso del etiquetador externo para etiquetar la transcripcion.
        /// </summary>
        /// <param name="texto">La transcripcion toquenizada.</param>
        /// <param name="ruta">La ruta donde esta ubicado el etiquetador</param>
        private void freeling(texto texto,string ruta)
        {
            #region 1: Crear archivo de entrada para el etiquetador Freeling
                StreamWriter sw = new StreamWriter(ruta+"texto_a_etiquetar.txt",false, Encoding.Default);
                //aetiquetar-> variable auxiliar donde se almacenan la coleccion de palabras que seran la entrada del etiquetador externo
                string aetiquetar = "";
            
                foreach(linea l in texto.Lineas.Values)
                {
                    aetiquetar = "";
                    foreach (elemento e in l.Elementos.Values) 
                    {
                        if (e is palabra) 
                        { 
                            aetiquetar += RemoveAlargamiento((e as palabra).Aparicion); aetiquetar += " "; 
                        }
                    }
                    sw.WriteLine(aetiquetar);       
                }
                sw.Close();
            #endregion
            # region 2: Ejecutar analisis de Freeling
                //Lanzamos el proceso
                File.Delete(ruta + "texto_etiquetado.mrf");
                int proceso = System.Diagnostics.Process.Start(ruta + "freeling.bat").Id;
                try
                {
                    while (true)
                    {
                        //Esperamos a que el proceso termine para seguir con la ejecucion.
                        System.Diagnostics.Process.GetProcessById(proceso);
                    }
                }
                catch (ArgumentException e) 
                {
                    string error=e.Message;
                }
            #endregion
            #region 3: Procesar la salida proporcionada por Freeling
            #region 3.1: Inicializacion de variables
            StreamReader SR;
            //lectura->string donde almacenamos el contenido de cada linea leida con el StreamReader
            string lectura;
            SR = new StreamReader(ruta+"texto_etiquetado.mrf",Encoding.Default);
            //words-> Vector de strings que contiene en [0] el elemento reconocido por freeling, en [1] la etiqueta propuesta, en [2] la forma de cita propuesa
            string[] words=null;
            //compuesta/num_composicion-> variables auxiliares para el calculo de lecturas (con el StreamReader) que equivalen a cada palabra compuesta
            bool compuesta = false; int num_composicion = 0;
            #endregion
            #region 3.2: Para cada linea de nuestra transcripcion
            foreach (linea l in texto.Lineas.Values)
            {
                
                #region 3.2.1: Para cada elemento de la linea
                foreach (elemento e in l.Elementos.Values)
                {
                    #region 3.2.1.1: Si el elemento actual es palabra
                    if (e is palabra)
                    {
                        #region 3.2.1.1.1: Si compuesta==true
                        if (compuesta)
                        {
                            if (!words[0].Contains(RemoveAlargamiento((e as palabra).Aparicion))) throw new Classes.Excepciones.Excepcion_error_etiquetado("Error al intentar etiquetar la palabra compuesta " + words[0]);
                            //Si compuesta==true, hacemos una lectura adicional
                            (e as palabra).Formadecita = words[1];
                            (e as palabra).Etiqueta = words[2];
                            e.Estado = "Etiquetado";
                            //Con num_composicion controlamos el numero de lecturas adicionales necesarias para cada palabra compuesta que hayamos encontrado
                            num_composicion--;
                            if(num_composicion==0) compuesta = false;
                        }
                        #endregion
                        #region 3.2.1.1.2: Si compuesta==false
                        else
                        {
                            #region 3.2.1.1.2.1: Lectura del fichero con ReadLine()
                            lectura = SR.ReadLine();
                            #endregion
                            #region 3.2.1.1.2.2: Si se ha podido leer
                            if (lectura != null)
                            {
                                //Leemos hasta encontrar una linea con contenido
                                while (lectura.Length == 0) { lectura = SR.ReadLine(); if (lectura == null) break; }

                                    words = lectura.Split(' ');
                                    //Utilizamos esta variable auxiliar como equivalente de (e as palabra).Aparicion
                                    string aparicion = RemoveAlargamiento((e as palabra).Aparicion);
                                    #region 3.2.1.1.2.2.1: Coincidencia exacta
                                    if (aparicion.Equals(words[0]))
                                    {
                                        (e as palabra).Formadecita = words[1];
                                        (e as palabra).Etiqueta = words[2];
                                        e.Estado = "Etiquetado";
                                    }
                                    #endregion
                                    #region 3.2.1.1.2.2.2: Contraccion AL. Doble lectura necesaria
                                    else if ((aparicion.ToLowerInvariant()).Equals("al"))
                                    {
                                        //Primera asignacion
                                        (e as palabra).Formadecita = words[1];
                                        (e as palabra).Etiqueta = words[2];
                                        e.Estado = "Etiquetado";
                                        //Segunda lectura
                                        lectura = SR.ReadLine();
                                        words = lectura.Split(' ');
                                        //Segunda asignacion
                                        (e as palabra).Formadecita += " y " + words[1];
                                        (e as palabra).Etiqueta += " y " + words[2];
                                    }
                                    #endregion
                                    #region 3.2.1.1.2.2.3: Contraccion DEL. Doble lectura necesaria
                                    else if ((aparicion.ToLowerInvariant()).Equals("del"))
                                    {
                                        //Primera asignacion
                                        (e as palabra).Formadecita = words[1];
                                        (e as palabra).Etiqueta = words[2];
                                        e.Estado = "Etiquetado";
                                        //Segunda lectura
                                        lectura = SR.ReadLine();
                                        words = lectura.Split(' ');
                                        //Segunda asignacion
                                        (e as palabra).Formadecita += " y " + words[1];
                                        (e as palabra).Etiqueta += " y " + words[2];
                                    }
                                    #endregion
                                    #region 3.2.1.1.2.2.4: Lectura de palabra compuesta
                                    else if (words[1].Contains('_'))
                                    {
                                        //Tantas lecturas como separadores de palabra +1
                                        foreach (char caracter in words[1])
                                        {
                                            if (caracter.Equals('_')) num_composicion++;
                                        }
                                        (e as palabra).Formadecita = words[1];
                                        (e as palabra).Etiqueta = words[2];
                                        e.Estado = "Etiquetado";
                                        compuesta = true;
                                    }
                                    #endregion
                                    #region 3.2.1.1.2.2.5: Lectura dudosa: Encontramos ' en la lectura
                                    else if ((e as palabra).Aparicion.Contains("'")) 
                                    {
                                        int indice = aparicion.IndexOf("'");
                                        int value = 0;
                                        #region 3.2.1.1.2.2.5.1: Con la opción de detección de números desactivada el tokenizador del etiquetador separará los números decimales en tres partes
                                        if ((indice > 0) && (indice < (aparicion.Length)) && (int.TryParse(RemoveAlargamiento(((e as palabra).Aparicion).ElementAt(indice - 1).ToString()), out value)) && (int.TryParse(((aparicion.ElementAt(indice + 1).ToString())), out value)))
                                        {
                                            (e as palabra).Formadecita = words[1];
                                            (e as palabra).Etiqueta = words[2];
                                            e.Estado = "Etiquetado";
                                            lectura = SR.ReadLine();
                                            words = lectura.Split(' ');
                                            (e as palabra).Formadecita += " y " + words[1];
                                            (e as palabra).Etiqueta += " y " + words[2];
                                            lectura = SR.ReadLine();
                                            words = lectura.Split(' ');
                                            (e as palabra).Formadecita += " y " + words[1];
                                            (e as palabra).Etiqueta += " y " + words[2];
                                        }
                                        #endregion
                                        #region 3.2.1.1.2.2.5.2: Dos elementos unidos por una comilla simple son separados por el etiquetador
                                        else 
                                        {
                                            if (indice == (aparicion.Length - 1)) 
                                            {
                                                (e as palabra).Formadecita = words[1];
                                                (e as palabra).Etiqueta = words[2];
                                                e.Estado = "Etiquetado";
                                                lectura = SR.ReadLine();
                                                words = lectura.Split(' ');
                                                (e as palabra).Formadecita += " y " + words[1];
                                                (e as palabra).Etiqueta += " y " + words[2];
                                            }
                                        }
                                        #endregion
                                    }
                                    #endregion
                                    #region 3.2.1.1.2.2.6: Funcion para detectar pronombres enclíticos
                                    else if ((aparicion.Length) > words[0].Length)
                                    {
                                        #region 3.2.1.1.2.2.6.1: Inicializacion de variables
                                        //legth-> longitud del elemento leido por el StreamWriter
                                        int length = words[0].Length;
                                        //Base/Base_sin_acentos-> Variables auxiliares donde se almacena los primeros caracteres del elemento a etiquetar
                                        string Base = "";
                                        string Base_sin_acentos = "";
                                        
                                        for (int i = 0; i < length; i++)
                                        {
                                            Base += aparicion.ElementAt(i);
                                        }
                                        Base_sin_acentos = RemoveAccents(Base);
                                        //pronombre->Variable auxiliar donde se almacena la 
                                        string pronombre = "";
                                        #endregion
                                        #region 3.2.1.1.2.2.6.2: Coincidencia exacta
                                        if (Base.Equals(words[0]) || Base_sin_acentos.Equals(words[0]))
                                        {
                                            //Calculamos el numero de caracteres que tendra el pronombre
                                            switch ((aparicion.Length) - length)
                                            {
                                                #region 3.2.1.1.2.2.6.2.1: Case 2 -> Pronombre de 2 caracteres
                                                case 2:
                                                    {
                                                        pronombre = aparicion.ElementAt(length).ToString() + aparicion.ElementAt(length + 1).ToString();
                                                        if (pronombre.Equals("me") || pronombre.Equals("la") || pronombre.Equals("le") || pronombre.Equals("lo") || pronombre.Equals("se") || pronombre.Equals("os") || pronombre.Equals("te"))
                                                        {
                                                            (e as palabra).Formadecita = words[1];
                                                            (e as palabra).Etiqueta = words[2];
                                                            e.Estado = "Etiquetado";
                                                            lectura = SR.ReadLine();
                                                            words = lectura.Split(' ');
                                                            (e as palabra).Formadecita += " y " + words[1];
                                                            (e as palabra).Etiqueta += " y " + words[2];
                                                        }
                                                        else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: "+(e as palabra).Aparicion+" de la linea número "+l.Numero+" del texto: "+texto.Nombre);
                                                    } break;
                                                #endregion
                                                #region 3.2.1.1.2.2.6.2.2: Case 3 -> Pronombre de 3 caracteres
                                                case 3:
                                                    {
                                                        pronombre = aparicion.ElementAt(length).ToString() + aparicion.ElementAt(length + 1).ToString() + aparicion.ElementAt(length + 2).ToString();
                                                        if (pronombre.Equals("las") || pronombre.Equals("les") || pronombre.Equals("los") || pronombre.Equals("nos"))
                                                        {
                                                            (e as palabra).Formadecita = words[1];
                                                            (e as palabra).Etiqueta = words[2];
                                                            e.Estado = "Etiquetado";
                                                            lectura = SR.ReadLine();
                                                            words = lectura.Split(' ');
                                                            (e as palabra).Formadecita += " y " + words[1];
                                                            (e as palabra).Etiqueta += " y " + words[2];
                                                        }
                                                        else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                    } break;
                                                #endregion
                                                #region 3.2.1.1.2.2.6.2.3: Case 4 -> 2 Pronombres de 2 caracteres
                                                case 4:
                                                    {
                                                        pronombre = aparicion.ElementAt(length).ToString() + aparicion.ElementAt(length + 1).ToString();
                                                        if (pronombre.Equals("me") || pronombre.Equals("la") || pronombre.Equals("le") || pronombre.Equals("lo") || pronombre.Equals("se") || pronombre.Equals("os") || pronombre.Equals("te"))
                                                        {
                                                            pronombre = aparicion.ElementAt(length + 2).ToString() + aparicion.ElementAt(length + 3).ToString();
                                                            if (pronombre.Equals("me") || pronombre.Equals("la") || pronombre.Equals("le") || pronombre.Equals("lo") || pronombre.Equals("se") || pronombre.Equals("os") || pronombre.Equals("te"))
                                                            {
                                                                (e as palabra).Formadecita = words[1];
                                                                (e as palabra).Etiqueta = words[2];
                                                                e.Estado = "Etiquetado";
                                                                lectura = SR.ReadLine();
                                                                words = lectura.Split(' ');
                                                                (e as palabra).Formadecita += " y " + words[1];
                                                                (e as palabra).Etiqueta += " y " + words[2];
                                                                lectura = SR.ReadLine();
                                                                words = lectura.Split(' ');
                                                                (e as palabra).Formadecita += " y " + words[1];
                                                                (e as palabra).Etiqueta += " y " + words[2];
                                                            }
                                                            else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                        }
                                                        else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);

                                                    } break;
                                                #endregion
                                                #region 3.2.1.1.2.2.6.2.4: Case 5 -> 2 Pronombres de 2 y 3 caracteres
                                                case 5:
                                                    {
                                                        #region 3.2.1.1.2.2.6.2.4.1: Case 2 + 3
                                                        pronombre = aparicion.ElementAt(length).ToString() + aparicion.ElementAt(length + 1).ToString();
                                                        
                                                        if (pronombre.Equals("me") || pronombre.Equals("la") || pronombre.Equals("le") || pronombre.Equals("lo") || pronombre.Equals("se") || pronombre.Equals("os") || pronombre.Equals("te"))
                                                        {
                                                            pronombre = aparicion.ElementAt(length + 2).ToString() + aparicion.ElementAt(length + 3).ToString() + aparicion.ElementAt(length + 4).ToString();
                                                            if (pronombre.Equals("las") || pronombre.Equals("les") || pronombre.Equals("los") || pronombre.Equals("nos"))
                                                            {
                                                                (e as palabra).Formadecita = words[1];
                                                                (e as palabra).Etiqueta = words[2];
                                                                e.Estado = "Etiquetado";
                                                                lectura = SR.ReadLine();
                                                                words = lectura.Split(' ');
                                                                (e as palabra).Formadecita += " y " + words[1];
                                                                (e as palabra).Etiqueta += " y " + words[2];
                                                                lectura = SR.ReadLine();
                                                                words = lectura.Split(' ');
                                                                (e as palabra).Formadecita += " y " + words[1];
                                                                (e as palabra).Etiqueta += " y " + words[2];
                                                            }
                                                            else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                        }
                                                        #endregion
                                                        #region 3.2.1.1.2.2.6.2.4.2: Case 3 + 2
                                                        else
                                                        {
                                                            pronombre += aparicion.ElementAt(length + 2).ToString();
                                                            if (pronombre.Equals("las") || pronombre.Equals("les") || pronombre.Equals("los") || pronombre.Equals("nos"))
                                                            {
                                                                pronombre = aparicion.ElementAt(length + 3).ToString() + aparicion.ElementAt(length + 4).ToString();
                                                                if (pronombre.Equals("me") || pronombre.Equals("la") || pronombre.Equals("le") || pronombre.Equals("lo") || pronombre.Equals("se") || pronombre.Equals("os") || pronombre.Equals("te"))
                                                                {
                                                                    (e as palabra).Formadecita = words[1];
                                                                    (e as palabra).Etiqueta = words[2];
                                                                    e.Estado = "Etiquetado";
                                                                    lectura = SR.ReadLine();
                                                                    words = lectura.Split(' ');
                                                                    (e as palabra).Formadecita += " y " + words[1];
                                                                    (e as palabra).Etiqueta += " y " + words[2];
                                                                    lectura = SR.ReadLine();
                                                                    words = lectura.Split(' ');
                                                                    (e as palabra).Formadecita += " y " + words[1];
                                                                    (e as palabra).Etiqueta += " y " + words[2];
                                                                }
                                                                else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                            }
                                                            else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                        }
                                                        #endregion
                                                    } break;
                                                #endregion
                                                #region 3.2.1.1.2.2.6.2.5: Case 6 -> 2 Pronombres 3 caracteres
                                                case 6:
                                                    {
                                                        pronombre = (e as palabra).Aparicion.ElementAt(length).ToString() + (e as palabra).Aparicion.ElementAt(length + 1).ToString() + (e as palabra).Aparicion.ElementAt(length + 2).ToString();
                                                        if (pronombre.Equals("las") || pronombre.Equals("les") || pronombre.Equals("los") || pronombre.Equals("nos"))
                                                        {
                                                            pronombre = (e as palabra).Aparicion.ElementAt(length + 3).ToString() + (e as palabra).Aparicion.ElementAt(length + 4).ToString() + (e as palabra).Aparicion.ElementAt(length + 5).ToString();
                                                            if (pronombre.Equals("las") || pronombre.Equals("les") || pronombre.Equals("los") || pronombre.Equals("nos"))
                                                            {
                                                                (e as palabra).Formadecita = words[1];
                                                                (e as palabra).Etiqueta = words[2];
                                                                e.Estado = "Etiquetado";
                                                                lectura = SR.ReadLine();
                                                                words = lectura.Split(' ');
                                                                (e as palabra).Formadecita += " y " + words[1];
                                                                (e as palabra).Etiqueta += " y " + words[2];
                                                                lectura = SR.ReadLine();
                                                                words = lectura.Split(' ');
                                                                (e as palabra).Formadecita += " y " + words[1];
                                                                (e as palabra).Etiqueta += " y " + words[2];
                                                            }
                                                            else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                        }
                                                        else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                        break;
                                                    }
                                                #endregion
                                            }
                                        }
                                        #endregion
                                        #region 3.2.1.1.2.2.6.3: Coincidencia parcial
                                        //Si el elemento acaba en alguno de los pronombres enclíticos
                                        else
                                        {
                                            #region 3.2.1.1.2.2.6.3.1: 1 Pronombre de 3 caracteres o 2 Pronombres (3+3 o 2+3)
                                            if (aparicion.Substring(aparicion.Length - 3, 3).Contains("las") || aparicion.Substring(aparicion.Length - 3, 3).Contains("les") || aparicion.Substring(aparicion.Length - 3, 3).Contains("los") || aparicion.Substring(aparicion.Length - 3, 3).Contains("nos"))
                                            {
                                                // Determinar si hay 1 o 2 pronombres enclíticos para leer 2 o 3 veces.
                                                #region 3.2.1.1.2.2.6.3.1.1: 1 Pronombre de 3 caracteres
                                                if ((words[0].Contains(aparicion.Substring(0, aparicion.Length - 3))) || words[0].Contains(RemoveAccents(aparicion.Substring(0, aparicion.Length - 3))))
                                                {
                                                    (e as palabra).Formadecita = words[1];
                                                    (e as palabra).Etiqueta = words[2];
                                                    e.Estado = "Etiquetado";
                                                    lectura = SR.ReadLine();
                                                    words = lectura.Split(' ');
                                                    (e as palabra).Formadecita += " y " + words[1];
                                                    (e as palabra).Etiqueta += " y " + words[2];
                                                }
                                                #endregion
                                                #region 3.2.1.1.2.2.6.3.1.2: 2 Pronombres de 3 caracteres (3+3)
                                                else if (aparicion.Substring(aparicion.Length - 6, 3).Contains("las") || aparicion.Substring(aparicion.Length - 6, 3).Contains("les") || aparicion.Substring(aparicion.Length - 6, 3).Contains("los") || aparicion.Substring(aparicion.Length - 6, 3).Contains("nos"))
                                                {
                                                    if ((words[0].Contains(aparicion.Substring(0, aparicion.Length - 6))) || words[0].Contains(RemoveAccents(aparicion.Substring(0, aparicion.Length - 6))))
                                                    {
                                                        (e as palabra).Formadecita = words[1];
                                                        (e as palabra).Etiqueta = words[2];
                                                        e.Estado = "Etiquetado";
                                                        lectura = SR.ReadLine();
                                                        words = lectura.Split(' ');
                                                        (e as palabra).Formadecita += " y " + words[1];
                                                        (e as palabra).Etiqueta += " y " + words[2];
                                                        lectura = SR.ReadLine();
                                                        words = lectura.Split(' ');
                                                        (e as palabra).Formadecita += " y " + words[1];
                                                        (e as palabra).Etiqueta += " y " + words[2];
                                                    }
                                                    else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                }
                                                #endregion
                                                #region 3.2.1.1.2.2.6.3.1.3: 2 Pronombres de 2 y 3 caracteres (2+3)
                                                else if (aparicion.Substring(aparicion.Length - 5, 2).Contains("me") || aparicion.Substring(aparicion.Length - 5, 2).Contains("la") || aparicion.Substring(aparicion.Length - 5, 2).Contains("le") || aparicion.Substring(aparicion.Length - 5, 2).Contains("lo") || aparicion.Substring(aparicion.Length - 5, 2).Contains("se") || aparicion.Substring(aparicion.Length - 5, 2).Contains("os") || aparicion.Substring(aparicion.Length - 5, 2).Contains("te"))
                                                {
                                                    if ((words[0].Contains(aparicion.Substring(0, aparicion.Length - 5))) || words[0].Contains(RemoveAccents(aparicion.Substring(0, aparicion.Length - 5))))
                                                    {
                                                        (e as palabra).Formadecita = words[1];
                                                        (e as palabra).Etiqueta = words[2];
                                                        e.Estado = "Etiquetado";
                                                        lectura = SR.ReadLine();
                                                        words = lectura.Split(' ');
                                                        (e as palabra).Formadecita += " y " + words[1];
                                                        (e as palabra).Etiqueta += " y " + words[2];
                                                        lectura = SR.ReadLine();
                                                        words = lectura.Split(' ');
                                                        (e as palabra).Formadecita += " y " + words[1];
                                                        (e as palabra).Etiqueta += " y " + words[2];
                                                    }
                                                    else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                }
                                                #endregion
                                            }
                                            #endregion
                                            #region 3.2.1.1.2.2.6.3.2: 1 Pronombre de 2 caracteres o 2 Pronombres (3+2 o 2+2)
                                            else if (aparicion.Substring(aparicion.Length - 2, 2).Contains("me") || aparicion.Substring(aparicion.Length - 2, 2).Contains("la") || aparicion.Substring(aparicion.Length - 2, 2).Contains("le") || aparicion.Substring(aparicion.Length - 2, 2).Contains("lo") || aparicion.Substring(aparicion.Length - 2, 2).Contains("se") || aparicion.Substring(aparicion.Length - 2, 2).Contains("os") || aparicion.Substring(aparicion.Length - 2, 2).Contains("te"))
                                            {
                                                // Determinar si hay 1 o 2 pronombres enclíticos para leer 2 o 3 veces.
                                                #region 3.2.1.1.2.2.6.3.2.1: 1 Pronombre de 2 caracteres
                                                if ((words[0].Contains(aparicion.Substring(0, aparicion.Length - 2))) || words[0].Contains(RemoveAccents(aparicion.Substring(0, aparicion.Length - 2))))
                                                {
                                                    (e as palabra).Formadecita = words[1];
                                                    (e as palabra).Etiqueta = words[2];
                                                    e.Estado = "Etiquetado";
                                                    lectura = SR.ReadLine();
                                                    words = lectura.Split(' ');
                                                    (e as palabra).Formadecita += " y " + words[1];
                                                    (e as palabra).Etiqueta += " y " + words[2];
                                                }
                                                #endregion
                                                #region 3.2.1.1.2.2.6.3.2.2: 2 Pronombres de 3 y 2 caracteres (3+2)
                                                else if (aparicion.Substring(aparicion.Length - 5, 3).Contains("las") || aparicion.Substring(aparicion.Length - 5, 3).Contains("les") || aparicion.Substring(aparicion.Length - 5, 3).Contains("los") || aparicion.Substring(aparicion.Length - 5, 3).Contains("nos"))
                                                {
                                                    if (words[0].Contains(aparicion.Substring(0, aparicion.Length - 5)) || words[0].Contains(RemoveAccents(aparicion.Substring(0, aparicion.Length - 5))))
                                                    {
                                                        (e as palabra).Formadecita = words[1];
                                                        (e as palabra).Etiqueta = words[2];
                                                        e.Estado = "Etiquetado";
                                                        lectura = SR.ReadLine();
                                                        words = lectura.Split(' ');
                                                        (e as palabra).Formadecita += " y " + words[1];
                                                        (e as palabra).Etiqueta += " y " + words[2];
                                                        lectura = SR.ReadLine();
                                                        words = lectura.Split(' ');
                                                        (e as palabra).Formadecita += " y " + words[1];
                                                        (e as palabra).Etiqueta += " y " + words[2];
                                                    }
                                                    else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                }
                                                #endregion
                                                #region 3.2.1.1.2.2.6.3.2.3: 2 Pronombres de 2 caracteres (2+2)
                                                else if (aparicion.Substring(aparicion.Length - 4, 2).Contains("me") || aparicion.Substring(aparicion.Length - 4, 2).Contains("la") || aparicion.Substring(aparicion.Length - 4, 2).Contains("le") || aparicion.Substring(aparicion.Length - 4, 2).Contains("lo") || aparicion.Substring(aparicion.Length - 4, 2).Contains("se") || aparicion.Substring(aparicion.Length - 4, 2).Contains("os") || aparicion.Substring(aparicion.Length - 4, 2).Contains("te"))
                                                {
                                                    if ((words[0].Contains(aparicion.Substring(0, aparicion.Length - 4))) || words[0].Contains(RemoveAccents(aparicion.Substring(0, aparicion.Length - 4))))
                                                    {
                                                        (e as palabra).Formadecita = words[1];
                                                        (e as palabra).Etiqueta = words[2];
                                                        e.Estado = "Etiquetado";
                                                        lectura = SR.ReadLine();
                                                        words = lectura.Split(' ');
                                                        (e as palabra).Formadecita += " y " + words[1];
                                                        (e as palabra).Etiqueta += " y " + words[2];
                                                        lectura = SR.ReadLine();
                                                        words = lectura.Split(' ');
                                                        (e as palabra).Formadecita += " y " + words[1];
                                                        (e as palabra).Etiqueta += " y " + words[2];
                                                    }
                                                    else throw new Classes.Excepciones.Excepcion_enclitico("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                                }
                                                #endregion
                                            }
                                            else throw new Classes.Excepciones.Excepcion_error_etiquetado("Error al intentar etiquetar el elemento: " + (e as palabra).Aparicion + " de la linea número " + l.Numero + " del texto: " + texto.Nombre);
                                            #endregion
                                        }
                                        #endregion
                                    }
                                    #endregion
                               }
                            #endregion
                        }
                        #endregion
                    }
                    #endregion
                }
                #endregion
            }
            #endregion

            SR.Close();
            #endregion
        }
        /// <summary>
        /// XML almacena la transcripcion en formato xml.
        /// </summary>
        /// <param name="texto">La transcripcion a almacenar.</param>
        private void xml(texto texto,string ruta)
        {            
            Transcripcion transcripcion = new Transcripcion();

            TranscripcionLinea[] lineas=  new TranscripcionLinea[texto.Lineas.Count];
            int numlineas = 0;
            foreach (linea l in texto.Lineas.Values) 
            {
                TranscripcionLinea linea = new TranscripcionLinea();
                linea.Interlocutor = l.Interlocutor;
                linea.Numero=l.Numero;
                linea.Contenido=l.Contenido;
                TranscripcionLineaElemento[] elementos=new TranscripcionLineaElemento[l.Elementos.Count];
                int numelementos = 0;
                foreach (int i in l.Elementos.Keys) 
                {
                    elemento e;
                    l.Elementos.TryGetValue(i, out e);

                    TranscripcionLineaElemento elemento = new TranscripcionLineaElemento();
                    
                    if (e is palabra)
                    {
                        elemento.Tipo = "Palabra";
                        elemento.Posicion = i;
                        if((e as palabra).Aparicion != null)  elemento.Aparicion = (e as palabra).Aparicion;
                        else elemento.Aparicion = "";
                        if ((e as palabra).Etiqueta!= null) elemento.Etiqueta = (e as palabra).Etiqueta;
                        else elemento.Etiqueta = "";
                        if ((e as palabra).Formadecita != null) elemento.Forma_de_cita = (e as palabra).Formadecita;
                        else elemento.Forma_de_cita = "";
                        
                    }
                    else
                    {
                        elemento.Tipo = "Simbolo";
                        elemento.Posicion = i;
                        if ((e as simbolo).Aparicion != null) elemento.Aparicion = (e as simbolo).Aparicion;
                        else elemento.Aparicion = "";
                        if ((e as simbolo).Etiqueta != null) elemento.Etiqueta = (e as simbolo).Etiqueta;
                        else elemento.Etiqueta = "";
                        if ((e as simbolo).Formadecita != null) elemento.Forma_de_cita = (e as simbolo).Formadecita;
                        else elemento.Forma_de_cita = "";
                    }
                    elemento.Estado = e.Estado;
                    elementos[numelementos++] = elemento;
                }
                linea.Elementos = elementos;
                l.actualizarEstado();
                linea.Estado = l.Estado;
                lineas[numlineas++] = linea;
                          
            }
            transcripcion.Lineas = lineas;

            transcripcion.Nombre = texto.Nombre;
            transcripcion.Ultima_revisión = texto.Ultimarevision;
            texto.actualizarEstado();
            transcripcion.Estado = texto.Estado;

            XmlSerializer serializadorXML=new  XmlSerializer(typeof(Transcripcion));
            StreamWriter escritorXML = new StreamWriter(ruta + texto.Nombre + ".xml");
            serializadorXML.Serialize(escritorXML, transcripcion);
            escritorXML.Close();

        }
        /// <summary>
        /// RemoveAccents elimina todos los acentos de una string.
        /// </summary>
        /// <param name="inputString">La string con acentos.</param>
        /// <returns>La string sin acentos</returns>
        public static string RemoveAccents(string inputString)
        {
            Regex replace_a_Accents = new Regex("[á|à|ä|â]", RegexOptions.Compiled);
            Regex replace_e_Accents = new Regex("[é|è|ë|ê]", RegexOptions.Compiled);
            Regex replace_i_Accents = new Regex("[í|ì|ï|î]", RegexOptions.Compiled);
            Regex replace_o_Accents = new Regex("[ó|ò|ö|ô]", RegexOptions.Compiled);
            Regex replace_u_Accents = new Regex("[ú|ù|ü|û]", RegexOptions.Compiled);
            inputString = replace_a_Accents.Replace(inputString, "a");
            inputString = replace_e_Accents.Replace(inputString, "e");
            inputString = replace_i_Accents.Replace(inputString, "i");
            inputString = replace_o_Accents.Replace(inputString, "o");
            inputString = replace_u_Accents.Replace(inputString, "u");
            return inputString;
        }
        /// <summary>
        /// RemoveAlargamiento transforma las vocales duplicadas en una sola vocal
        /// </summary>
        /// <param name="inputString">La string con alargamiento.</param>
        /// <returns>La string sin alargamiento.</returns>
        public static string RemoveAlargamiento(string inputString) 
        {
            if (!inputString.Contains("lee") && !inputString.Contains("cree"))
            {
                Regex replace_a_Alargamiento = new Regex("aa", RegexOptions.Compiled);
                Regex replace_e_Alargamiento = new Regex("ee", RegexOptions.Compiled);
                Regex replace_i_Alargamiento = new Regex("ii", RegexOptions.Compiled);
                Regex replace_o_Alargamiento = new Regex("oo", RegexOptions.Compiled);
                Regex replace_u_Alargamiento = new Regex("uu", RegexOptions.Compiled);
                Regex replace_a2_Alargamiento = new Regex("áa", RegexOptions.Compiled);
                Regex replace_e2_Alargamiento = new Regex("ée", RegexOptions.Compiled);
                Regex replace_i2_Alargamiento = new Regex("íi", RegexOptions.Compiled);
                Regex replace_o2_Alargamiento = new Regex("óo", RegexOptions.Compiled);
                Regex replace_u2_Alargamiento = new Regex("úu", RegexOptions.Compiled);
                inputString = replace_a_Alargamiento.Replace(inputString, "a");
                inputString = replace_e_Alargamiento.Replace(inputString, "e");
                inputString = replace_i_Alargamiento.Replace(inputString, "i");
                inputString = replace_o_Alargamiento.Replace(inputString, "o");
                inputString = replace_u_Alargamiento.Replace(inputString, "u");
                inputString = replace_a2_Alargamiento.Replace(inputString, "á");
                inputString = replace_e2_Alargamiento.Replace(inputString, "é");
                inputString = replace_i2_Alargamiento.Replace(inputString, "í");
                inputString = replace_o2_Alargamiento.Replace(inputString, "ó");
                inputString = replace_u2_Alargamiento.Replace(inputString, "ú");
            }
            return inputString;
        }

        private void etiquetar_doc(string ruta)
        {
            try
            {
                Microsoft.Office.Interop.Word.Application wordObject = new Word.Application();
                object file = ruta; //this is the path
                object nullobject = System.Reflection.Missing.Value;
                Microsoft.Office.Interop.Word.Document docs = wordObject.Documents.Open
                    (ref file, ref nullobject, ref nullobject, ref nullobject,
                    ref nullobject, ref nullobject, ref nullobject, ref nullobject,
                    ref nullobject, ref nullobject, ref nullobject, ref nullobject,
                    ref nullobject, ref nullobject, ref nullobject, ref nullobject);


                IDataObject data;
                int contador = 1;
                SortedList<int, string> lineas = new SortedList<int, string>();
                foreach (Microsoft.Office.Interop.Word.Paragraph p in docs.Paragraphs)
                {
                    p.Range.Select();
                    docs.ActiveWindow.Selection.Copy();
                    data = Clipboard.GetDataObject();
                    lineas.Add(contador++, data.GetData(DataFormats.Text).ToString());
                }
                string ruta_ = "..\\..\\..\\..\\..\\";
                classes.Etiquetado etiquetar = new classes.Etiquetado();
                string nombre = docs.Name;
                bool etiquetado = etiquetar.etiquetar(nombre, lineas, true, ruta_);
                
                docs.Close(ref nullobject, ref nullobject, ref nullobject);

            }
            catch (Exception j)
            {
                MessageBox.Show(j.Message);
            }
        }

        public void guardar(string ruta)
        {
            try
            {
                Microsoft.Office.Interop.Word.Application wordObject = new Word.Application();
                object file = ruta; //this is the path
                object nullobject = System.Reflection.Missing.Value;
                Microsoft.Office.Interop.Word.Document docs = wordObject.Documents.Open
                    (ref file, ref nullobject, ref nullobject, ref nullobject,
                    ref nullobject, ref nullobject, ref nullobject, ref nullobject,
                    ref nullobject, ref nullobject, ref nullobject, ref nullobject,
                    ref nullobject, ref nullobject, ref nullobject, ref nullobject
                                    );

                IDataObject data;
                int contador = 1;
                SortedList<int, string> lineas = new SortedList<int, string>();
                foreach (Microsoft.Office.Interop.Word.Paragraph p in docs.Paragraphs)
                {
                    p.Range.Select();
                    docs.ActiveWindow.Selection.Copy();
                    data = Clipboard.GetDataObject();
                    lineas.Add(contador++, data.GetData(DataFormats.Text).ToString());
                }
                string ruta_ = "..\\..\\..\\..\\..\\";
                classes.Etiquetado etiquet = new classes.Etiquetado();
                string nombre = docs.Name;
                bool etiquetado = etiquet.etiquetar(nombre, lineas, false, ruta_);

                docs.Close(ref nullobject, ref nullobject, ref nullobject);

            }
            catch (Exception j)
            {
                MessageBox.Show(j.Message);
            }

        }
    }
}


