package view.ark;
import java.awt.event.KeyEvent;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import view.Vue;

/**
 * 
 */

/**
 * @author alexis
 *
 */
public class MonumentHistoriquePrincipale extends JTabbedPane implements ChangeListener{
	/**
	 * 
	 */
	private static final long serialVersionUID = 8285606308728277611L;
	private HashMap<String,HashMap<String,SubTab>> tab;
	private HashMap<String, Tab> mainTab;
	private List<HashSet<Character>> usedMnemoForSubTab;
	
	private static class SubTab{
		public Vue vue;
		public Object message;
		public int index;
		
		public SubTab(Vue _vue, Object _message, int _index){
			this.vue = _vue;
			this.message = _message;
			this.index = _index;
	}}
	
	private static class Tab{
		public JTabbedPane vue;
		public int index;
		
		public Tab(JTabbedPane _vue, int _index){
			this.vue = _vue;
			this.index = _index;
	}}
	
	public MonumentHistoriquePrincipale() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		super(SwingConstants.TOP);
		initVariable();
		initListener();
	}
	
	private void initVariable(){
		tab = new HashMap<String,HashMap<String,SubTab>>();
		mainTab = new HashMap<String, Tab>();
		usedMnemoForSubTab = new ArrayList<HashSet<Character>>();
	}
	
	private void initListener(){
		this.addChangeListener(this);
	}
	
	public void setMnemonic() throws Exception{
		List<Character> usedMnemonic = new ArrayList<Character>();
		
		for(Map.Entry<String, Tab> entry : mainTab.entrySet())
		{
			usedMnemoForSubTab.add(new HashSet<Character>());
			
			Character mnemo = Character.toUpperCase(entry.getKey().charAt(entry.getKey().indexOf('%')+1));
			if(!usedMnemonic.contains(mnemo))
			{
				usedMnemonic.add(mnemo);
				this.setMnemonicAt(entry.getValue().index,getKeyEvent(mnemo));
			}
		}
		//merger les 2
		for(Map.Entry<String, HashMap<String,SubTab>> entry : tab.entrySet())
		{
			HashSet<Character> usedMnemonicForThisTab = usedMnemoForSubTab.get(mainTab.get(entry.getKey()).index);
			
			for(Entry<String, SubTab> subEntry : entry.getValue().entrySet())
			{
				if(subEntry.getKey().length() > 0)
				{
					Character tab_mnemo = Character.toUpperCase(subEntry.getKey().charAt(subEntry.getKey().indexOf('%')+1));
					usedMnemonicForThisTab.add(tab_mnemo);
				
					mainTab.get(entry.getKey()).vue.setMnemonicAt(subEntry.getValue().index,tab_mnemo);
				}
			}
		}
		/*List<Character> usedMnemonic = new ArrayList<Character>();
		
		for(Map.Entry<String, Tab> entry : mainTab.entrySet())
		{
			usedMnemoForSubTab.add(new HashSet<Character>());
			
			for(int i = 0; i < entry.getKey().length(); i++)
			{
				if(!usedMnemonic.contains(Character.toUpperCase(entry.getKey().charAt(i))))
				{
					usedMnemonic.add(Character.toUpperCase(entry.getKey().charAt(i)));
					this.setMnemonicAt(entry.getValue().index,getKeyEvent(entry.getKey().charAt(i)));
					break;
				}
			}
		}
		
		for(Map.Entry<String, HashMap<String,SubTab>> entry : tab.entrySet())
		{
			HashSet<Character> usedMnemonicForThisTab = usedMnemoForSubTab.get(mainTab.get(entry.getKey()).index);
			HashMap<SubTab,Character> whoUseWhat = new HashMap<SubTab,Character>();
			
			for(Entry<String, SubTab> subEntry : entry.getValue().entrySet())
			{
				for(int i = 0; i < subEntry.getKey().length(); i++)
				{
					if(!usedMnemonic.contains(Character.toUpperCase(subEntry.getKey().charAt(i))))
					{
						if(!usedMnemonicForThisTab.contains(Character.toUpperCase(subEntry.getKey().charAt(i))))
						{
							Character mnemonic = Character.toUpperCase(subEntry.getKey().charAt(i));
							usedMnemonicForThisTab.add(mnemonic);
							mainTab.get(entry.getKey()).vue.setMnemonicAt(subEntry.getValue().index, getKeyEvent(mnemonic));
							whoUseWhat.put(subEntry.getValue(), mnemonic);
							break;
						}
						else
						{
							if(i == subEntry.getKey().length()-1)
							{
								boolean found = false;
								for(int k = 0; k < subEntry.getKey().length(); k++)
								{
									Character new_character = Character.toUpperCase(subEntry.getKey().charAt(k));
									int new_mnemonic = getKeyEvent(new_character);
									
									if(!usedMnemonic.contains(new_character))
									{
										for(Entry<String, SubTab> subEntry_fixing : entry.getValue().entrySet())
										{
											if(subEntry_fixing != subEntry)
											{
												if(mainTab.get(entry.getKey()).vue.getMnemonicAt(subEntry_fixing.getValue().index) == getKeyEvent(new_character))
												{
													for(int o = 0; o < subEntry_fixing.getKey().length(); o++)
													{
														char character_for_mnemonic = Character.toUpperCase(subEntry_fixing.getKey().charAt(o));
														if(character_for_mnemonic != '/' && character_for_mnemonic != '.')
														{
															int mnemonic = getKeyEvent(character_for_mnemonic);
															if(new_character != mnemonic)
															{
																if(!usedMnemonic.contains(character_for_mnemonic))
																{
																	if(!usedMnemonicForThisTab.contains(character_for_mnemonic))
																	{
																		usedMnemonicForThisTab.add(character_for_mnemonic);
																		
																		mainTab.get(entry.getKey()).vue.setMnemonicAt(subEntry_fixing.getValue().index,mnemonic);
																		mainTab.get(entry.getKey()).vue.setMnemonicAt(subEntry.getValue().index,new_mnemonic);
																			
																		found = true;
																		break;
																	}
																}
															}
														}
													}
													if(found)
														break;
												}
											}
										}
										if(found)
											break;
									}
								}
							}
						}
					}
				}
			}
		}
		
		for(int i = 0; i < usedMnemoForSubTab.size(); i++)
		{
			usedMnemoForSubTab.get(i).addAll(usedMnemonic);
		}*/
	}
	
	public Character[] getMnemonicOnTab(int index){
		return usedMnemoForSubTab.get(index).toArray(new Character[usedMnemoForSubTab.get(index).size()]);
	}
	
	private static int getKeyEvent(Character c) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
	    Field f = KeyEvent.class.getField("VK_" + Character.toUpperCase(c));
	    f.setAccessible(true);
	    
	    return (Integer) f.get(null);
	}
	
	public void addTab(String mainTabName, String tabName, Vue _vue, Object _message, int _mainTab, int _subTab){
		if(!mainTab.containsKey(mainTabName))
		{
			JTabbedPane newTab = new JTabbedPane(JTabbedPane.LEFT);
			mainTab.put(mainTabName, new Tab(newTab,_mainTab));
			mainTab.get(mainTabName).vue.addChangeListener(this);
			tab.put(mainTabName, new HashMap<String,SubTab>());
			this.add(mainTabName.replace("%", ""),mainTab.get(mainTabName).vue);
		}
		tab.get(mainTabName).put(tabName,new SubTab(_vue,_message,_subTab));
		mainTab.get(mainTabName).vue.add(tabName.replace("%", ""),tab.get(mainTabName).get(tabName).vue);
	}
	
	public void setSelectedTab(String _mainTab, String _secondaryTab){
		Integer indexTabMain = mainTab.get(_mainTab).index;
		Integer indexTabSub = tab.get(_mainTab).get(_secondaryTab).index;
		
		this.setSelectedIndex(indexTabMain);
		mainTab.get(_mainTab).vue.setSelectedIndex(indexTabSub);
	}
	
	@Override
	public void stateChanged(ChangeEvent e) {
		//System.out.println(this.getTitleAt(this.getSelectedIndex()));
		JTabbedPane caller = ((JTabbedPane)e.getSource());
		System.out.println(caller.getTitleAt(caller.getSelectedIndex()));
	}

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		/*JFrame a = new JFrame();
		a.setLayout(new GridBagLayout());
		MonumentHistoriquePrincipale prin = (MonumentHistoriquePrincipale) PrincipaleGestionFactory.build(Francais.getInstance());
		prin.setMnemonic();
		
		GridBagConstraints contraint = new GridBagConstraints();
		contraint.weightx = 1.0;
		contraint.weighty = 1.0;
		contraint.gridx = 0;
		contraint.gridy = 0;
		
		a.add(prin,contraint);
		//prin.setSelectedTab("%Recherche","%Utilisateur");
		
		/*Character[] w = prin.getMnemonicOnTab(3);
		for(int i = 0; i < w.length; i++)
			System.out.println(w[i]);*/

	    /*a.setSize(a.getToolkit().getScreenSize());
		a.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		a.setExtendedState(JFrame.MAXIMIZED_BOTH);
		a.pack();
		a.setVisible(true);*/
	}
}