/* Neha Gupta */

package iitb.cfilt.cpost.vgi;

import iitb.cfilt.cpost.ConfigReader;
import iitb.cfilt.cpost.UTFWriter;
import iitb.cfilt.cpost.dmstemmer.*;

import java.io.File;
import java.util.*;

public class VerbGroup9 {

	private static VerbGroupIdentifierRuleReader vgr = null;

	private static UTFWriter ob;

	public VerbGroup9() {
		try {
			if(vgr == null){
				vgr = new VerbGroupIdentifierRuleReader();
			}
			File outfile = new File(ConfigReader.get("VGI.VGMarkingFile"));
			if (outfile.exists()) {
				outfile.delete();
				outfile = new File(ConfigReader.get("VGI.VGMarkingFile"));
			}
			ob = new UTFWriter(outfile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//public Vector<MorphologicallyAnalyzedToken> identifyVerbGroups1(
	public int [] identifyVerbGroups1(Vector<MAResult> mrt) {
		// Vector<Integer> vgi = new Vector<Integer>();
		int[] vgi = new int[mrt.size()];
		int currentVGstartedAt = 0;
		int VGnumber = 1;
		int isEnd = 0, isAbort = 0;
		int next = 0;
		// String last = new String();
		boolean ContinueVG = false;

		for (int i = 0; i < mrt.size(); i = next) {
			boolean isLastWordOfSentence = (i == mrt.size() - 1);
			vgi[i] = 0;
			if(!isLastWordOfSentence){
				next = i+1;
			}
			//System.out.println("Working for " + token);
			//for(next = i+1; )
			MAResult mar = mrt.get(i);			
			MAResult marNext = mrt.get(next);
			while(marNext.getAmbiguityScheme().equalsIgnoreCase("particle") && next != mrt.size() - 1){
				//System.out.println("Particle found");
				next++;
				marNext = mrt.get(next);
			}
			String token = mar.getToken();
			String tokenNext = marNext.getToken();
			// TODO : code for conjunct verbs 
			/*if(!ContinueVG){
				if(vgr.coVerbsHash.containsKey(token)){
					if(vgr.coVerbsHash.get(token).contains(tokenNext + "ना")){
						
					}
				}
			}*/
			VGpropertiesdm vgp = new VGpropertiesdm(mar,marNext,vgr);
			boolean isQualified = vgp.isQualified;			
			boolean isMustEndWord = vgp.isMustEndWord;			
			boolean hasMustEndSuffix = vgp.hasMustEndAuxSuffix || vgp.hasMustEndVMSuffix;
			boolean hasNotNullStemmerOutput = vgp.hasNotNullStemmerOutput;
			System.out.println("Token : " + token + ", Next : " + tokenNext);
			if(!isQualified && isLastWordOfSentence){
				break;
			}
			if (hasNotNullStemmerOutput	&& mar.getMorphOutputs().get(0).getStemmerResult().getCategory().trim().equals("SYM")) {				
				continue;
			}			
			//boolean yes = false;
			if(vgr.coVerbsHash.containsKey(token) && !ContinueVG){
				boolean found = false;
				Vector<String> coVerbs = vgr.coVerbsHash.get(token);
				Vector<String> nextVerbRoots = new Vector<String>(vgp.nextVmRoots);
				nextVerbRoots.addAll(vgp.nextAuxRoots);
				for(int v=0; v<nextVerbRoots.size(); v++){
					if(coVerbs.contains(nextVerbRoots.get(v))){
						found = true;
						break;
					}
				}
				
				if(found){
					System.out.println("Found coverb " + token + "..");
					vgi[i] = VGnumber;
					vgi[i+1] = VGnumber+1;
					if(next<mrt.size()-1){
						next++;					
					}
					if(i < mrt.size()-2 && mrt.get(i+2).getAmbiguityScheme().contains("verb_aux")){
						VGnumber+=2;
						currentVGstartedAt = i+1;
						ContinueVG = true;
					}					
					continue;
				}				
			}
			if(vgr.possPRPs.contains(mar.getToken())){
				System.out.println("Found possessive pronoun");
				if(!isOnlyVerb(marNext)){
					next++;
				}
				continue;
			}						
			if ( hasNotNullStemmerOutput &&  isQualified  ) {
				// check if end word or end suffix //
				if(isLastWordOfSentence || hasMustEndSuffix || isMustEndWord){
					/* DONE : end here and break*/
					vgi[i] = VGnumber;
					VGnumber = 1;
					ContinueVG = false;
					if(isLastWordOfSentence){
						break;
					}
					continue;
				}
			
				// For main verb
				if(!ContinueVG && isVerb(mar)){
					currentVGstartedAt = i;
					//check for adverbial suffix-word pair//
					if(vgp.hasAdverbialAuxSuffixWord || vgp.hasAdverbialVMSuffixWord){					
							// End here.
							vgi[i] = VGnumber;
							vgi[next] = VGnumber+1;
							next++;
							VGnumber = 1;
							ContinueVG = false;
							continue;
						}
					//}
					if(!isVerbAux(marNext)){
						if(isVerb(marNext)){
							/* DONE : check reduplication */
							if(token.equals(tokenNext)){
								/* DONE : reduplication treatment */
								vgi[i] = VGnumber;
								vgi[next] = VGnumber+1;
								next++;
								VGnumber = 1;
								ContinueVG = false;
								continue;
							}
							/* TODO : check else case */
						}
						else{
							/* DONE : single word VG */
							if(isOnlyVerb(mar)){
								vgi[i] = VGnumber;
								VGnumber = 1;
								ContinueVG = false;
								continue;
							}
							/* TODO : check else case */
						}
					}
					else{  // Next is Aux
						/* TODO : Apply Main verb rules. */
						if(vgp.noVmSufixes){ // no suffix
							if(!vgr.tenseCases.contains(tokenNext)){
								/* start VG */
								//System.out.println("1. VG Started at " + i);
								currentVGstartedAt = i;
								vgi[i] = VGnumber;
								VGnumber++;
								ContinueVG = true;
								continue;
							}
							/* TODO : check else case */
							/* I guess nothing to do. */
						}
						else{ // It has suffix
							//String suffix = getVMSuffix(mat);							
							if(vgp.isNextAuxAllowedAfterThisVM){
								/* start VG */
								//System.out.println("2. VG Started at " + i);
								currentVGstartedAt = i;
								vgi[i] = VGnumber;
								VGnumber++;
								ContinueVG = true;
								continue;
							}
							/* TODO : check else case */
							else{
								if(vgp.hasAdverbialVMSuffix){
									vgi[i] = VGnumber;
									VGnumber = 1;
									ContinueVG = false;
									continue;
								}
								/* Abort here */
								next = currentVGstartedAt + 1; 
								VGnumber = 1;
								vgi[currentVGstartedAt] = 0;
								/*if(matv.get(currentVGstartedAt).getAmbiguityScheme().contains("noun")){
									vgi[currentVGstartedAt] = 100;
								}*/
								ContinueVG = false;
								isAbort = 1;
							}
						}
					}
				}
				else if(ContinueVG && isVerbAux(mar)){
					/* TODO : Apply new aux rules */					
					HashMap<String, Vector<String>> nextRootHash = vgr.auxSuffixNextRootRuleHash.get(getAuxRoot(mar));
					HashMap<String, Vector<String>> nextTokenHash = vgr.auxSuffixNextTokenRuleHash.get(getAuxRoot(mar));
					String suffix = "";
					if(getAuxSuffix(mar).isEmpty()){
						suffix = "Null";
					}
					else{
						suffix = getAuxSuffix(mar);
					}
					if(isVerbAux(marNext)){ // Check if next word is qualified to VAUX.
						if(vgp.isNextAuxAllowedAfterThisAux){
							vgi[i] = VGnumber;
							VGnumber++;
							ContinueVG = true;
							continue;
						}
						else if(vgp.hasAdverbialAuxSuffix){
							vgi[i] = VGnumber;
							VGnumber = 1;
							ContinueVG = false;
							continue;
						}
						/* TODO : this is commented but need to think about it.
						/*else if (nextTokenHash != null && nextTokenHash.containsKey(suffix) && nextTokenHash.get(suffix).contains("Null")) {  // || nextRootHash.get(suffix).contains("Null")
							vgi[i] = VGnumber;	VGnumber = 1;	ContinueVG = false;	continue;	}*/						
						/* TODO : check else case */
						else{
							/* Abort here */
							next = currentVGstartedAt + 1; 
							VGnumber = 1;
							vgi[currentVGstartedAt] = 0;
							/*if(matv.get(currentVGstartedAt).getAmbiguityScheme().contains("noun")){
								vgi[currentVGstartedAt] = 100;
							}*/
							ContinueVG = false;
							isAbort = 1;
						}
					}
					else if (vgp.isCanEndToken) { 
						vgi[i] = VGnumber;
						VGnumber = 1;
						ContinueVG = false;
						continue;
					}
					/* TODO : check else case 
					 * Guess : should Abort in case of next word is an auxiliary*/
					/*else if(isVerbAux(matNext)) {	 Abort here	
					 * 	next = currentVGstartedAt + 1;	VGnumber = 1;	vgi[currentVGstartedAt] = 0; System.out.println("3. Going back to : " + next);
						ContinueVG = false;	isAbort = 1;	}*/
					else{
						vgi[i] = VGnumber;
						VGnumber = 1;
						ContinueVG = false;
						continue;
					}
				}
				/* TODO : check else case 
				 * I think : case will never apear*/
			}
		}
		return vgi;
	}

	boolean hasSuffix(StemmerResult srt) {
		boolean retval = false;
		retval = !(srt.getSuffix().isEmpty());
		return retval;
	}

	boolean isVerb(StemmerResult srt) {
		boolean retval = false;
		retval = srt.getCategory().equals("verb");
		return retval;
	}

	boolean isVerb(MAResult mar) {
		boolean retval = false;
		retval = mar.getAmbiguityScheme().contains("*verb*") || mar.getAmbiguityScheme().contains("*verb") 
			|| mar.getAmbiguityScheme().contains("verb*") || mar.getAmbiguityScheme().equals("verb")
			|| mar.getAmbiguityScheme().startsWith("verb*");
		/*for(int i=0; i< mat.getStemmedOutputs().size(); i++){
			if(isVerb(mat.getStemmedOutputs().get(i))){
				retval = true;
				break;
			}
		}*/
		return retval;
	}

	boolean isOnlyParticle(MAResult mar) {
		boolean retval = false;
		retval = mar.getAmbiguityScheme().equals("particle");
		return retval;
	}
	
	boolean isVerbAux(MAResult mar) {
		boolean retval = false;
		retval = mar.getAmbiguityScheme().contains("verb_aux");
		return retval;
	}

	boolean isVerbAux(StemmerResult srt) {
		boolean retval = false;
		retval = srt.getCategory().equals("verb_aux");
		return retval;
	}
	
	boolean isOnlyVM(MAResult mar) {
		boolean retval = false;
		retval = mar.getAmbiguityScheme().equals("verb");
		return retval;
	}

	boolean isOnlyVAux(MAResult mar) {
		boolean retval = false;
		retval = mar.getAmbiguityScheme().equals("verb_aux");
		return retval;
	}
	
	boolean isOnlyVerb(MAResult mar) {
		boolean retval = false;
		retval = isOnlyVM(mar) || isOnlyVAux(mar) || mar.getAmbiguityScheme().equals("verb*verb_aux") || mar.getAmbiguityScheme().equals("verb_aux*verb");
		return retval;
	}
	
	boolean agree(StemmerResult srt, MAResult mar) {
		boolean retval = false;
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getSuffix().contentEquals(
					srt.getSuffix())) {
				retval = true;
				break;
			}
		}
		return retval;
	}
	
	Vector<String> getAuxRoots(MAResult mar){
		Vector <String> retval= new Vector<String>();
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getCategory().equals("verb_aux")) {
				retval.add(mar.getMorphOutputs().get(i).getStemmerResult().getRoot());
				//break;
			}
		}
		return retval;
	}
	
	Vector <String> getVMRoots(MAResult mar){
		Vector <String> retval= new Vector<String>();
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getCategory().equals("verb")) {
				retval.add(mar.getMorphOutputs().get(i).getStemmerResult().getRoot());
				//break;
			}
		}
		return retval;
	}
	
	Vector <String> getAuxSuffixes(MAResult mar){
		Vector <String> retval= new Vector<String>();
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getCategory().equals("verb_aux")) {
				if(!mar.getMorphOutputs().get(i).getStemmerResult().getSuffix().contentEquals("Null")){
					retval.add(mar.getMorphOutputs().get(i).getStemmerResult().getSuffix());
				}
				else{
					retval.add("");
				}				
			}
		}
		return retval;
	}
	
	Vector<String> getVMSuffixes(MAResult mar){
		Vector <String> retval= new Vector<String>();
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getCategory().equals("verb")) {
				if(!mar.getMorphOutputs().get(i).getStemmerResult().getSuffix().contentEquals("Null")){
					retval.add(mar.getMorphOutputs().get(i).getStemmerResult().getSuffix());
					//break;
				}	
			}
		}
		return retval;
	}
	
	String getAuxRoot(MAResult mar){
		String retval= "";
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getCategory().equals("verb_aux")) {
				retval = mar.getMorphOutputs().get(i).getStemmerResult().getRoot();
				break;
			}
		}
		return retval;
	}
	
	String getVMRoot(MAResult mar){
		String retval= "";
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getCategory().equals("verb")) {
				retval = mar.getMorphOutputs().get(i).getStemmerResult().getRoot();
				break;
			}
		}
		return retval;
	}
	
	String getAuxSuffix(MAResult mar){
		String retval= "";
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getCategory().equals("verb_aux")) {
				if(!mar.getMorphOutputs().get(i).getStemmerResult().getSuffix().contentEquals("Null")){
					retval = mar.getMorphOutputs().get(i).getStemmerResult().getSuffix();
					break;
				}
			}
		}
		return retval;
	}
	
	String getVMSuffix(MAResult mar){
		String retval= "";
		for (int i = 0; i < mar.getMorphOutputs().size(); i++) {
			if (mar.getMorphOutputs().get(i).getStemmerResult().getCategory().equals("verb")) {
				if(!mar.getMorphOutputs().get(i).getStemmerResult().getSuffix().contentEquals("Null")){
					retval = mar.getMorphOutputs().get(i).getStemmerResult().getSuffix();
					break;
				}	
			}
		}
		return retval;
	}
	
	/*boolean applyRule(String rule, String param, String	replace){
		boolean retval = false;
		
		return retval;
	}
	
	public boolean isCoVerb(MorphologicallyAnalyzedToken mat, MorphologicallyAnalyzedToken matNext){
		boolean retVal = false;
		if(vgr.coVerbsHash.containsKey(mat.getToken())){
			
		}
		return retVal;
	}*/

	public static void main(String args[]) {
		ConfigReader.read(args[0]);
		NewStemmer dmstemmer = new NewStemmer();
		VerbGroup9 vb = new VerbGroup9();
		Vector<MAResult> maResult = new Vector<MAResult>();
		String sentence = "गिरफ़्तार किया गया है";//सुलझा लेना चाहिए था";//संतोष करना पड़";// पड़";//ले जाया जा सकता था";//कर दिया गया है";//संतोष करना पड़";//पड़ा";//पड़ा";//संपर्क बनाया हुआ है";//घायल हुए थे";//योजना बना रहे थे";//आत्मदाह कर लिया";// टीम का साथ दे सकेंगे";//निशाना बनाता आया है";//हमला करने की योजना बना रहे थे";//आत्मदाह कर लिया .";//गिरफ़्तार किया गया है";
		//निर्मला का यह पन्द्रहवां साल था";//पुलिस का होना था";//राम कर चुका देगा";//होगा";// राम खाना खाता है ";
		String tokens[] = sentence.split(" ");
		List l = Arrays.asList(tokens);
		Vector<String> tokenList = new Vector<String>(l);
		for(int i=0;i<tokenList.size();i++)
		{
			if(tokenList.get(i)==null || (tokenList.get(i).toString().contentEquals("")))
				continue;
			MAResult mar = dmstemmer.stem(tokenList.get(i));
			mar.printDetail();
			maResult.add(mar);
		}
		
		int vg[] = new int[maResult.size()];
		vg = vb.identifyVerbGroups1(maResult);
		for (int i = 0; i < vg.length; i++) {
			System.out.println(maResult.get(i).getToken() + "-" + vg[i] + "\t");
		}
		
		/*boolean is = vgr.mustEndWords.contains("");
		if(is){
			System.out.println("Working..");
		}
		else{
			System.out.println("Sorry..");
		}
		for(int i=0; i< vgr.mustEndWords.size(); i++){
			System.out.println(vgr.mustEndWords.get(i));
		}*/
	}
}

