package actions;

import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.apache.log4j.Logger;

import utils.Constantes;
import utils.Utilidades;
import business.Arista;
import business.Configuracion;
import business.Grafo;
import business.Resultados;
import business.Vertice;
import core.Aplicacion;
import core.BarraHerramientas;
import core.ModalAceptar;
import core.PanelEdicion;
import core.PanelInfo;

public class SimplesAction implements ActionListener, ChangeListener {
	
	private static Logger logger = Logger.getLogger(SimplesAction.class);

	private Aplicacion aplicacion;
	private PanelEdicion panelEdicion;
	private PanelInfo panelInfo;
	private BarraHerramientas barra;

	public SimplesAction (Aplicacion a) {
		aplicacion = a;
		panelEdicion = Aplicacion.getPanelEdicion();
		panelInfo = Aplicacion.getPanelInfo();
		barra = Aplicacion.getBarraHerramientas();
	}

	public void actionPerformed(ActionEvent e) {
		JButton b = new JButton();
		JMenuItem m = new JMenuItem();
		JComboBox c = new JComboBox();
		if (e.getSource() instanceof JButton) {
			b = (JButton) e.getSource();
			m.setName("");
			c.setName("");
		} else if (e.getSource() instanceof JMenuItem) {
			b.setName("");
			m = (JMenuItem) e.getSource();
			c.setName("");
		} else if(e.getSource() instanceof JComboBox) {
			b.setName("");
			m.setName("");
			c = (JComboBox)e.getSource();
		}

		if (b.getName().equals("Borrar")) {
			borrar();
		} else if (m.getName().equals("3D")) {
			poner3D();
		} else if (c.getName().equals("Idioma")) {
			cambiarIdioma();
		} else if (b.getName().equals("masZoom") && barra.getBarraZoom().getValue() < 300){
			aumentarZoomBoton();
		} else if (b.getName().equals("menosZoom") && barra.getBarraZoom().getValue() > 30){
			reducirZoomBoton();
		} else if (m.getName().equals("Salir")) {
			salir();
		}
	}

	public void stateChanged(ChangeEvent e) {
		if(e.getSource() instanceof JSlider) {
			cambiarZoomBarra();
		}
	}


	public void borrar() {
		ResourceBundle mensajes = panelEdicion.getMensajes();
		Resultados.setResultados(new Vector<ArrayList<Integer>>());
		Resultados.setMatriz((int[][])null);
		panelEdicion.setGrafo(new Grafo());
		panelEdicion.setMensajes(mensajes);
		panelInfo.mostrarNumeroVertices(0);
		panelInfo.mostrarNumeroAristas(0);
		panelInfo.mostrarNumeroVerticesSeleccionados(0);
		panelInfo.mostrarNumeroAristasSeleccionadas(0);
		panelInfo.activarModoLectura(false);
		barra.getNumeroSolucion().setText("-");
		barra.getNumeroSoluciones().setText("(-)");
		panelEdicion.repaint();
		panelEdicion.setZoom((double)barra.getBarraZoom().getValue()/100);
		panelInfo.repaint();
		logger.info("Grafo borrado");
	}

	public void poner3D() {
		if (panelEdicion.getGrafo().getVertices().size() == 0) {
			ModalAceptar modal = new ModalAceptar(panelEdicion.getMensajes(), Constantes.INFORMACION, "NoExisteGrafo");
			modal.setVisible(true);
		} else if (!Utilidades.esGrafoCiclo(panelEdicion.getGrafo())) {
			ModalAceptar modal = new ModalAceptar(panelEdicion.getMensajes(), Constantes.ADVERTENCIA, "3D.solo.ciclo");
			modal.setVisible(true);
		} else {
			if(validar3D()) {
				panelInfo.mostrarNumeroVertices(panelEdicion.getGrafo().getVertices().size());
				panelInfo.mostrarNumeroAristas(panelEdicion.getGrafo().getAristas().size());
				panelEdicion.repaint();
				Resultados.setMatriz((int[][])null);
				logger.info("Grafo convertido a 3D");
			}
		}
	}

