import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;


public class DRBLTranslator {
	
	ArrayList<String> lines;
	ArrayList<Boolean> IsTranslated;
	ArrayList<Boolean> HasBeginQuote;
	ArrayList<Boolean> HasEndQuote;
	ArrayList<String> lstrs;
	ArrayList<String> rstrs;
	ArrayList<String> quotes;
	ArrayList<String> tstrs;
	ArrayList<String> ends;
	String output;
	
	public DRBLTranslator() {
		lines = new ArrayList<String>();
		IsTranslated = new ArrayList<Boolean>();
		HasBeginQuote = new ArrayList<Boolean>();
		HasEndQuote = new ArrayList<Boolean>();
		lstrs = new ArrayList<String>();
		rstrs = new ArrayList<String>();
		quotes = new ArrayList<String>();
		tstrs = new ArrayList<String>();
		ends = new ArrayList<String>();
		output = "";
	}

	public void reset() {
		lines.clear();
		IsTranslated.clear();
		HasBeginQuote.clear();
		HasEndQuote.clear();
		lstrs.clear();
		rstrs.clear();
		quotes.clear();
		tstrs.clear();
		ends.clear();
		output = "";
	}
	
	private static String googleTranslate(String langpair, String text) {

		/***********************************************************************
		 * commons-logging commons-codec
		 */
		HttpClient client = new HttpClient();

		/***********************************************************
		 */
		client.getHostConfiguration().setHost("www.google.com", 80, "http");

		/***********************************************************
		 */
		PostMethod post = new PostMethod("/translate_t");
		// post.addParameter(new NameValuePair("url", url));
		post.addParameter("langpair", langpair);
		post.addParameter("text", text);

		String s = null;
		try {
			/***********************************************************
			 */
			client.executeMethod(post);

			/***********************************************************
			 */
			InputStream in = post.getResponseBodyAsStream();
			BufferedReader buf = new BufferedReader(new InputStreamReader(in));
			Pattern p = Pattern
					.compile(".*id=\"*result_box\"*\\ *dir=\"*ltr\"*\\>");
			Matcher m = null;

			String line;
			while ((line = buf.readLine()) != null) {
				m = p.matcher(line);
				// System.out.println(line);
				if (m.find()) {
					s = line.substring(m.end());
					line = s;
					p = Pattern.compile("\\<\\ */\\ *div\\ *\\>");
					m = p.matcher(line);
					if (m.find()) {
						s = line.substring(0, m.start());
					}
					break;
				}
			}

			// s = GetTranslation.instostr(in);
		} catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return s;
	}

	public static String instostr(InputStream in) throws IOException {
		StringBuffer out = new StringBuffer();
		byte[] b = new byte[4096];
		for (int n; (n = in.read(b)) != -1;) {
			out.append(new String(b, 0, n));
		}
		return out.toString();
	}
    		
	public void dump() {
		for (int i=0; i<lines.size(); i++) {
			System.out.println("======== Line "+i+" ========");
			System.out.println(lines.get(i));
			System.out.println(IsTranslated.get(i));
			System.out.println(HasBeginQuote.get(i));
			System.out.println(HasEndQuote.get(i));
			System.out.println(lstrs.get(i));
			System.out.println(rstrs.get(i));
			System.out.println(tstrs.get(i));
			System.out.println(quotes.get(i));
			System.out.println(ends.get(i));
			System.out.println("======== Line "+i+" ========");
			System.out.println();
		}
	}
	
	public String toConfiguration() {
		output="";
		for (int i=0; i<lines.size(); i++) {
			
			if (IsTranslated.get(i)) {
				//strlines += lstrs.get(i) + "=" + quotes.get(i) + tstrs.get(i) + quotes.get(i);
				output += lstrs.get(i);
				if (HasBeginQuote.get(i)) {
					output += "=" + quotes.get(i);
				}
				output += tstrs.get(i);
				if (HasEndQuote.get(i)) {
					output += quotes.get(i);
				}
				output += ends.get(i);
				output += "\n";
			} else {
				output += lines.get(i) + "\n";
			}						
		}			
		return output;
	}

