package actions;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.apache.log4j.Logger;

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

public class AbrirAction implements ActionListener {
	
	private static Logger logger = Logger.getLogger(AbrirAction.class);

	private Grafo grafo;
	private PanelEdicion panelEdicion;
	private PanelInfo panelInfo;

	public AbrirAction (PanelEdicion pEdicion, PanelInfo pInfo) {
		panelEdicion = pEdicion;
		panelInfo = pInfo;
	}

	public void actionPerformed(ActionEvent e) {
		ModalAbrir modal = new ModalAbrir();
		modal.setVisible(true);
	}

	private class ModalAbrir extends JDialog {

		private static final long serialVersionUID = 8933585531600354991L;
		private ResourceBundle mensajes;
		private JFileChooser selectorArchivo = new JFileChooser();

		private ModalAbrir() {
			mensajes = panelEdicion.getMensajes();
			construirPanel();
		}

		private void construirPanel() {
			JPanel panelContenedor = new JPanel();
			JButton botonAceptar = new JButton();
			JButton botonCancelar = new JButton();

			try {
				setTitle(new String(mensajes.getString("Abrir").getBytes("ISO-8859-1"),"UTF-8"));
				botonAceptar.setText(new String(mensajes.getString("Aceptar").getBytes("ISO-8859-1"),"UTF-8"));
				botonCancelar.setText(new String(mensajes.getString("Cancelar").getBytes("ISO-8859-1"),"UTF-8"));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}


			selectorArchivo.addChoosableFileFilter(new FileNameExtensionFilter("Excel \t (*.csv)", "csv"));
			selectorArchivo.addChoosableFileFilter(new FileNameExtensionFilter("Grafo \t (*.gra)", "gra"));
			for (int i = 0; i < selectorArchivo.getComponentCount(); i++) {
				selectorArchivo.getComponent(i).setBackground(new Color(189,250,107));
			}


			botonAceptar.setName("Aceptar");
			botonCancelar.setName("Cancelar");
			botonAceptar.setBounds(160, 295, 85, 28);
			botonCancelar.setBounds(260, 295, 85, 28);

			panelContenedor.setBounds(-5, -5, 508, 280);
			panelContenedor.add(selectorArchivo);


			getContentPane().add(panelContenedor);
			getContentPane().add(botonAceptar);
			getContentPane().add(botonCancelar);
			getContentPane().setBackground(new Color(189,250,107));
			getContentPane().setLayout(null);


			setSize(508, 355);
			setResizable(false);
			Toolkit kit = Toolkit.getDefaultToolkit();
			Dimension dim = kit.getScreenSize();
			setLocation(dim.width / 2 - getWidth() / 2, dim.height / 2 - getHeight() / 2);

			ActionListener botones = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					Object obj = e.getSource();
					if (obj instanceof JButton) {
						if(((JButton)obj).getName().equals("Aceptar")) {
							aceptar();
						} else if(((JButton)obj).getName().equals("Cancelar")) {
							cancelar();
						}
					}
				}
			};
			botonAceptar.addActionListener(botones);
			botonCancelar.addActionListener(botones);
		}

		public void aceptar() {
			try {
				if(Utilidades.calcularExtensionArchivo(selectorArchivo.getSelectedFile().getAbsolutePath()).equals("gra")) {
					String filename = selectorArchivo.getSelectedFile().getAbsolutePath();
					BufferedReader br = new BufferedReader(new FileReader(filename));
					int numeroAristas = Integer.parseInt(br.readLine());
					int numeroAristasSeleccionadas = 0;
					int numeroVerticesSeleccionados = 0;
					int numeroVertices = Integer.parseInt(br.readLine());
					int nI = Integer.parseInt(br.readLine());
					int aI = Integer.parseInt(br.readLine());
					panelInfo.mostrarNumeroVertices(numeroVertices);
					panelInfo.mostrarNumeroAristas(numeroAristas);
					grafo = new Grafo();
					grafo.setVerticeId(nI);
					grafo.setAristaId(aI);
					for(; numeroVertices != 0; numeroVertices--) {
						int id = Integer.parseInt(br.readLine());
						int x = Integer.parseInt(br.readLine());
						int y = Integer.parseInt(br.readLine());
						Boolean seleccionado = Boolean.parseBoolean(br.readLine());
						Vertice v = new Vertice(new Point(x, y), id, seleccionado);
						grafo.anadirVertice(v);
						if(seleccionado) {
							numeroVerticesSeleccionados++;
							grafo.getVerticesSeleccionados().add(v);
						}
					}
					for(; numeroAristas != 0; numeroAristas--) {
						int id = Integer.parseInt(br.readLine());
						int origenId = Integer.parseInt(br.readLine());
						int destinoId = Integer.parseInt(br.readLine());
						Vertice verticeOrigen = grafo.obtenerVerticePorId(origenId);
						Vertice verticeDestino = grafo.obtenerVerticePorId(destinoId);
						Boolean seleccionada = Boolean.parseBoolean(br.readLine());
						Arista a = new Arista(verticeOrigen, verticeDestino, id, seleccionada);
						grafo.anadirArista(a);
						if(seleccionada) {
							numeroAristasSeleccionadas++;
							grafo.getAristasSeleccionadas().add(a);
						}
					}
					grafo.setMensajes(panelEdicion.getMensajes());
					br.close();
					panelEdicion.setGrafo(grafo);
					panelEdicion.repaint();
					panelInfo.mostrarNumeroVerticesSeleccionados(numeroVerticesSeleccionados);
					panelInfo.mostrarNumeroAristasSeleccionadas(numeroAristasSeleccionadas);
					panelInfo.repaint();
					Resultados.setMatriz((int[][])null);
					logger.info("Abierto grafo .gra");
					cancelar();
				} else if (Utilidades.calcularExtensionArchivo(selectorArchivo.getSelectedFile().getAbsolutePath()).equals("csv")) {
					CsvReader grafos = new CsvReader(selectorArchivo.getSelectedFile().getAbsolutePath());
					int numeroVertices = 0;
					int numeroAristas = 0;
					Map<Integer,List<String>> adyacencias = new HashMap<Integer,List<String>>();
					while (grafos.readRecord()) {
						numeroVertices++;
						List<String> aristas = new ArrayList<String>();
						for(int i=0; i<grafos.getValues().length; i++) {
							aristas.add(grafos.get(i));
						}
						adyacencias.put(numeroVertices, aristas);
					}
					grafos.close();
					int radio = 80 + 5 * numeroVertices;
					int xPrimero = radio + 250;
					int yPrimero = 80;
					
					grafo = new Grafo();
					for(int i = 0; i < numeroVertices; i++) {
						double angulo = i * 2 * Constantes.PI / numeroVertices - Constantes.PI / 2 ;
						int x = xPrimero + (int)(radio * Math.cos(angulo));
						int y = yPrimero + radio + (int)(radio * Math.sin(angulo));
						grafo.anadirVertice(new Vertice(new Point(x,y), grafo.getVerticeId(), false));
					}
					for(int i=1; i<=numeroVertices; i++) {
						List<String> vertices = adyacencias.get(i);
						for(String s : vertices) {
							if(!s.equals("0")) {
								if(grafo.obtenerAristaPorVertices(i, new Integer(s)) == null) {
									numeroAristas++;
									grafo.anadirArista(new Arista(grafo.obtenerVerticePorId(i), grafo.obtenerVerticePorId(new Integer(s)), grafo.getAristaId(), false));
								}
							}
						}
					}
					panelInfo.mostrarNumeroVertices(numeroVertices);
					panelInfo.mostrarNumeroAristas(numeroAristas);
					grafo.setMensajes(panelEdicion.getMensajes());
					panelEdicion.setGrafo(grafo);
					panelEdicion.repaint();
					panelInfo.repaint();
					Resultados.setMatriz((int[][])null);
					logger.info("Abierto grafo .csv");
					cancelar();
				} else {
					error();
				}
			} catch(Throwable exc) {
				error();
			}
		}

		public void cancelar() {
			setVisible(false);
			dispose();
		}
		
		public void error() {
			String mensaje;
			if(Configuracion.isModoArbol()) {
				mensaje = "validacion10";
			} else {
				mensaje = "ErrorAbrirGrafo";
				logger.error("Error al abrir el grafo");
			}
			ModalAceptar modal = new ModalAceptar(panelEdicion.getMensajes(), Constantes.ERROR, mensaje);
			modal.setVisible(true);
		}
	}
}