package VistaControlador;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.io.IOException;
import java.time.LocalDate;
import java.time.Month;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.github.lgooddatepicker.components.DatePicker;
import com.github.lgooddatepicker.optionalusertools.DateChangeListener;

import Ficheros.Configuracion;
import Logica.Gestion;
import Logica.Meses;
import Logica.Transaccion;
import loggin.Vista;

public class Menu extends JFrame{
	static final int VISTA_MODIFICAR = 0;
	static final int VISTA_GESTION = 1;
	static final int VISTA_INTERFAZ =2;
	
	JPanel panelCentral;
	JTabbedPane pestania;
	VistaAniadirVisualizar ingresos;
	VistaAniadirVisualizar gastos;
	VistaPanelGestion panelGestion;
	VistaPanelModificar panelModificar;
	VistaPanel panel;
	String rutaGuardado;
	int tema;
	Meses meses;
	ArrayList<VistaAniadirVisualizar> pestanias;
	ArrayList<ControladorAniadirVisualizar> controladores;
	BarraOpciones barra;
	Gestion datosGastos;
	Gestion datosIngresos;
	DatePicker elegirMes;
	int anio;
	Month mes;
	VistaPanelInterfaz panelInterfaz;
	
	/**
	 * Constructor que carga los datos del menu
	 */
	public Menu() {
		Vista loggin = new Vista(Vista.Comprobar);
		
		if(!loggin.verResultado()) {
			System.exit(0);
		}
		this.rutaGuardado = ".mes";
		this.tema = 0;
		this.barra = new BarraOpciones();
		ControladorBarra controladorBarra = new ControladorBarra(barra, this);
		
		setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
		 
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                close();
            }
        });
		this.pestania = new JTabbedPane();
		GridBagConstraints constrain = new GridBagConstraints();
		
		this.cargarGestiones(LocalDate.now().getYear(), LocalDate.now().getMonth());
		this.cargarPestanias();
		this.panelCentral = new JPanel();
		this.panelCentral.setLayout(new GridBagLayout());
		this.panelGestion = new VistaPanelGestion(this.meses);
		this.panelModificar = new VistaPanelModificar();
		this.panelInterfaz = new VistaPanelInterfaz();
		this.panel = this.panelGestion;
		
		constrain.fill = GridBagConstraints.HORIZONTAL;
		constrain.gridx = 0;
		constrain.gridwidth = 2;
		constrain.gridy = 0;
		constrain.weightx = 0;
		this.panelCentral.add(this.barra,constrain);
		
		constrain.fill = GridBagConstraints.HORIZONTAL;
		constrain.gridwidth = 1;
		constrain.gridx = 0;
		constrain.gridy = 1;
		constrain.gridheight = 2;
		constrain.weightx = 0.25;
		this.panelCentral.add(pestania,constrain);
		setTitle("Titulo");
		setSize(new Dimension(420,320));
		setDefaultCloseOperation(3);
		setLocationRelativeTo(null);
		ControladorPanelGestion controlador3 = new ControladorPanelGestion(this.panelGestion, this);
		ControladorPanelModificar controlador4 = new ControladorPanelModificar(this.panelModificar, this);
		ControladorPanelInterfaz controlador5 = new ControladorPanelInterfaz(this.panelInterfaz, this);
		this.listenerPestania();
		
		this.elegirMes = new DatePicker();
		this.elegirMes.setDate(LocalDate.now());
		this.elegirMes.addDateChangeListener((DateChangeListener)->{
			if(!this.elegirMes.getDate().getMonth().equals(this.mes) || !(this.elegirMes.getDate().getYear() == this.anio) ) {
				this.mes = this.elegirMes.getDate().getMonth();
				this.anio = this.elegirMes.getDate().getYear();
				this.cargarGestiones(this.anio, this.mes);
			}
		});
		constrain.fill = GridBagConstraints.HORIZONTAL;
		constrain.gridx = 1;
		constrain.gridy = 1;
		constrain.gridheight = 1;
		constrain.weightx = 0.25;
		this.panelCentral.add(this.elegirMes, constrain);
		
		constrain.fill = GridBagConstraints.HORIZONTAL;
		constrain.gridx = 1;
		constrain.gridy = 2;
		constrain.weightx = 0.25;
		this.panelCentral.add(this.panel,constrain);
		this.add(this.panelCentral);
		try {
			Configuracion.cargarConfiguracion(this);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Cierra la ventana
	 */
	private void close(){
        if (JOptionPane.showConfirmDialog(rootPane, "¿Desea guardar el estado?",
                "Salir del sistema", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
        	try {
				this.meses.guardarMeses(this.rutaGuardado);
				Configuracion.guardarConfiguracion(this);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
            System.exit(0);
    }   
	
	/**
	 * Inicia las listas de elementos graficos pertenecientes a el mes correspondiente
	 * 
	 * @param anio	anio del que cargaremos los datos
	 * @param mes	mes del que cargaremos los datos
	 */
	private void iniciarMes(int anio, Month mes) {
		this.pestania.removeAll();
		this.listenerPestania();
		meses.aniadirGestion("Ingresos", anio, mes, true);
		meses.aniadirGestion("Gastos", anio, mes, false);
		this.pestanias=new ArrayList<VistaAniadirVisualizar>();
		this.pestanias.add(new VistaAniadirVisualizar(this,meses.getGestionesActuales().get(0)));
		this.pestanias.add(new VistaAniadirVisualizar(this,meses.getGestionesActuales().get(1)));
		this.controladores=new ArrayList<ControladorAniadirVisualizar>();
		this.controladores.add(new ControladorAniadirVisualizar(this.pestanias.get(0)));
		this.controladores.add(new ControladorAniadirVisualizar(this.pestanias.get(1)));
		this.cargarPestanias();
	}
	
	/**
	 * Carga los datos de las gestiones en caso de cambio de mes
	 * 
	 * @param nio	anio del que cargaremos los datos
	 * @param mes	mes del que cargaremos los datos
	 */
	void cargarGestiones(int anio, Month mes) {
		if(this.meses==null) {
			this.meses=new Meses();
			try {
				meses.cargarMeses(this.rutaGuardado);
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.meses.elegirMes(anio, mes);
		if(this.meses.getGestionesActuales().size() == 0) {
			this.iniciarMes(anio, mes);
		}else {
			this.cargarMes();
		}
	}
	
	/**
	 * Carga la parte grafica de ese mes
	 */
	private void cargarMes() {
		this.pestania.removeAll();
		this.listenerPestania();
		if(this.pestanias == null) {
			this.pestanias = new ArrayList<VistaAniadirVisualizar>();
		}else {
			this.pestanias.clear();
		}
		if(this.controladores == null) {
			this.controladores = new ArrayList<ControladorAniadirVisualizar>();
		}else {
			this.controladores.clear();
		}
		for(Gestion gestion:this.meses.getGestionesActuales()) {
			VistaAniadirVisualizar vista = new VistaAniadirVisualizar(this, gestion);
			ControladorAniadirVisualizar controlador = new ControladorAniadirVisualizar(vista);
			vista.iniciarGestion(controlador);
			this.pestanias.add(vista);
			this.controladores.add(controlador);
		}
		this.cargarPestanias();
	}
	
	/**
	 * Carga todas las pestanias nuevas
	 */
	void cargarPestanias() {
		this.pestania.removeAll();
		this.listenerPestania();
		for(VistaAniadirVisualizar vista:this.pestanias) {
			this.pestania.addTab(vista.getName(),vista);
		}
		this.pestania.setSelectedIndex(0);
	}
	
	/**
	 * aniade una nueva gestion
	 * 
	 * @param nombre		nombre de la gestion
	 * @param sumaOResta	tipo de gestion
	 */
	void aniadirGestion(String nombre, boolean sumaOResta) {
		Gestion gestion=this.meses.aniadirGestion(nombre, this.anio, this.mes, sumaOResta);
		VistaAniadirVisualizar vista = new VistaAniadirVisualizar(this, gestion);
		this.pestanias.add(vista);
		this.controladores.add(new ControladorAniadirVisualizar(vista));
		this.pestania.addTab(vista.getName(),vista);
		this.meses.getGestionesActuales().add(gestion);
	}
	
	/**
	 * Carga el listener de las pestanias en caso de que no lo tengan
	 */
	void listenerPestania(){
		if(this.pestania.getChangeListeners().length == 1) {
			this.pestania.addChangeListener((ChangeListener)->{
				if(this.pestania.getTabCount()>0) {
					try {
						this.panelGestion.actualizarDatos(meses.getGestionesActuales().get(this.pestania.getSelectedIndex()));
					}catch (Exception e) {
						// TODO: handle exception
					}
				}
			});
		}	
	}
	
	/**
	 * Devuelve la ruta en la que se guardan los datos de persistencia
	 * 
	 * @return	ruta de los datos de persistencia
	 */
	public String getRuta() {
		return this.rutaGuardado;
	}
	
	/**
	 * Estabece ula ruta de los datos de persistencia
	 * 
	 * @param ruta	ruta de los datos de persistencia
	 */
	public void setRuta(String ruta) {
		this.rutaGuardado=ruta;
	}
	
	/**
	 * devuelve el tema seleccionado
	 * 
	 * @return id del teme
	 */
	public int getTema() {
		return this.tema;
	}
	
	/**
	 * Cambia el tema
	 * 
	 * @param tema	id del tema
	 */
	public void setTheme(int tema) {
		switch(tema) {
		case 0:{
			this.tema = 0;
			this.setBackground(Color.WHITE);
			this.setOpacity(1);
			this.repaint();
			this.revalidate();
			this.panelCentral.setOpaque(true);
			this.panelCentral.setBackground(Color.WHITE);
			this.panelCentral.repaint();
			this.panelCentral.revalidate();
			this.panelGestion.setBackground(Color.WHITE);
			this.panelModificar.setBackground(Color.WHITE);
			this.panel.repaint();
			this.panel.revalidate();
			break;
		}
		case 1:{
			this.tema = 1;
			this.setBackground(Color.PINK);
			this.setOpacity(1);
			this.repaint();
			this.revalidate();
			this.panelCentral.setOpaque(true);
			this.panelCentral.setBackground(Color.PINK);
			this.panelCentral.repaint();
			this.panelCentral.revalidate();
			this.panelGestion.setBackground(Color.PINK);
			this.panelModificar.setBackground(Color.PINK);
			this.panel.repaint();
			this.panel.revalidate();
			break;
		}
		case 2:{
			this.tema = 2;
			this.setBackground(Color.BLACK);
			this.setOpacity(1);
			this.repaint();
			this.revalidate();
			this.panelCentral.setOpaque(true);
			this.panelCentral.setBackground(Color.BLACK);
			this.panelCentral.repaint();
			this.panelCentral.revalidate();
			this.panelGestion.setBackground(Color.BLACK);
			this.panelModificar.setBackground(Color.BLACK);
			this.panel.repaint();
			this.panel.revalidate();
			break;
		}
		default: return;
		}
	}
	
	void cambiarVista(int vista) {
		GridBagConstraints constrain = new GridBagConstraints();
		this.panelCentral.remove(this.panel);
		constrain = new GridBagConstraints();
		constrain.fill = GridBagConstraints.HORIZONTAL;
		constrain.gridx = 1;
		constrain.gridy = 2;
		constrain.weightx = 0.25;
		switch(vista) {
		case Menu.VISTA_GESTION:{
			this.panel = this.panelGestion;
			break;
		}
		case Menu.VISTA_MODIFICAR:{
			this.panel = this.panelModificar;
			break;
		}
		case Menu.VISTA_INTERFAZ:{
			this.panel = this.panelInterfaz;
			break;
		}
		}
		this.panelCentral.add(this.panel,constrain);
		this.panel.repaint();
		this.panel.revalidate();
		this.panelCentral.repaint();
		this.panelCentral.revalidate();
		
	}
	
}