	public String getConfiguration() {
		return output;
	}
	public void loadFile(String filepath) {
		reset();
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(filepath));			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}		
		
		int count = 0, index = 0;
		String line = null, lstr = null, rstr = null;
		Boolean hasEndQuote;
		try {			
			while ((line = reader.readLine()) != null) {
				line = line.trim();
				lines.add(line);
				if (line.contains("=")) {                    
					count++;
					index = line.indexOf("=");
					lstr = line.substring(0, index);
					rstr = line.substring(index + 2, line.length()-1);
					HasBeginQuote.add(true);
					if (line.charAt(index+1)!=line.charAt(line.length()-1)) {
						
						if (line.charAt(index+1)==line.charAt(line.length()-2)) {
							ends.add(String.valueOf(line.charAt(line.length()-1)));
							rstr = line.substring(index + 2, line.length()-2);
							HasEndQuote.add(true);
						} else {
							ends.add("");
							HasEndQuote.add(false);
						}
					} else {
						HasEndQuote.add(true);
						ends.add("");
					}
					lstrs.add(lstr);
					rstrs.add(rstr);
					IsTranslated.add(true);
					quotes.add(String.valueOf(line.charAt(index+1)));
				} else if (line.startsWith("#") || line.equals("")){
					IsTranslated.add(false);
					lstrs.add("");
					rstrs.add("");
					quotes.add("");
					HasBeginQuote.add(false);
					HasEndQuote.add(false);
					ends.add("");
				} else {
					hasEndQuote=false;
					IsTranslated.add(true);
					lstrs.add("");
					int lidx=0, ridx=0;
					char quote=' ';
					if (line.startsWith("'") || line.startsWith("\"")) {
						HasBeginQuote.add(true);
						lidx=1;
					} else {
						HasBeginQuote.add(false);
						lidx=0;
					}
					if (line.endsWith("'") || line.endsWith("\"")) {
						HasEndQuote.add(true);
						hasEndQuote=true;
						ridx=line.length()-1;
					} else if (line.charAt(line.length()-2)=='\'' || line.charAt(line.length()-2)=='\"'){
						HasEndQuote.add(true);
						hasEndQuote=true;
						ridx=line.length()-2;
					} else {
						HasEndQuote.add(false);
						ridx=line.length();
					}
					if (hasEndQuote) {
						if (line.endsWith("'") || line.endsWith("\"")) {
					    	quote = line.charAt(line.length()-1);
						    quotes.add(String.valueOf(quote));
						} else {
					    	quote = line.charAt(line.length()-2);
						    quotes.add(String.valueOf(quote));							
						}    
					} else {
						quote = line.charAt(0);
						quotes.add(String.valueOf(quote));
					}
					
					if (hasEndQuote) { 
						  if (quote!=line.charAt(line.length()-1)) {
							  ends.add(String.valueOf(line.charAt(line.length()-1)));
						  } else
							  ends.add("");
					} else
						ends.add("");
					rstrs.add(line.substring(lidx,ridx));					
				}
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}		
	}
	
	public void translate(String langpair) {								
		String str = "", tstr="";				
		for (int i=0; i<rstrs.size(); i++){
			str += rstrs.get(i) + "\n";			
			
			if (i==0 && rstrs.size()>1)
				tstrs.add("");
			if ((i!=0 || (i==0 && rstrs.size()==1)) && (((i%300)==0) || i==(rstrs.size()-1)) ) { 				
				//System.out.println("i="+i);
				//System.out.println("lstr="+lstrs.get(i));
			    tstr = DRBLTranslator.googleTranslate(langpair, str).trim()
			                               .replaceAll("\\s*&quot;\\s*", "\"")
			                               .replaceAll("\\s*&gt;\\s*", ">")
			                               .replaceAll("\\s*&#39;\\s*", "'");

			    str = "";					
			    tstrs.addAll(Arrays.asList(tstr.split("\\s*<br>\\s*")));
			    //System.out.println("tstr="+tstrs.get(i));			    
			    try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {					
					e.printStackTrace();
				}
			}
		}
	}
	
	public void toFile(String out) {
		
		try {			
			BufferedWriter writer = new BufferedWriter(new FileWriter(out));								
			writer.write(getConfiguration());
			writer.flush();
			writer.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}		
	
	}

	public void srcToFile(String langpair, String in, String out) {
		loadFile(in);
		translate(langpair);
		toConfiguration();
		toFile(out);
	}
	public static void main(String[] args) throws HttpException, IOException {

		if (null == args || args.length < 3) {
			System.out
					.println("Usage: java DRBLTranslator (language_pair) (source_file) (target_file)");
			System.out
					.println("Example: java DRBLTranslator \"en|zh-TW\" \"en_US\" \"zh_TW\"");
			System.exit(1);
		}
				
		DRBLTranslator trans = new DRBLTranslator();		
		trans.srcToFile(args[0], args[1], args[2]);
		//trans.srcToFile("en|zh-TW", "en_US", "zh_TW");
		System.out.println("ok");
		//System.out.println(trans.toConfiguration());
		//trans.dump();

	}
}