	public void cambiarIdioma() {
		ImageIcon i = (ImageIcon)barra.getComboIdioma().getSelectedItem();
		aplicacion.cambiarIdioma(i);
		logger.info("Idioma cambiado");
	}

	public void aumentarZoomBoton() {
		double resto = barra.getBarraZoom().getValue() % 10;
		double zoom;
		if(resto == 0) {
			zoom = panelEdicion.getZoom() + 0.1;
			panelEdicion.setZoom(zoom);
			barra.getBarraZoom().setValue(barra.getBarraZoom().getValue() + 10);
		} else {
			zoom = panelEdicion.getZoom() + 0.1 - resto / 100;
			panelEdicion.setZoom(zoom);
			barra.getBarraZoom().setValue(barra.getBarraZoom().getValue() + 10 - (int)resto);
		}
		barra.getNumeroZoom().setText(((Integer)barra.getBarraZoom().getValue()).toString() + "%");
		aplicacion.repaint();
	}

	public void reducirZoomBoton() {
		double resto = barra.getBarraZoom().getValue() % 10;
		double zoom;
		if(resto == 0) {
			zoom = panelEdicion.getZoom() - 0.1;
			panelEdicion.setZoom(zoom);
			barra.getBarraZoom().setValue(barra.getBarraZoom().getValue() - 10);
		} else {
			zoom = panelEdicion.getZoom() - resto / 100;
			panelEdicion.setZoom(zoom);
			barra.getBarraZoom().setValue(barra.getBarraZoom().getValue() - (int)resto);
		}
		barra.getNumeroZoom().setText(((Integer)barra.getBarraZoom().getValue()).toString() + "%");
		aplicacion.repaint();
	}

	public void cambiarZoomBarra() {
		double zoom = (double)barra.getBarraZoom().getValue()/100;
		panelEdicion.setZoom(zoom);
		barra.getNumeroZoom().setText(((Integer)barra.getBarraZoom().getValue()).toString() + "%");
		aplicacion.repaint();
	}

	public void salir() {
		System.exit(0);
	}
	
	@SuppressWarnings("unchecked")
	public boolean validar3D() {
		Grafo grafo = panelEdicion.getGrafo();
		ResourceBundle mensajes = panelEdicion.getMensajes();
		ArrayList<Vertice> vertices = grafo.getVertices();
		ArrayList<Arista> aristas = grafo.getAristas();
		int numeroVertices = vertices.size();
		for(Vertice v : vertices) {
			Point punto = v.getPunto();
			int x = punto.x + Configuracion.getX3D();
			int y = punto.y + Configuracion.getY3D();
			if(x < 0 || y < 0 || x > Constantes.PANEL_ANCHO || y > Constantes.PANEL_ALTO) {
				ModalAceptar modal = new ModalAceptar(mensajes, Constantes.ERROR, "ExcedePanel");
				modal.setVisible(true);
				return false;
			}
		}

		for(Vertice v : (ArrayList<Vertice>)vertices.clone()) { //Crea los vértices nuevos
			Point punto = v.getPunto();
			int x = punto.x + Configuracion.getX3D();
			int y = punto.y + Configuracion.getY3D();
			Vertice verticeNuevo = new Vertice(new Point(x, y), grafo.getVerticeId(), false);
			grafo.anadirVertice(verticeNuevo);
		}

		for(Arista a : (ArrayList<Arista>)aristas.clone()) { // Une los vértices nuevos entre sí
			int indiceOrigen = vertices.indexOf(a.getVerticeOrigen());
			int indiceDestino = vertices.indexOf(a.getVerticeDestino());
			Arista aristaNueva = new Arista(vertices.get(indiceOrigen + numeroVertices), vertices.get(indiceDestino + numeroVertices), grafo.getAristaId(), false);
			grafo.anadirArista(aristaNueva);
		}

		for(int i = 0; i < numeroVertices; i++) { // Une los vértices originales con los nuevos
			Arista aristaNueva = new Arista(vertices.get(i), vertices.get(i + numeroVertices), grafo.getAristaId(), false);
			grafo.anadirArista(aristaNueva);
		}
		return true;
	}

}