using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace Gestor_de_Contenidos
{
    /*
     User control padre. Implementa las funcionalidades comunes a la mayoria de UC, además del menú comun para toda la aplicacion.
     */
    public partial class uc_base : UserControl
    {
        protected bool hayCambios;             // Se pone a true si se ha modifcado algo sobre el nivel que estamos cambiando.
        protected bool esEliminacion = false; // Se pone a true si estamos eliminando un nivel en las Historias Sociales.

        public uc_base()
        {
            InitializeComponent();
        }

        /*
         Se pulsa salir sobre el menu de arriba
         */
        private void salirToolStripMenuItem_Click(object sender, EventArgs e)
        {
            

            if (getNivel() == null)
            {
                frm_principal.getInstance().borrarCarpetasObsoletas();
                Application.Exit();
                    
            }

            else
            {
                if (DialogResult.Yes == MessageBox.Show("¿Está seguro que desea salir de la aplicación? No se guardarán los cambios que haya realizado en la historia", "Salir sin guardar", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {
                    frm_principal.getInstance().borrarCarpetasObsoletas();
                    Application.Exit();
                }
            }
        }

        /* Volver al menu principal */
        private void menuPrincipalToolStripMenuItem_Click(object sender, EventArgs e)
        {

            if (getNivel() == null)
            {
                frm_principal.getInstance().cambiarPantalla(new uc_pantalla_principal());
            }

            else
            {
                if (DialogResult.Yes == MessageBox.Show("¿Está seguro que desea ir al menú principal? No se guardarán los cambios que haya realizado", "Salir sin guardar", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {
                    frm_principal.getInstance().cambiarPantalla(new uc_pantalla_principal());
                }
            }
        }

        /*Nos devuelve el nivel en que nos encontramos*/
        public virtual Nivel getNivel() { 
        
            return null;
        }

        /*Nos devuelve el treeNode en que nos encontramos*/
        public virtual TreeNode getTreeNode() { 
        
            return null;
        }

        /*Se encarga de cambiar de nivel cuando clickamos sobre un treeNode en el treeView*/
        public virtual void seleccionarNodoTreeView(TreeNode node, bool hayCambios, TreeView sender){
        
            Nivel nivel = getNivel();
            TreeNode treeNode = getTreeNode();
            if (node != null)
            {
                Nivel siguiente_nivel;
                frm_principal.getInstance().Dic_historia.TryGetValue(node, out siguiente_nivel);

                if (siguiente_nivel != null && !siguiente_nivel.Equals(nivel))
                {
                        guardarNivel();
                        if (siguiente_nivel.GetType().Equals(new NivelHistoriaSocial().GetType()))
                            frm_principal.getInstance().cambiarPantalla(new uc_nueva_hs((NivelHistoriaSocial)siguiente_nivel, node));
                        if (siguiente_nivel.GetType().Equals(new NivelExplicacion().GetType()))
                            frm_principal.getInstance().cambiarPantalla(new uc_hs_explicacion((NivelExplicacion)siguiente_nivel, node));
                        if (siguiente_nivel.GetType().Equals(new NivelEleccionUnica().GetType()))
                            frm_principal.getInstance().cambiarPantalla(new uc_hs_eleccion_unica((NivelEleccionUnica)siguiente_nivel, node));
                        if (siguiente_nivel.GetType().Equals(new NivelOrdenacion().GetType()))
                            frm_principal.getInstance().cambiarPantalla(new uc_hs_ordenacion((NivelOrdenacion)siguiente_nivel, node));
                        if (siguiente_nivel.GetType().Equals(new NivelClasificacion().GetType()))
                            frm_principal.getInstance().cambiarPantalla(new uc_hs_clasificacion((NivelClasificacion)siguiente_nivel, node));
                        if (siguiente_nivel.GetType().Equals(new NivelColaboracion().GetType()))
                            frm_principal.getInstance().cambiarPantalla(new uc_hs_colaboracion((NivelColaboracion)siguiente_nivel, node));
                        if (siguiente_nivel.GetType().Equals(new NivelEleccionLibre().GetType()))
                            frm_principal.getInstance().cambiarPantalla(new uc_hs_eleccion_libre((NivelEleccionLibre)siguiente_nivel, node));

                }
            } 
        }

        /*Guarda el nivel en memoria, pero no persistentemente*/
        public virtual bool guardarNivel() {

            return false;
        }

        /*Se encarga de eliminar el nivel donde nos encontramos*/
        public virtual void eliminarNivel() {
            Nivel nivel = getNivel();
            TreeNode treeNode = getTreeNode();
            
            //Nivel anterior es EL
            if (nivel.NivelAnterior.GetType().Equals(new NivelEleccionLibre().GetType()))
            {
                if (DialogResult.Yes == MessageBox.Show("Este nivel es un Item de un nivel de Elección Libre. Si se elimina, se eliminarán todos los niveles que siguen a este. ¿Desea continuar?", "Eliminar Nivel", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {

                    NivelEleccionLibre nel = (NivelEleccionLibre)nivel.NivelAnterior;
                    ItemEleccionLibre it = nel.buscarEleccion(nivel);
                    nel.eliminarEleccion(it);

                    try
                    {
                        foreach (TreeNode t in treeNode.Nodes)
                        {

                            frm_principal.getInstance().Dic_historia.Remove(t);

                        }
                        frm_principal.getInstance().Dic_historia.Remove(treeNode);
                        frm_principal.getInstance().Tv_histora.Nodes.Remove(treeNode);
                    }
                    catch (Exception) { }

                    //Si el nivel anterior se queda sin items se pone en amarillo
                    if (!nel.estaImplementado()) {
                        Nivel n=null;
                        try
                        {
                            foreach (TreeNode t in frm_principal.getInstance().Dic_historia.Keys) { 
                                frm_principal.getInstance().Dic_historia.TryGetValue(t, out n);
                                if (n.Equals(nel))
                                    t.BackColor = Color.Yellow;
                            }
                        }
                        catch (Exception) { }
                    
                    
                    }

                    //Vamos a la pantalla prncipal                    
                    NivelHistoriaSocial nh = obtenerNHSrecursivamente(nivel.NivelAnterior);
                    frm_principal.getInstance().Dic_historia.Remove(frm_principal.getInstance().Tv_histora.TopNode);
                    frm_principal.getInstance().Dic_historia.Add(frm_principal.getInstance().Tv_histora.TopNode, nh);
                    frm_principal.getInstance().cambiarPantalla(new uc_nueva_hs((NivelHistoriaSocial)nh, frm_principal.getInstance().Tv_histora.TopNode));
                }

            }
            
            // El nivel anterior no es EL
            else
            {
                // Si el nivel es EL.
                if (nivel.GetType().Equals(new NivelEleccionLibre().GetType()))
                {
                    if (DialogResult.Yes == MessageBox.Show("Va a eliminar un nivel de Elección Libre. Se eliminarán todos sus hijos. ¿Desea continuar?", "Eliminar Nivel", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                    {
                        nivel.NivelAnterior.SiguienteNivel = null;
                        eliminarNodos(treeNode);
                        frm_principal.getInstance().Tv_histora.Nodes.Remove(treeNode);

                        try
                        {
                            frm_principal.getInstance().Dic_historia.Remove(treeNode);
                        }
                        catch (Exception) { }

                        NivelHistoriaSocial nh = obtenerNHSrecursivamente(nivel.NivelAnterior);
                        frm_principal.getInstance().Dic_historia.Remove(frm_principal.getInstance().Tv_histora.TopNode);
                        frm_principal.getInstance().Dic_historia.Add(frm_principal.getInstance().Tv_histora.TopNode, nh);
                        frm_principal.getInstance().cambiarPantalla(new uc_nueva_hs((NivelHistoriaSocial)nh, frm_principal.getInstance().Tv_histora.TopNode));

                    }

                }
                
                // El nivel no es EL
                else
                {
                    if (DialogResult.Yes == MessageBox.Show("Va a eliminar el nivel ¿Desea continuar?", "Eliminar Nivel", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                    {
                        // Se arregla el tree view.
                        if (treeNode.FirstNode != null)
                        {
                            TreeNode tnhijo = treeNode.FirstNode;
                            TreeNode tnpadre = treeNode.Parent;
                            frm_principal.getInstance().Tv_histora.Nodes.Remove(treeNode);
                            tnpadre.Nodes.Add(tnhijo);
                            tnpadre.Expand();
                        }
                        else
                            frm_principal.getInstance().Tv_histora.Nodes.Remove(treeNode);
                        //Si no se ha guardado, dará excepcion
                        try
                        {
                            frm_principal.getInstance().Dic_historia.Remove(treeNode);
                        }
                        catch (Exception) { }

                        nivel.NivelAnterior.SiguienteNivel = nivel.SiguienteNivel;
                        if (nivel.SiguienteNivel != null)
                            nivel.SiguienteNivel.NivelAnterior = nivel.NivelAnterior;
                       
                        //Vamos a la pantalla principal
                        NivelHistoriaSocial nh = obtenerNHSrecursivamente(nivel.NivelAnterior);
                        frm_principal.getInstance().Dic_historia.Remove(frm_principal.getInstance().Tv_histora.TopNode);
                        frm_principal.getInstance().Dic_historia.Add(frm_principal.getInstance().Tv_histora.TopNode, nh);
                        frm_principal.getInstance().cambiarPantalla(new uc_nueva_hs((NivelHistoriaSocial)nh, frm_principal.getInstance().Tv_histora.TopNode));
                    }
                }


            }
        
        }

        /* Este médodo obtiene la raiz de la historia social, pasandole el nivel donde nos encontramos */
        public NivelHistoriaSocial obtenerNHSrecursivamente(Nivel nactual) { 
        
            Nivel n=null;
            do
            {
                if (nactual.NivelAnterior == null)
                {
                    return (NivelHistoriaSocial)nactual;
                }
                n = nactual.NivelAnterior;
                nactual = n;

            } while (!n.GetType().Equals(new NivelHistoriaSocial().GetType()));

            return (NivelHistoriaSocial)n;
        
        }

        /* Elimina todos los nodos por debajo del nodo que le pasamos */
        private void eliminarNodos(TreeNode treeNode) {

            if (treeNode.Nodes.Count == 0)
                frm_principal.getInstance().Dic_historia.Remove(treeNode);
            else
            {
                foreach (TreeNode tn in treeNode.Nodes) {

                    eliminarNodos(tn);
                    
                }
                frm_principal.getInstance().Dic_historia.Remove(treeNode);
            }
        
        }

        /* Se Finaliza la Historia Social. Se guardan los datos en archivos XML. */
        public virtual void finalizarHistoriaSocial(){
          
        if(DialogResult.Yes==MessageBox.Show("¿Desea finalizar la historia social y guardarla en disco?", "Finalizar Historia Social",MessageBoxButtons.YesNo,MessageBoxIcon.Question)){

            if (guardarNivel())
            {
                if (frm_principal.getInstance().todosNivelesCompletos())
                {
                    frm_guardar_hs frm = new frm_guardar_hs();
                    frm_principal.getInstance().cambiarPantalla(new uc_pantalla_principal());
                    if (frm.ShowDialog() == DialogResult.OK)
                    {
                       
                    }
                    else {

                        MessageBox.Show("Se ha producido un error guardando. Por favor, intentalo de nuevo", "Error guardando datos", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
                    }
                    
                    
                }
                else
                    MessageBox.Show("Hay niveles incompletos en la ruta. Completelos para guardar.", "Niveles no implementados", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
            else
                MessageBox.Show("El nivel está incompleto. Completelo y continue.", "Nivel Incompleto", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
        }


    }
}
