package iitb.cfilt.cpost.lexicon;
import java.io.*;
import java.sql.Timestamp;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import iitb.cfilt.cpost.dmstemmer.StemmedResult;
import iitb.cfilt.cpost.*;

public class LexReader {
	private static HashMap<String, HashMap<String, Vector<Lex>>> lexHash;
	private static HashMap<String, HashMap<String, HashMap<String, Vector<Lex>>>> lexHashByCategory;
	private static HashMap<String, Vector<String>> wordsHash;
	private static Vector<String> wordsList;
	public static Vector<String> categories;
	public Vector<String> symbols;
	
	public String devNormRulesFile;// = ConfigReader.get("Lexicon.devNormRulesFile");
	public Properties normRulesMapping;
	public LexReader() {
		
		devNormRulesFile = ConfigReader.get("Lexicon.devNormRulesFile");
		normRulesMapping = new Properties();
		try{
			normRulesMapping.load(new FileInputStream(devNormRulesFile));
		}catch(IOException e) {
			e.printStackTrace();
		}
		devNormRulesFile = ConfigReader.get("Lexicon.devNormRulesFile");
		lexHashByCategory = new HashMap<String, HashMap<String,HashMap<String,Vector<Lex>>>>();
		lexHash = new HashMap<String, HashMap<String,Vector<Lex>>>();
		wordsHash = new HashMap<String, Vector<String>>();
		wordsList = new Vector<String>();
		categories = new Vector<String>();
		symbols = new Vector<String>();
		String line;
		String file = ConfigReader.get("Lexicon.newLexName");
		try{
		BufferedReader bRead = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF8"));		
		line = " ";
		while (line != null){
			line = bRead.readLine();
			if(line != null){
				line = line.trim();
				if(line.length()!=0 && !line.startsWith("//"))
					hashIt(line);
			}
		}
		bRead.close();
		
		String symbolsfile = ConfigReader.get("Lexicon.symbols");
		//System.out.println("Symbols File = " + symbolsfile);
		BufferedReader bfs = new BufferedReader(new InputStreamReader(new FileInputStream(symbolsfile), "UTF8"));
		line = "";
		while((line = bfs.readLine()) != null)
		{
			line = line.trim();
			if (line != "" && line != " "){
				if (!symbols.contains(line)){
					symbols.add(line);
				}
			}
		}
		bfs.close();

		}catch(FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void hashIt(String line){
		
		String[] lineComponents = line.split(">,<");
		
		for(int lc = 0; lc < lineComponents.length; lc++ ){
			lineComponents[lc] = lineComponents[lc].replaceAll("<", "");
			lineComponents[lc] = lineComponents[lc].replaceAll(">", "");			
		}
		String word = lineComponents[0].trim();
		/*if(word.equals("घोड़ा")){
			System.out.println("Working... Here....");
		}*/
		word = normalizeHindiString(word);
		wordsList.add(word);
		String firstChar = word.substring(0, 1);
		
		if(wordsHash.containsKey(firstChar)){
			Vector<String> words = wordsHash.get(firstChar);
			words.add(word);
			wordsHash.put(firstChar, words);
		}else{
			Vector<String> words = new Vector<String>();
			words.add(word);
			wordsHash.put(firstChar, words);
		}
		if(lineComponents.length<3){
			System.out.println("Fault : " + line);
			System.out.println("First : " + lineComponents[0] + ", Second : " + lineComponents[1]);
		}
		String cat = lineComponents[2].trim();
		char clas = ' ';
		char gender = ' ';
		String ending = "";
		if(cat.equals("noun")){
			String[] properties = lineComponents[1].trim().split(",");
			//System.out.println(properties[0].trim());
			clas = properties[0].trim().charAt(1);
			gender = 'F';
			ending = "";
			//String endsWith = "";
			if(properties.length>1){
				if(properties[1].startsWith("+")){
					gender = 'M';
				}
				if(properties.length>2){
					ending = properties[2].trim();
				}
				//endsWith = properties[2].substring(1);
			}
		}		
		else if(cat.equals("verb") || cat.equals("verb_aux") ){
			ending = lineComponents[1].trim();
		}
		/*else if(cat.equalsIgnoreCase("demonstrative")){
			clas = lineComponents[1].trim().charAt(0);
			
		}*/
		//else if(cat.equals("adjective") || cat.equals("quantifier") || cat.equals("intensifier") || cat.equals("ordinal") || others){
		else{
			clas = lineComponents[1].trim().charAt(0);
		}
		
		Lex lexEntry = new Lex(word,clas,gender,ending,cat);
		
		if(lexHashByCategory.containsKey(cat)){
			HashMap<String, HashMap<String, Vector<Lex>>> categoryHash = lexHashByCategory.get(cat);
			if(categoryHash.containsKey(firstChar)){
				HashMap<String, Vector<Lex>> wordHash = categoryHash.get(firstChar);
				if(wordHash.containsKey(word)){
					Vector<Lex> lexVector = wordHash.get(word);
					lexVector.add(lexEntry);
					wordHash.put(word, lexVector);
				}
				else{
					Vector<Lex> lexVector = new Vector<Lex>();
					lexVector.add(lexEntry);
					wordHash.put(word, lexVector);
				}
			}
			else{
				HashMap<String, Vector<Lex>> wordsHash = new HashMap<String, Vector<Lex>>();
				Vector<Lex> lexVector = new Vector<Lex>();
				lexVector.add(lexEntry);
				wordsHash.put(word, lexVector);
				categoryHash.put(firstChar, wordsHash);
			}
		}
		else{
			categories.add(cat);
			HashMap<String, HashMap<String, Vector<Lex>>> categoryHash = new HashMap<String, HashMap<String,Vector<Lex>>>();
			HashMap<String, Vector<Lex>> wordsHash = new HashMap<String, Vector<Lex>>();
			Vector<Lex> lexVector = new Vector<Lex>();
			lexVector.add(lexEntry);
			wordsHash.put(word, lexVector);
			categoryHash.put(firstChar, wordsHash);
			lexHashByCategory.put(cat, categoryHash);
		}
		
		if(lexHash.containsKey(firstChar)){
			HashMap<String, Vector<Lex>> wordHash = lexHash.get(firstChar);
			if(wordHash.containsKey(word)){
				Vector<Lex> lexVector = wordHash.get(word);
				lexVector.add(lexEntry);
				wordHash.put(word, lexVector);
			}
			else{
				Vector<Lex> lexVector = new Vector<Lex>();
				lexVector.add(lexEntry);
				wordHash.put(word, lexVector);
			}			
		}
		else{
			HashMap<String, Vector<Lex>> wordsHash = new HashMap<String, Vector<Lex>>();
			Vector<Lex> lexVector = new Vector<Lex>();
			lexVector.add(lexEntry);
			wordsHash.put(word, lexVector);
			lexHash.put(firstChar, wordsHash);
		}
		
		
	}
	
	public String normalizeHindiString(String inputStr) {
		
        String outputStr="";
        // First try bigram combinations
       int i;
       for (i=0; i<inputStr.length()-1 && inputStr.length()>0;) {
    	   String biGram=Integer.toHexString(inputStr.charAt(i));
	       if (inputStr.length()>1)
	    	   biGram += Integer.toHexString(inputStr.charAt(i+1));
           String mapping =	normRulesMapping.getProperty(biGram);
	       if (mapping!=null) {
	    	   char map = (char)Integer.parseInt(mapping, 16);
	    	   outputStr += map;
	    	   i+=2;
	       }
	       else {
	    	   outputStr += inputStr.substring(i, i+1);
	    	   i++;
	       }
       }
	   if (i==inputStr.length()-1)
		   outputStr += inputStr.substring(i, i+1);
      return outputStr;
}

	public boolean checkInLex(String stem){
		boolean retval = false;
		if(stem.length()>0 && stem!=null){			
		
		String firstChar = stem.trim().substring(0,1);
		if(wordsHash.containsKey(firstChar)){
			Vector<String> words = wordsHash.get(firstChar);
			if(words.contains(stem)){
				retval = true;
			}
		}
		if(!retval){
			if(wordsList.contains(stem)){
				retval = true;
			}
		}
		}
		return retval;
	}
	
	public boolean checkInLex(String stem, String category){
		boolean retval = false;
		String firstChar = stem.trim().substring(0,1);
		if(wordsHash.containsKey(firstChar)){
			Vector<String> words = wordsHash.get(firstChar);
			if(words.contains(stem)){
				retval = true;
			}
		}
		if(!retval){
			if(wordsList.contains(stem)){
				retval = true;
			}
		}
		return retval;
	}
	
	public Vector<Lex> getLexResults(String stem){
		//Vector<StemmedResult> stemmedResults = new Vector<StemmedResult>();
		Vector<Lex> lexVector = new Vector<Lex>();
		if(checkInLex(stem)){
			String firstChar = stem.substring(0,1);			
			HashMap<String, Vector<Lex>> wordHash = lexHash.get(firstChar);
			lexVector = wordHash.get(stem);			
		}
		return lexVector;
	}
	
	public Vector<Lex> getLexResults(String stem, String category){
		//Vector<StemmedResult> stemmedResults = new Vector<StemmedResult>();
		Vector<Lex> lexVector = new Vector<Lex>();
		if(checkInLex(stem)){
			String firstChar = stem.substring(0,1);
			HashMap<String, Vector<Lex>> wordHash = lexHashByCategory.get(category).get(firstChar);
			if(wordHash!=null && !wordHash.isEmpty()){
				lexVector = wordHash.get(stem);			
			}
		}
		return lexVector;
	}
	
	public static void main(String args[]){
		ConfigReader.read(args[0]);
		LexReader lr = new LexReader();
		//System.out.println(wordsList);
		if(wordsList.contains("अंगूरी")){
			System.out.println("Working..");
		}else{		
			System.out.println("Not Working..");
		}
	}
	
	

}
