import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import java.util.Vector;
import javax.swing.AbstractListModel;

public class Directory extends JFrame {
	//private promenne
	private int inicializace_is_completed = 0;
	//public promenne
	public List czech = new ArrayList();
	public List english = new ArrayList();
	public List meaning = new ArrayList();
	public JPanel pane;
	public JLabel statusbar;
	public javax.swing.JList AwtList;
	JTextField searchbox;
	DefaultListModel listModel;
	public int rezim = 0; // 0 - cz-en 1 - en-cz
	
	public Directory() {
		this.setTitle("Slovník");
		//lokacion okna
		this.setLocation(50, 50);
		//size okna
		this.setSize(300, 270);
		//visible okna
		this.setVisible(true);
		//vytvoreni noveho JPamelu
		JPanel cont = new JPanel();
		//umisteni panelu
		this.add(cont);
		
		this.setResizable(false);
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		//vytvoreni statoveho radku
		//text po spusteni
		statusbar = new JLabel("Načítám slovník, prosím čekejte");
		statusbar.setVerticalAlignment(SwingConstants.CENTER );
		statusbar.setHorizontalAlignment(SwingConstants.CENTER );
	    statusbar.setBackground(Color.LIGHT_GRAY );
	    
	    //Popisek pro hledaci pole
	    JLabel searchlabel = new JLabel("Slovo: ");
	    cont.add(searchlabel);
	    //pole pro hledani
	    searchbox = new JTextField( 15 );
	    cont.add(searchbox);
	    //JList pro vypis nalezenych slov
	    listModel = new DefaultListModel();
		AwtList = new JList(listModel);
		//nastaveni JListu
		AwtList.setPreferredSize(new Dimension(260, 250) );
		AwtList.setMinimumSize(new Dimension(260, 250));
		AwtList.setMaximumSize(new Dimension(260,250) );
		
		//mouse listener pro JList
		AwtList.addMouseListener(new MouseListener(){
			public void mouseClicked(MouseEvent arg0) {
			}
			public void mouseEntered(MouseEvent arg0) {
			}
			public void mouseExited(MouseEvent arg0) {
			}
			public void mousePressed(MouseEvent arg0) {
				//po kliknuti na polozku vyskoci JOptionPane s celym slovem nebo frazi
				JOptionPane.showInputDialog("Slovíčko", AwtList.getSelectedValue());
			}
			public void mouseReleased(MouseEvent arg0) {
			}
		});
		//scroll pane pro JList
		JScrollPane listScroller = new JScrollPane(AwtList);
		
		//tlacitko pro hledani
		JButton search = new JButton("Najít");
		cont.add( search );
		
		//radionbuttony pro zmenu hledani
		JRadioButton czeen = new JRadioButton("Česko anglický", true);
		cont.add( czeen);
		//po kliknuti se zmeni rezim na cesko-anglicky slovnik
		czeen.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				statusbar.setText("Přepnuli jste na česko-anglický slovník");
				rezim = 0;
			}
		});
		JRadioButton encze = new JRadioButton("Anglicko-český");
		cont.add( encze );
		//po kliknuti se zmeni rezim na anglicko-cesky
		encze.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				statusbar.setText("Přepnuli jste na anglicko-český slovník");
				rezim = 1;
			}
		});
		ButtonGroup group = new ButtonGroup();
		group.add(encze);
		group.add(czeen );
		
		cont.add( listScroller);
		cont.add(statusbar, BorderLayout.SOUTH);
		
		//pridani action listeneru na tlacitko pro vyhledavani
		search.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				if( inicializace_is_completed == 0 ){
					JOptionPane.showMessageDialog(null,"Počkejte na načtení všech potřebných dat.",  
							  "Informační okno", JOptionPane.INFORMATION_MESSAGE );  
					return;
				}
				find_and_print_words();
			}
		});
	    
		//funkce pro nacteni dat
		load_data();		
	}
	
	/**
	 * @function find_and_print_words
	 */
	public void find_and_print_words(){
		//zjistime hledane slovo
		String search_string = searchbox.getText().trim();
		//pokud existuje slvo, budeme hledat
		if( search_string.length() == 0 )
			return;
		
		//dle rezimu predame funkci pro hledani sprvane poradi parametru
		if( rezim == 0 ){
			search_words(search_string, czech, english);
		}
		else{
			search_words(search_string, english, czech);
		}
	}
	
	/**
	 * @function search_words
	 * @param word
	 * @param search_list
	 * @param output_list
	 */
	public void search_words(String word, List search_list, List output_list ){
		int word_hash = word.hashCode();
		//vymazeme stavajici seznam nalezenych slov
		listModel.removeAllElements();
		//vytvorime dve hashMapy
		Map tm = new HashMap();
		Map tm2 = new HashMap();
		
		for( int i = 0; i < search_list.size(); i++ ){
			//hledame slova
			if( String.valueOf( search_list.get(i)).toLowerCase().hashCode() == word_hash ){
				tm.put(String.valueOf(output_list.get(i)), meaning.get(i) );
			}
			//dale hledame fraze, ktere danym slovem zacinaji
			if( String.valueOf( search_list.get(i)).toLowerCase().startsWith( word + " ") && word.length() > 1 ){
				tm2.put( String.valueOf( search_list.get(i)) + ": " + String.valueOf(output_list.get(i)), meaning.get(i) );
			}
		}
		
		List myList = new ArrayList(tm.keySet() );
		List meaning_values = new ArrayList( tm.values() );
	
		for( int i = 0; i < myList.size(); i++ ){
			String s = "  - " + myList.get(i);
			if( meaning_values.get(i) != null ){
				s = s + " " + meaning_values.get(i);
			}
			listModel.addElement(s);
		}
		
		//z obou HashMap vytvorime ArrayListy
		List myList2 = new ArrayList(tm2.keySet() );
		List meaning_values2 = new ArrayList( tm2.values() );
		
		//do JListu vypisujeme nejprve samotna slovicka a potom fraze
		for( int i = 0; i < myList2.size(); i++ ){
			String s = String.valueOf( myList2.get(i) );
			if( meaning_values2.get(i) != null ){
				s = s + String.valueOf( meaning_values2.get(i) );
			}
			listModel.addElement(s);
		}
		//informace o hledani vypiseme do stavoveho radku
		if( myList.size() == 0 )
			statusbar.setText("Nebylo nalezeno žádné slovíčko.");
		else
			statusbar.setText("Bylo nalezeno " + ( myList.size() + myList2.size() ) + " výsledků");
	}
	
	/**
	 * @function load_data
	 * @return
	 */
	public void load_data() {
		//pokud existuje soubor direcotory/slovnik_data_utf8.txt, nacteme z nej vsechna data
		File file = new File("directory/slovnik_data_utf8.txt");
		if (!file.exists()) {
			//pokud soubor neexistuje vypiseme to ve stavovem radku.
			statusbar.setText("File doesn't exists");
			return;
		}
		try {
			//vytvoreni bufferdReaderu
			BufferedReader in = new BufferedReader(new InputStreamReader(
					new FileInputStream("directory/slovnik_data_utf8.txt"), "UTF8"));
	
			String line = null;
			try {
				line = in.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			//cteme soubor postupne po radcich
			while (line != null) {
				//pokud soubor zacina #, jedna se o poznamku, kterou nebereme v uvahu
				if( !line.trim().startsWith("#") ){
					//rozdelime radek dle tabulatoru.
					String [] lines = line.split("t");
					//pokud je velikost vetsi nez 1, existuji anglicka i ceska slova
					if( lines.length > 1 ){
						czech.add(lines[1].trim());
						english.add(lines[0].trim());
						//pokud je velikost vetsi nez 2, existuje i dalsi vyznam slova 
						if( lines.length > 2 )
							meaning.add(lines[2].trim());
						else
							meaning.add(null);
					}		
				}
				try {
					line = in.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		//do stavoveho radku vypiseme informace o poctu nactenych slov, ktere slovnik obsahuje
		this.statusbar.setText("Databáze obsahuje " + czech.size() + " přeložených slov");
		//hodnotu promenne inicializace nastavime na 1
		this.inicializace_is_completed = 1;
		return;
	}
}

class ListModel extends AbstractListModel {
	  private Vector objekty;
	  public ListModel() {
	    objekty = new Vector();
	  }
	  public void pridej(Object ob) {
	    objekty.addElement(ob);
	  }
	  
	  public Object getElementAt(int index) {    
	    return objekty.elementAt(index);
	  }
	  
	  public int getSize() {
	    return objekty.size();
	  }
}
